From cd4b404b9c41cc5060e50519813bdf9a20df650c Mon Sep 17 00:00:00 2001 From: lsocha Date: Thu, 29 May 2025 15:22:36 +0200 Subject: [PATCH] POC --- box_sdk_gen/__init__.py | 15 + box_sdk_gen/box/__init__.py | 11 + box_sdk_gen/box/ccg_auth.py | 149 ++ box_sdk_gen/box/developer_token_auth.py | 92 ++ box_sdk_gen/box/errors.py | 78 ++ box_sdk_gen/box/jwt_auth.py | 270 ++++ box_sdk_gen/box/oauth.py | 148 ++ box_sdk_gen/box/token_storage.py | 74 + box_sdk_gen/client.py | 287 ++++ box_sdk_gen/internal/__init__.py | 9 + box_sdk_gen/internal/base_object.py | 156 +++ box_sdk_gen/internal/errors.py | 7 + box_sdk_gen/internal/logging.py | 15 + box_sdk_gen/internal/null_value.py | 5 + box_sdk_gen/internal/utils.py | 459 +++++++ box_sdk_gen/managers/__init__.py | 147 ++ box_sdk_gen/managers/ai.py | 285 ++++ box_sdk_gen/managers/ai_studio.py | 168 +++ box_sdk_gen/managers/app_item_associations.py | 127 ++ box_sdk_gen/managers/authorization.py | 285 ++++ box_sdk_gen/managers/avatars.py | 92 ++ box_sdk_gen/managers/chunked_uploads.py | 530 +++++++ box_sdk_gen/managers/classifications.py | 424 ++++++ .../collaboration_allowlist_entries.py | 126 ++ .../collaboration_allowlist_exempt_targets.py | 128 ++ box_sdk_gen/managers/collections.py | 132 ++ box_sdk_gen/managers/comments.py | 221 +++ box_sdk_gen/managers/device_pinners.py | 107 ++ box_sdk_gen/managers/docgen.py | 159 +++ box_sdk_gen/managers/docgen_template.py | 175 +++ box_sdk_gen/managers/downloads.py | 169 +++ box_sdk_gen/managers/email_aliases.py | 101 ++ box_sdk_gen/managers/events.py | 333 +++++ box_sdk_gen/managers/file_classifications.py | 207 +++ box_sdk_gen/managers/file_metadata.py | 258 ++++ box_sdk_gen/managers/file_requests.py | 261 ++++ .../managers/file_version_legal_holds.py | 123 ++ .../managers/file_version_retentions.py | 120 ++ box_sdk_gen/managers/file_versions.py | 276 ++++ box_sdk_gen/managers/file_watermarks.py | 123 ++ box_sdk_gen/managers/files.py | 537 ++++++++ .../managers/folder_classifications.py | 219 +++ box_sdk_gen/managers/folder_locks.py | 147 ++ box_sdk_gen/managers/folder_metadata.py | 285 ++++ box_sdk_gen/managers/folder_watermarks.py | 132 ++ box_sdk_gen/managers/folders.py | 694 ++++++++++ box_sdk_gen/managers/groups.py | 302 ++++ box_sdk_gen/managers/integration_mappings.py | 268 ++++ box_sdk_gen/managers/invites.py | 134 ++ box_sdk_gen/managers/legal_hold_policies.py | 187 +++ .../managers/legal_hold_policy_assignments.py | 242 ++++ box_sdk_gen/managers/list_collaborations.py | 201 +++ box_sdk_gen/managers/memberships.py | 277 ++++ .../managers/metadata_cascade_policies.py | 199 +++ box_sdk_gen/managers/metadata_templates.py | 369 +++++ box_sdk_gen/managers/recent_items.py | 77 ++ box_sdk_gen/managers/retention_policies.py | 276 ++++ .../managers/retention_policy_assignments.py | 215 +++ box_sdk_gen/managers/search.py | 438 ++++++ box_sdk_gen/managers/session_termination.py | 88 ++ .../managers/shared_links_app_items.py | 59 + box_sdk_gen/managers/shared_links_files.py | 362 +++++ box_sdk_gen/managers/shared_links_folders.py | 363 +++++ .../managers/shared_links_web_links.py | 325 +++++ .../shield_information_barrier_reports.py | 95 ++ ...eld_information_barrier_segment_members.py | 149 ++ ...nformation_barrier_segment_restrictions.py | 170 +++ .../shield_information_barrier_segments.py | 141 ++ .../managers/shield_information_barriers.py | 122 ++ box_sdk_gen/managers/sign_requests.py | 193 +++ box_sdk_gen/managers/sign_templates.py | 75 + box_sdk_gen/managers/skills.py | 254 ++++ box_sdk_gen/managers/storage_policies.py | 87 ++ .../managers/storage_policy_assignments.py | 201 +++ box_sdk_gen/managers/task_assignments.py | 178 +++ box_sdk_gen/managers/tasks.py | 205 +++ .../terms_of_service_user_statuses.py | 137 ++ box_sdk_gen/managers/terms_of_services.py | 138 ++ box_sdk_gen/managers/transfer.py | 156 +++ box_sdk_gen/managers/trashed_files.py | 175 +++ box_sdk_gen/managers/trashed_folders.py | 199 +++ box_sdk_gen/managers/trashed_items.py | 126 ++ box_sdk_gen/managers/trashed_web_links.py | 133 ++ box_sdk_gen/managers/uploads.py | 357 +++++ box_sdk_gen/managers/user_collaborations.py | 305 +++++ box_sdk_gen/managers/users.py | 465 +++++++ box_sdk_gen/managers/web_links.py | 200 +++ box_sdk_gen/managers/webhooks.py | 302 ++++ box_sdk_gen/managers/workflows.py | 170 +++ box_sdk_gen/managers/zip_downloads.py | 245 ++++ box_sdk_gen/networking/__init__.py | 19 + box_sdk_gen/networking/auth.py | 28 + box_sdk_gen/networking/base_urls.py | 14 + box_sdk_gen/networking/box_network_client.py | 369 +++++ box_sdk_gen/networking/fetch_options.py | 87 ++ box_sdk_gen/networking/fetch_response.py | 27 + box_sdk_gen/networking/network.py | 154 +++ box_sdk_gen/networking/network_client.py | 12 + box_sdk_gen/networking/proxy_config.py | 7 + box_sdk_gen/networking/retries.py | 49 + box_sdk_gen/networking/version.py | 1 + box_sdk_gen/parameters/__init__.py | 1 + box_sdk_gen/parameters/v2025_r0/__init__.py | 1 + .../v2025_r0/box_version_header_v2025_r0.py | 6 + box_sdk_gen/schemas/__init__.py | 515 +++++++ box_sdk_gen/schemas/access_token.py | 45 + .../schemas/ai_agent_allowed_entity.py | 9 + box_sdk_gen/schemas/ai_agent_ask.py | 30 + .../schemas/ai_agent_basic_gen_tool.py | 35 + .../schemas/ai_agent_basic_text_tool.py | 25 + .../schemas/ai_agent_basic_text_tool_base.py | 20 + .../ai_agent_basic_text_tool_text_gen.py | 27 + box_sdk_gen/schemas/ai_agent_extract.py | 27 + .../schemas/ai_agent_extract_structured.py | 27 + box_sdk_gen/schemas/ai_agent_info.py | 34 + .../schemas/ai_agent_long_text_tool.py | 50 + .../ai_agent_long_text_tool_text_gen.py | 52 + box_sdk_gen/schemas/ai_agent_reference.py | 23 + box_sdk_gen/schemas/ai_agent_text_gen.py | 23 + box_sdk_gen/schemas/ai_ask.py | 45 + box_sdk_gen/schemas/ai_citation.py | 29 + box_sdk_gen/schemas/ai_dialogue_history.py | 22 + box_sdk_gen/schemas/ai_extract.py | 28 + box_sdk_gen/schemas/ai_extract_response.py | 7 + box_sdk_gen/schemas/ai_extract_structured.py | 96 ++ .../schemas/ai_extract_structured_response.py | 25 + box_sdk_gen/schemas/ai_item_ask.py | 27 + box_sdk_gen/schemas/ai_item_base.py | 26 + box_sdk_gen/schemas/ai_llm_endpoint_params.py | 13 + .../schemas/ai_llm_endpoint_params_aws.py | 31 + .../schemas/ai_llm_endpoint_params_google.py | 32 + .../schemas/ai_llm_endpoint_params_ibm.py | 36 + .../schemas/ai_llm_endpoint_params_open_ai.py | 41 + .../schemas/ai_multiple_agent_response.py | 29 + box_sdk_gen/schemas/ai_response.py | 25 + box_sdk_gen/schemas/ai_response_full.py | 28 + .../schemas/ai_single_agent_response.py | 58 + .../schemas/ai_single_agent_response_full.py | 52 + box_sdk_gen/schemas/ai_studio_agent_ask.py | 37 + .../schemas/ai_studio_agent_ask_response.py | 37 + .../schemas/ai_studio_agent_basic_gen_tool.py | 39 + ...ai_studio_agent_basic_gen_tool_response.py | 45 + .../ai_studio_agent_basic_text_tool.py | 28 + ...i_studio_agent_basic_text_tool_response.py | 34 + .../schemas/ai_studio_agent_extract.py | 35 + .../ai_studio_agent_extract_response.py | 35 + .../schemas/ai_studio_agent_long_text_tool.py | 32 + ...ai_studio_agent_long_text_tool_response.py | 38 + .../schemas/ai_studio_agent_text_gen.py | 32 + .../ai_studio_agent_text_gen_response.py | 32 + box_sdk_gen/schemas/ai_text_gen.py | 56 + box_sdk_gen/schemas/app_item.py | 24 + box_sdk_gen/schemas/app_item_association.py | 33 + box_sdk_gen/schemas/app_item_associations.py | 27 + box_sdk_gen/schemas/app_item_event_source.py | 33 + box_sdk_gen/schemas/classification.py | 53 + .../schemas/classification_template.py | 157 +++ box_sdk_gen/schemas/client_error.py | 62 + box_sdk_gen/schemas/collaboration.py | 143 ++ .../collaboration_allowlist_entries.py | 29 + .../schemas/collaboration_allowlist_entry.py | 59 + .../collaboration_allowlist_exempt_target.py | 54 + .../collaboration_allowlist_exempt_targets.py | 31 + box_sdk_gen/schemas/collaborations.py | 29 + .../collaborations_offset_paginated.py | 38 + box_sdk_gen/schemas/collaborator_variable.py | 50 + box_sdk_gen/schemas/collection.py | 37 + box_sdk_gen/schemas/collections.py | 62 + box_sdk_gen/schemas/comment.py | 50 + box_sdk_gen/schemas/comment_base.py | 23 + box_sdk_gen/schemas/comment_full.py | 40 + box_sdk_gen/schemas/comments.py | 62 + .../schemas/completion_rule_variable.py | 39 + box_sdk_gen/schemas/conflict_error.py | 49 + box_sdk_gen/schemas/create_ai_agent.py | 46 + box_sdk_gen/schemas/device_pinner.py | 29 + box_sdk_gen/schemas/device_pinners.py | 50 + box_sdk_gen/schemas/email_alias.py | 29 + box_sdk_gen/schemas/email_aliases.py | 21 + box_sdk_gen/schemas/enterprise_base.py | 23 + box_sdk_gen/schemas/event.py | 205 +++ box_sdk_gen/schemas/event_source.py | 52 + box_sdk_gen/schemas/events.py | 27 + box_sdk_gen/schemas/file.py | 219 +++ box_sdk_gen/schemas/file_base.py | 34 + box_sdk_gen/schemas/file_conflict.py | 36 + box_sdk_gen/schemas/file_full.py | 416 ++++++ box_sdk_gen/schemas/file_mini.py | 42 + box_sdk_gen/schemas/file_or_folder_scope.py | 39 + box_sdk_gen/schemas/file_request.py | 106 ++ .../schemas/file_request_copy_request.py | 82 ++ .../schemas/file_request_update_request.py | 68 + box_sdk_gen/schemas/file_version.py | 50 + box_sdk_gen/schemas/file_version_base.py | 21 + box_sdk_gen/schemas/file_version_full.py | 44 + .../schemas/file_version_legal_hold.py | 42 + .../schemas/file_version_legal_holds.py | 29 + box_sdk_gen/schemas/file_version_mini.py | 24 + box_sdk_gen/schemas/file_version_retention.py | 42 + .../schemas/file_version_retentions.py | 29 + box_sdk_gen/schemas/file_versions.py | 62 + box_sdk_gen/schemas/files.py | 21 + box_sdk_gen/schemas/files_on_hold.py | 29 + box_sdk_gen/schemas/files_under_retention.py | 29 + box_sdk_gen/schemas/folder.py | 253 ++++ box_sdk_gen/schemas/folder_base.py | 34 + box_sdk_gen/schemas/folder_full.py | 218 +++ box_sdk_gen/schemas/folder_lock.py | 49 + box_sdk_gen/schemas/folder_locks.py | 26 + box_sdk_gen/schemas/folder_mini.py | 31 + box_sdk_gen/schemas/folder_reference.py | 21 + box_sdk_gen/schemas/generic_source.py | 1 + box_sdk_gen/schemas/group.py | 33 + box_sdk_gen/schemas/group_base.py | 21 + box_sdk_gen/schemas/group_full.py | 100 ++ box_sdk_gen/schemas/group_membership.py | 44 + box_sdk_gen/schemas/group_memberships.py | 62 + box_sdk_gen/schemas/group_mini.py | 29 + box_sdk_gen/schemas/groups.py | 62 + box_sdk_gen/schemas/integration_mapping.py | 69 + .../schemas/integration_mapping_base.py | 23 + .../integration_mapping_box_item_slack.py | 21 + .../integration_mapping_partner_item_slack.py | 29 + .../integration_mapping_partner_item_teams.py | 25 + ...pping_partner_item_teams_create_request.py | 28 + ...ntegration_mapping_slack_create_request.py | 18 + .../integration_mapping_slack_options.py | 18 + .../schemas/integration_mapping_teams.py | 53 + ...ntegration_mapping_teams_create_request.py | 13 + box_sdk_gen/schemas/integration_mappings.py | 26 + .../schemas/integration_mappings_teams.py | 18 + box_sdk_gen/schemas/invite.py | 60 + box_sdk_gen/schemas/items.py | 74 + box_sdk_gen/schemas/items_offset_paginated.py | 68 + box_sdk_gen/schemas/keyword_skill_card.py | 104 ++ box_sdk_gen/schemas/legal_hold_policies.py | 29 + box_sdk_gen/schemas/legal_hold_policy.py | 93 ++ .../schemas/legal_hold_policy_assignment.py | 45 + .../legal_hold_policy_assignment_base.py | 23 + .../schemas/legal_hold_policy_assignments.py | 30 + box_sdk_gen/schemas/legal_hold_policy_mini.py | 21 + box_sdk_gen/schemas/metadata.py | 25 + box_sdk_gen/schemas/metadata_base.py | 33 + .../schemas/metadata_cascade_policies.py | 29 + .../schemas/metadata_cascade_policy.py | 89 ++ .../metadata_field_filter_date_range.py | 25 + .../metadata_field_filter_float_range.py | 23 + box_sdk_gen/schemas/metadata_filter.py | 59 + box_sdk_gen/schemas/metadata_full.py | 48 + .../schemas/metadata_instance_value.py | 7 + box_sdk_gen/schemas/metadata_query.py | 101 ++ box_sdk_gen/schemas/metadata_query_index.py | 48 + box_sdk_gen/schemas/metadata_query_results.py | 35 + box_sdk_gen/schemas/metadata_template.py | 122 ++ box_sdk_gen/schemas/metadata_templates.py | 29 + box_sdk_gen/schemas/metadatas.py | 21 + box_sdk_gen/schemas/o_auth_2_error.py | 17 + box_sdk_gen/schemas/outcome.py | 25 + box_sdk_gen/schemas/post_o_auth_2_revoke.py | 22 + box_sdk_gen/schemas/post_o_auth_2_token.py | 114 ++ ...ost_o_auth_2_token_refresh_access_token.py | 26 + box_sdk_gen/schemas/realtime_server.py | 33 + box_sdk_gen/schemas/realtime_servers.py | 21 + box_sdk_gen/schemas/recent_item.py | 45 + box_sdk_gen/schemas/recent_items.py | 29 + box_sdk_gen/schemas/retention_policies.py | 26 + box_sdk_gen/schemas/retention_policy.py | 132 ++ .../schemas/retention_policy_assignment.py | 84 ++ .../retention_policy_assignment_base.py | 21 + .../schemas/retention_policy_assignments.py | 26 + box_sdk_gen/schemas/retention_policy_base.py | 21 + box_sdk_gen/schemas/retention_policy_mini.py | 43 + box_sdk_gen/schemas/role_variable.py | 37 + .../schemas/search_result_with_shared_link.py | 29 + box_sdk_gen/schemas/search_results.py | 47 + .../search_results_with_shared_links.py | 43 + .../schemas/session_termination_message.py | 14 + .../schemas/shield_information_barrier.py | 59 + .../shield_information_barrier_base.py | 23 + .../shield_information_barrier_reference.py | 12 + .../shield_information_barrier_report.py | 47 + .../shield_information_barrier_report_base.py | 23 + ...ield_information_barrier_report_details.py | 19 + .../shield_information_barrier_reports.py | 27 + .../shield_information_barrier_segment.py | 46 + ...ield_information_barrier_segment_member.py | 62 + ...information_barrier_segment_member_base.py | 24 + ...information_barrier_segment_member_mini.py | 21 + ...eld_information_barrier_segment_members.py | 27 + ...information_barrier_segment_restriction.py | 49 + ...mation_barrier_segment_restriction_base.py | 24 + ...mation_barrier_segment_restriction_mini.py | 64 + ...nformation_barrier_segment_restrictions.py | 27 + .../shield_information_barrier_segments.py | 27 + .../schemas/shield_information_barriers.py | 26 + box_sdk_gen/schemas/sign_request.py | 131 ++ box_sdk_gen/schemas/sign_request_base.py | 54 + .../schemas/sign_request_create_request.py | 71 + .../schemas/sign_request_create_signer.py | 80 ++ .../schemas/sign_request_prefill_tag.py | 25 + box_sdk_gen/schemas/sign_request_signer.py | 111 ++ .../schemas/sign_request_signer_input.py | 60 + box_sdk_gen/schemas/sign_requests.py | 26 + box_sdk_gen/schemas/sign_template.py | 160 +++ box_sdk_gen/schemas/sign_templates.py | 29 + box_sdk_gen/schemas/skill_cards_metadata.py | 58 + box_sdk_gen/schemas/skill_invocation.py | 182 +++ box_sdk_gen/schemas/status_skill_card.py | 116 ++ box_sdk_gen/schemas/storage_policies.py | 29 + box_sdk_gen/schemas/storage_policy.py | 20 + .../schemas/storage_policy_assignment.py | 39 + .../schemas/storage_policy_assignments.py | 29 + box_sdk_gen/schemas/storage_policy_mini.py | 21 + box_sdk_gen/schemas/task.py | 67 + box_sdk_gen/schemas/task_assignment.py | 58 + box_sdk_gen/schemas/task_assignments.py | 21 + box_sdk_gen/schemas/tasks.py | 23 + box_sdk_gen/schemas/template_signer.py | 63 + box_sdk_gen/schemas/template_signer_input.py | 110 ++ box_sdk_gen/schemas/terms_of_service.py | 67 + box_sdk_gen/schemas/terms_of_service_base.py | 21 + .../schemas/terms_of_service_user_status.py | 40 + .../schemas/terms_of_service_user_statuses.py | 21 + box_sdk_gen/schemas/terms_of_services.py | 21 + box_sdk_gen/schemas/timeline_skill_card.py | 136 ++ box_sdk_gen/schemas/tracking_code.py | 27 + box_sdk_gen/schemas/transcript_skill_card.py | 126 ++ box_sdk_gen/schemas/trash_file.py | 144 ++ box_sdk_gen/schemas/trash_file_restored.py | 120 ++ box_sdk_gen/schemas/trash_folder.py | 141 ++ box_sdk_gen/schemas/trash_folder_restored.py | 117 ++ box_sdk_gen/schemas/trash_web_link.py | 116 ++ .../schemas/trash_web_link_restored.py | 93 ++ box_sdk_gen/schemas/upload_part.py | 26 + box_sdk_gen/schemas/upload_part_mini.py | 22 + box_sdk_gen/schemas/upload_parts.py | 63 + box_sdk_gen/schemas/upload_session.py | 70 + box_sdk_gen/schemas/upload_url.py | 18 + box_sdk_gen/schemas/uploaded_part.py | 12 + box_sdk_gen/schemas/user.py | 90 ++ box_sdk_gen/schemas/user_avatar.py | 29 + box_sdk_gen/schemas/user_base.py | 21 + box_sdk_gen/schemas/user_collaborations.py | 26 + box_sdk_gen/schemas/user_full.py | 135 ++ .../schemas/user_integration_mappings.py | 23 + box_sdk_gen/schemas/user_mini.py | 23 + box_sdk_gen/schemas/users.py | 68 + box_sdk_gen/schemas/v2025_r0/__init__.py | 39 + .../schemas/v2025_r0/client_error_v2025_r0.py | 69 + .../v2025_r0/doc_gen_batch_base_v2025_r0.py | 21 + .../doc_gen_batch_create_request_v2025_r0.py | 47 + ...c_gen_document_generation_data_v2025_r0.py | 15 + .../v2025_r0/doc_gen_job_base_v2025_r0.py | 21 + .../v2025_r0/doc_gen_job_full_v2025_r0.py | 43 + .../schemas/v2025_r0/doc_gen_job_v2025_r0.py | 43 + .../v2025_r0/doc_gen_jobs_full_v2025_r0.py | 29 + .../schemas/v2025_r0/doc_gen_jobs_v2025_r0.py | 29 + .../schemas/v2025_r0/doc_gen_tag_v2025_r0.py | 30 + ...oc_gen_tags_processing_message_v2025_r0.py | 12 + .../schemas/v2025_r0/doc_gen_tags_v2025_r0.py | 29 + .../doc_gen_template_base_v2025_r0.py | 12 + ...oc_gen_template_create_request_v2025_r0.py | 10 + .../v2025_r0/doc_gen_template_v2025_r0.py | 16 + .../v2025_r0/doc_gen_templates_v2025_r0.py | 29 + .../v2025_r0/enterprise_reference_v2025_r0.py | 23 + .../v2025_r0/file_reference_v2025_r0.py | 21 + .../v2025_r0/file_version_base_v2025_r0.py | 21 + .../schemas/v2025_r0/user_base_v2025_r0.py | 21 + box_sdk_gen/schemas/watermark.py | 24 + box_sdk_gen/schemas/web_link.py | 194 +++ box_sdk_gen/schemas/web_link_base.py | 27 + box_sdk_gen/schemas/web_link_mini.py | 27 + box_sdk_gen/schemas/webhook.py | 83 ++ box_sdk_gen/schemas/webhook_invocation.py | 85 ++ box_sdk_gen/schemas/webhook_mini.py | 43 + box_sdk_gen/schemas/webhooks.py | 29 + box_sdk_gen/schemas/workflow.py | 209 +++ box_sdk_gen/schemas/workflow_full.py | 43 + box_sdk_gen/schemas/workflow_mini.py | 32 + box_sdk_gen/schemas/workflows.py | 29 + box_sdk_gen/schemas/zip_download.py | 83 ++ box_sdk_gen/schemas/zip_download_request.py | 41 + box_sdk_gen/schemas/zip_download_status.py | 39 + box_sdk_gen/serialization/__init__.py | 1 + box_sdk_gen/serialization/json.py | 62 + pytest.ini | 2 +- setup.py | 4 +- test/commons.py | 139 ++ test/test_gen/__init__.py | 0 test/test_gen/ai.py | 188 +++ test/test_gen/ai_studio.py | 64 + test/test_gen/app_item_associations.py | 45 + test/test_gen/auth.py | 239 ++++ test/test_gen/avatars.py | 39 + test/test_gen/box_network_client.py | 1219 +++++++++++++++++ test/test_gen/chunked_uploads.py | 166 +++ test/test_gen/classifications.py | 40 + test/test_gen/client.py | 130 ++ .../collaboration_allowlist_entries.py | 33 + .../collaboration_allowlist_exempt_targets.py | 34 + test/test_gen/collections.py | 36 + test/test_gen/comments.py | 56 + test/test_gen/device_pinners.py | 25 + test/test_gen/docgen.py | 77 ++ test/test_gen/docgen_template.py | 34 + test/test_gen/downloads.py | 73 + test/test_gen/email_aliases.py | 29 + test/test_gen/events.py | 78 ++ test/test_gen/file_classifications.py | 61 + test/test_gen/file_metadata.py | 98 ++ test/test_gen/file_requests.py | 34 + test/test_gen/file_version_legal_holds.py | 24 + test/test_gen/file_version_retentions.py | 72 + test/test_gen/file_versions.py | 77 ++ test/test_gen/file_watermarks.py | 36 + test/test_gen/files.py | 117 ++ test/test_gen/folder_classifications.py | 61 + test/test_gen/folder_locks.py | 36 + test/test_gen/folder_metadata.py | 96 ++ test/test_gen/folder_watermarks.py | 29 + test/test_gen/folders.py | 67 + test/test_gen/groups.py | 32 + test/test_gen/integration_mappings.py | 92 ++ test/test_gen/invites.py | 29 + test/test_gen/legal_hold_policies.py | 45 + .../test_gen/legal_hold_policy_assignments.py | 57 + test/test_gen/list_collaborations.py | 59 + test/test_gen/memberships.py | 47 + test/test_gen/metadata_cascade_policies.py | 65 + test/test_gen/metadata_templates.py | 91 ++ test/test_gen/recent_items.py | 16 + test/test_gen/retention_policies.py | 32 + test/test_gen/retention_policy_assignments.py | 69 + test/test_gen/search.py | 91 ++ test/test_gen/session_termination.py | 30 + test/test_gen/shared_links_app_items.py | 17 + test/test_gen/shared_links_files.py | 54 + test/test_gen/shared_links_folders.py | 49 + test/test_gen/shared_links_web_links.py | 53 + .../shield_information_barrier_reports.py | 38 + ...eld_information_barrier_segment_members.py | 49 + ...nformation_barrier_segment_restrictions.py | 58 + .../shield_information_barrier_segments.py | 48 + test/test_gen/shield_information_barriers.py | 33 + test/test_gen/sign_requests.py | 84 ++ test/test_gen/sign_templates.py | 27 + test/test_gen/skills.py | 53 + test/test_gen/storage_policicy_assignments.py | 57 + test/test_gen/storage_policies.py | 21 + test/test_gen/task_assignments.py | 62 + test/test_gen/tasks.py | 52 + .../terms_of_service_user_statuses.py | 41 + test/test_gen/terms_of_services.py | 26 + test/test_gen/transfer.py | 22 + test/test_gen/trashed_files.py | 49 + test/test_gen/trashed_folders.py | 34 + test/test_gen/trashed_items.py | 17 + test/test_gen/trashed_web_links.py | 42 + test/test_gen/uploads.py | 62 + test/test_gen/user_collaborations.py | 92 ++ test/test_gen/users.py | 35 + test/test_gen/webhooks.py | 98 ++ test/test_gen/weblinks.py | 41 + test/test_gen/workflows.py | 59 + test/test_gen/zip_downloads.py | 65 + tox.ini | 12 +- 466 files changed, 39020 insertions(+), 4 deletions(-) create mode 100644 box_sdk_gen/__init__.py create mode 100644 box_sdk_gen/box/__init__.py create mode 100644 box_sdk_gen/box/ccg_auth.py create mode 100644 box_sdk_gen/box/developer_token_auth.py create mode 100644 box_sdk_gen/box/errors.py create mode 100644 box_sdk_gen/box/jwt_auth.py create mode 100644 box_sdk_gen/box/oauth.py create mode 100644 box_sdk_gen/box/token_storage.py create mode 100644 box_sdk_gen/client.py create mode 100644 box_sdk_gen/internal/__init__.py create mode 100644 box_sdk_gen/internal/base_object.py create mode 100644 box_sdk_gen/internal/errors.py create mode 100644 box_sdk_gen/internal/logging.py create mode 100644 box_sdk_gen/internal/null_value.py create mode 100644 box_sdk_gen/internal/utils.py create mode 100644 box_sdk_gen/managers/__init__.py create mode 100644 box_sdk_gen/managers/ai.py create mode 100644 box_sdk_gen/managers/ai_studio.py create mode 100644 box_sdk_gen/managers/app_item_associations.py create mode 100644 box_sdk_gen/managers/authorization.py create mode 100644 box_sdk_gen/managers/avatars.py create mode 100644 box_sdk_gen/managers/chunked_uploads.py create mode 100644 box_sdk_gen/managers/classifications.py create mode 100644 box_sdk_gen/managers/collaboration_allowlist_entries.py create mode 100644 box_sdk_gen/managers/collaboration_allowlist_exempt_targets.py create mode 100644 box_sdk_gen/managers/collections.py create mode 100644 box_sdk_gen/managers/comments.py create mode 100644 box_sdk_gen/managers/device_pinners.py create mode 100644 box_sdk_gen/managers/docgen.py create mode 100644 box_sdk_gen/managers/docgen_template.py create mode 100644 box_sdk_gen/managers/downloads.py create mode 100644 box_sdk_gen/managers/email_aliases.py create mode 100644 box_sdk_gen/managers/events.py create mode 100644 box_sdk_gen/managers/file_classifications.py create mode 100644 box_sdk_gen/managers/file_metadata.py create mode 100644 box_sdk_gen/managers/file_requests.py create mode 100644 box_sdk_gen/managers/file_version_legal_holds.py create mode 100644 box_sdk_gen/managers/file_version_retentions.py create mode 100644 box_sdk_gen/managers/file_versions.py create mode 100644 box_sdk_gen/managers/file_watermarks.py create mode 100644 box_sdk_gen/managers/files.py create mode 100644 box_sdk_gen/managers/folder_classifications.py create mode 100644 box_sdk_gen/managers/folder_locks.py create mode 100644 box_sdk_gen/managers/folder_metadata.py create mode 100644 box_sdk_gen/managers/folder_watermarks.py create mode 100644 box_sdk_gen/managers/folders.py create mode 100644 box_sdk_gen/managers/groups.py create mode 100644 box_sdk_gen/managers/integration_mappings.py create mode 100644 box_sdk_gen/managers/invites.py create mode 100644 box_sdk_gen/managers/legal_hold_policies.py create mode 100644 box_sdk_gen/managers/legal_hold_policy_assignments.py create mode 100644 box_sdk_gen/managers/list_collaborations.py create mode 100644 box_sdk_gen/managers/memberships.py create mode 100644 box_sdk_gen/managers/metadata_cascade_policies.py create mode 100644 box_sdk_gen/managers/metadata_templates.py create mode 100644 box_sdk_gen/managers/recent_items.py create mode 100644 box_sdk_gen/managers/retention_policies.py create mode 100644 box_sdk_gen/managers/retention_policy_assignments.py create mode 100644 box_sdk_gen/managers/search.py create mode 100644 box_sdk_gen/managers/session_termination.py create mode 100644 box_sdk_gen/managers/shared_links_app_items.py create mode 100644 box_sdk_gen/managers/shared_links_files.py create mode 100644 box_sdk_gen/managers/shared_links_folders.py create mode 100644 box_sdk_gen/managers/shared_links_web_links.py create mode 100644 box_sdk_gen/managers/shield_information_barrier_reports.py create mode 100644 box_sdk_gen/managers/shield_information_barrier_segment_members.py create mode 100644 box_sdk_gen/managers/shield_information_barrier_segment_restrictions.py create mode 100644 box_sdk_gen/managers/shield_information_barrier_segments.py create mode 100644 box_sdk_gen/managers/shield_information_barriers.py create mode 100644 box_sdk_gen/managers/sign_requests.py create mode 100644 box_sdk_gen/managers/sign_templates.py create mode 100644 box_sdk_gen/managers/skills.py create mode 100644 box_sdk_gen/managers/storage_policies.py create mode 100644 box_sdk_gen/managers/storage_policy_assignments.py create mode 100644 box_sdk_gen/managers/task_assignments.py create mode 100644 box_sdk_gen/managers/tasks.py create mode 100644 box_sdk_gen/managers/terms_of_service_user_statuses.py create mode 100644 box_sdk_gen/managers/terms_of_services.py create mode 100644 box_sdk_gen/managers/transfer.py create mode 100644 box_sdk_gen/managers/trashed_files.py create mode 100644 box_sdk_gen/managers/trashed_folders.py create mode 100644 box_sdk_gen/managers/trashed_items.py create mode 100644 box_sdk_gen/managers/trashed_web_links.py create mode 100644 box_sdk_gen/managers/uploads.py create mode 100644 box_sdk_gen/managers/user_collaborations.py create mode 100644 box_sdk_gen/managers/users.py create mode 100644 box_sdk_gen/managers/web_links.py create mode 100644 box_sdk_gen/managers/webhooks.py create mode 100644 box_sdk_gen/managers/workflows.py create mode 100644 box_sdk_gen/managers/zip_downloads.py create mode 100644 box_sdk_gen/networking/__init__.py create mode 100644 box_sdk_gen/networking/auth.py create mode 100644 box_sdk_gen/networking/base_urls.py create mode 100644 box_sdk_gen/networking/box_network_client.py create mode 100644 box_sdk_gen/networking/fetch_options.py create mode 100644 box_sdk_gen/networking/fetch_response.py create mode 100644 box_sdk_gen/networking/network.py create mode 100644 box_sdk_gen/networking/network_client.py create mode 100644 box_sdk_gen/networking/proxy_config.py create mode 100644 box_sdk_gen/networking/retries.py create mode 100644 box_sdk_gen/networking/version.py create mode 100644 box_sdk_gen/parameters/__init__.py create mode 100644 box_sdk_gen/parameters/v2025_r0/__init__.py create mode 100644 box_sdk_gen/parameters/v2025_r0/box_version_header_v2025_r0.py create mode 100644 box_sdk_gen/schemas/__init__.py create mode 100644 box_sdk_gen/schemas/access_token.py create mode 100644 box_sdk_gen/schemas/ai_agent_allowed_entity.py create mode 100644 box_sdk_gen/schemas/ai_agent_ask.py create mode 100644 box_sdk_gen/schemas/ai_agent_basic_gen_tool.py create mode 100644 box_sdk_gen/schemas/ai_agent_basic_text_tool.py create mode 100644 box_sdk_gen/schemas/ai_agent_basic_text_tool_base.py create mode 100644 box_sdk_gen/schemas/ai_agent_basic_text_tool_text_gen.py create mode 100644 box_sdk_gen/schemas/ai_agent_extract.py create mode 100644 box_sdk_gen/schemas/ai_agent_extract_structured.py create mode 100644 box_sdk_gen/schemas/ai_agent_info.py create mode 100644 box_sdk_gen/schemas/ai_agent_long_text_tool.py create mode 100644 box_sdk_gen/schemas/ai_agent_long_text_tool_text_gen.py create mode 100644 box_sdk_gen/schemas/ai_agent_reference.py create mode 100644 box_sdk_gen/schemas/ai_agent_text_gen.py create mode 100644 box_sdk_gen/schemas/ai_ask.py create mode 100644 box_sdk_gen/schemas/ai_citation.py create mode 100644 box_sdk_gen/schemas/ai_dialogue_history.py create mode 100644 box_sdk_gen/schemas/ai_extract.py create mode 100644 box_sdk_gen/schemas/ai_extract_response.py create mode 100644 box_sdk_gen/schemas/ai_extract_structured.py create mode 100644 box_sdk_gen/schemas/ai_extract_structured_response.py create mode 100644 box_sdk_gen/schemas/ai_item_ask.py create mode 100644 box_sdk_gen/schemas/ai_item_base.py create mode 100644 box_sdk_gen/schemas/ai_llm_endpoint_params.py create mode 100644 box_sdk_gen/schemas/ai_llm_endpoint_params_aws.py create mode 100644 box_sdk_gen/schemas/ai_llm_endpoint_params_google.py create mode 100644 box_sdk_gen/schemas/ai_llm_endpoint_params_ibm.py create mode 100644 box_sdk_gen/schemas/ai_llm_endpoint_params_open_ai.py create mode 100644 box_sdk_gen/schemas/ai_multiple_agent_response.py create mode 100644 box_sdk_gen/schemas/ai_response.py create mode 100644 box_sdk_gen/schemas/ai_response_full.py create mode 100644 box_sdk_gen/schemas/ai_single_agent_response.py create mode 100644 box_sdk_gen/schemas/ai_single_agent_response_full.py create mode 100644 box_sdk_gen/schemas/ai_studio_agent_ask.py create mode 100644 box_sdk_gen/schemas/ai_studio_agent_ask_response.py create mode 100644 box_sdk_gen/schemas/ai_studio_agent_basic_gen_tool.py create mode 100644 box_sdk_gen/schemas/ai_studio_agent_basic_gen_tool_response.py create mode 100644 box_sdk_gen/schemas/ai_studio_agent_basic_text_tool.py create mode 100644 box_sdk_gen/schemas/ai_studio_agent_basic_text_tool_response.py create mode 100644 box_sdk_gen/schemas/ai_studio_agent_extract.py create mode 100644 box_sdk_gen/schemas/ai_studio_agent_extract_response.py create mode 100644 box_sdk_gen/schemas/ai_studio_agent_long_text_tool.py create mode 100644 box_sdk_gen/schemas/ai_studio_agent_long_text_tool_response.py create mode 100644 box_sdk_gen/schemas/ai_studio_agent_text_gen.py create mode 100644 box_sdk_gen/schemas/ai_studio_agent_text_gen_response.py create mode 100644 box_sdk_gen/schemas/ai_text_gen.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 box_sdk_gen/schemas/app_item_event_source.py create mode 100644 box_sdk_gen/schemas/classification.py create mode 100644 box_sdk_gen/schemas/classification_template.py create mode 100644 box_sdk_gen/schemas/client_error.py create mode 100644 box_sdk_gen/schemas/collaboration.py create mode 100644 box_sdk_gen/schemas/collaboration_allowlist_entries.py create mode 100644 box_sdk_gen/schemas/collaboration_allowlist_entry.py create mode 100644 box_sdk_gen/schemas/collaboration_allowlist_exempt_target.py create mode 100644 box_sdk_gen/schemas/collaboration_allowlist_exempt_targets.py create mode 100644 box_sdk_gen/schemas/collaborations.py create mode 100644 box_sdk_gen/schemas/collaborations_offset_paginated.py create mode 100644 box_sdk_gen/schemas/collaborator_variable.py create mode 100644 box_sdk_gen/schemas/collection.py create mode 100644 box_sdk_gen/schemas/collections.py create mode 100644 box_sdk_gen/schemas/comment.py create mode 100644 box_sdk_gen/schemas/comment_base.py create mode 100644 box_sdk_gen/schemas/comment_full.py create mode 100644 box_sdk_gen/schemas/comments.py create mode 100644 box_sdk_gen/schemas/completion_rule_variable.py create mode 100644 box_sdk_gen/schemas/conflict_error.py create mode 100644 box_sdk_gen/schemas/create_ai_agent.py create mode 100644 box_sdk_gen/schemas/device_pinner.py create mode 100644 box_sdk_gen/schemas/device_pinners.py create mode 100644 box_sdk_gen/schemas/email_alias.py create mode 100644 box_sdk_gen/schemas/email_aliases.py create mode 100644 box_sdk_gen/schemas/enterprise_base.py create mode 100644 box_sdk_gen/schemas/event.py create mode 100644 box_sdk_gen/schemas/event_source.py create mode 100644 box_sdk_gen/schemas/events.py create mode 100644 box_sdk_gen/schemas/file.py create mode 100644 box_sdk_gen/schemas/file_base.py create mode 100644 box_sdk_gen/schemas/file_conflict.py create mode 100644 box_sdk_gen/schemas/file_full.py create mode 100644 box_sdk_gen/schemas/file_mini.py create mode 100644 box_sdk_gen/schemas/file_or_folder_scope.py create mode 100644 box_sdk_gen/schemas/file_request.py create mode 100644 box_sdk_gen/schemas/file_request_copy_request.py create mode 100644 box_sdk_gen/schemas/file_request_update_request.py create mode 100644 box_sdk_gen/schemas/file_version.py create mode 100644 box_sdk_gen/schemas/file_version_base.py create mode 100644 box_sdk_gen/schemas/file_version_full.py create mode 100644 box_sdk_gen/schemas/file_version_legal_hold.py create mode 100644 box_sdk_gen/schemas/file_version_legal_holds.py create mode 100644 box_sdk_gen/schemas/file_version_mini.py create mode 100644 box_sdk_gen/schemas/file_version_retention.py create mode 100644 box_sdk_gen/schemas/file_version_retentions.py create mode 100644 box_sdk_gen/schemas/file_versions.py create mode 100644 box_sdk_gen/schemas/files.py create mode 100644 box_sdk_gen/schemas/files_on_hold.py create mode 100644 box_sdk_gen/schemas/files_under_retention.py create mode 100644 box_sdk_gen/schemas/folder.py create mode 100644 box_sdk_gen/schemas/folder_base.py create mode 100644 box_sdk_gen/schemas/folder_full.py create mode 100644 box_sdk_gen/schemas/folder_lock.py create mode 100644 box_sdk_gen/schemas/folder_locks.py create mode 100644 box_sdk_gen/schemas/folder_mini.py create mode 100644 box_sdk_gen/schemas/folder_reference.py create mode 100644 box_sdk_gen/schemas/generic_source.py create mode 100644 box_sdk_gen/schemas/group.py create mode 100644 box_sdk_gen/schemas/group_base.py create mode 100644 box_sdk_gen/schemas/group_full.py create mode 100644 box_sdk_gen/schemas/group_membership.py create mode 100644 box_sdk_gen/schemas/group_memberships.py create mode 100644 box_sdk_gen/schemas/group_mini.py create mode 100644 box_sdk_gen/schemas/groups.py create mode 100644 box_sdk_gen/schemas/integration_mapping.py create mode 100644 box_sdk_gen/schemas/integration_mapping_base.py create mode 100644 box_sdk_gen/schemas/integration_mapping_box_item_slack.py create mode 100644 box_sdk_gen/schemas/integration_mapping_partner_item_slack.py create mode 100644 box_sdk_gen/schemas/integration_mapping_partner_item_teams.py create mode 100644 box_sdk_gen/schemas/integration_mapping_partner_item_teams_create_request.py create mode 100644 box_sdk_gen/schemas/integration_mapping_slack_create_request.py create mode 100644 box_sdk_gen/schemas/integration_mapping_slack_options.py create mode 100644 box_sdk_gen/schemas/integration_mapping_teams.py create mode 100644 box_sdk_gen/schemas/integration_mapping_teams_create_request.py create mode 100644 box_sdk_gen/schemas/integration_mappings.py create mode 100644 box_sdk_gen/schemas/integration_mappings_teams.py create mode 100644 box_sdk_gen/schemas/invite.py create mode 100644 box_sdk_gen/schemas/items.py create mode 100644 box_sdk_gen/schemas/items_offset_paginated.py create mode 100644 box_sdk_gen/schemas/keyword_skill_card.py create mode 100644 box_sdk_gen/schemas/legal_hold_policies.py create mode 100644 box_sdk_gen/schemas/legal_hold_policy.py create mode 100644 box_sdk_gen/schemas/legal_hold_policy_assignment.py create mode 100644 box_sdk_gen/schemas/legal_hold_policy_assignment_base.py create mode 100644 box_sdk_gen/schemas/legal_hold_policy_assignments.py create mode 100644 box_sdk_gen/schemas/legal_hold_policy_mini.py create mode 100644 box_sdk_gen/schemas/metadata.py create mode 100644 box_sdk_gen/schemas/metadata_base.py create mode 100644 box_sdk_gen/schemas/metadata_cascade_policies.py create mode 100644 box_sdk_gen/schemas/metadata_cascade_policy.py create mode 100644 box_sdk_gen/schemas/metadata_field_filter_date_range.py create mode 100644 box_sdk_gen/schemas/metadata_field_filter_float_range.py create mode 100644 box_sdk_gen/schemas/metadata_filter.py create mode 100644 box_sdk_gen/schemas/metadata_full.py create mode 100644 box_sdk_gen/schemas/metadata_instance_value.py create mode 100644 box_sdk_gen/schemas/metadata_query.py create mode 100644 box_sdk_gen/schemas/metadata_query_index.py create mode 100644 box_sdk_gen/schemas/metadata_query_results.py create mode 100644 box_sdk_gen/schemas/metadata_template.py create mode 100644 box_sdk_gen/schemas/metadata_templates.py create mode 100644 box_sdk_gen/schemas/metadatas.py create mode 100644 box_sdk_gen/schemas/o_auth_2_error.py create mode 100644 box_sdk_gen/schemas/outcome.py create mode 100644 box_sdk_gen/schemas/post_o_auth_2_revoke.py create mode 100644 box_sdk_gen/schemas/post_o_auth_2_token.py create mode 100644 box_sdk_gen/schemas/post_o_auth_2_token_refresh_access_token.py create mode 100644 box_sdk_gen/schemas/realtime_server.py create mode 100644 box_sdk_gen/schemas/realtime_servers.py create mode 100644 box_sdk_gen/schemas/recent_item.py create mode 100644 box_sdk_gen/schemas/recent_items.py create mode 100644 box_sdk_gen/schemas/retention_policies.py create mode 100644 box_sdk_gen/schemas/retention_policy.py create mode 100644 box_sdk_gen/schemas/retention_policy_assignment.py create mode 100644 box_sdk_gen/schemas/retention_policy_assignment_base.py create mode 100644 box_sdk_gen/schemas/retention_policy_assignments.py create mode 100644 box_sdk_gen/schemas/retention_policy_base.py create mode 100644 box_sdk_gen/schemas/retention_policy_mini.py create mode 100644 box_sdk_gen/schemas/role_variable.py create mode 100644 box_sdk_gen/schemas/search_result_with_shared_link.py create mode 100644 box_sdk_gen/schemas/search_results.py create mode 100644 box_sdk_gen/schemas/search_results_with_shared_links.py create mode 100644 box_sdk_gen/schemas/session_termination_message.py create mode 100644 box_sdk_gen/schemas/shield_information_barrier.py create mode 100644 box_sdk_gen/schemas/shield_information_barrier_base.py create mode 100644 box_sdk_gen/schemas/shield_information_barrier_reference.py create mode 100644 box_sdk_gen/schemas/shield_information_barrier_report.py create mode 100644 box_sdk_gen/schemas/shield_information_barrier_report_base.py create mode 100644 box_sdk_gen/schemas/shield_information_barrier_report_details.py create mode 100644 box_sdk_gen/schemas/shield_information_barrier_reports.py create mode 100644 box_sdk_gen/schemas/shield_information_barrier_segment.py create mode 100644 box_sdk_gen/schemas/shield_information_barrier_segment_member.py create mode 100644 box_sdk_gen/schemas/shield_information_barrier_segment_member_base.py create mode 100644 box_sdk_gen/schemas/shield_information_barrier_segment_member_mini.py create mode 100644 box_sdk_gen/schemas/shield_information_barrier_segment_members.py create mode 100644 box_sdk_gen/schemas/shield_information_barrier_segment_restriction.py create mode 100644 box_sdk_gen/schemas/shield_information_barrier_segment_restriction_base.py create mode 100644 box_sdk_gen/schemas/shield_information_barrier_segment_restriction_mini.py create mode 100644 box_sdk_gen/schemas/shield_information_barrier_segment_restrictions.py create mode 100644 box_sdk_gen/schemas/shield_information_barrier_segments.py create mode 100644 box_sdk_gen/schemas/shield_information_barriers.py create mode 100644 box_sdk_gen/schemas/sign_request.py create mode 100644 box_sdk_gen/schemas/sign_request_base.py create mode 100644 box_sdk_gen/schemas/sign_request_create_request.py create mode 100644 box_sdk_gen/schemas/sign_request_create_signer.py create mode 100644 box_sdk_gen/schemas/sign_request_prefill_tag.py create mode 100644 box_sdk_gen/schemas/sign_request_signer.py create mode 100644 box_sdk_gen/schemas/sign_request_signer_input.py create mode 100644 box_sdk_gen/schemas/sign_requests.py create mode 100644 box_sdk_gen/schemas/sign_template.py create mode 100644 box_sdk_gen/schemas/sign_templates.py create mode 100644 box_sdk_gen/schemas/skill_cards_metadata.py create mode 100644 box_sdk_gen/schemas/skill_invocation.py create mode 100644 box_sdk_gen/schemas/status_skill_card.py create mode 100644 box_sdk_gen/schemas/storage_policies.py create mode 100644 box_sdk_gen/schemas/storage_policy.py create mode 100644 box_sdk_gen/schemas/storage_policy_assignment.py create mode 100644 box_sdk_gen/schemas/storage_policy_assignments.py create mode 100644 box_sdk_gen/schemas/storage_policy_mini.py create mode 100644 box_sdk_gen/schemas/task.py create mode 100644 box_sdk_gen/schemas/task_assignment.py create mode 100644 box_sdk_gen/schemas/task_assignments.py create mode 100644 box_sdk_gen/schemas/tasks.py create mode 100644 box_sdk_gen/schemas/template_signer.py create mode 100644 box_sdk_gen/schemas/template_signer_input.py create mode 100644 box_sdk_gen/schemas/terms_of_service.py create mode 100644 box_sdk_gen/schemas/terms_of_service_base.py create mode 100644 box_sdk_gen/schemas/terms_of_service_user_status.py create mode 100644 box_sdk_gen/schemas/terms_of_service_user_statuses.py create mode 100644 box_sdk_gen/schemas/terms_of_services.py create mode 100644 box_sdk_gen/schemas/timeline_skill_card.py create mode 100644 box_sdk_gen/schemas/tracking_code.py create mode 100644 box_sdk_gen/schemas/transcript_skill_card.py create mode 100644 box_sdk_gen/schemas/trash_file.py create mode 100644 box_sdk_gen/schemas/trash_file_restored.py create mode 100644 box_sdk_gen/schemas/trash_folder.py create mode 100644 box_sdk_gen/schemas/trash_folder_restored.py create mode 100644 box_sdk_gen/schemas/trash_web_link.py create mode 100644 box_sdk_gen/schemas/trash_web_link_restored.py create mode 100644 box_sdk_gen/schemas/upload_part.py create mode 100644 box_sdk_gen/schemas/upload_part_mini.py create mode 100644 box_sdk_gen/schemas/upload_parts.py create mode 100644 box_sdk_gen/schemas/upload_session.py create mode 100644 box_sdk_gen/schemas/upload_url.py create mode 100644 box_sdk_gen/schemas/uploaded_part.py create mode 100644 box_sdk_gen/schemas/user.py create mode 100644 box_sdk_gen/schemas/user_avatar.py create mode 100644 box_sdk_gen/schemas/user_base.py create mode 100644 box_sdk_gen/schemas/user_collaborations.py create mode 100644 box_sdk_gen/schemas/user_full.py create mode 100644 box_sdk_gen/schemas/user_integration_mappings.py create mode 100644 box_sdk_gen/schemas/user_mini.py create mode 100644 box_sdk_gen/schemas/users.py create mode 100644 box_sdk_gen/schemas/v2025_r0/__init__.py create mode 100644 box_sdk_gen/schemas/v2025_r0/client_error_v2025_r0.py create mode 100644 box_sdk_gen/schemas/v2025_r0/doc_gen_batch_base_v2025_r0.py create mode 100644 box_sdk_gen/schemas/v2025_r0/doc_gen_batch_create_request_v2025_r0.py create mode 100644 box_sdk_gen/schemas/v2025_r0/doc_gen_document_generation_data_v2025_r0.py create mode 100644 box_sdk_gen/schemas/v2025_r0/doc_gen_job_base_v2025_r0.py create mode 100644 box_sdk_gen/schemas/v2025_r0/doc_gen_job_full_v2025_r0.py create mode 100644 box_sdk_gen/schemas/v2025_r0/doc_gen_job_v2025_r0.py create mode 100644 box_sdk_gen/schemas/v2025_r0/doc_gen_jobs_full_v2025_r0.py create mode 100644 box_sdk_gen/schemas/v2025_r0/doc_gen_jobs_v2025_r0.py create mode 100644 box_sdk_gen/schemas/v2025_r0/doc_gen_tag_v2025_r0.py create mode 100644 box_sdk_gen/schemas/v2025_r0/doc_gen_tags_processing_message_v2025_r0.py create mode 100644 box_sdk_gen/schemas/v2025_r0/doc_gen_tags_v2025_r0.py create mode 100644 box_sdk_gen/schemas/v2025_r0/doc_gen_template_base_v2025_r0.py create mode 100644 box_sdk_gen/schemas/v2025_r0/doc_gen_template_create_request_v2025_r0.py create mode 100644 box_sdk_gen/schemas/v2025_r0/doc_gen_template_v2025_r0.py create mode 100644 box_sdk_gen/schemas/v2025_r0/doc_gen_templates_v2025_r0.py create mode 100644 box_sdk_gen/schemas/v2025_r0/enterprise_reference_v2025_r0.py create mode 100644 box_sdk_gen/schemas/v2025_r0/file_reference_v2025_r0.py create mode 100644 box_sdk_gen/schemas/v2025_r0/file_version_base_v2025_r0.py create mode 100644 box_sdk_gen/schemas/v2025_r0/user_base_v2025_r0.py create mode 100644 box_sdk_gen/schemas/watermark.py create mode 100644 box_sdk_gen/schemas/web_link.py create mode 100644 box_sdk_gen/schemas/web_link_base.py create mode 100644 box_sdk_gen/schemas/web_link_mini.py create mode 100644 box_sdk_gen/schemas/webhook.py create mode 100644 box_sdk_gen/schemas/webhook_invocation.py create mode 100644 box_sdk_gen/schemas/webhook_mini.py create mode 100644 box_sdk_gen/schemas/webhooks.py create mode 100644 box_sdk_gen/schemas/workflow.py create mode 100644 box_sdk_gen/schemas/workflow_full.py create mode 100644 box_sdk_gen/schemas/workflow_mini.py create mode 100644 box_sdk_gen/schemas/workflows.py create mode 100644 box_sdk_gen/schemas/zip_download.py create mode 100644 box_sdk_gen/schemas/zip_download_request.py create mode 100644 box_sdk_gen/schemas/zip_download_status.py create mode 100644 box_sdk_gen/serialization/__init__.py create mode 100644 box_sdk_gen/serialization/json.py create mode 100644 test/commons.py create mode 100644 test/test_gen/__init__.py create mode 100644 test/test_gen/ai.py create mode 100644 test/test_gen/ai_studio.py create mode 100644 test/test_gen/app_item_associations.py create mode 100644 test/test_gen/auth.py create mode 100644 test/test_gen/avatars.py create mode 100644 test/test_gen/box_network_client.py create mode 100644 test/test_gen/chunked_uploads.py create mode 100644 test/test_gen/classifications.py create mode 100644 test/test_gen/client.py create mode 100644 test/test_gen/collaboration_allowlist_entries.py create mode 100644 test/test_gen/collaboration_allowlist_exempt_targets.py create mode 100644 test/test_gen/collections.py create mode 100644 test/test_gen/comments.py create mode 100644 test/test_gen/device_pinners.py create mode 100644 test/test_gen/docgen.py create mode 100644 test/test_gen/docgen_template.py create mode 100644 test/test_gen/downloads.py create mode 100644 test/test_gen/email_aliases.py create mode 100644 test/test_gen/events.py create mode 100644 test/test_gen/file_classifications.py create mode 100644 test/test_gen/file_metadata.py create mode 100644 test/test_gen/file_requests.py create mode 100644 test/test_gen/file_version_legal_holds.py create mode 100644 test/test_gen/file_version_retentions.py create mode 100644 test/test_gen/file_versions.py create mode 100644 test/test_gen/file_watermarks.py create mode 100644 test/test_gen/files.py create mode 100644 test/test_gen/folder_classifications.py create mode 100644 test/test_gen/folder_locks.py create mode 100644 test/test_gen/folder_metadata.py create mode 100644 test/test_gen/folder_watermarks.py create mode 100644 test/test_gen/folders.py create mode 100644 test/test_gen/groups.py create mode 100644 test/test_gen/integration_mappings.py create mode 100644 test/test_gen/invites.py create mode 100644 test/test_gen/legal_hold_policies.py create mode 100644 test/test_gen/legal_hold_policy_assignments.py create mode 100644 test/test_gen/list_collaborations.py create mode 100644 test/test_gen/memberships.py create mode 100644 test/test_gen/metadata_cascade_policies.py create mode 100644 test/test_gen/metadata_templates.py create mode 100644 test/test_gen/recent_items.py create mode 100644 test/test_gen/retention_policies.py create mode 100644 test/test_gen/retention_policy_assignments.py create mode 100644 test/test_gen/search.py create mode 100644 test/test_gen/session_termination.py create mode 100644 test/test_gen/shared_links_app_items.py create mode 100644 test/test_gen/shared_links_files.py create mode 100644 test/test_gen/shared_links_folders.py create mode 100644 test/test_gen/shared_links_web_links.py create mode 100644 test/test_gen/shield_information_barrier_reports.py create mode 100644 test/test_gen/shield_information_barrier_segment_members.py create mode 100644 test/test_gen/shield_information_barrier_segment_restrictions.py create mode 100644 test/test_gen/shield_information_barrier_segments.py create mode 100644 test/test_gen/shield_information_barriers.py create mode 100644 test/test_gen/sign_requests.py create mode 100644 test/test_gen/sign_templates.py create mode 100644 test/test_gen/skills.py create mode 100644 test/test_gen/storage_policicy_assignments.py create mode 100644 test/test_gen/storage_policies.py create mode 100644 test/test_gen/task_assignments.py create mode 100644 test/test_gen/tasks.py create mode 100644 test/test_gen/terms_of_service_user_statuses.py create mode 100644 test/test_gen/terms_of_services.py create mode 100644 test/test_gen/transfer.py create mode 100644 test/test_gen/trashed_files.py create mode 100644 test/test_gen/trashed_folders.py create mode 100644 test/test_gen/trashed_items.py create mode 100644 test/test_gen/trashed_web_links.py create mode 100644 test/test_gen/uploads.py create mode 100644 test/test_gen/user_collaborations.py create mode 100644 test/test_gen/users.py create mode 100644 test/test_gen/webhooks.py create mode 100644 test/test_gen/weblinks.py create mode 100644 test/test_gen/workflows.py create mode 100644 test/test_gen/zip_downloads.py diff --git a/box_sdk_gen/__init__.py b/box_sdk_gen/__init__.py new file mode 100644 index 000000000..1110a0dd8 --- /dev/null +++ b/box_sdk_gen/__init__.py @@ -0,0 +1,15 @@ +from box_sdk_gen.box import * + +from box_sdk_gen.serialization import * + +from box_sdk_gen.internal import * + +from box_sdk_gen.networking import * + +from box_sdk_gen.schemas import * + +from box_sdk_gen.parameters import * + +from box_sdk_gen.managers import * + +from box_sdk_gen.client import * \ No newline at end of file diff --git a/box_sdk_gen/box/__init__.py b/box_sdk_gen/box/__init__.py new file mode 100644 index 000000000..ade8a0d6c --- /dev/null +++ b/box_sdk_gen/box/__init__.py @@ -0,0 +1,11 @@ +from box_sdk_gen.box.errors import * + +from box_sdk_gen.box.token_storage import * + +from box_sdk_gen.box.developer_token_auth import * + +from box_sdk_gen.box.oauth import * + +from box_sdk_gen.box.jwt_auth import * + +from box_sdk_gen.box.ccg_auth import * \ No newline at end of file diff --git a/box_sdk_gen/box/ccg_auth.py b/box_sdk_gen/box/ccg_auth.py new file mode 100644 index 000000000..53001a6af --- /dev/null +++ b/box_sdk_gen/box/ccg_auth.py @@ -0,0 +1,149 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.schemas.post_o_auth_2_token import PostOAuth2TokenGrantTypeField + +from box_sdk_gen.schemas.post_o_auth_2_token import PostOAuth2TokenSubjectTokenTypeField + +from box_sdk_gen.schemas.access_token import AccessToken + +from box_sdk_gen.schemas.post_o_auth_2_token import PostOAuth2TokenBoxSubjectTypeField + +from box_sdk_gen.networking.auth import Authentication + +from box_sdk_gen.networking.network import NetworkSession + +from box_sdk_gen.box.token_storage import TokenStorage + +from box_sdk_gen.box.token_storage import InMemoryTokenStorage + +from box_sdk_gen.managers.authorization import AuthorizationManager + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.schemas.post_o_auth_2_token import PostOAuth2Token + +from box_sdk_gen.schemas.post_o_auth_2_revoke import PostOAuth2Revoke + +class CCGConfig: + def __init__(self, client_id: str, client_secret: str, *, enterprise_id: Optional[str] = None, user_id: Optional[str] = None, token_storage: TokenStorage = None): + """ + :param client_id: Box API key used for identifying the application the user is authenticating with + :type client_id: str + :param client_secret: Box API secret used for making auth requests. + :type client_secret: str + :param enterprise_id: The ID of the Box Developer Edition enterprise., defaults to None + :type enterprise_id: Optional[str], optional + :param user_id: The user id to authenticate. This value is not required. But if it is provided, then the user will be auto-authenticated at the time of the first API call., defaults to None + :type user_id: Optional[str], optional + :param token_storage: Object responsible for storing token. If no custom implementation provided,the token will be stored in memory., defaults to None + :type token_storage: TokenStorage, optional + """ + if token_storage is None: + token_storage = InMemoryTokenStorage() + self.client_id = client_id + self.client_secret = client_secret + self.enterprise_id = enterprise_id + self.user_id = user_id + self.token_storage = token_storage + +class BoxCCGAuth(Authentication): + def __init__(self, config: CCGConfig, **kwargs): + """ + :param config: Configuration object of Client Credentials Grant auth. + :type config: CCGConfig + """ + super().__init__(**kwargs) + self.config = config + self.token_storage = self.config.token_storage + self.subject_id = self.config.user_id if not self.config.user_id == None else self.config.enterprise_id + self.subject_type = PostOAuth2TokenBoxSubjectTypeField.USER if not self.config.user_id == None else PostOAuth2TokenBoxSubjectTypeField.ENTERPRISE + def refresh_token(self, *, network_session: Optional[NetworkSession] = None) -> AccessToken: + """ + Get a new access token using CCG auth + :param network_session: An object to keep network session state, defaults to None + :type network_session: Optional[NetworkSession], optional + """ + auth_manager: AuthorizationManager = AuthorizationManager(network_session=network_session if not network_session == None else NetworkSession()) + token: AccessToken = auth_manager.request_access_token(PostOAuth2TokenGrantTypeField.CLIENT_CREDENTIALS, client_id=self.config.client_id, client_secret=self.config.client_secret, box_subject_type=self.subject_type, box_subject_id=self.subject_id) + self.token_storage.store(token) + return token + def retrieve_token(self, *, network_session: Optional[NetworkSession] = None) -> AccessToken: + """ + Return a current token or get a new one when not available. + :param network_session: An object to keep network session state, defaults to None + :type network_session: Optional[NetworkSession], optional + """ + old_token: Optional[AccessToken] = self.token_storage.get() + if old_token == None: + new_token: AccessToken = self.refresh_token(network_session=network_session) + return new_token + return old_token + def retrieve_authorization_header(self, *, network_session: Optional[NetworkSession] = None) -> str: + token: AccessToken = self.retrieve_token(network_session=network_session) + return ''.join(['Bearer ', token.access_token]) + def with_user_subject(self, user_id: str, *, token_storage: TokenStorage = None) -> 'BoxCCGAuth': + """ + Create a new BoxCCGAuth instance that uses the provided user ID as the subject ID. + + May be one of this application's created App User. Depending on the configured User Access Level, may also be any other App User or Managed User in the enterprise. + + + + + + + + :param user_id: The id of the user to authenticate + :type user_id: str + :param token_storage: Object responsible for storing token in newly created BoxCCGAuth. If no custom implementation provided, the token will be stored in memory., defaults to None + :type token_storage: TokenStorage, optional + """ + if token_storage is None: + token_storage = InMemoryTokenStorage() + new_config: CCGConfig = CCGConfig(client_id=self.config.client_id, client_secret=self.config.client_secret, enterprise_id=self.config.enterprise_id, user_id=user_id, token_storage=token_storage) + return BoxCCGAuth(config=new_config) + def with_enterprise_subject(self, enterprise_id: str, *, token_storage: TokenStorage = None) -> 'BoxCCGAuth': + """ + Create a new BoxCCGAuth instance that uses the provided enterprise ID as the subject ID. + :param enterprise_id: The id of the enterprise to authenticate + :type enterprise_id: str + :param token_storage: Object responsible for storing token in newly created BoxCCGAuth. If no custom implementation provided, the token will be stored in memory., defaults to None + :type token_storage: TokenStorage, optional + """ + if token_storage is None: + token_storage = InMemoryTokenStorage() + new_config: CCGConfig = CCGConfig(client_id=self.config.client_id, client_secret=self.config.client_secret, enterprise_id=enterprise_id, user_id=None, token_storage=token_storage) + return BoxCCGAuth(config=new_config) + def downscope_token(self, scopes: List[str], *, resource: Optional[str] = None, shared_link: Optional[str] = None, network_session: Optional[NetworkSession] = None) -> AccessToken: + """ + Downscope access token to the provided scopes. Returning a new access token with the provided scopes, with the original access token unchanged. + :param scopes: The scope(s) to apply to the resulting token. + :type scopes: List[str] + :param resource: The file or folder to get a downscoped token for. If None and shared_link None, the resulting token will not be scoped down to just a single item. The resource should be a full URL to an item, e.g. https://api.box.com/2.0/files/123456., defaults to None + :type resource: Optional[str], optional + :param shared_link: The shared link to get a downscoped token for. If None and item None, the resulting token will not be scoped down to just a single item., defaults to None + :type shared_link: Optional[str], optional + :param network_session: An object to keep network session state, defaults to None + :type network_session: Optional[NetworkSession], optional + """ + token: Optional[AccessToken] = self.retrieve_token(network_session=network_session) + if token == None: + raise BoxSDKError(message='No access token is available. Make an API call to retrieve a token before calling this method.') + auth_manager: AuthorizationManager = AuthorizationManager(network_session=network_session if not network_session == None else NetworkSession()) + downscoped_token: AccessToken = auth_manager.request_access_token(PostOAuth2TokenGrantTypeField.URN_IETF_PARAMS_OAUTH_GRANT_TYPE_TOKEN_EXCHANGE, subject_token=token.access_token, subject_token_type=PostOAuth2TokenSubjectTokenTypeField.URN_IETF_PARAMS_OAUTH_TOKEN_TYPE_ACCESS_TOKEN, resource=resource, scope=' '.join(scopes), box_shared_link=shared_link) + return downscoped_token + def revoke_token(self, *, network_session: Optional[NetworkSession] = None) -> None: + """ + Revoke the current access token and remove it from token storage. + :param network_session: An object to keep network session state, defaults to None + :type network_session: Optional[NetworkSession], optional + """ + old_token: Optional[AccessToken] = self.token_storage.get() + if old_token == None: + return None + auth_manager: AuthorizationManager = AuthorizationManager(network_session=network_session if not network_session == None else NetworkSession()) + auth_manager.revoke_access_token(client_id=self.config.client_id, client_secret=self.config.client_secret, token=old_token.access_token) + self.token_storage.clear() + return None \ No newline at end of file diff --git a/box_sdk_gen/box/developer_token_auth.py b/box_sdk_gen/box/developer_token_auth.py new file mode 100644 index 000000000..ad2eafb70 --- /dev/null +++ b/box_sdk_gen/box/developer_token_auth.py @@ -0,0 +1,92 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.schemas.post_o_auth_2_token import PostOAuth2TokenGrantTypeField + +from box_sdk_gen.schemas.post_o_auth_2_token import PostOAuth2TokenSubjectTokenTypeField + +from box_sdk_gen.schemas.access_token import AccessToken + +from box_sdk_gen.networking.auth import Authentication + +from box_sdk_gen.networking.network import NetworkSession + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.box.token_storage import TokenStorage + +from box_sdk_gen.box.token_storage import InMemoryTokenStorage + +from box_sdk_gen.managers.authorization import AuthorizationManager + +from box_sdk_gen.schemas.post_o_auth_2_token import PostOAuth2Token + +from box_sdk_gen.schemas.post_o_auth_2_revoke import PostOAuth2Revoke + +class DeveloperTokenConfig: + def __init__(self, *, client_id: Optional[str] = None, client_secret: Optional[str] = None): + self.client_id = client_id + self.client_secret = client_secret + +class BoxDeveloperTokenAuth(Authentication): + def __init__(self, token: str, *, config: DeveloperTokenConfig = None, **kwargs): + """ + :param config: Configuration object of DeveloperTokenAuth., defaults to None + :type config: DeveloperTokenConfig, optional + """ + super().__init__(**kwargs) + self.token = token + self.config = config + self.token_storage = InMemoryTokenStorage(token=AccessToken(access_token=self.token)) + def retrieve_token(self, *, network_session: Optional[NetworkSession] = None) -> AccessToken: + """ + Retrieves stored developer token + :param network_session: An object to keep network session state, defaults to None + :type network_session: Optional[NetworkSession], optional + """ + token: Optional[AccessToken] = self.token_storage.get() + if token == None: + raise BoxSDKError(message='No access token is available.') + return token + def refresh_token(self, *, network_session: Optional[NetworkSession] = None) -> AccessToken: + """ + Developer token cannot be refreshed + :param network_session: An object to keep network session state, defaults to None + :type network_session: Optional[NetworkSession], optional + """ + raise BoxSDKError(message='Developer token has expired. Please provide a new one.') + def retrieve_authorization_header(self, *, network_session: Optional[NetworkSession] = None) -> str: + token: AccessToken = self.retrieve_token(network_session=network_session) + return ''.join(['Bearer ', token.access_token]) + def revoke_token(self, *, network_session: Optional[NetworkSession] = None) -> None: + """ + Revoke an active Access Token, effectively logging a user out that has been previously authenticated. + :param network_session: An object to keep network session state, defaults to None + :type network_session: Optional[NetworkSession], optional + """ + token: Optional[AccessToken] = self.token_storage.get() + if token == None: + return None + auth_manager: AuthorizationManager = AuthorizationManager(network_session=network_session if not network_session == None else NetworkSession()) + auth_manager.revoke_access_token(client_id=self.config.client_id, client_secret=self.config.client_secret, token=token.access_token) + self.token_storage.clear() + return None + def downscope_token(self, scopes: List[str], *, resource: Optional[str] = None, shared_link: Optional[str] = None, network_session: Optional[NetworkSession] = None) -> AccessToken: + """ + Downscope access token to the provided scopes. Returning a new access token with the provided scopes, with the original access token unchanged. + :param scopes: The scope(s) to apply to the resulting token. + :type scopes: List[str] + :param resource: The file or folder to get a downscoped token for. If None and shared_link None, the resulting token will not be scoped down to just a single item. The resource should be a full URL to an item, e.g. https://api.box.com/2.0/files/123456., defaults to None + :type resource: Optional[str], optional + :param shared_link: The shared link to get a downscoped token for. If None and item None, the resulting token will not be scoped down to just a single item., defaults to None + :type shared_link: Optional[str], optional + :param network_session: An object to keep network session state, defaults to None + :type network_session: Optional[NetworkSession], optional + """ + token: Optional[AccessToken] = self.retrieve_token(network_session=network_session) + if token == None or token.access_token == None: + raise BoxSDKError(message='No access token is available.') + auth_manager: AuthorizationManager = AuthorizationManager(network_session=network_session if not network_session == None else NetworkSession()) + downscoped_token: AccessToken = auth_manager.request_access_token(PostOAuth2TokenGrantTypeField.URN_IETF_PARAMS_OAUTH_GRANT_TYPE_TOKEN_EXCHANGE, subject_token=token.access_token, subject_token_type=PostOAuth2TokenSubjectTokenTypeField.URN_IETF_PARAMS_OAUTH_TOKEN_TYPE_ACCESS_TOKEN, resource=resource, scope=' '.join(scopes), box_shared_link=shared_link) + return downscoped_token \ No newline at end of file diff --git a/box_sdk_gen/box/errors.py b/box_sdk_gen/box/errors.py new file mode 100644 index 000000000..ba6e848a9 --- /dev/null +++ b/box_sdk_gen/box/errors.py @@ -0,0 +1,78 @@ +import pprint +from datetime import datetime +from typing import Any, Dict, Optional + +from ..internal.logging import DataSanitizer +from ..internal.errors import GeneratedCodeError + +class BoxSDKError(GeneratedCodeError): + def __init__(self, message: str, timestamp: Optional[datetime] = None, error: Optional[Exception] = None, **kwargs): + super().__init__(message, **kwargs) + self.name = 'BoxSDKError' + self.message = message + self.timestamp = timestamp if timestamp is not None else datetime.now() + self.error = error + + def __str__(self): + return ''.join(( + f'\nTimestamp: {self.timestamp}', + f'\nUnderlying error: {self.error}', + f'\nMessage: {self.message}', + )) + +class RequestInfo: + def __init__(self, method: str, url: str, query_params: Dict[str, str], headers: Dict[str, str], body: Optional[str] = None): + self.method = method + self.url = url + self.query_params = query_params + self.headers = headers + self.body = body + + def print(self, data_sanitizer: DataSanitizer): + return ''.join(( + f'\n\tMethod: {self.method}', + f'\n\tURL: {self.url}', + f'\n\tQuery params: \n{pprint.pformat(self.query_params, indent=8)}', + f'\n\tHeaders: \n{pprint.pformat(data_sanitizer.sanitize_headers(self.headers), indent=8)}', + ''.join(['\n\tBody: ', '\n' if self.body else '', pprint.pformat(self.body, indent=8)]), + )) + +class ResponseInfo: + def __init__(self, status_code: int, headers: Dict[str, str], body: Dict = None, raw_body: Optional[str] = None, code: Optional[str] = None, context_info: Optional[Dict[str, Any]] = None, request_id: Optional[str] = None, help_url: Optional[str] = None): + self.status_code = status_code + self.headers = headers + self.body = body + self.raw_body = raw_body + self.code = code + self.context_info = context_info + self.request_id = request_id + self.help_url = help_url + + def print(self, data_sanitizer: DataSanitizer): + return ''.join(( + f'\n\tStatus code: {self.status_code}', + f'\n\tHeaders: \n{pprint.pformat(data_sanitizer.sanitize_headers(self.headers), indent=8)}', + f'\n\tCode: {self.code}', + f'\n\tContext Info: \n{pprint.pformat(self.context_info, indent=8)}', + f'\n\tRequest Id: {self.request_id}', + f'\n\tHelp Url: {self.help_url}', + ''.join(['\n\tBody: ', '\n' if self.body else '', pprint.pformat(data_sanitizer.sanitize_body(self.body), indent=8)]), + )) + + +class BoxAPIError(BoxSDKError): + def __init__(self, request_info: RequestInfo, response_info: ResponseInfo, message: str, timestamp: Optional[datetime] = None, error: Optional[str] = None, *, data_sanitizer: DataSanitizer = None, **kwargs): + super().__init__(message=message, timestamp=timestamp, error=error, **kwargs) + if data_sanitizer is None: + data_sanitizer = DataSanitizer() + self.name = 'BoxAPIError' + self.request_info = request_info + self.response_info = response_info + self.data_sanitizer = data_sanitizer + + def __str__(self): + return ''.join([ + f'\t{super(BoxAPIError, self).__str__()}', + f'\nRequest: {self.request_info.print(self.data_sanitizer)}', + f'\nResponse: {self.response_info.print(self.data_sanitizer)}', + ]) diff --git a/box_sdk_gen/box/jwt_auth.py b/box_sdk_gen/box/jwt_auth.py new file mode 100644 index 000000000..70e821e7a --- /dev/null +++ b/box_sdk_gen/box/jwt_auth.py @@ -0,0 +1,270 @@ +from typing import Dict + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Optional + +from box_sdk_gen.serialization.json import deserialize + +from typing import List + +from box_sdk_gen.schemas.post_o_auth_2_token import PostOAuth2TokenGrantTypeField + +from box_sdk_gen.schemas.post_o_auth_2_token import PostOAuth2TokenSubjectTokenTypeField + +from box_sdk_gen.networking.auth import Authentication + +from box_sdk_gen.networking.network import NetworkSession + +from box_sdk_gen.schemas.access_token import AccessToken + +from box_sdk_gen.schemas.post_o_auth_2_token import PostOAuth2Token + +from box_sdk_gen.schemas.post_o_auth_2_revoke import PostOAuth2Revoke + +from box_sdk_gen.box.token_storage import TokenStorage + +from box_sdk_gen.box.token_storage import InMemoryTokenStorage + +from box_sdk_gen.serialization.json import json_to_serialized_data + +from box_sdk_gen.serialization.json import SerializedData + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import read_text_from_file + +from box_sdk_gen.internal.utils import is_browser + +from box_sdk_gen.internal.utils import get_epoch_time_in_seconds + +from box_sdk_gen.internal.utils import create_jwt_assertion + +from box_sdk_gen.internal.utils import JwtSignOptions + +from box_sdk_gen.internal.utils import JwtKey + +from box_sdk_gen.internal.utils import JwtAlgorithm + +from box_sdk_gen.managers.authorization import AuthorizationManager + +from box_sdk_gen.box.errors import BoxSDKError + +class JwtConfigAppSettingsAppAuth(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'public_key_id': 'publicKeyID', 'private_key': 'privateKey', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'publicKeyID': 'public_key_id', 'privateKey': 'private_key', **BaseObject._json_to_fields_mapping} + def __init__(self, public_key_id: str, private_key: str, passphrase: str, **kwargs): + """ + :param public_key_id: Public key ID + :type public_key_id: str + :param private_key: Private key + :type private_key: str + :param passphrase: Passphrase + :type passphrase: str + """ + super().__init__(**kwargs) + self.public_key_id = public_key_id + self.private_key = private_key + self.passphrase = passphrase + +class JwtConfigAppSettings(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'client_id': 'clientID', 'client_secret': 'clientSecret', 'app_auth': 'appAuth', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'clientID': 'client_id', 'clientSecret': 'client_secret', 'appAuth': 'app_auth', **BaseObject._json_to_fields_mapping} + def __init__(self, client_id: str, client_secret: str, app_auth: JwtConfigAppSettingsAppAuth, **kwargs): + """ + :param client_id: App client ID + :type client_id: str + :param client_secret: App client secret + :type client_secret: str + :param app_auth: App auth settings + :type app_auth: JwtConfigAppSettingsAppAuth + """ + super().__init__(**kwargs) + self.client_id = client_id + self.client_secret = client_secret + self.app_auth = app_auth + +class JwtConfigFile(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'enterprise_id': 'enterpriseID', 'user_id': 'userID', 'box_app_settings': 'boxAppSettings', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'enterpriseID': 'enterprise_id', 'userID': 'user_id', 'boxAppSettings': 'box_app_settings', **BaseObject._json_to_fields_mapping} + def __init__(self, box_app_settings: JwtConfigAppSettings, *, enterprise_id: Optional[str] = None, user_id: Optional[str] = None, **kwargs): + """ + :param box_app_settings: App settings + :type box_app_settings: JwtConfigAppSettings + :param enterprise_id: Enterprise ID, defaults to None + :type enterprise_id: Optional[str], optional + :param user_id: User ID, defaults to None + :type user_id: Optional[str], optional + """ + super().__init__(**kwargs) + self.box_app_settings = box_app_settings + self.enterprise_id = enterprise_id + self.user_id = user_id + +class JWTConfig: + def __init__(self, client_id: str, client_secret: str, jwt_key_id: str, private_key: str, private_key_passphrase: str, *, enterprise_id: Optional[str] = None, user_id: Optional[str] = None, algorithm: Optional[JwtAlgorithm] = JwtAlgorithm.RS256, token_storage: TokenStorage = None): + """ + :param client_id: App client ID + :type client_id: str + :param client_secret: App client secret + :type client_secret: str + :param jwt_key_id: Public key ID + :type jwt_key_id: str + :param private_key: Private key + :type private_key: str + :param private_key_passphrase: Passphrase + :type private_key_passphrase: str + :param enterprise_id: Enterprise ID, defaults to None + :type enterprise_id: Optional[str], optional + :param user_id: User ID, defaults to None + :type user_id: Optional[str], optional + """ + if token_storage is None: + token_storage = InMemoryTokenStorage() + self.client_id = client_id + self.client_secret = client_secret + self.jwt_key_id = jwt_key_id + self.private_key = private_key + self.private_key_passphrase = private_key_passphrase + self.enterprise_id = enterprise_id + self.user_id = user_id + self.algorithm = algorithm + self.token_storage = token_storage + @staticmethod + def from_config_json_string(config_json_string: str, *, token_storage: Optional[TokenStorage] = None) -> 'JWTConfig': + """ + Create an auth instance as defined by a string content of JSON file downloaded from the Box Developer Console. + + See https://developer.box.com/en/guides/authentication/jwt/ for more information. + + :param config_json_string: String content of JSON file containing the configuration. + :type config_json_string: str + :param token_storage: Object responsible for storing token. If no custom implementation provided, the token will be stored in memory.g, defaults to None + :type token_storage: Optional[TokenStorage], optional + """ + config_json: JwtConfigFile = deserialize(json_to_serialized_data(config_json_string), JwtConfigFile) + new_config: 'JWTConfig' = JWTConfig(client_id=config_json.box_app_settings.client_id, client_secret=config_json.box_app_settings.client_secret, enterprise_id=config_json.enterprise_id, user_id=config_json.user_id, jwt_key_id=config_json.box_app_settings.app_auth.public_key_id, private_key=config_json.box_app_settings.app_auth.private_key, private_key_passphrase=config_json.box_app_settings.app_auth.passphrase, token_storage=token_storage) if not token_storage == None else JWTConfig(client_id=config_json.box_app_settings.client_id, client_secret=config_json.box_app_settings.client_secret, enterprise_id=config_json.enterprise_id, user_id=config_json.user_id, jwt_key_id=config_json.box_app_settings.app_auth.public_key_id, private_key=config_json.box_app_settings.app_auth.private_key, private_key_passphrase=config_json.box_app_settings.app_auth.passphrase) + return new_config + @staticmethod + def from_config_file(config_file_path: str, *, token_storage: Optional[TokenStorage] = None) -> 'JWTConfig': + """ + Create an auth instance as defined by a JSON file downloaded from the Box Developer Console. + + See https://developer.box.com/en/guides/authentication/jwt/ for more information. + + :param config_file_path: Path to the JSON file containing the configuration. + :type config_file_path: str + :param token_storage: Object responsible for storing token. If no custom implementation provided, the token will be stored in memory., defaults to None + :type token_storage: Optional[TokenStorage], optional + """ + config_json_string: str = read_text_from_file(config_file_path) + return JWTConfig.from_config_json_string(config_json_string, token_storage=token_storage) + +class BoxJWTAuth(Authentication): + def __init__(self, config: JWTConfig, **kwargs): + """ + :param config: An object containing all JWT configuration to use for authentication + :type config: JWTConfig + """ + super().__init__(**kwargs) + self.config = config + self.token_storage = self.config.token_storage + self.subject_id = self.config.enterprise_id if not self.config.enterprise_id == None else self.config.user_id + self.subject_type = 'enterprise' if not self.config.enterprise_id == None else 'user' + def refresh_token(self, *, network_session: Optional[NetworkSession] = None) -> AccessToken: + """ + Get new access token using JWT auth. + :param network_session: An object to keep network session state, defaults to None + :type network_session: Optional[NetworkSession], optional + """ + if is_browser(): + raise BoxSDKError(message='JWT auth is not supported in browser environment.') + alg: JwtAlgorithm = self.config.algorithm if not self.config.algorithm == None else JwtAlgorithm.RS256 + claims: Dict = {'exp': get_epoch_time_in_seconds() + 30, 'box_sub_type': self.subject_type} + jwt_options: JwtSignOptions = JwtSignOptions(algorithm=alg, audience='https://api.box.com/oauth2/token', subject=self.subject_id, issuer=self.config.client_id, jwtid=get_uuid(), keyid=self.config.jwt_key_id) + jwt_key: JwtKey = JwtKey(key=self.config.private_key, passphrase=self.config.private_key_passphrase) + assertion: str = create_jwt_assertion(claims, jwt_key, jwt_options) + auth_manager: AuthorizationManager = AuthorizationManager(network_session=network_session if not network_session == None else NetworkSession()) + token: AccessToken = auth_manager.request_access_token(PostOAuth2TokenGrantTypeField.URN_IETF_PARAMS_OAUTH_GRANT_TYPE_JWT_BEARER, assertion=assertion, client_id=self.config.client_id, client_secret=self.config.client_secret) + self.token_storage.store(token) + return token + def retrieve_token(self, *, network_session: Optional[NetworkSession] = None) -> AccessToken: + """ + Get the current access token. If the current access token is expired or not found, this method will attempt to refresh the token. + :param network_session: An object to keep network session state, defaults to None + :type network_session: Optional[NetworkSession], optional + """ + old_token: Optional[AccessToken] = self.token_storage.get() + if old_token == None: + new_token: AccessToken = self.refresh_token(network_session=network_session) + return new_token + return old_token + def retrieve_authorization_header(self, *, network_session: Optional[NetworkSession] = None) -> str: + token: AccessToken = self.retrieve_token(network_session=network_session) + return ''.join(['Bearer ', token.access_token]) + def with_user_subject(self, user_id: str, *, token_storage: TokenStorage = None) -> 'BoxJWTAuth': + """ + Create a new BoxJWTAuth instance that uses the provided user ID as the subject of the JWT assertion. + + May be one of this application's created App User. Depending on the configured User Access Level, may also be any other App User or Managed User in the enterprise. + + + + + + + + :param user_id: The id of the user to authenticate + :type user_id: str + :param token_storage: Object responsible for storing token in newly created BoxJWTAuth. If no custom implementation provided, the token will be stored in memory., defaults to None + :type token_storage: TokenStorage, optional + """ + if token_storage is None: + token_storage = InMemoryTokenStorage() + new_config: JWTConfig = JWTConfig(client_id=self.config.client_id, client_secret=self.config.client_secret, enterprise_id=None, user_id=user_id, jwt_key_id=self.config.jwt_key_id, private_key=self.config.private_key, private_key_passphrase=self.config.private_key_passphrase, token_storage=token_storage) + new_auth: 'BoxJWTAuth' = BoxJWTAuth(config=new_config) + return new_auth + def with_enterprise_subject(self, enterprise_id: str, *, token_storage: TokenStorage = None) -> 'BoxJWTAuth': + """ + Create a new BoxJWTAuth instance that uses the provided enterprise ID as the subject of the JWT assertion. + :param enterprise_id: The id of the enterprise to authenticate + :type enterprise_id: str + :param token_storage: Object responsible for storing token in newly created BoxJWTAuth. If no custom implementation provided, the token will be stored in memory., defaults to None + :type token_storage: TokenStorage, optional + """ + if token_storage is None: + token_storage = InMemoryTokenStorage() + new_config: JWTConfig = JWTConfig(client_id=self.config.client_id, client_secret=self.config.client_secret, enterprise_id=enterprise_id, user_id=None, jwt_key_id=self.config.jwt_key_id, private_key=self.config.private_key, private_key_passphrase=self.config.private_key_passphrase, token_storage=token_storage) + new_auth: 'BoxJWTAuth' = BoxJWTAuth(config=new_config) + return new_auth + def downscope_token(self, scopes: List[str], *, resource: Optional[str] = None, shared_link: Optional[str] = None, network_session: Optional[NetworkSession] = None) -> AccessToken: + """ + Downscope access token to the provided scopes. Returning a new access token with the provided scopes, with the original access token unchanged. + :param scopes: The scope(s) to apply to the resulting token. + :type scopes: List[str] + :param resource: The file or folder to get a downscoped token for. If None and shared_link None, the resulting token will not be scoped down to just a single item. The resource should be a full URL to an item, e.g. https://api.box.com/2.0/files/123456., defaults to None + :type resource: Optional[str], optional + :param shared_link: The shared link to get a downscoped token for. If None and item None, the resulting token will not be scoped down to just a single item., defaults to None + :type shared_link: Optional[str], optional + :param network_session: An object to keep network session state, defaults to None + :type network_session: Optional[NetworkSession], optional + """ + token: Optional[AccessToken] = self.retrieve_token(network_session=network_session) + if token == None: + raise BoxSDKError(message='No access token is available. Make an API call to retrieve a token before calling this method.') + auth_manager: AuthorizationManager = AuthorizationManager(network_session=network_session if not network_session == None else NetworkSession()) + downscoped_token: AccessToken = auth_manager.request_access_token(PostOAuth2TokenGrantTypeField.URN_IETF_PARAMS_OAUTH_GRANT_TYPE_TOKEN_EXCHANGE, subject_token=token.access_token, subject_token_type=PostOAuth2TokenSubjectTokenTypeField.URN_IETF_PARAMS_OAUTH_TOKEN_TYPE_ACCESS_TOKEN, resource=resource, scope=' '.join(scopes), box_shared_link=shared_link) + return downscoped_token + def revoke_token(self, *, network_session: Optional[NetworkSession] = None) -> None: + """ + Revoke the current access token and remove it from token storage. + :param network_session: An object to keep network session state, defaults to None + :type network_session: Optional[NetworkSession], optional + """ + old_token: Optional[AccessToken] = self.token_storage.get() + if old_token == None: + return None + auth_manager: AuthorizationManager = AuthorizationManager(network_session=network_session if not network_session == None else NetworkSession()) + auth_manager.revoke_access_token(client_id=self.config.client_id, client_secret=self.config.client_secret, token=old_token.access_token) + self.token_storage.clear() + return None \ No newline at end of file diff --git a/box_sdk_gen/box/oauth.py b/box_sdk_gen/box/oauth.py new file mode 100644 index 000000000..63c0783fa --- /dev/null +++ b/box_sdk_gen/box/oauth.py @@ -0,0 +1,148 @@ +from typing import Optional + +from typing import Dict + +from box_sdk_gen.serialization.json import serialize + +from typing import List + +from box_sdk_gen.schemas.post_o_auth_2_token import PostOAuth2TokenGrantTypeField + +from box_sdk_gen.schemas.post_o_auth_2_token import PostOAuth2TokenSubjectTokenTypeField + +from box_sdk_gen.networking.auth import Authentication + +from box_sdk_gen.networking.network import NetworkSession + +from box_sdk_gen.schemas.access_token import AccessToken + +from box_sdk_gen.schemas.post_o_auth_2_token import PostOAuth2Token + +from box_sdk_gen.schemas.post_o_auth_2_revoke import PostOAuth2Revoke + +from box_sdk_gen.managers.authorization import AuthorizationManager + +from box_sdk_gen.box.token_storage import TokenStorage + +from box_sdk_gen.box.token_storage import InMemoryTokenStorage + +from box_sdk_gen.serialization.json import sd_to_url_params + +from box_sdk_gen.internal.utils import prepare_params + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.serialization.json import SerializedData + +class OAuthConfig: + def __init__(self, client_id: str, client_secret: str, *, token_storage: TokenStorage = None): + if token_storage is None: + token_storage = InMemoryTokenStorage() + self.client_id = client_id + self.client_secret = client_secret + self.token_storage = token_storage + +class GetAuthorizeUrlOptions: + def __init__(self, *, client_id: Optional[str] = None, redirect_uri: Optional[str] = None, response_type: Optional[str] = None, state: Optional[str] = None, scope: Optional[str] = None): + """ + :param client_id: Box API key used for identifying the application the user is authenticating with, defaults to None + :type client_id: Optional[str], optional + :param redirect_uri: The URI to which Box redirects the browser after the user has granted or denied the application permission. This URI match one of the redirect URIs in the configuration of your application., defaults to None + :type redirect_uri: Optional[str], optional + :param response_type: The type of response we would like to receive., defaults to None + :type response_type: Optional[str], optional + :param state: A custom string of your choice. Box will pass the same string to the redirect URL when authentication is complete. This parameter can be used to identify a user on redirect, as well as protect against hijacked sessions and other exploits., defaults to None + :type state: Optional[str], optional + :param scope: A space-separated list of application scopes you'd like to authenticate the user for. This defaults to all the scopes configured for the application in its configuration page., defaults to None + :type scope: Optional[str], optional + """ + self.client_id = client_id + self.redirect_uri = redirect_uri + self.response_type = response_type + self.state = state + self.scope = scope + +class BoxOAuth(Authentication): + def __init__(self, config: OAuthConfig, **kwargs): + """ + :param config: Configuration object of OAuth. + :type config: OAuthConfig + """ + super().__init__(**kwargs) + self.config = config + self.token_storage = self.config.token_storage + def get_authorize_url(self, *, options: GetAuthorizeUrlOptions = None) -> str: + """ + Get the authorization URL for the app user. + """ + if options is None: + options = GetAuthorizeUrlOptions() + params_map: Dict[str, str] = prepare_params({'client_id': options.client_id if not options.client_id == None else self.config.client_id, 'response_type': options.response_type if not options.response_type == None else 'code', 'redirect_uri': options.redirect_uri, 'state': options.state, 'scope': options.scope}) + return ''.join(['https://account.box.com/api/oauth2/authorize?', sd_to_url_params(serialize(params_map))]) + def get_tokens_authorization_code_grant(self, authorization_code: str, *, network_session: Optional[NetworkSession] = None) -> AccessToken: + """ + Acquires token info using an authorization code. + :param authorization_code: The authorization code to use to get tokens. + :type authorization_code: str + :param network_session: An object to keep network session state, defaults to None + :type network_session: Optional[NetworkSession], optional + """ + auth_manager: AuthorizationManager = AuthorizationManager(network_session=network_session if not network_session == None else NetworkSession()) + token: AccessToken = auth_manager.request_access_token(PostOAuth2TokenGrantTypeField.AUTHORIZATION_CODE, code=authorization_code, client_id=self.config.client_id, client_secret=self.config.client_secret) + self.token_storage.store(token) + return token + def retrieve_token(self, *, network_session: Optional[NetworkSession] = None) -> AccessToken: + """ + Get the current access token. If the current access token is expired or not found, this method will attempt to refresh the token. + :param network_session: An object to keep network session state, defaults to None + :type network_session: Optional[NetworkSession], optional + """ + token: Optional[AccessToken] = self.token_storage.get() + if token == None: + raise BoxSDKError(message='Access and refresh tokens not available. Authenticate before making any API call first.') + return token + def refresh_token(self, *, network_session: Optional[NetworkSession] = None) -> AccessToken: + """ + Get a new access token for the platform app user. + :param network_session: An object to keep network session state, defaults to None + :type network_session: Optional[NetworkSession], optional + """ + old_token: Optional[AccessToken] = self.token_storage.get() + token_used_for_refresh: Optional[str] = old_token.refresh_token if not old_token == None else None + auth_manager: AuthorizationManager = AuthorizationManager(network_session=network_session if not network_session == None else NetworkSession()) + token: AccessToken = auth_manager.request_access_token(PostOAuth2TokenGrantTypeField.REFRESH_TOKEN, client_id=self.config.client_id, client_secret=self.config.client_secret, refresh_token=token_used_for_refresh) + self.token_storage.store(token) + return token + def retrieve_authorization_header(self, *, network_session: Optional[NetworkSession] = None) -> str: + token: AccessToken = self.retrieve_token(network_session=network_session) + return ''.join(['Bearer ', token.access_token]) + def revoke_token(self, *, network_session: Optional[NetworkSession] = None) -> None: + """ + Revoke an active Access Token, effectively logging a user out that has been previously authenticated. + :param network_session: An object to keep network session state, defaults to None + :type network_session: Optional[NetworkSession], optional + """ + token: Optional[AccessToken] = self.token_storage.get() + if token == None: + return None + auth_manager: AuthorizationManager = AuthorizationManager(network_session=network_session if not network_session == None else NetworkSession()) + auth_manager.revoke_access_token(client_id=self.config.client_id, client_secret=self.config.client_secret, token=token.access_token) + return None + def downscope_token(self, scopes: List[str], *, resource: Optional[str] = None, shared_link: Optional[str] = None, network_session: Optional[NetworkSession] = None) -> AccessToken: + """ + Downscope access token to the provided scopes. Returning a new access token with the provided scopes, with the original access token unchanged. + :param scopes: The scope(s) to apply to the resulting token. + :type scopes: List[str] + :param resource: The file or folder to get a downscoped token for. If None and shared_link None, the resulting token will not be scoped down to just a single item. The resource should be a full URL to an item, e.g. https://api.box.com/2.0/files/123456., defaults to None + :type resource: Optional[str], optional + :param shared_link: The shared link to get a downscoped token for. If None and item None, the resulting token will not be scoped down to just a single item., defaults to None + :type shared_link: Optional[str], optional + :param network_session: An object to keep network session state, defaults to None + :type network_session: Optional[NetworkSession], optional + """ + token: Optional[AccessToken] = self.retrieve_token(network_session=network_session) + if token == None or token.access_token == None: + raise BoxSDKError(message='No access token is available.') + auth_manager: AuthorizationManager = AuthorizationManager(network_session=network_session if not network_session == None else NetworkSession()) + downscoped_token: AccessToken = auth_manager.request_access_token(PostOAuth2TokenGrantTypeField.URN_IETF_PARAMS_OAUTH_GRANT_TYPE_TOKEN_EXCHANGE, subject_token=token.access_token, subject_token_type=PostOAuth2TokenSubjectTokenTypeField.URN_IETF_PARAMS_OAUTH_TOKEN_TYPE_ACCESS_TOKEN, resource=resource, scope=' '.join(scopes), box_shared_link=shared_link) + return downscoped_token \ No newline at end of file diff --git a/box_sdk_gen/box/token_storage.py b/box_sdk_gen/box/token_storage.py new file mode 100644 index 000000000..5b4d2e4b7 --- /dev/null +++ b/box_sdk_gen/box/token_storage.py @@ -0,0 +1,74 @@ +import shelve +from abc import abstractmethod +from typing import Optional + +from ..schemas.access_token import AccessToken + + +class TokenStorage: + @abstractmethod + def store(self, token: AccessToken) -> None: + pass + + @abstractmethod + def get(self) -> Optional[AccessToken]: + pass + + @abstractmethod + def clear(self) -> None: + pass + + +class InMemoryTokenStorage(TokenStorage): + def __init__(self, token: Optional[AccessToken] = None): + self._token = token + + def store(self, token: AccessToken) -> None: + self._token = token + + def get(self) -> Optional[AccessToken]: + return self._token + + def clear(self) -> None: + self._token = None + + +class FileTokenStorage(TokenStorage): + def __init__(self, filename: str = 'token_storage'): + self.filename = filename + + def store(self, token: AccessToken) -> None: + with shelve.open(self.filename) as file: + file['token'] = token + + def get(self) -> Optional[AccessToken]: + with shelve.open(self.filename) as file: + return file.get('token', None) + + def clear(self) -> None: + with shelve.open(self.filename) as file: + if 'token' in file: + del file['token'] + + +class FileWithInMemoryCacheTokenStorage(TokenStorage): + def __init__(self, filename: str = 'token_storage'): + self.filename = filename + self.cached_token: Optional[AccessToken] = None + + def store(self, token: AccessToken) -> None: + with shelve.open(self.filename) as file: + file['token'] = token + self.cached_token = token + + def get(self) -> Optional[AccessToken]: + if self.cached_token is None: + with shelve.open(self.filename) as file: + self.cached_token = file.get('token', None) + return self.cached_token + + def clear(self) -> None: + with shelve.open(self.filename) as file: + if 'token' in file: + del file['token'] + self.cached_token = None diff --git a/box_sdk_gen/client.py b/box_sdk_gen/client.py new file mode 100644 index 000000000..835a1bc18 --- /dev/null +++ b/box_sdk_gen/client.py @@ -0,0 +1,287 @@ +from typing import Dict + +from box_sdk_gen.managers.authorization import AuthorizationManager + +from box_sdk_gen.managers.files import FilesManager + +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 + +from box_sdk_gen.managers.chunked_uploads import ChunkedUploadsManager + +from box_sdk_gen.managers.list_collaborations import ListCollaborationsManager + +from box_sdk_gen.managers.comments import CommentsManager + +from box_sdk_gen.managers.tasks import TasksManager + +from box_sdk_gen.managers.file_versions import FileVersionsManager + +from box_sdk_gen.managers.file_metadata import FileMetadataManager + +from box_sdk_gen.managers.file_classifications import FileClassificationsManager + +from box_sdk_gen.managers.skills import SkillsManager + +from box_sdk_gen.managers.file_watermarks import FileWatermarksManager + +from box_sdk_gen.managers.file_requests import FileRequestsManager + +from box_sdk_gen.managers.folders import FoldersManager + +from box_sdk_gen.managers.trashed_folders import TrashedFoldersManager + +from box_sdk_gen.managers.folder_metadata import FolderMetadataManager + +from box_sdk_gen.managers.folder_classifications import FolderClassificationsManager + +from box_sdk_gen.managers.trashed_items import TrashedItemsManager + +from box_sdk_gen.managers.folder_watermarks import FolderWatermarksManager + +from box_sdk_gen.managers.folder_locks import FolderLocksManager + +from box_sdk_gen.managers.metadata_templates import MetadataTemplatesManager + +from box_sdk_gen.managers.classifications import ClassificationsManager + +from box_sdk_gen.managers.metadata_cascade_policies import MetadataCascadePoliciesManager + +from box_sdk_gen.managers.search import SearchManager + +from box_sdk_gen.managers.user_collaborations import UserCollaborationsManager + +from box_sdk_gen.managers.task_assignments import TaskAssignmentsManager + +from box_sdk_gen.managers.shared_links_files import SharedLinksFilesManager + +from box_sdk_gen.managers.shared_links_folders import SharedLinksFoldersManager + +from box_sdk_gen.managers.web_links import WebLinksManager + +from box_sdk_gen.managers.trashed_web_links import TrashedWebLinksManager + +from box_sdk_gen.managers.shared_links_web_links import SharedLinksWebLinksManager + +from box_sdk_gen.managers.shared_links_app_items import SharedLinksAppItemsManager + +from box_sdk_gen.managers.users import UsersManager + +from box_sdk_gen.managers.session_termination import SessionTerminationManager + +from box_sdk_gen.managers.avatars import AvatarsManager + +from box_sdk_gen.managers.transfer import TransferManager + +from box_sdk_gen.managers.email_aliases import EmailAliasesManager + +from box_sdk_gen.managers.memberships import MembershipsManager + +from box_sdk_gen.managers.invites import InvitesManager + +from box_sdk_gen.managers.groups import GroupsManager + +from box_sdk_gen.managers.webhooks import WebhooksManager + +from box_sdk_gen.managers.events import EventsManager + +from box_sdk_gen.managers.collections import CollectionsManager + +from box_sdk_gen.managers.recent_items import RecentItemsManager + +from box_sdk_gen.managers.retention_policies import RetentionPoliciesManager + +from box_sdk_gen.managers.retention_policy_assignments import RetentionPolicyAssignmentsManager + +from box_sdk_gen.managers.legal_hold_policies import LegalHoldPoliciesManager + +from box_sdk_gen.managers.legal_hold_policy_assignments import LegalHoldPolicyAssignmentsManager + +from box_sdk_gen.managers.file_version_retentions import FileVersionRetentionsManager + +from box_sdk_gen.managers.file_version_legal_holds import FileVersionLegalHoldsManager + +from box_sdk_gen.managers.shield_information_barriers import ShieldInformationBarriersManager + +from box_sdk_gen.managers.shield_information_barrier_reports import ShieldInformationBarrierReportsManager + +from box_sdk_gen.managers.shield_information_barrier_segments import ShieldInformationBarrierSegmentsManager + +from box_sdk_gen.managers.shield_information_barrier_segment_members import ShieldInformationBarrierSegmentMembersManager + +from box_sdk_gen.managers.shield_information_barrier_segment_restrictions import ShieldInformationBarrierSegmentRestrictionsManager + +from box_sdk_gen.managers.device_pinners import DevicePinnersManager + +from box_sdk_gen.managers.terms_of_services import TermsOfServicesManager + +from box_sdk_gen.managers.terms_of_service_user_statuses import TermsOfServiceUserStatusesManager + +from box_sdk_gen.managers.collaboration_allowlist_entries import CollaborationAllowlistEntriesManager + +from box_sdk_gen.managers.collaboration_allowlist_exempt_targets import CollaborationAllowlistExemptTargetsManager + +from box_sdk_gen.managers.storage_policies import StoragePoliciesManager + +from box_sdk_gen.managers.storage_policy_assignments import StoragePolicyAssignmentsManager + +from box_sdk_gen.managers.zip_downloads import ZipDownloadsManager + +from box_sdk_gen.managers.sign_requests import SignRequestsManager + +from box_sdk_gen.managers.workflows import WorkflowsManager + +from box_sdk_gen.managers.sign_templates import SignTemplatesManager + +from box_sdk_gen.managers.integration_mappings import IntegrationMappingsManager + +from box_sdk_gen.managers.ai import AiManager + +from box_sdk_gen.managers.ai_studio import AiStudioManager + +from box_sdk_gen.managers.docgen_template import DocgenTemplateManager + +from box_sdk_gen.managers.docgen import DocgenManager + +from box_sdk_gen.networking.auth import Authentication + +from box_sdk_gen.networking.network import NetworkSession + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.networking.fetch_options import FetchOptions + +from box_sdk_gen.networking.fetch_response import FetchResponse + +from box_sdk_gen.networking.base_urls import BaseUrls + +from box_sdk_gen.networking.proxy_config import ProxyConfig + +class BoxClient: + def __init__(self, auth: Authentication, *, network_session: NetworkSession = None): + if network_session is None: + network_session = NetworkSession(base_urls=BaseUrls()) + self.auth = auth + self.network_session = network_session + self.authorization = AuthorizationManager(auth=self.auth, network_session=self.network_session) + self.files = FilesManager(auth=self.auth, network_session=self.network_session) + 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) + self.uploads = UploadsManager(auth=self.auth, network_session=self.network_session) + self.chunked_uploads = ChunkedUploadsManager(auth=self.auth, network_session=self.network_session) + self.list_collaborations = ListCollaborationsManager(auth=self.auth, network_session=self.network_session) + self.comments = CommentsManager(auth=self.auth, network_session=self.network_session) + self.tasks = TasksManager(auth=self.auth, network_session=self.network_session) + self.file_versions = FileVersionsManager(auth=self.auth, network_session=self.network_session) + self.file_metadata = FileMetadataManager(auth=self.auth, network_session=self.network_session) + self.file_classifications = FileClassificationsManager(auth=self.auth, network_session=self.network_session) + self.skills = SkillsManager(auth=self.auth, network_session=self.network_session) + self.file_watermarks = FileWatermarksManager(auth=self.auth, network_session=self.network_session) + self.file_requests = FileRequestsManager(auth=self.auth, network_session=self.network_session) + self.folders = FoldersManager(auth=self.auth, network_session=self.network_session) + self.trashed_folders = TrashedFoldersManager(auth=self.auth, network_session=self.network_session) + self.folder_metadata = FolderMetadataManager(auth=self.auth, network_session=self.network_session) + self.folder_classifications = FolderClassificationsManager(auth=self.auth, network_session=self.network_session) + self.trashed_items = TrashedItemsManager(auth=self.auth, network_session=self.network_session) + self.folder_watermarks = FolderWatermarksManager(auth=self.auth, network_session=self.network_session) + self.folder_locks = FolderLocksManager(auth=self.auth, network_session=self.network_session) + self.metadata_templates = MetadataTemplatesManager(auth=self.auth, network_session=self.network_session) + self.classifications = ClassificationsManager(auth=self.auth, network_session=self.network_session) + self.metadata_cascade_policies = MetadataCascadePoliciesManager(auth=self.auth, network_session=self.network_session) + self.search = SearchManager(auth=self.auth, network_session=self.network_session) + self.user_collaborations = UserCollaborationsManager(auth=self.auth, network_session=self.network_session) + self.task_assignments = TaskAssignmentsManager(auth=self.auth, network_session=self.network_session) + self.shared_links_files = SharedLinksFilesManager(auth=self.auth, network_session=self.network_session) + self.shared_links_folders = SharedLinksFoldersManager(auth=self.auth, network_session=self.network_session) + self.web_links = WebLinksManager(auth=self.auth, network_session=self.network_session) + self.trashed_web_links = TrashedWebLinksManager(auth=self.auth, network_session=self.network_session) + self.shared_links_web_links = SharedLinksWebLinksManager(auth=self.auth, network_session=self.network_session) + self.shared_links_app_items = SharedLinksAppItemsManager(auth=self.auth, network_session=self.network_session) + self.users = UsersManager(auth=self.auth, network_session=self.network_session) + self.session_termination = SessionTerminationManager(auth=self.auth, network_session=self.network_session) + self.avatars = AvatarsManager(auth=self.auth, network_session=self.network_session) + self.transfer = TransferManager(auth=self.auth, network_session=self.network_session) + self.email_aliases = EmailAliasesManager(auth=self.auth, network_session=self.network_session) + self.memberships = MembershipsManager(auth=self.auth, network_session=self.network_session) + self.invites = InvitesManager(auth=self.auth, network_session=self.network_session) + self.groups = GroupsManager(auth=self.auth, network_session=self.network_session) + self.webhooks = WebhooksManager(auth=self.auth, network_session=self.network_session) + self.events = EventsManager(auth=self.auth, network_session=self.network_session) + self.collections = CollectionsManager(auth=self.auth, network_session=self.network_session) + self.recent_items = RecentItemsManager(auth=self.auth, network_session=self.network_session) + self.retention_policies = RetentionPoliciesManager(auth=self.auth, network_session=self.network_session) + self.retention_policy_assignments = RetentionPolicyAssignmentsManager(auth=self.auth, network_session=self.network_session) + self.legal_hold_policies = LegalHoldPoliciesManager(auth=self.auth, network_session=self.network_session) + self.legal_hold_policy_assignments = LegalHoldPolicyAssignmentsManager(auth=self.auth, network_session=self.network_session) + self.file_version_retentions = FileVersionRetentionsManager(auth=self.auth, network_session=self.network_session) + self.file_version_legal_holds = FileVersionLegalHoldsManager(auth=self.auth, network_session=self.network_session) + self.shield_information_barriers = ShieldInformationBarriersManager(auth=self.auth, network_session=self.network_session) + self.shield_information_barrier_reports = ShieldInformationBarrierReportsManager(auth=self.auth, network_session=self.network_session) + self.shield_information_barrier_segments = ShieldInformationBarrierSegmentsManager(auth=self.auth, network_session=self.network_session) + self.shield_information_barrier_segment_members = ShieldInformationBarrierSegmentMembersManager(auth=self.auth, network_session=self.network_session) + self.shield_information_barrier_segment_restrictions = ShieldInformationBarrierSegmentRestrictionsManager(auth=self.auth, network_session=self.network_session) + self.device_pinners = DevicePinnersManager(auth=self.auth, network_session=self.network_session) + self.terms_of_services = TermsOfServicesManager(auth=self.auth, network_session=self.network_session) + self.terms_of_service_user_statuses = TermsOfServiceUserStatusesManager(auth=self.auth, network_session=self.network_session) + self.collaboration_allowlist_entries = CollaborationAllowlistEntriesManager(auth=self.auth, network_session=self.network_session) + self.collaboration_allowlist_exempt_targets = CollaborationAllowlistExemptTargetsManager(auth=self.auth, network_session=self.network_session) + self.storage_policies = StoragePoliciesManager(auth=self.auth, network_session=self.network_session) + self.storage_policy_assignments = StoragePolicyAssignmentsManager(auth=self.auth, network_session=self.network_session) + self.zip_downloads = ZipDownloadsManager(auth=self.auth, network_session=self.network_session) + self.sign_requests = SignRequestsManager(auth=self.auth, network_session=self.network_session) + self.workflows = WorkflowsManager(auth=self.auth, network_session=self.network_session) + self.sign_templates = SignTemplatesManager(auth=self.auth, network_session=self.network_session) + self.integration_mappings = IntegrationMappingsManager(auth=self.auth, network_session=self.network_session) + self.ai = AiManager(auth=self.auth, network_session=self.network_session) + self.ai_studio = AiStudioManager(auth=self.auth, network_session=self.network_session) + self.docgen_template = DocgenTemplateManager(auth=self.auth, network_session=self.network_session) + self.docgen = DocgenManager(auth=self.auth, network_session=self.network_session) + def make_request(self, fetch_options: FetchOptions) -> FetchResponse: + """ + Make a custom http request using the client authentication and network session. + :param fetch_options: Options to be passed to the fetch call + :type fetch_options: FetchOptions + """ + auth: Authentication = self.auth if fetch_options.auth == None else fetch_options.auth + network_session: NetworkSession = self.network_session if fetch_options.network_session == None else fetch_options.network_session + enriched_fetch_options: FetchOptions = FetchOptions(auth=auth, network_session=network_session, url=fetch_options.url, method=fetch_options.method, params=fetch_options.params, headers=fetch_options.headers, data=fetch_options.data, file_stream=fetch_options.file_stream, multipart_data=fetch_options.multipart_data, content_type=fetch_options.content_type, response_format=fetch_options.response_format, follow_redirects=fetch_options.follow_redirects) + return network_session.network_client.fetch(enriched_fetch_options) + def with_as_user_header(self, user_id: str) -> 'BoxClient': + """ + Create a new client to impersonate user with the provided ID. All calls made with the new client will be made in context of the impersonated user, leaving the original client unmodified. + :param user_id: ID of an user to impersonate + :type user_id: str + """ + return BoxClient(auth=self.auth, network_session=self.network_session.with_additional_headers({'As-User': user_id})) + def with_suppressed_notifications(self) -> 'BoxClient': + """ + Create a new client with suppressed notifications. Calls made with the new client will not trigger email or webhook notifications + """ + return BoxClient(auth=self.auth, network_session=self.network_session.with_additional_headers({'Box-Notifications': 'off'})) + def with_extra_headers(self, *, extra_headers: Dict[str, str] = None) -> 'BoxClient': + """ + Create a new client with a custom set of headers that will be included in every API call + :param extra_headers: Custom set of headers that will be included in every API call, defaults to None + :type extra_headers: Dict[str, str], optional + """ + if extra_headers is None: + extra_headers = {} + return BoxClient(auth=self.auth, network_session=self.network_session.with_additional_headers(extra_headers)) + def with_custom_base_urls(self, base_urls: BaseUrls) -> 'BoxClient': + """ + Create a new client with a custom set of base urls that will be used for every API call + :param base_urls: Custom set of base urls that will be used for every API call + :type base_urls: BaseUrls + """ + return BoxClient(auth=self.auth, network_session=self.network_session.with_custom_base_urls(base_urls)) + def with_proxy(self, config: ProxyConfig) -> 'BoxClient': + """ + Create a new client with a custom proxy that will be used for every API call + """ + return BoxClient(auth=self.auth, network_session=self.network_session.with_proxy(config)) \ No newline at end of file diff --git a/box_sdk_gen/internal/__init__.py b/box_sdk_gen/internal/__init__.py new file mode 100644 index 000000000..4493b030f --- /dev/null +++ b/box_sdk_gen/internal/__init__.py @@ -0,0 +1,9 @@ +from box_sdk_gen.internal.utils import * + +from box_sdk_gen.internal.logging import * + +from box_sdk_gen.internal.errors import * + +from box_sdk_gen.internal.base_object import * + +from box_sdk_gen.internal.null_value import * \ No newline at end of file diff --git a/box_sdk_gen/internal/base_object.py b/box_sdk_gen/internal/base_object.py new file mode 100644 index 000000000..4c7ed1984 --- /dev/null +++ b/box_sdk_gen/internal/base_object.py @@ -0,0 +1,156 @@ +from datetime import datetime, date +from enum import EnumMeta, Enum +from typing import Union, Optional +from .null_value import NullValue + + +class BaseObject: + _discriminator = (None, {}) + _json_to_fields_mapping = {} + _fields_to_json_mapping = {} + + def __init__(self, **kwargs): + self._raw_data: dict = {} + self.__dict__.update(kwargs) + + @classmethod + def from_dict(cls, data: dict): + unpacked_attributes = {} + for key, value in data.items(): + mapping_field_name = cls._json_to_fields_mapping.get(key, key) + annotation = cls.__init__.__annotations__.get(mapping_field_name, None) + unpacked_attributes[mapping_field_name] = cls._deserialize(key, value, annotation) + return cls(**unpacked_attributes) + + @property + def raw_data(self): + """ + Returns the raw json representation returned by the API + :return: dict with the raw json data + """ + return self._raw_data + + def to_dict(self) -> dict: + result_dict = {} + for k, v in vars(self).items(): + # Skip private and protected attributes + if k.startswith("_"): + continue + if v is None: + continue + if isinstance(v, NullValue): + value = None + elif type(v) is list: + value = [item.to_dict() if isinstance(item, BaseObject) else item for item in v] + elif type(v) is dict: + value = {key: value.to_dict() if isinstance(value, BaseObject) else value for key, value in v.items()} + elif isinstance(v, BaseObject): + value = v.to_dict() + elif isinstance(v, Enum): + value = v.value + elif isinstance(v, date): + value = v.isoformat() + elif isinstance(v, datetime): + value = v.isoformat().replace('+00:00', 'Z') + else: + value = v + result_dict[self._fields_to_json_mapping.get(k, k)] = value + + return result_dict + + @classmethod + def get_origin(cls, tp): + return getattr(tp, '__origin__', None) + + @classmethod + def get_args(cls, tp): + return getattr(tp, '__args__', ()) + + @classmethod + def _deserialize(cls, key, value, annotation=None): + if annotation is None or value is None: + return value + if cls.get_origin(annotation) == Optional: + return cls._deserialize(key, value, cls.get_args(annotation.__args__)) + if cls.get_origin(annotation) == Union: + union_without_none_type = [arg for arg in cls.get_args(annotation) if arg is not type(None)] + if len(union_without_none_type) == 1: + return cls._deserialize(key, value, union_without_none_type[0]) + + if cls.get_origin(annotation) == list: + return cls._deserialize_list(key, value, annotation) + elif cls.get_origin(annotation) == Union: + return cls._deserialize_union(key, value, annotation) + elif isinstance(annotation, EnumMeta): + return cls._deserialize_enum(key, value, annotation) + elif annotation == datetime: + return cls._deserialize_datetime(key, value, annotation) + elif annotation == date: + return cls._deserialize_date(key, value, annotation) + elif isinstance(annotation, type) and issubclass(annotation, BaseObject): + return cls._deserialize_nested_type(key, value, annotation) + else: + return value + + @classmethod + def _deserialize_list(cls, key, value, annotation: list): + try: + list_type = cls.get_args(annotation)[0] + return [cls._deserialize(key, list_entry, list_type) for list_entry in value] + except Exception: + return value + + @classmethod + def _deserialize_union(cls, key, value, annotation): + try: + possible_types = cls.get_args(annotation) + if value is None: + if type(None) not in possible_types: + print('Value: ', value, 'should not be allowed in Union:', annotation) + return value + + for possible_type in possible_types: + if isinstance(possible_type, type) \ + and issubclass(possible_type, BaseObject) \ + and value.get(possible_type._discriminator[0], None) in possible_type._discriminator[1]: + return cls._deserialize(key, value, possible_type) + + for possible_type in possible_types: + try: + return cls._deserialize(key, value, possible_type) + except Exception: + continue + return value + except Exception: + return value + + @classmethod + def _deserialize_enum(cls, key, value, annotation): + try: + return getattr(annotation, value.upper().replace(' ', '_')) + except Exception: + return value + + @classmethod + def _deserialize_datetime(cls, key, value, annotation): + try: + return datetime.fromisoformat(value.replace('Z', '+00:00')) + except Exception: + return value + + @classmethod + def _deserialize_date(cls, key, value, annotation): + try: + return date.fromisoformat(value) + except Exception: + return value + + @classmethod + def _deserialize_nested_type(cls, key, value, annotation): + try: + return annotation.from_dict(value) + except Exception: + return value + + def __repr__(self) -> str: + return f'{self.__class__} {self.to_dict()}' diff --git a/box_sdk_gen/internal/errors.py b/box_sdk_gen/internal/errors.py new file mode 100644 index 000000000..1f4e52b19 --- /dev/null +++ b/box_sdk_gen/internal/errors.py @@ -0,0 +1,7 @@ +class GeneratedCodeError(Exception): + def __init__(self, message: str, **kwargs): + super().__init__(message) + self.name = 'GeneratedCodeError' + self.message = message + self.extra = kwargs + diff --git a/box_sdk_gen/internal/logging.py b/box_sdk_gen/internal/logging.py new file mode 100644 index 000000000..d2f133a52 --- /dev/null +++ b/box_sdk_gen/internal/logging.py @@ -0,0 +1,15 @@ +from typing import Dict + +from box_sdk_gen.serialization.json import SerializedData + +from box_sdk_gen.internal.utils import sanitize_map + +from box_sdk_gen.serialization.json import sanitize_serialized_data + +class DataSanitizer: + def __init__(self): + self._keys_to_sanitize = {'authorization': '', 'access_token': '', 'refresh_token': '', 'subject_token': '', 'token': '', 'client_id': '', 'client_secret': '', 'shared_link': '', 'download_url': '', 'jwt_private_key': '', 'jwt_private_key_passphrase': '', 'password': ''} + def sanitize_headers(self, headers: Dict[str, str]) -> Dict[str, str]: + return sanitize_map(headers, self._keys_to_sanitize) + def sanitize_body(self, body: SerializedData) -> SerializedData: + return sanitize_serialized_data(body, self._keys_to_sanitize) \ No newline at end of file diff --git a/box_sdk_gen/internal/null_value.py b/box_sdk_gen/internal/null_value.py new file mode 100644 index 000000000..9001c9a06 --- /dev/null +++ b/box_sdk_gen/internal/null_value.py @@ -0,0 +1,5 @@ +class NullValue: + pass + + +null = NullValue() diff --git a/box_sdk_gen/internal/utils.py b/box_sdk_gen/internal/utils.py new file mode 100644 index 000000000..4208642aa --- /dev/null +++ b/box_sdk_gen/internal/utils.py @@ -0,0 +1,459 @@ +import base64 +import datetime +import hashlib +import os +import re +import shutil +import uuid +import time +import hmac +from random import uniform +from enum import Enum +from io import SEEK_CUR, SEEK_END, SEEK_SET, BufferedIOBase, BytesIO +from typing import Any, Callable, Dict, Iterable, Optional, TypeVar, BinaryIO + +try: + import jwt + from cryptography.hazmat.backends import default_backend + from cryptography.hazmat.primitives import serialization +except ImportError: + jwt, default_backend, serialization = None, None, None + +from .base_object import BaseObject +from ..serialization.json import sd_to_json, sanitized_value +from ..serialization.json import serialize +from .null_value import null + +ByteStream = BufferedIOBase +OutputStream = BinaryIO +Buffer = bytes + + +class ResponseByteStream(ByteStream): + def __init__(self, request_iterator): + self._iterator = request_iterator + self._buffer = b'' + self._position = 0 + self._eos = False + + def _read_from_iterator(self, size): + """ + Read up to `size` bytes from the iterator into the buffer + :param size: Number of bytes to read. If None, read the entire stream. + """ + if self._eos: + return + + while len(self._buffer) < size: + try: + chunk = next(self._iterator) + self._buffer += chunk + except StopIteration: + self._eos = True + break + + def tell(self): + """ + Returns the current position in the stream + :return: + """ + return self._position + + def read(self, size=None): + """ + Reads up to `size` bytes from the stream + :param size: Read up to `size` bytes from the stream. If None read the entire stream. + :return: Bytes read from the stream + """ + if size is None: + # Read everything remaining in the stream. + result = self._buffer + b''.join(self._iterator) + self._buffer = b'' + self._position += len(result) + self._eos = True + return result + + self._read_from_iterator(size) + result = self._buffer[:size] + self._buffer = self._buffer[size:] + self._position += len(result) + return result + + def seek(self, position, whence=SEEK_SET): + """ + Move the stream to given position + :param position: Position to move to + :param whence: One of SEEK_SET = 0, SEEK_CUR = 1 or SEEK_END = 2 + :return: The new position in the stream + """ + if whence == SEEK_SET: + if position < self._position: + raise ValueError('Cannot seek backwards in a stream') + self.read(position - self._position) + elif whence == SEEK_CUR: + self.read(position) + elif whence == SEEK_END: + raise NotImplementedError('SEEK_END is not supported for streams') + else: + raise ValueError('Invalid value for `whence`') + + return self._position + + +def get_env_var(name: str) -> str: + return os.getenv(name) + + +def get_uuid() -> str: + return str(uuid.uuid1()) + + +def decode_base_64(value: str) -> str: + return base64.b64decode(value).decode() + + +def generate_byte_buffer(size: int) -> Buffer: + return Buffer(os.urandom(size)) + + +def generate_byte_stream_from_buffer(buffer: Buffer) -> ByteStream: + return BytesIO(buffer) + + +def generate_byte_stream(size: int) -> ByteStream: + return BytesIO(os.urandom(size)) + + +def buffer_equals(buffer1: Buffer, buffer2: Buffer) -> bool: + return buffer1 == buffer2 + + +def buffer_length(buffer: Buffer) -> int: + return len(buffer) + + +def decode_base_64_byte_stream(value: str) -> ByteStream: + return BytesIO(base64.b64decode(value)) + + +def string_to_byte_stream(value: str) -> ByteStream: + return BytesIO(bytes(value, 'utf-8')) + + +def read_byte_stream(byte_stream: ByteStream) -> Buffer: + return Buffer(byte_stream.read()) + + +def write_input_stream_to_output_stream(input_stream: ByteStream, output_stream: OutputStream): + shutil.copyfileobj(input_stream, output_stream) + + +def get_file_output_stream(file_path: str) -> OutputStream: + return open(file_path, 'wb') + + +def close_file_output_stream(file_output_stream: OutputStream): + file_output_stream.close() + + +def read_buffer_from_file(path: str) -> bytes: + with open(path, 'rb') as file: + return file.read() + + +def prepare_params(map: Dict[str, Optional[str]]) -> Dict[str, str]: + return {k: v for k, v in map.items() if v is not None} + + +def to_string(value: Any) -> Optional[str]: + if value is None: + return None + if isinstance(value, datetime.datetime): + return date_time_to_string(value) + if isinstance(value, datetime.date): + return date_to_string(value) + if ( + isinstance(value, BaseObject) + or isinstance(value, list) + and len(value) >= 1 + and isinstance(value[0], BaseObject) + ): + return ''.join(sd_to_json(serialize(value)).split()) + if isinstance(value, list): + return ','.join(map(to_string, value)) + if isinstance(value, Enum): + return value.value + return str(value) + + +class HashName(str, Enum): + SHA1 = 'sha1' + + +class Hash: + def __init__(self, algorithm: HashName): + self.algorithm = algorithm + self.hash = hashlib.sha1() + + def update_hash(self, data: Buffer): + self.hash.update(data) + + def digest_hash(self, encoding): + return base64.b64encode(self.hash.digest()).decode("utf-8") + + +def hex_to_base_64(data: hex): + return base64.b64encode(bytes.fromhex(data)).decode() + + +T = TypeVar('T') +Iterator = Iterable[T] +Accumulator = TypeVar('Accumulator') + + +def iterate_chunks( + stream: ByteStream, chunk_size: int, file_size: int +) -> Iterable[ByteStream]: + stream_is_finished = False + while not stream_is_finished: + copied_length = 0 + chunk = b'' + while copied_length < chunk_size: + bytes_read = stream.read(chunk_size - copied_length) + if bytes_read is None: + # stream returns none when no bytes are ready currently but there are + # potentially more bytes in the stream to be read. + continue + if not bytes_read: + # stream is exhausted. + stream_is_finished = True + break + chunk += bytes_read + copied_length += len(bytes_read) + if chunk: + yield BytesIO(chunk) + + +def reduce_iterator( + iterator: Iterator, + reducer: Callable[[Accumulator, T], Accumulator], + initial_value: Accumulator, +) -> Accumulator: + result = initial_value + + for item in iterator: + result = reducer(result, item) + + return result + + +def read_text_from_file(file_path: str) -> str: + with open(file_path, 'r') as file: + return file.read() + + +def is_browser() -> bool: + return False + + +def get_epoch_time_in_seconds() -> int: + return int(time.time()) + + +def get_value_from_object_raw_data(obj: BaseObject, key: str) -> Any: + keys = key.split('.') + value: dict = obj.raw_data + for k in keys: + value = value.get(k, {}) + return value + + +class JwtAlgorithm(str, Enum): + HS256 = 'HS256' + HS384 = 'HS384' + HS512 = 'HS512' + RS256 = 'RS256' + RS384 = 'RS384' + RS512 = 'RS512' + ES256 = 'ES256' + ES384 = 'ES384' + ES512 = 'ES512' + PS256 = 'PS256' + PS384 = 'PS384' + PS512 = 'PS512' + none = 'none' + + +class JwtSignOptions(BaseObject): + def __init__( + self, + algorithm: JwtAlgorithm, + headers: Dict[str, str] = None, + audience: Optional[str] = None, + issuer: Optional[str] = None, + subject: Optional[str] = None, + jwtid: Optional[str] = None, + keyid: Optional[str] = None, + **kwargs + ): + super().__init__(**kwargs) + if headers is None: + headers = {} + self.algorithm = algorithm + self.headers = headers + self.audience = audience + self.issuer = issuer + self.subject = subject + self.jwtid = jwtid + self.keyid = keyid + + +class JwtKey(BaseObject): + def __init__(self, key: str, passphrase: str, **kwargs): + super().__init__(**kwargs) + self.key = key + self.passphrase = passphrase + + +def encode_str_ascii_or_raise(passphrase: str) -> bytes: + try: + return passphrase.encode('ascii') + except UnicodeError as unicode_error: + raise TypeError( + "private_key and private_key_passphrase must contain binary data (bytes/str), not a text/unicode string" + ) from unicode_error + + +def get_rsa_private_key( + private_key: str, + passphrase: str, +) -> Any: + if default_backend is None or serialization is None: + raise ImportError( + 'Missing `cryptography` dependency. `cryptography` library is required to create JWT assertion.' + ) + encoded_private_key = encode_str_ascii_or_raise(private_key) + encoded_passphrase = encode_str_ascii_or_raise(passphrase) + + return serialization.load_pem_private_key( + encoded_private_key, + password=encoded_passphrase, + backend=default_backend(), + ) + + +def create_jwt_assertion(claims: dict, key: JwtKey, options: JwtSignOptions) -> str: + if jwt is None: + raise ImportError( + 'Missing `PyJWT` dependency. `PyJWT` library is required to create JWT assertion.' + ) + return jwt.encode( + { + 'iss': options.issuer, + 'sub': options.subject, + 'box_sub_type': claims['box_sub_type'], + 'aud': options.audience, + 'jti': options.jwtid, + 'exp': claims['exp'], + }, + get_rsa_private_key(key.key, key.passphrase), + algorithm=options.algorithm, + headers={'kid': options.keyid}, + ) + + +Date = datetime.date +DateTime = datetime.datetime + + +def date_to_string(date: Date) -> str: + return date.isoformat() + + +def date_from_string(date: str) -> Date: + return Date.fromisoformat(date) + + +def date_time_to_string(date_time: DateTime) -> str: + return date_time.isoformat().replace('+00:00', 'Z') + + +def date_time_from_string(date_time: str) -> DateTime: + return DateTime.fromisoformat(date_time.replace('Z', '+00:00')) + + +def date_time_to_epoch_seconds(date_time: DateTime) -> int: + return int(date_time.timestamp()) + + +def epoch_seconds_to_date_time(epoch_seconds: int) -> DateTime: + return DateTime.fromtimestamp(epoch_seconds, datetime.timezone.utc) + + +def delay_in_seconds(seconds: int): + time.sleep(seconds) + + +def create_null(): + return null + + +def escape_unicode(value: str) -> str: + def replace_char(match): + char = match.group(0) + code_point = ord(char) + if char == '\n': + return '\\n' + elif char == '\r': + return '\\r' + elif char == '\t': + return '\\t' + elif char == '\\': + return '\\\\' + elif code_point <= 0xFFFF: # Basic Multilingual Plane (BMP) + return f"\\u{code_point:04x}" + else: # Supplementary Plane (Surrogate Pair) + code_point -= 0x10000 + high_surrogate = 0xD800 + (code_point >> 10) + low_surrogate = 0xDC00 + (code_point & 0x3FF) + return f"\\u{high_surrogate:04x}\\u{low_surrogate:04x}" + + # Match special characters, non-ASCII characters, and backslashes + return re.sub(r'[^\x20-\x7e]|[\n\r\t\\]', replace_char, value) + + +def compute_webhook_signature(body: str, headers: Dict[str, str], signature_key: str) -> str: + """ + Computes the Hmac for the webhook notification given one signature key. + + :param body: + The encoded webhook body. + :param headers: + The headers for the `Webhook` notification. + :param signature_key: + The `Webhook` signature key for this application. + :return: + An Hmac signature. + """ + if signature_key is None: + return None + if headers.get('box-signature-version') != '1': + return None + if headers.get('box-signature-algorithm') != 'HmacSHA256': + return None + encoded_body = escape_unicode(body).encode('utf-8') + encoded_signature_key = signature_key.encode('utf-8') + encoded_delivery_time_stamp = headers.get('box-delivery-timestamp').encode('utf-8') + new_hmac = hmac.new(encoded_signature_key, digestmod=hashlib.sha256) + new_hmac.update(encoded_body) + new_hmac.update(encoded_delivery_time_stamp) + signature = base64.b64encode(new_hmac.digest()).decode() + return signature + + +def random(min: float, max: float) -> float: + return uniform(min, max) + + +def sanitize_map(dictionary: Dict[str, str], keys_to_sanitize: Dict[str, str]) -> Dict[str, str]: + return {k: sanitized_value() if k.lower() in keys_to_sanitize else v for k, v in dictionary.items()} diff --git a/box_sdk_gen/managers/__init__.py b/box_sdk_gen/managers/__init__.py new file mode 100644 index 000000000..c6cbabc36 --- /dev/null +++ b/box_sdk_gen/managers/__init__.py @@ -0,0 +1,147 @@ +from box_sdk_gen.managers.authorization import * + +from box_sdk_gen.managers.files import * + +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 * + +from box_sdk_gen.managers.chunked_uploads import * + +from box_sdk_gen.managers.list_collaborations import * + +from box_sdk_gen.managers.comments import * + +from box_sdk_gen.managers.tasks import * + +from box_sdk_gen.managers.file_versions import * + +from box_sdk_gen.managers.file_metadata import * + +from box_sdk_gen.managers.file_classifications import * + +from box_sdk_gen.managers.skills import * + +from box_sdk_gen.managers.file_watermarks import * + +from box_sdk_gen.managers.file_requests import * + +from box_sdk_gen.managers.folders import * + +from box_sdk_gen.managers.trashed_folders import * + +from box_sdk_gen.managers.folder_metadata import * + +from box_sdk_gen.managers.folder_classifications import * + +from box_sdk_gen.managers.trashed_items import * + +from box_sdk_gen.managers.folder_watermarks import * + +from box_sdk_gen.managers.folder_locks import * + +from box_sdk_gen.managers.metadata_templates import * + +from box_sdk_gen.managers.classifications import * + +from box_sdk_gen.managers.metadata_cascade_policies import * + +from box_sdk_gen.managers.search import * + +from box_sdk_gen.managers.user_collaborations import * + +from box_sdk_gen.managers.task_assignments import * + +from box_sdk_gen.managers.shared_links_files import * + +from box_sdk_gen.managers.shared_links_folders import * + +from box_sdk_gen.managers.web_links import * + +from box_sdk_gen.managers.trashed_web_links import * + +from box_sdk_gen.managers.shared_links_web_links import * + +from box_sdk_gen.managers.shared_links_app_items import * + +from box_sdk_gen.managers.users import * + +from box_sdk_gen.managers.session_termination import * + +from box_sdk_gen.managers.avatars import * + +from box_sdk_gen.managers.transfer import * + +from box_sdk_gen.managers.email_aliases import * + +from box_sdk_gen.managers.memberships import * + +from box_sdk_gen.managers.invites import * + +from box_sdk_gen.managers.groups import * + +from box_sdk_gen.managers.webhooks import * + +from box_sdk_gen.managers.events import * + +from box_sdk_gen.managers.collections import * + +from box_sdk_gen.managers.recent_items import * + +from box_sdk_gen.managers.retention_policies import * + +from box_sdk_gen.managers.retention_policy_assignments import * + +from box_sdk_gen.managers.legal_hold_policies import * + +from box_sdk_gen.managers.legal_hold_policy_assignments import * + +from box_sdk_gen.managers.file_version_retentions import * + +from box_sdk_gen.managers.file_version_legal_holds import * + +from box_sdk_gen.managers.shield_information_barriers import * + +from box_sdk_gen.managers.shield_information_barrier_reports import * + +from box_sdk_gen.managers.shield_information_barrier_segments import * + +from box_sdk_gen.managers.shield_information_barrier_segment_members import * + +from box_sdk_gen.managers.shield_information_barrier_segment_restrictions import * + +from box_sdk_gen.managers.device_pinners import * + +from box_sdk_gen.managers.terms_of_services import * + +from box_sdk_gen.managers.terms_of_service_user_statuses import * + +from box_sdk_gen.managers.collaboration_allowlist_entries import * + +from box_sdk_gen.managers.collaboration_allowlist_exempt_targets import * + +from box_sdk_gen.managers.storage_policies import * + +from box_sdk_gen.managers.storage_policy_assignments import * + +from box_sdk_gen.managers.zip_downloads import * + +from box_sdk_gen.managers.sign_requests import * + +from box_sdk_gen.managers.workflows import * + +from box_sdk_gen.managers.sign_templates import * + +from box_sdk_gen.managers.integration_mappings import * + +from box_sdk_gen.managers.ai import * + +from box_sdk_gen.managers.ai_studio import * + +from box_sdk_gen.managers.docgen_template import * + +from box_sdk_gen.managers.docgen import * \ No newline at end of file diff --git a/box_sdk_gen/managers/ai.py b/box_sdk_gen/managers/ai.py new file mode 100644 index 000000000..84a2bee0d --- /dev/null +++ b/box_sdk_gen/managers/ai.py @@ -0,0 +1,285 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from typing import Dict + +from typing import Union + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.schemas.ai_item_ask import AiItemAsk + +from box_sdk_gen.schemas.ai_dialogue_history import AiDialogueHistory + +from box_sdk_gen.schemas.ai_agent_reference import AiAgentReference + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.ai_item_base import AiItemBase + +from box_sdk_gen.schemas.ai_response_full import AiResponseFull + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.ai_ask import AiAsk + +from box_sdk_gen.schemas.ai_response import AiResponse + +from box_sdk_gen.schemas.ai_text_gen import AiTextGen + +from box_sdk_gen.schemas.ai_agent_ask import AiAgentAsk + +from box_sdk_gen.schemas.ai_agent_text_gen import AiAgentTextGen + +from box_sdk_gen.schemas.ai_agent_extract import AiAgentExtract + +from box_sdk_gen.schemas.ai_agent_extract_structured import AiAgentExtractStructured + +from box_sdk_gen.schemas.ai_extract import AiExtract + +from box_sdk_gen.schemas.ai_extract_structured_response import AiExtractStructuredResponse + +from box_sdk_gen.schemas.ai_extract_structured import AiExtractStructured + +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 SerializedData + +from box_sdk_gen.serialization.json import sd_to_json + +class CreateAiAskMode(str, Enum): + MULTIPLE_ITEM_QA = 'multiple_item_qa' + SINGLE_ITEM_QA = 'single_item_qa' + +class CreateAiTextGenItemsTypeField(str, Enum): + FILE = 'file' + +class CreateAiTextGenItems(BaseObject): + _discriminator = 'type', {'file'} + def __init__(self, id: str, *, type: CreateAiTextGenItemsTypeField = CreateAiTextGenItemsTypeField.FILE, content: Optional[str] = None, **kwargs): + """ + :param id: The ID of the item. + :type id: str + :param type: The type of the item., defaults to CreateAiTextGenItemsTypeField.FILE + :type type: CreateAiTextGenItemsTypeField, optional + :param content: The content to use as context for generating new text or editing existing text., defaults to None + :type content: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.content = content + +class GetAiAgentDefaultConfigMode(str, Enum): + ASK = 'ask' + TEXT_GEN = 'text_gen' + EXTRACT = 'extract' + EXTRACT_STRUCTURED = 'extract_structured' + +class CreateAiExtractStructuredMetadataTemplateTypeField(str, Enum): + METADATA_TEMPLATE = 'metadata_template' + +class CreateAiExtractStructuredMetadataTemplate(BaseObject): + _discriminator = 'type', {'metadata_template'} + def __init__(self, *, template_key: Optional[str] = None, type: Optional[CreateAiExtractStructuredMetadataTemplateTypeField] = None, scope: Optional[str] = None, **kwargs): + """ + :param template_key: The name of the metadata template., defaults to None + :type template_key: Optional[str], optional + :param type: Value is always `metadata_template`., defaults to None + :type type: Optional[CreateAiExtractStructuredMetadataTemplateTypeField], optional + :param scope: The scope of the metadata template that can either be global or +enterprise. +* The **global** scope is used for templates that are +available to any Box enterprise. +* The **enterprise** scope represents templates created within a specific enterprise, + containing the ID of that enterprise., defaults to None + :type scope: Optional[str], optional + """ + super().__init__(**kwargs) + self.template_key = template_key + self.type = type + self.scope = scope + +class CreateAiExtractStructuredFieldsOptionsField(BaseObject): + def __init__(self, key: str, **kwargs): + """ + :param key: A unique identifier for the field. + :type key: str + """ + super().__init__(**kwargs) + self.key = key + +class CreateAiExtractStructuredFields(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'display_name': 'displayName', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'displayName': 'display_name', **BaseObject._json_to_fields_mapping} + def __init__(self, key: str, *, description: Optional[str] = None, display_name: Optional[str] = None, prompt: Optional[str] = None, type: Optional[str] = None, options: Optional[List[CreateAiExtractStructuredFieldsOptionsField]] = None, **kwargs): + """ + :param key: A unique identifier for the field. + :type key: str + :param description: A description of the field., defaults to None + :type description: Optional[str], optional + :param display_name: The display name of the field., defaults to None + :type display_name: Optional[str], optional + :param prompt: The context about the key that may include how to find and format it., defaults to None + :type prompt: Optional[str], optional + :param type: The type of the field. It include but is not limited to string, float, date, enum, and multiSelect., defaults to None + :type type: Optional[str], optional + :param options: A list of options for this field. This is most often used in combination with the enum and multiSelect field types., defaults to None + :type options: Optional[List[CreateAiExtractStructuredFieldsOptionsField]], optional + """ + super().__init__(**kwargs) + self.key = key + self.description = description + self.display_name = display_name + self.prompt = prompt + self.type = type + self.options = options + +class AiManager: + 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_ai_ask(self, mode: CreateAiAskMode, prompt: str, items: List[AiItemAsk], *, dialogue_history: Optional[List[AiDialogueHistory]] = None, include_citations: Optional[bool] = None, ai_agent: Optional[Union[AiAgentAsk, AiAgentReference]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Optional[AiResponseFull]: + """ + Sends an AI request to supported LLMs and returns an answer specifically focused on the user's question given the provided context. + :param mode: Box AI handles text documents with text representations up to 1MB in size, or a maximum of 25 files, whichever comes first. If the text file size exceeds 1MB, the first 1MB of text representation will be processed. Box AI handles image documents with a resolution of 1024 x 1024 pixels, with a maximum of 5 images or 5 pages for multi-page images. If the number of image or image pages exceeds 5, the first 5 images or pages will be processed. If you set mode parameter to `single_item_qa`, the items array can have one element only. Currently Box AI does not support multi-modal requests. If both images and text are sent Box AI will only process the text. + :type mode: CreateAiAskMode + :param prompt: The prompt provided by the client to be answered by the LLM. The prompt's length is limited to 10000 characters. + :type prompt: str + :param items: The items to be processed by the LLM, often files. + :type items: List[AiItemAsk] + :param dialogue_history: The history of prompts and answers previously passed to the LLM. This provides additional context to the LLM in generating the response., defaults to None + :type dialogue_history: Optional[List[AiDialogueHistory]], optional + :param include_citations: A flag to indicate whether citations should be returned., defaults to None + :type include_citations: Optional[bool], 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 = {'mode': mode, 'prompt': prompt, 'items': items, 'dialogue_history': dialogue_history, 'include_citations': include_citations, 'ai_agent': ai_agent} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/ai/ask']), 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)) + if to_string(response.status) == '204': + return None + return deserialize(response.data, AiResponseFull) + def create_ai_text_gen(self, prompt: str, items: List[CreateAiTextGenItems], *, dialogue_history: Optional[List[AiDialogueHistory]] = None, ai_agent: Optional[Union[AiAgentReference, AiAgentTextGen]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> AiResponse: + """ + Sends an AI request to supported Large Language Models (LLMs) and returns generated text based on the provided prompt. + :param prompt: The prompt provided by the client to be answered by the LLM. The prompt's length is limited to 10000 characters. + :type prompt: str + :param items: The items to be processed by the LLM, often files. +The array can include **exactly one** element. + +**Note**: Box AI handles documents with text representations up to 1MB in size. +If the file size exceeds 1MB, the first 1MB of text representation will be processed. + :type items: List[CreateAiTextGenItems] + :param dialogue_history: The history of prompts and answers previously passed to the LLM. This parameter provides the additional context to the LLM when generating the response., defaults to None + :type dialogue_history: Optional[List[AiDialogueHistory]], 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 = {'prompt': prompt, 'items': items, 'dialogue_history': dialogue_history, 'ai_agent': ai_agent} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/ai/text_gen']), 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, AiResponse) + def get_ai_agent_default_config(self, mode: GetAiAgentDefaultConfigMode, *, language: Optional[str] = None, model: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Union[AiAgentAsk, AiAgentTextGen, AiAgentExtract, AiAgentExtractStructured]: + """ + Get the AI agent default config + :param mode: The mode to filter the agent config to return. + :type mode: GetAiAgentDefaultConfigMode + :param language: The ISO language code to return the agent config for. +If the language is not supported the default agent config is returned., defaults to None + :type language: Optional[str], optional + :param model: The model to return the default agent config for., defaults to None + :type model: 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({'mode': to_string(mode), 'language': to_string(language), 'model': to_string(model)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/ai_agent_default']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Union[AiAgentAsk, AiAgentTextGen, AiAgentExtract, AiAgentExtractStructured]) + def create_ai_extract(self, prompt: str, items: List[AiItemBase], *, ai_agent: Optional[Union[AiAgentReference, AiAgentExtract]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> AiResponse: + """ + Sends an AI request to supported Large Language Models (LLMs) and extracts metadata in form of key-value pairs. + + In this request, both the prompt and the output can be freeform. + + + Metadata template setup before sending the request is not required. + + :param prompt: The prompt provided to a Large Language Model (LLM) in the request. The prompt can be up to 10000 characters long and it can be an XML or a JSON schema. + :type prompt: str + :param items: The items that LLM will process. Currently, you can use files only. + :type items: List[AiItemBase] + :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 = {'prompt': prompt, 'items': items, 'ai_agent': ai_agent} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/ai/extract']), 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, AiResponse) + def create_ai_extract_structured(self, items: List[AiItemBase], *, metadata_template: Optional[CreateAiExtractStructuredMetadataTemplate] = None, fields: Optional[List[CreateAiExtractStructuredFields]] = None, ai_agent: Optional[Union[AiAgentReference, AiAgentExtractStructured]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> AiExtractStructuredResponse: + """ + Sends an AI request to supported Large Language Models (LLMs) and returns extracted metadata as a set of key-value pairs. + + For this request, you either need a metadata template or a list of fields you want to extract. + + + Input is **either** a metadata template or a list of fields to ensure the structure. + + + To learn more about creating templates, see [Creating metadata templates in the Admin Console](https://support.box.com/hc/en-us/articles/360044194033-Customizing-Metadata-Templates) + + + or use the [metadata template API](g://metadata/templates/create). + + :param items: The items to be processed by the LLM. Currently you can use files only. + :type items: List[AiItemBase] + :param metadata_template: The metadata template containing the fields to extract. +For your request to work, you must provide either `metadata_template` or `fields`, but not both., defaults to None + :type metadata_template: Optional[CreateAiExtractStructuredMetadataTemplate], optional + :param fields: The fields to be extracted from the provided items. +For your request to work, you must provide either `metadata_template` or `fields`, but not both., defaults to None + :type fields: Optional[List[CreateAiExtractStructuredFields]], 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 = {'items': items, 'metadata_template': metadata_template, 'fields': fields, 'ai_agent': ai_agent} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/ai/extract_structured']), 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, AiExtractStructuredResponse) \ No newline at end of file diff --git a/box_sdk_gen/managers/ai_studio.py b/box_sdk_gen/managers/ai_studio.py new file mode 100644 index 000000000..35cd1d41f --- /dev/null +++ b/box_sdk_gen/managers/ai_studio.py @@ -0,0 +1,168 @@ +from enum import Enum + +from typing import Optional + +from typing import List + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.ai_agent_allowed_entity import AiAgentAllowedEntity + +from box_sdk_gen.schemas.ai_studio_agent_ask import AiStudioAgentAsk + +from box_sdk_gen.schemas.ai_studio_agent_text_gen import AiStudioAgentTextGen + +from box_sdk_gen.schemas.ai_studio_agent_extract import AiStudioAgentExtract + +from box_sdk_gen.schemas.ai_multiple_agent_response import AiMultipleAgentResponse + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.ai_single_agent_response_full import AiSingleAgentResponseFull + +from box_sdk_gen.schemas.create_ai_agent import CreateAiAgent + +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 CreateAiAgentType(str, Enum): + AI_AGENT = 'ai_agent' + +class UpdateAiAgentByIdType(str, Enum): + AI_AGENT = 'ai_agent' + +class AiStudioManager: + 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_ai_agents(self, *, mode: Optional[List[str]] = None, fields: Optional[List[str]] = None, agent_state: Optional[List[str]] = None, include_box_default: Optional[bool] = None, marker: Optional[str] = None, limit: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> AiMultipleAgentResponse: + """ + Lists AI agents based on the provided parameters. + :param mode: The mode to filter the agent config to return. Possible values are: `ask`, `text_gen`, and `extract`., defaults to None + :type mode: Optional[List[str]], optional + :param fields: The fields to return in the response., defaults to None + :type fields: Optional[List[str]], optional + :param agent_state: The state of the agents to return. Possible values are: `enabled`, `disabled` and `enabled_for_selected_users`., defaults to None + :type agent_state: Optional[List[str]], optional + :param include_box_default: Whether to include the Box default agents in the response., defaults to None + :type include_box_default: Optional[bool], optional + :param marker: Defines the position marker at which to begin returning results., defaults to None + :type marker: Optional[str], optional + :param limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], 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({'mode': to_string(mode), 'fields': to_string(fields), 'agent_state': to_string(agent_state), 'include_box_default': to_string(include_box_default), 'marker': to_string(marker), 'limit': to_string(limit)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/ai_agents']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, AiMultipleAgentResponse) + def create_ai_agent(self, name: str, access_state: str, *, type: CreateAiAgentType = CreateAiAgentType.AI_AGENT, icon_reference: Optional[str] = None, allowed_entities: Optional[List[AiAgentAllowedEntity]] = None, ask: Optional[AiStudioAgentAsk] = None, text_gen: Optional[AiStudioAgentTextGen] = None, extract: Optional[AiStudioAgentExtract] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> AiSingleAgentResponseFull: + """ + Creates an AI agent. At least one of the following capabilities must be provided: `ask`, `text_gen`, `extract`. + :param name: The name of the AI Agent. + :type name: str + :param access_state: The state of the AI Agent. Possible values are: `enabled`, `disabled`, and `enabled_for_selected_users`. + :type access_state: str + :param type: The type of agent used to handle queries., defaults to CreateAiAgentType.AI_AGENT + :type type: CreateAiAgentType, optional + :param icon_reference: The icon reference of the AI Agent. It should have format of the URL `https://cdn01.boxcdn.net/app-assets/aistudio/avatars/` +where possible values of `file_name` are: `logo_boxAi.png`,`logo_stamp.png`,`logo_legal.png`,`logo_finance.png`,`logo_config.png`,`logo_handshake.png`,`logo_analytics.png`,`logo_classification.png`, defaults to None + :type icon_reference: Optional[str], optional + :param allowed_entities: List of allowed users or groups., defaults to None + :type allowed_entities: Optional[List[AiAgentAllowedEntity]], 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 = {'type': type, 'name': name, 'access_state': access_state, 'icon_reference': icon_reference, 'allowed_entities': allowed_entities, 'ask': ask, 'text_gen': text_gen, 'extract': extract} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/ai_agents']), 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, AiSingleAgentResponseFull) + def update_ai_agent_by_id(self, agent_id: str, name: str, access_state: str, *, type: UpdateAiAgentByIdType = UpdateAiAgentByIdType.AI_AGENT, icon_reference: Optional[str] = None, allowed_entities: Optional[List[AiAgentAllowedEntity]] = None, ask: Optional[AiStudioAgentAsk] = None, text_gen: Optional[AiStudioAgentTextGen] = None, extract: Optional[AiStudioAgentExtract] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> AiSingleAgentResponseFull: + """ + Updates an AI agent. + :param agent_id: The ID of the agent to update. +Example: "1234" + :type agent_id: str + :param name: The name of the AI Agent. + :type name: str + :param access_state: The state of the AI Agent. Possible values are: `enabled`, `disabled`, and `enabled_for_selected_users`. + :type access_state: str + :param type: The type of agent used to handle queries., defaults to UpdateAiAgentByIdType.AI_AGENT + :type type: UpdateAiAgentByIdType, optional + :param icon_reference: The icon reference of the AI Agent. It should have format of the URL `https://cdn01.boxcdn.net/app-assets/aistudio/avatars/` +where possible values of `file_name` are: `logo_boxAi.png`,`logo_stamp.png`,`logo_legal.png`,`logo_finance.png`,`logo_config.png`,`logo_handshake.png`,`logo_analytics.png`,`logo_classification.png`, defaults to None + :type icon_reference: Optional[str], optional + :param allowed_entities: List of allowed users or groups., defaults to None + :type allowed_entities: Optional[List[AiAgentAllowedEntity]], 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 = {'type': type, 'name': name, 'access_state': access_state, 'icon_reference': icon_reference, 'allowed_entities': allowed_entities, 'ask': ask, 'text_gen': text_gen, 'extract': extract} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/ai_agents/', to_string(agent_id)]), method='PUT', 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, AiSingleAgentResponseFull) + def get_ai_agent_by_id(self, agent_id: str, *, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> AiSingleAgentResponseFull: + """ + Gets an AI Agent using the `agent_id` parameter. + :param agent_id: The agent id to get. +Example: "1234" + :type agent_id: str + :param fields: The fields to return in the response., defaults to None + :type fields: Optional[List[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({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/ai_agents/', to_string(agent_id)]), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, AiSingleAgentResponseFull) + def delete_ai_agent_by_id(self, agent_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Deletes an AI agent using the provided parameters. + :param agent_id: The ID of the agent to delete. +Example: "1234" + :type agent_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/ai_agents/', to_string(agent_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file 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 000000000..3c53ce52d --- /dev/null +++ b/box_sdk_gen/managers/app_item_associations.py @@ -0,0 +1,127 @@ +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.app_item_associations import AppItemAssociations + +from box_sdk_gen.schemas.client_error import ClientError + +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 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 = self.network_session.network_client.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=ResponseFormat.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 = self.network_session.network_client.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=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, AppItemAssociations) \ No newline at end of file diff --git a/box_sdk_gen/managers/authorization.py b/box_sdk_gen/managers/authorization.py new file mode 100644 index 000000000..3c21b3ade --- /dev/null +++ b/box_sdk_gen/managers/authorization.py @@ -0,0 +1,285 @@ +from enum import Enum + +from typing import Optional + +from typing import Dict + +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.post_o_auth_2_token import PostOAuth2TokenGrantTypeField + +from box_sdk_gen.schemas.post_o_auth_2_token import PostOAuth2TokenSubjectTokenTypeField + +from box_sdk_gen.schemas.post_o_auth_2_token import PostOAuth2TokenBoxSubjectTypeField + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.access_token import AccessToken + +from box_sdk_gen.schemas.o_auth_2_error import OAuth2Error + +from box_sdk_gen.schemas.post_o_auth_2_token import PostOAuth2Token + +from box_sdk_gen.schemas.post_o_auth_2_token_refresh_access_token import PostOAuth2TokenRefreshAccessToken + +from box_sdk_gen.schemas.post_o_auth_2_revoke import PostOAuth2Revoke + +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 AuthorizeUserResponseType(str, Enum): + CODE = 'code' + +class RequestAccessTokenGrantType(str, Enum): + AUTHORIZATION_CODE = 'authorization_code' + REFRESH_TOKEN = 'refresh_token' + CLIENT_CREDENTIALS = 'client_credentials' + URN_IETF_PARAMS_OAUTH_GRANT_TYPE_JWT_BEARER = 'urn:ietf:params:oauth:grant-type:jwt-bearer' + URN_IETF_PARAMS_OAUTH_GRANT_TYPE_TOKEN_EXCHANGE = 'urn:ietf:params:oauth:grant-type:token-exchange' + +class RequestAccessTokenSubjectTokenType(str, Enum): + URN_IETF_PARAMS_OAUTH_TOKEN_TYPE_ACCESS_TOKEN = 'urn:ietf:params:oauth:token-type:access_token' + +class RequestAccessTokenActorTokenType(str, Enum): + URN_IETF_PARAMS_OAUTH_TOKEN_TYPE_ID_TOKEN = 'urn:ietf:params:oauth:token-type:id_token' + +class RequestAccessTokenBoxSubjectType(str, Enum): + ENTERPRISE = 'enterprise' + USER = 'user' + +class RefreshAccessTokenGrantType(str, Enum): + REFRESH_TOKEN = 'refresh_token' + +class AuthorizationManager: + 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 authorize_user(self, response_type: AuthorizeUserResponseType, client_id: str, *, redirect_uri: Optional[str] = None, state: Optional[str] = None, scope: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Authorize a user by sending them through the [Box](https://box.com) + + website and request their permission to act on their behalf. + + + This is the first step when authenticating a user using + + + OAuth 2.0. To request a user's authorization to use the Box APIs + + + on their behalf you will need to send a user to the URL with this + + + format. + + :param response_type: The type of response we'd like to receive. + :type response_type: AuthorizeUserResponseType + :param client_id: The Client ID of the application that is requesting to authenticate +the user. To get the Client ID for your application, log in to your +Box developer console and click the **Edit Application** link for +the application you're working with. In the OAuth 2.0 Parameters section +of the configuration page, find the item labelled `client_id`. The +text of that item is your application's Client ID. + :type client_id: str + :param redirect_uri: The URI to which Box redirects the browser after the user has granted +or denied the application permission. This URI match one of the redirect +URIs in the configuration of your application. It must be a +valid HTTPS URI and it needs to be able to handle the redirection to +complete the next step in the OAuth 2.0 flow. +Although this parameter is optional, it must be a part of the +authorization URL if you configured multiple redirect URIs +for the application in the developer console. A missing parameter causes +a `redirect_uri_missing` error after the user grants application access., defaults to None + :type redirect_uri: Optional[str], optional + :param state: A custom string of your choice. Box will pass the same string to +the redirect URL when authentication is complete. This parameter +can be used to identify a user on redirect, as well as protect +against hijacked sessions and other exploits., defaults to None + :type state: Optional[str], optional + :param scope: A space-separated list of application scopes you'd like to +authenticate the user for. This defaults to all the scopes configured +for the application in its configuration page., defaults to None + :type scope: 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({'response_type': to_string(response_type), 'client_id': to_string(client_id), 'redirect_uri': to_string(redirect_uri), 'state': to_string(state), 'scope': to_string(scope)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.oauth_2_url, '/authorize']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None + def request_access_token(self, grant_type: RequestAccessTokenGrantType, *, client_id: Optional[str] = None, client_secret: Optional[str] = None, code: Optional[str] = None, refresh_token: Optional[str] = None, assertion: Optional[str] = None, subject_token: Optional[str] = None, subject_token_type: Optional[RequestAccessTokenSubjectTokenType] = None, actor_token: Optional[str] = None, actor_token_type: Optional[RequestAccessTokenActorTokenType] = None, scope: Optional[str] = None, resource: Optional[str] = None, box_subject_type: Optional[RequestAccessTokenBoxSubjectType] = None, box_subject_id: Optional[str] = None, box_shared_link: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> AccessToken: + """ + Request an Access Token using either a client-side obtained OAuth 2.0 + + authorization code or a server-side JWT assertion. + + + An Access Token is a string that enables Box to verify that a + + + request belongs to an authorized session. In the normal order of + + + operations you will begin by requesting authentication from the + + + [authorize](#get-authorize) endpoint and Box will send you an + + + authorization code. + + + You will then send this code to this endpoint to exchange it for + + + an Access Token. The returned Access Token can then be used to to make + + + Box API calls. + + :param grant_type: The type of request being made, either using a client-side obtained +authorization code, a refresh token, a JWT assertion, client credentials +grant or another access token for the purpose of downscoping a token. + :type grant_type: RequestAccessTokenGrantType + :param client_id: The Client ID of the application requesting an access token. + +Used in combination with `authorization_code`, `client_credentials`, or +`urn:ietf:params:oauth:grant-type:jwt-bearer` as the `grant_type`., defaults to None + :type client_id: Optional[str], optional + :param client_secret: The client secret of the application requesting an access token. + +Used in combination with `authorization_code`, `client_credentials`, or +`urn:ietf:params:oauth:grant-type:jwt-bearer` as the `grant_type`., defaults to None + :type client_secret: Optional[str], optional + :param code: The client-side authorization code passed to your application by +Box in the browser redirect after the user has successfully +granted your application permission to make API calls on their +behalf. + +Used in combination with `authorization_code` as the `grant_type`., defaults to None + :type code: Optional[str], optional + :param refresh_token: A refresh token used to get a new access token with. + +Used in combination with `refresh_token` as the `grant_type`., defaults to None + :type refresh_token: Optional[str], optional + :param assertion: A JWT assertion for which to request a new access token. + +Used in combination with `urn:ietf:params:oauth:grant-type:jwt-bearer` +as the `grant_type`., defaults to None + :type assertion: Optional[str], optional + :param subject_token: The token to exchange for a downscoped token. This can be a regular +access token, a JWT assertion, or an app token. + +Used in combination with `urn:ietf:params:oauth:grant-type:token-exchange` +as the `grant_type`., defaults to None + :type subject_token: Optional[str], optional + :param subject_token_type: The type of `subject_token` passed in. + +Used in combination with `urn:ietf:params:oauth:grant-type:token-exchange` +as the `grant_type`., defaults to None + :type subject_token_type: Optional[RequestAccessTokenSubjectTokenType], optional + :param actor_token: The token used to create an annotator token. +This is a JWT assertion. + +Used in combination with `urn:ietf:params:oauth:grant-type:token-exchange` +as the `grant_type`., defaults to None + :type actor_token: Optional[str], optional + :param actor_token_type: The type of `actor_token` passed in. + +Used in combination with `urn:ietf:params:oauth:grant-type:token-exchange` +as the `grant_type`., defaults to None + :type actor_token_type: Optional[RequestAccessTokenActorTokenType], optional + :param scope: The space-delimited list of scopes that you want apply to the +new access token. + +The `subject_token` will need to have all of these scopes or +the call will error with **401 Unauthorized**., defaults to None + :type scope: Optional[str], optional + :param resource: Full URL for the file that the token should be generated for., defaults to None + :type resource: Optional[str], optional + :param box_subject_type: Used in combination with `client_credentials` as the `grant_type`., defaults to None + :type box_subject_type: Optional[RequestAccessTokenBoxSubjectType], optional + :param box_subject_id: Used in combination with `client_credentials` as the `grant_type`. +Value is determined by `box_subject_type`. If `user` use user ID and if +`enterprise` use enterprise ID., defaults to None + :type box_subject_id: Optional[str], optional + :param box_shared_link: Full URL of the shared link on the file or folder +that the token should be generated for., defaults to None + :type box_shared_link: 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 = {} + request_body: Dict = {'grant_type': grant_type, 'client_id': client_id, 'client_secret': client_secret, 'code': code, 'refresh_token': refresh_token, 'assertion': assertion, 'subject_token': subject_token, 'subject_token_type': subject_token_type, 'actor_token': actor_token, 'actor_token_type': actor_token_type, 'scope': scope, 'resource': resource, 'box_subject_type': box_subject_type, 'box_subject_id': box_subject_id, 'box_shared_link': box_shared_link} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/oauth2/token']), method='POST', headers=headers_map, data=serialize(request_body), content_type='application/x-www-form-urlencoded', response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, AccessToken) + def refresh_access_token(self, client_id: str, client_secret: str, refresh_token: str, *, grant_type: RefreshAccessTokenGrantType = RefreshAccessTokenGrantType.REFRESH_TOKEN, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> AccessToken: + """ + Refresh an Access Token using its client ID, secret, and refresh token. + :param client_id: The client ID of the application requesting to refresh the token. + :type client_id: str + :param client_secret: The client secret of the application requesting to refresh the token. + :type client_secret: str + :param refresh_token: The refresh token to refresh. + :type refresh_token: str + :param grant_type: The type of request being made, in this case a refresh request., defaults to RefreshAccessTokenGrantType.REFRESH_TOKEN + :type grant_type: RefreshAccessTokenGrantType, 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 = {'grant_type': grant_type, 'client_id': client_id, 'client_secret': client_secret, 'refresh_token': refresh_token} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/oauth2/token#refresh']), method='POST', headers=headers_map, data=serialize(request_body), content_type='application/x-www-form-urlencoded', response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, AccessToken) + def revoke_access_token(self, *, client_id: Optional[str] = None, client_secret: Optional[str] = None, token: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Revoke an active Access Token, effectively logging a user out + + that has been previously authenticated. + + :param client_id: The Client ID of the application requesting to revoke the +access token., defaults to None + :type client_id: Optional[str], optional + :param client_secret: The client secret of the application requesting to revoke +an access token., defaults to None + :type client_secret: Optional[str], optional + :param token: The access token to revoke., defaults to None + :type token: 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 = {} + request_body: Dict = {'client_id': client_id, 'client_secret': client_secret, 'token': token} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/oauth2/revoke']), method='POST', headers=headers_map, data=serialize(request_body), content_type='application/x-www-form-urlencoded', response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/avatars.py b/box_sdk_gen/managers/avatars.py new file mode 100644 index 000000000..ef2270951 --- /dev/null +++ b/box_sdk_gen/managers/avatars.py @@ -0,0 +1,92 @@ +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.user_avatar import UserAvatar + +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.networking.fetch_options import MultipartItem + +from box_sdk_gen.serialization.json import SerializedData + +class AvatarsManager: + 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_user_avatar(self, user_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ByteStream: + """ + Retrieves an image of a the user's avatar. + :param user_id: The ID of the user. +Example: "12345" + :type user_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/users/', to_string(user_id), '/avatar']), method='GET', headers=headers_map, response_format=ResponseFormat.BINARY, auth=self.auth, network_session=self.network_session)) + return response.content + def create_user_avatar(self, user_id: str, pic: ByteStream, *, pic_file_name: Optional[str] = None, pic_content_type: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> UserAvatar: + """ + Adds or updates a user avatar. + :param user_id: The ID of the user. +Example: "12345" + :type user_id: str + :param pic: The image file to be uploaded to Box. +Accepted file extensions are `.jpg` or `.png`. +The maximum file size is 1MB. + :type pic: ByteStream + :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 = {'pic': pic, 'pic_file_name': pic_file_name, 'pic_content_type': pic_content_type} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/users/', to_string(user_id), '/avatar']), method='POST', headers=headers_map, multipart_data=[MultipartItem(part_name='pic', file_stream=pic, file_name=pic_file_name, content_type=pic_content_type)], content_type='multipart/form-data', response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, UserAvatar) + def delete_user_avatar(self, user_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Removes an existing user avatar. + + You cannot reverse this operation. + + :param user_id: The ID of the user. +Example: "12345" + :type user_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/users/', to_string(user_id), '/avatar']), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/chunked_uploads.py b/box_sdk_gen/managers/chunked_uploads.py new file mode 100644 index 000000000..827c0b33d --- /dev/null +++ b/box_sdk_gen/managers/chunked_uploads.py @@ -0,0 +1,530 @@ +from typing import List + +from typing import Optional + +from typing import Dict + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.internal.utils import Buffer + +from box_sdk_gen.internal.utils import HashName + +from box_sdk_gen.internal.utils import Iterator + +from box_sdk_gen.schemas.upload_session import UploadSession + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.uploaded_part import UploadedPart + +from box_sdk_gen.schemas.upload_parts import UploadParts + +from box_sdk_gen.schemas.files import Files + +from box_sdk_gen.schemas.upload_part import UploadPart + +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 SerializedData + +from box_sdk_gen.serialization.json import sd_to_json + +from box_sdk_gen.internal.utils import generate_byte_stream_from_buffer + +from box_sdk_gen.internal.utils import hex_to_base_64 + +from box_sdk_gen.internal.utils import iterate_chunks + +from box_sdk_gen.internal.utils import read_byte_stream + +from box_sdk_gen.internal.utils import reduce_iterator + +from box_sdk_gen.internal.utils import Hash + +from box_sdk_gen.internal.utils import buffer_length + +from box_sdk_gen.schemas.file_full import FileFull + +class _PartAccumulator: + def __init__(self, last_index: int, parts: List[UploadPart], file_size: int, upload_part_url: str, file_hash: Hash): + self.last_index = last_index + self.parts = parts + self.file_size = file_size + self.upload_part_url = upload_part_url + self.file_hash = file_hash + +class ChunkedUploadsManager: + 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_file_upload_session(self, folder_id: str, file_size: int, file_name: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> UploadSession: + """ + Creates an upload session for a new file. + :param folder_id: The ID of the folder to upload the new file to. + :type folder_id: str + :param file_size: The total number of bytes of the file to be uploaded + :type file_size: int + :param file_name: The name of new file + :type file_name: str + :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 = {'folder_id': folder_id, 'file_size': file_size, 'file_name': file_name} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.upload_url, '/2.0/files/upload_sessions']), 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, UploadSession) + def create_file_upload_session_for_existing_file(self, file_id: str, file_size: int, *, file_name: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> UploadSession: + """ + Creates an upload session for an existing file. + :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 file_size: The total number of bytes of the file to be uploaded + :type file_size: int + :param file_name: The optional new name of new file, defaults to None + :type file_name: 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 = {} + request_body: Dict = {'file_size': file_size, 'file_name': file_name} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.upload_url, '/2.0/files/', to_string(file_id), '/upload_sessions']), 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, UploadSession) + def get_file_upload_session_by_url(self, url: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> UploadSession: + """ + Using this method with urls provided in response when creating a new upload session is preferred to use over GetFileUploadSessionById method. + + This allows to always upload your content to the closest Box data center and can significantly improve upload speed. + + + Return information about an upload session. + + + The actual endpoint URL is returned by the [`Create upload session`](e://post-files-upload-sessions) endpoint. + + :param url: URL of getFileUploadSessionById method + :type url: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=url, method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, UploadSession) + def get_file_upload_session_by_id(self, upload_session_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> UploadSession: + """ + Return information about an upload session. + + The actual endpoint URL is returned by the [`Create upload session`](e://post-files-upload-sessions) endpoint. + + :param upload_session_id: The ID of the upload session. +Example: "D5E3F7A" + :type upload_session_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.upload_url, '/2.0/files/upload_sessions/', to_string(upload_session_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, UploadSession) + def upload_file_part_by_url(self, url: str, request_body: ByteStream, digest: str, content_range: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> UploadedPart: + """ + Using this method with urls provided in response when creating a new upload session is preferred to use over UploadFilePart method. + + This allows to always upload your content to the closest Box data center and can significantly improve upload speed. + + + Uploads a chunk of a file for an upload session. + + + The actual endpoint URL is returned by the [`Create upload session`](e://post-files-upload-sessions) + + + and [`Get upload session`](e://get-files-upload-sessions-id) endpoints. + + :param url: URL of uploadFilePart method + :type url: str + :param request_body: Request body of uploadFilePart method + :type request_body: ByteStream + :param digest: The [RFC3230][1] message digest of the chunk uploaded. + +Only SHA1 is supported. The SHA1 digest must be base64 +encoded. The format of this header is as +`sha=BASE64_ENCODED_DIGEST`. + +To get the value for the `SHA` digest, use the +openSSL command to encode the file part: +`openssl sha1 -binary | base64` + +[1]: https://tools.ietf.org/html/rfc3230 + :type digest: str + :param content_range: The byte range of the chunk. + +Must not overlap with the range of a part already +uploaded this session. Each part’s size must be +exactly equal in size to the part size specified +in the upload session that you created. +One exception is the last part of the file, as this can be smaller. + +When providing the value for `content-range`, remember that: + +* The lower bound of each part's byte range + must be a multiple of the part size. +* The higher bound must be a multiple of the part size - 1. + :type content_range: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({'digest': to_string(digest), 'content-range': to_string(content_range), **extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=url, method='PUT', headers=headers_map, file_stream=request_body, content_type='application/octet-stream', response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, UploadedPart) + def upload_file_part(self, upload_session_id: str, request_body: ByteStream, digest: str, content_range: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> UploadedPart: + """ + Uploads a chunk of a file for an upload session. + + The actual endpoint URL is returned by the [`Create upload session`](e://post-files-upload-sessions) + + + and [`Get upload session`](e://get-files-upload-sessions-id) endpoints. + + :param upload_session_id: The ID of the upload session. +Example: "D5E3F7A" + :type upload_session_id: str + :param request_body: Request body of uploadFilePart method + :type request_body: ByteStream + :param digest: The [RFC3230][1] message digest of the chunk uploaded. + +Only SHA1 is supported. The SHA1 digest must be base64 +encoded. The format of this header is as +`sha=BASE64_ENCODED_DIGEST`. + +To get the value for the `SHA` digest, use the +openSSL command to encode the file part: +`openssl sha1 -binary | base64` + +[1]: https://tools.ietf.org/html/rfc3230 + :type digest: str + :param content_range: The byte range of the chunk. + +Must not overlap with the range of a part already +uploaded this session. Each part’s size must be +exactly equal in size to the part size specified +in the upload session that you created. +One exception is the last part of the file, as this can be smaller. + +When providing the value for `content-range`, remember that: + +* The lower bound of each part's byte range + must be a multiple of the part size. +* The higher bound must be a multiple of the part size - 1. + :type content_range: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({'digest': to_string(digest), 'content-range': to_string(content_range), **extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.upload_url, '/2.0/files/upload_sessions/', to_string(upload_session_id)]), method='PUT', headers=headers_map, file_stream=request_body, content_type='application/octet-stream', response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, UploadedPart) + def delete_file_upload_session_by_url(self, url: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Using this method with urls provided in response when creating a new upload session is preferred to use over DeleteFileUploadSessionById method. + + This allows to always upload your content to the closest Box data center and can significantly improve upload speed. + + + Abort an upload session and discard all data uploaded. + + + This cannot be reversed. + + + The actual endpoint URL is returned by the [`Create upload session`](e://post-files-upload-sessions) + + + and [`Get upload session`](e://get-files-upload-sessions-id) endpoints. + + :param url: URL of deleteFileUploadSessionById method + :type url: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=url, method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None + def delete_file_upload_session_by_id(self, upload_session_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Abort an upload session and discard all data uploaded. + + This cannot be reversed. + + + The actual endpoint URL is returned by the [`Create upload session`](e://post-files-upload-sessions) + + + and [`Get upload session`](e://get-files-upload-sessions-id) endpoints. + + :param upload_session_id: The ID of the upload session. +Example: "D5E3F7A" + :type upload_session_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.upload_url, '/2.0/files/upload_sessions/', to_string(upload_session_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None + def get_file_upload_session_parts_by_url(self, url: str, *, offset: Optional[int] = None, limit: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> UploadParts: + """ + Using this method with urls provided in response when creating a new upload session is preferred to use over GetFileUploadSessionParts method. + + This allows to always upload your content to the closest Box data center and can significantly improve upload speed. + + + Return a list of the chunks uploaded to the upload session so far. + + + The actual endpoint URL is returned by the [`Create upload session`](e://post-files-upload-sessions) + + + and [`Get upload session`](e://get-files-upload-sessions-id) endpoints. + + :param url: URL of getFileUploadSessionParts method + :type url: str + :param offset: The offset of the item at which to begin the response. + +Queries with offset parameter value +exceeding 10000 will be rejected +with a 400 response., defaults to None + :type offset: Optional[int], optional + :param limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], 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({'offset': to_string(offset), 'limit': to_string(limit)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=url, method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, UploadParts) + def get_file_upload_session_parts(self, upload_session_id: str, *, offset: Optional[int] = None, limit: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> UploadParts: + """ + Return a list of the chunks uploaded to the upload session so far. + + The actual endpoint URL is returned by the [`Create upload session`](e://post-files-upload-sessions) + + + and [`Get upload session`](e://get-files-upload-sessions-id) endpoints. + + :param upload_session_id: The ID of the upload session. +Example: "D5E3F7A" + :type upload_session_id: str + :param offset: The offset of the item at which to begin the response. + +Queries with offset parameter value +exceeding 10000 will be rejected +with a 400 response., defaults to None + :type offset: Optional[int], optional + :param limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], 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({'offset': to_string(offset), 'limit': to_string(limit)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.upload_url, '/2.0/files/upload_sessions/', to_string(upload_session_id), '/parts']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, UploadParts) + def create_file_upload_session_commit_by_url(self, url: str, parts: List[UploadPart], digest: str, *, if_match: Optional[str] = None, if_none_match: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Optional[Files]: + """ + Using this method with urls provided in response when creating a new upload session is preferred to use over CreateFileUploadSessionCommit method. + + This allows to always upload your content to the closest Box data center and can significantly improve upload speed. + + + Close an upload session and create a file from the uploaded chunks. + + + The actual endpoint URL is returned by the [`Create upload session`](e://post-files-upload-sessions) + + + and [`Get upload session`](e://get-files-upload-sessions-id) endpoints. + + :param url: URL of createFileUploadSessionCommit method + :type url: str + :param parts: The list details for the uploaded parts + :type parts: List[UploadPart] + :param digest: The [RFC3230][1] message digest of the whole file. + +Only SHA1 is supported. The SHA1 digest must be Base64 +encoded. The format of this header is as +`sha=BASE64_ENCODED_DIGEST`. + +[1]: https://tools.ietf.org/html/rfc3230 + :type digest: str + :param if_match: Ensures this item hasn't recently changed before +making changes. + +Pass in the item's last observed `etag` value +into this header and the endpoint will fail +with a `412 Precondition Failed` if it +has changed since., defaults to None + :type if_match: Optional[str], optional + :param if_none_match: Ensures an item is only returned if it has changed. + +Pass in the item's last observed `etag` value +into this header and the endpoint will fail +with a `304 Not Modified` if the item has not +changed since., defaults to None + :type if_none_match: 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 = {} + request_body: Dict = {'parts': parts} + headers_map: Dict[str, str] = prepare_params({'digest': to_string(digest), 'if-match': to_string(if_match), 'if-none-match': to_string(if_none_match), **extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=url, 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)) + if to_string(response.status) == '202': + return None + return deserialize(response.data, Files) + def create_file_upload_session_commit(self, upload_session_id: str, parts: List[UploadPart], digest: str, *, if_match: Optional[str] = None, if_none_match: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Optional[Files]: + """ + Close an upload session and create a file from the uploaded chunks. + + The actual endpoint URL is returned by the [`Create upload session`](e://post-files-upload-sessions) + + + and [`Get upload session`](e://get-files-upload-sessions-id) endpoints. + + :param upload_session_id: The ID of the upload session. +Example: "D5E3F7A" + :type upload_session_id: str + :param parts: The list details for the uploaded parts + :type parts: List[UploadPart] + :param digest: The [RFC3230][1] message digest of the whole file. + +Only SHA1 is supported. The SHA1 digest must be Base64 +encoded. The format of this header is as +`sha=BASE64_ENCODED_DIGEST`. + +[1]: https://tools.ietf.org/html/rfc3230 + :type digest: str + :param if_match: Ensures this item hasn't recently changed before +making changes. + +Pass in the item's last observed `etag` value +into this header and the endpoint will fail +with a `412 Precondition Failed` if it +has changed since., defaults to None + :type if_match: Optional[str], optional + :param if_none_match: Ensures an item is only returned if it has changed. + +Pass in the item's last observed `etag` value +into this header and the endpoint will fail +with a `304 Not Modified` if the item has not +changed since., defaults to None + :type if_none_match: 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 = {} + request_body: Dict = {'parts': parts} + headers_map: Dict[str, str] = prepare_params({'digest': to_string(digest), 'if-match': to_string(if_match), 'if-none-match': to_string(if_none_match), **extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.upload_url, '/2.0/files/upload_sessions/', to_string(upload_session_id), '/commit']), 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)) + if to_string(response.status) == '202': + return None + return deserialize(response.data, Files) + def _reducer(self, acc: _PartAccumulator, chunk: ByteStream) -> _PartAccumulator: + last_index: int = acc.last_index + parts: List[UploadPart] = acc.parts + chunk_buffer: Buffer = read_byte_stream(chunk) + hash: Hash = Hash(algorithm=HashName.SHA1) + hash.update_hash(chunk_buffer) + sha_1: str = hash.digest_hash('base64') + digest: str = ''.join(['sha=', sha_1]) + chunk_size: int = buffer_length(chunk_buffer) + bytes_start: int = last_index + 1 + bytes_end: int = last_index + chunk_size + content_range: str = ''.join(['bytes ', to_string(bytes_start), '-', to_string(bytes_end), '/', to_string(acc.file_size)]) + uploaded_part: UploadedPart = self.upload_file_part_by_url(acc.upload_part_url, generate_byte_stream_from_buffer(chunk_buffer), digest, content_range) + part: UploadPart = uploaded_part.part + part_sha_1: str = hex_to_base_64(part.sha_1) + assert part_sha_1 == sha_1 + assert part.size == chunk_size + assert part.offset == bytes_start + acc.file_hash.update_hash(chunk_buffer) + return _PartAccumulator(last_index=bytes_end, parts=parts + [part], file_size=acc.file_size, upload_part_url=acc.upload_part_url, file_hash=acc.file_hash) + def upload_big_file(self, file: ByteStream, file_name: str, file_size: int, parent_folder_id: str) -> FileFull: + """ + Starts the process of chunk uploading a big file. Should return a File object representing uploaded file. + :param file: The stream of the file to upload. + :type file: ByteStream + :param file_name: The name of the file, which will be used for storage in Box. + :type file_name: str + :param file_size: The total size of the file for the chunked upload in bytes. + :type file_size: int + :param parent_folder_id: The ID of the folder where the file should be uploaded. + :type parent_folder_id: str + """ + upload_session: UploadSession = self.create_file_upload_session(parent_folder_id, file_size, file_name) + upload_part_url: str = upload_session.session_endpoints.upload_part + commit_url: str = upload_session.session_endpoints.commit + list_parts_url: str = upload_session.session_endpoints.list_parts + part_size: int = upload_session.part_size + total_parts: int = upload_session.total_parts + assert part_size * total_parts >= file_size + assert upload_session.num_parts_processed == 0 + file_hash: Hash = Hash(algorithm=HashName.SHA1) + chunks_iterator: Iterator = iterate_chunks(file, part_size, file_size) + results: _PartAccumulator = reduce_iterator(chunks_iterator, self._reducer, _PartAccumulator(last_index=-1, parts=[], file_size=file_size, upload_part_url=upload_part_url, file_hash=file_hash)) + parts: List[UploadPart] = results.parts + processed_session_parts: UploadParts = self.get_file_upload_session_parts_by_url(list_parts_url) + assert processed_session_parts.total_count == total_parts + sha_1: str = file_hash.digest_hash('base64') + digest: str = ''.join(['sha=', sha_1]) + committed_session: Optional[Files] = self.create_file_upload_session_commit_by_url(commit_url, parts, digest) + return committed_session.entries[0] \ No newline at end of file diff --git a/box_sdk_gen/managers/classifications.py b/box_sdk_gen/managers/classifications.py new file mode 100644 index 000000000..4ab43ced5 --- /dev/null +++ b/box_sdk_gen/managers/classifications.py @@ -0,0 +1,424 @@ +from enum import Enum + +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.classification_template import ClassificationTemplate + +from box_sdk_gen.schemas.client_error import ClientError + +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 SerializedData + +class AddClassificationRequestBodyOpField(str, Enum): + ADDENUMOPTION = 'addEnumOption' + +class AddClassificationRequestBodyFieldKeyField(str, Enum): + BOX__SECURITY__CLASSIFICATION__KEY = 'Box__Security__Classification__Key' + +class AddClassificationRequestBodyDataStaticConfigClassificationField(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'classification_definition': 'classificationDefinition', 'color_id': 'colorID', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'classificationDefinition': 'classification_definition', 'colorID': 'color_id', **BaseObject._json_to_fields_mapping} + def __init__(self, *, classification_definition: Optional[str] = None, color_id: Optional[int] = None, **kwargs): + """ + :param classification_definition: A longer description of the classification., defaults to None + :type classification_definition: Optional[str], optional + :param color_id: An internal Box identifier used to assign a color to +a classification label. + +Mapping between a `colorID` and a color may change +without notice. Currently, the color mappings are as +follows. + +* `0`: Yellow +* `1`: Orange +* `2`: Watermelon red +* `3`: Purple rain +* `4`: Light blue +* `5`: Dark blue +* `6`: Light green +* `7`: Gray, defaults to None + :type color_id: Optional[int], optional + """ + super().__init__(**kwargs) + self.classification_definition = classification_definition + self.color_id = color_id + +class AddClassificationRequestBodyDataStaticConfigField(BaseObject): + def __init__(self, *, classification: Optional[AddClassificationRequestBodyDataStaticConfigClassificationField] = None, **kwargs): + """ + :param classification: Additional details for the classification., defaults to None + :type classification: Optional[AddClassificationRequestBodyDataStaticConfigClassificationField], optional + """ + super().__init__(**kwargs) + self.classification = classification + +class AddClassificationRequestBodyDataField(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'static_config': 'staticConfig', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'staticConfig': 'static_config', **BaseObject._json_to_fields_mapping} + def __init__(self, key: str, *, static_config: Optional[AddClassificationRequestBodyDataStaticConfigField] = None, **kwargs): + """ + :param key: The label of the classification as shown in the web and +mobile interfaces. This is the only field required to +add a classification. + :type key: str + :param static_config: A static configuration for the classification., defaults to None + :type static_config: Optional[AddClassificationRequestBodyDataStaticConfigField], optional + """ + super().__init__(**kwargs) + self.key = key + self.static_config = static_config + +class AddClassificationRequestBody(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'field_key': 'fieldKey', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'fieldKey': 'field_key', **BaseObject._json_to_fields_mapping} + def __init__(self, data: AddClassificationRequestBodyDataField, *, op: AddClassificationRequestBodyOpField = AddClassificationRequestBodyOpField.ADDENUMOPTION, field_key: AddClassificationRequestBodyFieldKeyField = AddClassificationRequestBodyFieldKeyField.BOX__SECURITY__CLASSIFICATION__KEY, **kwargs): + """ + :param data: The details of the classification to add. + :type data: AddClassificationRequestBodyDataField + :param op: The type of change to perform on the classification +object., defaults to AddClassificationRequestBodyOpField.ADDENUMOPTION + :type op: AddClassificationRequestBodyOpField, optional + :param field_key: Defines classifications +available in the enterprise., defaults to AddClassificationRequestBodyFieldKeyField.BOX__SECURITY__CLASSIFICATION__KEY + :type field_key: AddClassificationRequestBodyFieldKeyField, optional + """ + super().__init__(**kwargs) + self.data = data + self.op = op + self.field_key = field_key + +class UpdateClassificationRequestBodyOpField(str, Enum): + EDITENUMOPTION = 'editEnumOption' + +class UpdateClassificationRequestBodyFieldKeyField(str, Enum): + BOX__SECURITY__CLASSIFICATION__KEY = 'Box__Security__Classification__Key' + +class UpdateClassificationRequestBodyDataStaticConfigClassificationField(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'classification_definition': 'classificationDefinition', 'color_id': 'colorID', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'classificationDefinition': 'classification_definition', 'colorID': 'color_id', **BaseObject._json_to_fields_mapping} + def __init__(self, *, classification_definition: Optional[str] = None, color_id: Optional[int] = None, **kwargs): + """ + :param classification_definition: A longer description of the classification., defaults to None + :type classification_definition: Optional[str], optional + :param color_id: An internal Box identifier used to assign a color to +a classification label. + +Mapping between a `colorID` and a color may change +without notice. Currently, the color mappings are as +follows. + +* `0`: Yellow +* `1`: Orange +* `2`: Watermelon red +* `3`: Purple rain +* `4`: Light blue +* `5`: Dark blue +* `6`: Light green +* `7`: Gray, defaults to None + :type color_id: Optional[int], optional + """ + super().__init__(**kwargs) + self.classification_definition = classification_definition + self.color_id = color_id + +class UpdateClassificationRequestBodyDataStaticConfigField(BaseObject): + def __init__(self, *, classification: Optional[UpdateClassificationRequestBodyDataStaticConfigClassificationField] = None, **kwargs): + """ + :param classification: Additional details for the classification., defaults to None + :type classification: Optional[UpdateClassificationRequestBodyDataStaticConfigClassificationField], optional + """ + super().__init__(**kwargs) + self.classification = classification + +class UpdateClassificationRequestBodyDataField(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'static_config': 'staticConfig', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'staticConfig': 'static_config', **BaseObject._json_to_fields_mapping} + def __init__(self, key: str, *, static_config: Optional[UpdateClassificationRequestBodyDataStaticConfigField] = None, **kwargs): + """ + :param key: A new label for the classification, as it will be +shown in the web and mobile interfaces. + :type key: str + :param static_config: A static configuration for the classification., defaults to None + :type static_config: Optional[UpdateClassificationRequestBodyDataStaticConfigField], optional + """ + super().__init__(**kwargs) + self.key = key + self.static_config = static_config + +class UpdateClassificationRequestBody(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'field_key': 'fieldKey', 'enum_option_key': 'enumOptionKey', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'fieldKey': 'field_key', 'enumOptionKey': 'enum_option_key', **BaseObject._json_to_fields_mapping} + def __init__(self, enum_option_key: str, data: UpdateClassificationRequestBodyDataField, *, op: UpdateClassificationRequestBodyOpField = UpdateClassificationRequestBodyOpField.EDITENUMOPTION, field_key: UpdateClassificationRequestBodyFieldKeyField = UpdateClassificationRequestBodyFieldKeyField.BOX__SECURITY__CLASSIFICATION__KEY, **kwargs): + """ + :param enum_option_key: The original label of the classification to change. + :type enum_option_key: str + :param data: The details of the updated classification. + :type data: UpdateClassificationRequestBodyDataField + :param op: The type of change to perform on the classification +object., defaults to UpdateClassificationRequestBodyOpField.EDITENUMOPTION + :type op: UpdateClassificationRequestBodyOpField, optional + :param field_key: Defines classifications +available in the enterprise., defaults to UpdateClassificationRequestBodyFieldKeyField.BOX__SECURITY__CLASSIFICATION__KEY + :type field_key: UpdateClassificationRequestBodyFieldKeyField, optional + """ + super().__init__(**kwargs) + self.enum_option_key = enum_option_key + self.data = data + self.op = op + self.field_key = field_key + +class CreateClassificationTemplateScope(str, Enum): + ENTERPRISE = 'enterprise' + +class CreateClassificationTemplateTemplateKey(str, Enum): + SECURITYCLASSIFICATION_6VMVOCHWUWO = 'securityClassification-6VMVochwUWo' + +class CreateClassificationTemplateDisplayName(str, Enum): + CLASSIFICATION = 'Classification' + +class CreateClassificationTemplateFieldsTypeField(str, Enum): + ENUM = 'enum' + +class CreateClassificationTemplateFieldsKeyField(str, Enum): + BOX__SECURITY__CLASSIFICATION__KEY = 'Box__Security__Classification__Key' + +class CreateClassificationTemplateFieldsDisplayNameField(str, Enum): + CLASSIFICATION = 'Classification' + +class CreateClassificationTemplateFieldsOptionsStaticConfigClassificationField(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'classification_definition': 'classificationDefinition', 'color_id': 'colorID', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'classificationDefinition': 'classification_definition', 'colorID': 'color_id', **BaseObject._json_to_fields_mapping} + def __init__(self, *, classification_definition: Optional[str] = None, color_id: Optional[int] = None, **kwargs): + """ + :param classification_definition: A longer description of the classification., defaults to None + :type classification_definition: Optional[str], optional + :param color_id: An identifier used to assign a color to +a classification label. + +Mapping between a `colorID` and a color may +change without notice. Currently, the color +mappings are as follows. + +* `0`: Yellow +* `1`: Orange +* `2`: Watermelon red +* `3`: Purple rain +* `4`: Light blue +* `5`: Dark blue +* `6`: Light green +* `7`: Gray, defaults to None + :type color_id: Optional[int], optional + """ + super().__init__(**kwargs) + self.classification_definition = classification_definition + self.color_id = color_id + +class CreateClassificationTemplateFieldsOptionsStaticConfigField(BaseObject): + def __init__(self, *, classification: Optional[CreateClassificationTemplateFieldsOptionsStaticConfigClassificationField] = None, **kwargs): + """ + :param classification: Additional information about the classification., defaults to None + :type classification: Optional[CreateClassificationTemplateFieldsOptionsStaticConfigClassificationField], optional + """ + super().__init__(**kwargs) + self.classification = classification + +class CreateClassificationTemplateFieldsOptionsField(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'static_config': 'staticConfig', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'staticConfig': 'static_config', **BaseObject._json_to_fields_mapping} + def __init__(self, key: str, *, static_config: Optional[CreateClassificationTemplateFieldsOptionsStaticConfigField] = None, **kwargs): + """ + :param key: The display name and key this classification. This +will be show in the Box UI. + :type key: str + :param static_config: Additional information about the classification., defaults to None + :type static_config: Optional[CreateClassificationTemplateFieldsOptionsStaticConfigField], optional + """ + super().__init__(**kwargs) + self.key = key + self.static_config = static_config + +class CreateClassificationTemplateFields(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'display_name': 'displayName', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'displayName': 'display_name', **BaseObject._json_to_fields_mapping} + _discriminator = 'type', {'enum'} + def __init__(self, options: List[CreateClassificationTemplateFieldsOptionsField], *, type: CreateClassificationTemplateFieldsTypeField = CreateClassificationTemplateFieldsTypeField.ENUM, key: CreateClassificationTemplateFieldsKeyField = CreateClassificationTemplateFieldsKeyField.BOX__SECURITY__CLASSIFICATION__KEY, display_name: CreateClassificationTemplateFieldsDisplayNameField = CreateClassificationTemplateFieldsDisplayNameField.CLASSIFICATION, hidden: Optional[bool] = None, **kwargs): + """ + :param options: The actual list of classifications that are present on +this template. + :type options: List[CreateClassificationTemplateFieldsOptionsField] + :param type: The type of the field +that is always enum., defaults to CreateClassificationTemplateFieldsTypeField.ENUM + :type type: CreateClassificationTemplateFieldsTypeField, optional + :param key: Defines classifications +available in the enterprise., defaults to CreateClassificationTemplateFieldsKeyField.BOX__SECURITY__CLASSIFICATION__KEY + :type key: CreateClassificationTemplateFieldsKeyField, optional + :param display_name: A display name for the classification., defaults to CreateClassificationTemplateFieldsDisplayNameField.CLASSIFICATION + :type display_name: CreateClassificationTemplateFieldsDisplayNameField, optional + :param hidden: Determines if the classification +template is +hidden or available on +web and mobile +devices., defaults to None + :type hidden: Optional[bool], optional + """ + super().__init__(**kwargs) + self.options = options + self.type = type + self.key = key + self.display_name = display_name + self.hidden = hidden + +class ClassificationsManager: + 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_classification_template(self, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ClassificationTemplate: + """ + Retrieves the classification metadata template and lists all the + + classifications available to this enterprise. + + + This API can also be called by including the enterprise ID in the + + + URL explicitly, for example + + + `/metadata_templates/enterprise_12345/securityClassification-6VMVochwUWo/schema`. + + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/metadata_templates/enterprise/securityClassification-6VMVochwUWo/schema']), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, ClassificationTemplate) + def add_classification(self, request_body: List[AddClassificationRequestBody], *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ClassificationTemplate: + """ + Adds one or more new classifications to the list of classifications + + available to the enterprise. + + + This API can also be called by including the enterprise ID in the + + + URL explicitly, for example + + + `/metadata_templates/enterprise_12345/securityClassification-6VMVochwUWo/schema`. + + :param request_body: Request body of addClassification method + :type request_body: List[AddClassificationRequestBody] + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/metadata_templates/enterprise/securityClassification-6VMVochwUWo/schema#add']), method='PUT', 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, ClassificationTemplate) + def update_classification(self, request_body: List[UpdateClassificationRequestBody], *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ClassificationTemplate: + """ + Updates the labels and descriptions of one or more classifications + + available to the enterprise. + + + This API can also be called by including the enterprise ID in the + + + URL explicitly, for example + + + `/metadata_templates/enterprise_12345/securityClassification-6VMVochwUWo/schema`. + + :param request_body: Request body of updateClassification method + :type request_body: List[UpdateClassificationRequestBody] + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/metadata_templates/enterprise/securityClassification-6VMVochwUWo/schema#update']), method='PUT', headers=headers_map, data=serialize(request_body), content_type='application/json-patch+json', response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, ClassificationTemplate) + def create_classification_template(self, fields: List[CreateClassificationTemplateFields], *, scope: CreateClassificationTemplateScope = CreateClassificationTemplateScope.ENTERPRISE, template_key: CreateClassificationTemplateTemplateKey = CreateClassificationTemplateTemplateKey.SECURITYCLASSIFICATION_6VMVOCHWUWO, display_name: CreateClassificationTemplateDisplayName = CreateClassificationTemplateDisplayName.CLASSIFICATION, hidden: Optional[bool] = None, copy_instance_on_item_copy: Optional[bool] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ClassificationTemplate: + """ + When an enterprise does not yet have any classifications, this API call + + initializes the classification template with an initial set of + + + classifications. + + + If an enterprise already has a classification, the template will already + + + exist and instead an API call should be made to add additional + + + classifications. + + :param fields: The classification template requires exactly +one field, which holds +all the valid classification values. + :type fields: List[CreateClassificationTemplateFields] + :param scope: The scope in which to create the classifications. This should +be `enterprise` or `enterprise_{id}` where `id` is the unique +ID of the enterprise., defaults to CreateClassificationTemplateScope.ENTERPRISE + :type scope: CreateClassificationTemplateScope, optional + :param template_key: Defines the list of metadata templates., defaults to CreateClassificationTemplateTemplateKey.SECURITYCLASSIFICATION_6VMVOCHWUWO + :type template_key: CreateClassificationTemplateTemplateKey, optional + :param display_name: The name of the +template as shown in web and mobile interfaces., defaults to CreateClassificationTemplateDisplayName.CLASSIFICATION + :type display_name: CreateClassificationTemplateDisplayName, optional + :param hidden: Determines if the classification template is +hidden or available on web and mobile +devices., defaults to None + :type hidden: Optional[bool], optional + :param copy_instance_on_item_copy: Determines if classifications are +copied along when the file or folder is +copied., defaults to None + :type copy_instance_on_item_copy: Optional[bool], 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 = {'scope': scope, 'templateKey': template_key, 'displayName': display_name, 'hidden': hidden, 'copyInstanceOnItemCopy': copy_instance_on_item_copy, 'fields': fields} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/metadata_templates/schema#classifications']), 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, ClassificationTemplate) \ No newline at end of file diff --git a/box_sdk_gen/managers/collaboration_allowlist_entries.py b/box_sdk_gen/managers/collaboration_allowlist_entries.py new file mode 100644 index 000000000..677b07f22 --- /dev/null +++ b/box_sdk_gen/managers/collaboration_allowlist_entries.py @@ -0,0 +1,126 @@ +from enum import Enum + +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.collaboration_allowlist_entries import CollaborationAllowlistEntries + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.collaboration_allowlist_entry import CollaborationAllowlistEntry + +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 CreateCollaborationWhitelistEntryDirection(str, Enum): + INBOUND = 'inbound' + OUTBOUND = 'outbound' + BOTH = 'both' + +class CollaborationAllowlistEntriesManager: + 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_collaboration_whitelist_entries(self, *, marker: Optional[str] = None, limit: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> CollaborationAllowlistEntries: + """ + Returns the list domains that have been deemed safe to create collaborations + + for within the current enterprise. + + :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 limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], 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({'marker': to_string(marker), 'limit': to_string(limit)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/collaboration_whitelist_entries']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, CollaborationAllowlistEntries) + def create_collaboration_whitelist_entry(self, domain: str, direction: CreateCollaborationWhitelistEntryDirection, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> CollaborationAllowlistEntry: + """ + Creates a new entry in the list of allowed domains to allow + + collaboration for. + + :param domain: The domain to add to the list of allowed domains. + :type domain: str + :param direction: The direction in which to allow collaborations. + :type direction: CreateCollaborationWhitelistEntryDirection + :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 = {'domain': domain, 'direction': direction} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/collaboration_whitelist_entries']), 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, CollaborationAllowlistEntry) + def get_collaboration_whitelist_entry_by_id(self, collaboration_whitelist_entry_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> CollaborationAllowlistEntry: + """ + Returns a domain that has been deemed safe to create collaborations + + for within the current enterprise. + + :param collaboration_whitelist_entry_id: The ID of the entry in the list. +Example: "213123" + :type collaboration_whitelist_entry_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/collaboration_whitelist_entries/', to_string(collaboration_whitelist_entry_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, CollaborationAllowlistEntry) + def delete_collaboration_whitelist_entry_by_id(self, collaboration_whitelist_entry_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Removes a domain from the list of domains that have been deemed safe to create + + collaborations for within the current enterprise. + + :param collaboration_whitelist_entry_id: The ID of the entry in the list. +Example: "213123" + :type collaboration_whitelist_entry_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/collaboration_whitelist_entries/', to_string(collaboration_whitelist_entry_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/collaboration_allowlist_exempt_targets.py b/box_sdk_gen/managers/collaboration_allowlist_exempt_targets.py new file mode 100644 index 000000000..adfdd0343 --- /dev/null +++ b/box_sdk_gen/managers/collaboration_allowlist_exempt_targets.py @@ -0,0 +1,128 @@ +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.collaboration_allowlist_exempt_targets import CollaborationAllowlistExemptTargets + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.collaboration_allowlist_exempt_target import CollaborationAllowlistExemptTarget + +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 CreateCollaborationWhitelistExemptTargetUser(BaseObject): + def __init__(self, id: str, **kwargs): + """ + :param id: The ID of the user to exempt. + :type id: str + """ + super().__init__(**kwargs) + self.id = id + +class CollaborationAllowlistExemptTargetsManager: + 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_collaboration_whitelist_exempt_targets(self, *, marker: Optional[str] = None, limit: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> CollaborationAllowlistExemptTargets: + """ + Returns a list of users who have been exempt from the collaboration + + domain restrictions. + + :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 limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], 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({'marker': to_string(marker), 'limit': to_string(limit)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/collaboration_whitelist_exempt_targets']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, CollaborationAllowlistExemptTargets) + def create_collaboration_whitelist_exempt_target(self, user: CreateCollaborationWhitelistExemptTargetUser, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> CollaborationAllowlistExemptTarget: + """ + Exempts a user from the restrictions set out by the allowed list of domains + + for collaborations. + + :param user: The user to exempt. + :type user: CreateCollaborationWhitelistExemptTargetUser + :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 = {'user': user} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/collaboration_whitelist_exempt_targets']), 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, CollaborationAllowlistExemptTarget) + def get_collaboration_whitelist_exempt_target_by_id(self, collaboration_whitelist_exempt_target_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> CollaborationAllowlistExemptTarget: + """ + Returns a users who has been exempt from the collaboration + + domain restrictions. + + :param collaboration_whitelist_exempt_target_id: The ID of the exemption to the list. +Example: "984923" + :type collaboration_whitelist_exempt_target_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/collaboration_whitelist_exempt_targets/', to_string(collaboration_whitelist_exempt_target_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, CollaborationAllowlistExemptTarget) + def delete_collaboration_whitelist_exempt_target_by_id(self, collaboration_whitelist_exempt_target_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Removes a user's exemption from the restrictions set out by the allowed list + + of domains for collaborations. + + :param collaboration_whitelist_exempt_target_id: The ID of the exemption to the list. +Example: "984923" + :type collaboration_whitelist_exempt_target_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/collaboration_whitelist_exempt_targets/', to_string(collaboration_whitelist_exempt_target_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/collections.py b/box_sdk_gen/managers/collections.py new file mode 100644 index 000000000..e96cfeddc --- /dev/null +++ b/box_sdk_gen/managers/collections.py @@ -0,0 +1,132 @@ +from typing import Optional + +from typing import List + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.collections import Collections + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.items_offset_paginated import ItemsOffsetPaginated + +from box_sdk_gen.schemas.collection import Collection + +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 CollectionsManager: + 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_collections(self, *, fields: Optional[List[str]] = None, offset: Optional[int] = None, limit: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Collections: + """ + Retrieves all collections for a given user. + + Currently, only the `favorites` collection + + + is supported. + + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[str]], optional + :param offset: The offset of the item at which to begin the response. + +Queries with offset parameter value +exceeding 10000 will be rejected +with a 400 response., defaults to None + :type offset: Optional[int], optional + :param limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], 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({'fields': to_string(fields), 'offset': to_string(offset), 'limit': to_string(limit)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/collections']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Collections) + def get_collection_items(self, collection_id: str, *, fields: Optional[List[str]] = None, offset: Optional[int] = None, limit: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ItemsOffsetPaginated: + """ + Retrieves the files and/or folders contained within + + this collection. + + :param collection_id: The ID of the collection. +Example: "926489" + :type collection_id: str + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[str]], optional + :param offset: The offset of the item at which to begin the response. + +Queries with offset parameter value +exceeding 10000 will be rejected +with a 400 response., defaults to None + :type offset: Optional[int], optional + :param limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], 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({'fields': to_string(fields), 'offset': to_string(offset), 'limit': to_string(limit)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/collections/', to_string(collection_id), '/items']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, ItemsOffsetPaginated) + def get_collection_by_id(self, collection_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Collection: + """ + Retrieves a collection by its ID. + :param collection_id: The ID of the collection. +Example: "926489" + :type collection_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/collections/', to_string(collection_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Collection) \ No newline at end of file diff --git a/box_sdk_gen/managers/comments.py b/box_sdk_gen/managers/comments.py new file mode 100644 index 000000000..2403edca9 --- /dev/null +++ b/box_sdk_gen/managers/comments.py @@ -0,0 +1,221 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Optional + +from typing import List + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.comments import Comments + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.comment_full import CommentFull + +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 CreateCommentItemTypeField(str, Enum): + FILE = 'file' + COMMENT = 'comment' + +class CreateCommentItem(BaseObject): + _discriminator = 'type', {'file', 'comment'} + def __init__(self, id: str, type: CreateCommentItemTypeField, **kwargs): + """ + :param id: The ID of the item + :type id: str + :param type: The type of the item that this comment will be placed on. + :type type: CreateCommentItemTypeField + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class CommentsManager: + 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_comments(self, file_id: str, *, fields: Optional[List[str]] = None, limit: Optional[int] = None, offset: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Comments: + """ + Retrieves a list of comments for a file. + :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 fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[str]], optional + :param limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], optional + :param offset: The offset of the item at which to begin the response. + +Queries with offset parameter value +exceeding 10000 will be rejected +with a 400 response., defaults to None + :type offset: Optional[int], 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({'fields': to_string(fields), 'limit': to_string(limit), 'offset': to_string(offset)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/comments']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Comments) + def get_comment_by_id(self, comment_id: str, *, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> CommentFull: + """ + Retrieves the message and metadata for a specific comment, as well + + as information on the user who created the comment. + + :param comment_id: The ID of the comment. +Example: "12345" + :type comment_id: str + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/comments/', to_string(comment_id)]), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, CommentFull) + def update_comment_by_id(self, comment_id: str, *, message: Optional[str] = None, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> CommentFull: + """ + Update the message of a comment. + :param comment_id: The ID of the comment. +Example: "12345" + :type comment_id: str + :param message: The text of the comment to update, defaults to None + :type message: Optional[str], optional + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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 = {} + request_body: Dict = {'message': message} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/comments/', to_string(comment_id)]), method='PUT', params=query_params_map, 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, CommentFull) + def delete_comment_by_id(self, comment_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Permanently deletes a comment. + :param comment_id: The ID of the comment. +Example: "12345" + :type comment_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/comments/', to_string(comment_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None + def create_comment(self, message: str, item: CreateCommentItem, *, tagged_message: Optional[str] = None, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> CommentFull: + """ + Adds a comment by the user to a specific file, or + + as a reply to an other comment. + + :param message: The text of the comment. + +To mention a user, use the `tagged_message` +parameter instead. + :type message: str + :param item: The item to attach the comment to. + :type item: CreateCommentItem + :param tagged_message: The text of the comment, including `@[user_id:name]` +somewhere in the message to mention another user, which +will send them an email notification, letting them know +they have been mentioned. + +The `user_id` is the target user's ID, where the `name` +can be any custom phrase. In the Box UI this name will +link to the user's profile. + +If you are not mentioning another user, use `message` +instead., defaults to None + :type tagged_message: Optional[str], optional + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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 = {} + request_body: Dict = {'message': message, 'tagged_message': tagged_message, 'item': item} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/comments']), method='POST', params=query_params_map, 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, CommentFull) \ No newline at end of file diff --git a/box_sdk_gen/managers/device_pinners.py b/box_sdk_gen/managers/device_pinners.py new file mode 100644 index 000000000..cbdd60d78 --- /dev/null +++ b/box_sdk_gen/managers/device_pinners.py @@ -0,0 +1,107 @@ +from enum import Enum + +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.device_pinner import DevicePinner + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.device_pinners import DevicePinners + +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 GetEnterpriseDevicePinnersDirection(str, Enum): + ASC = 'ASC' + DESC = 'DESC' + +class DevicePinnersManager: + 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_device_pinner_by_id(self, device_pinner_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> DevicePinner: + """ + Retrieves information about an individual device pin. + :param device_pinner_id: The ID of the device pin +Example: "2324234" + :type device_pinner_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/device_pinners/', to_string(device_pinner_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, DevicePinner) + def delete_device_pinner_by_id(self, device_pinner_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Deletes an individual device pin. + :param device_pinner_id: The ID of the device pin +Example: "2324234" + :type device_pinner_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/device_pinners/', to_string(device_pinner_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None + def get_enterprise_device_pinners(self, enterprise_id: str, *, marker: Optional[str] = None, limit: Optional[int] = None, direction: Optional[GetEnterpriseDevicePinnersDirection] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> DevicePinners: + """ + Retrieves all the device pins within an enterprise. + + The user must have admin privileges, and the application + + + needs the "manage enterprise" scope to make this call. + + :param enterprise_id: The ID of the enterprise +Example: "3442311" + :type enterprise_id: str + :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 limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], optional + :param direction: The direction to sort results in. This can be either in alphabetical ascending +(`ASC`) or descending (`DESC`) order., defaults to None + :type direction: Optional[GetEnterpriseDevicePinnersDirection], 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({'marker': to_string(marker), 'limit': to_string(limit), 'direction': to_string(direction)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/enterprises/', to_string(enterprise_id), '/device_pinners']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, DevicePinners) \ No newline at end of file diff --git a/box_sdk_gen/managers/docgen.py b/box_sdk_gen/managers/docgen.py new file mode 100644 index 000000000..db2741fc6 --- /dev/null +++ b/box_sdk_gen/managers/docgen.py @@ -0,0 +1,159 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from typing import List + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.v2025_r0.file_reference_v2025_r0 import FileReferenceV2025R0 + +from box_sdk_gen.schemas.v2025_r0.file_version_base_v2025_r0 import FileVersionBaseV2025R0 + +from box_sdk_gen.schemas.v2025_r0.doc_gen_document_generation_data_v2025_r0 import DocGenDocumentGenerationDataV2025R0 + +from box_sdk_gen.schemas.v2025_r0.doc_gen_job_v2025_r0 import DocGenJobV2025R0 + +from box_sdk_gen.schemas.v2025_r0.client_error_v2025_r0 import ClientErrorV2025R0 + +from box_sdk_gen.parameters.v2025_r0.box_version_header_v2025_r0 import BoxVersionHeaderV2025R0 + +from box_sdk_gen.schemas.v2025_r0.doc_gen_jobs_full_v2025_r0 import DocGenJobsFullV2025R0 + +from box_sdk_gen.schemas.v2025_r0.doc_gen_jobs_v2025_r0 import DocGenJobsV2025R0 + +from box_sdk_gen.schemas.v2025_r0.doc_gen_batch_base_v2025_r0 import DocGenBatchBaseV2025R0 + +from box_sdk_gen.schemas.v2025_r0.doc_gen_batch_create_request_v2025_r0 import DocGenBatchCreateRequestV2025R0 + +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 CreateDocgenBatchV2025R0DestinationFolderTypeField(str, Enum): + FOLDER = 'folder' + +class CreateDocgenBatchV2025R0DestinationFolder(BaseObject): + _discriminator = 'type', {'folder'} + def __init__(self, id: str, *, type: CreateDocgenBatchV2025R0DestinationFolderTypeField = CreateDocgenBatchV2025R0DestinationFolderTypeField.FOLDER, **kwargs): + """ + :param id: ID of the folder + :type id: str + :param type: `folder`, defaults to CreateDocgenBatchV2025R0DestinationFolderTypeField.FOLDER + :type type: CreateDocgenBatchV2025R0DestinationFolderTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class DocgenManager: + 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_docgen_job_by_id_v2025_r0(self, job_id: str, *, box_version: BoxVersionHeaderV2025R0 = BoxVersionHeaderV2025R0._2025_0, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> DocGenJobV2025R0: + """ + Get details of the Box Doc Gen job. + :param job_id: Box Doc Gen job ID. +Example: 123 + :type job_id: str + :param box_version: Version header, defaults to BoxVersionHeaderV2025R0._2025_0 + :type box_version: BoxVersionHeaderV2025R0, 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 = {} + 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/docgen_jobs/', to_string(job_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, DocGenJobV2025R0) + def get_docgen_jobs_v2025_r0(self, *, marker: Optional[str] = None, limit: Optional[int] = None, box_version: BoxVersionHeaderV2025R0 = BoxVersionHeaderV2025R0._2025_0, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> DocGenJobsFullV2025R0: + """ + Lists all Box Doc Gen jobs for a user. + :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 limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], optional + :param box_version: Version header, defaults to BoxVersionHeaderV2025R0._2025_0 + :type box_version: BoxVersionHeaderV2025R0, 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({'marker': to_string(marker), 'limit': to_string(limit)}) + 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/docgen_jobs']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, DocGenJobsFullV2025R0) + def get_docgen_batch_job_by_id_v2025_r0(self, batch_id: str, *, marker: Optional[str] = None, limit: Optional[int] = None, box_version: BoxVersionHeaderV2025R0 = BoxVersionHeaderV2025R0._2025_0, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> DocGenJobsV2025R0: + """ + Lists Box Doc Gen jobs in a batch + :param batch_id: Box Doc Gen batch ID. +Example: 123 + :type batch_id: str + :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 limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], optional + :param box_version: Version header, defaults to BoxVersionHeaderV2025R0._2025_0 + :type box_version: BoxVersionHeaderV2025R0, 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({'marker': to_string(marker), 'limit': to_string(limit)}) + 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/docgen_batch_jobs/', to_string(batch_id)]), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, DocGenJobsV2025R0) + def create_docgen_batch_v2025_r0(self, file: FileReferenceV2025R0, input_source: str, destination_folder: CreateDocgenBatchV2025R0DestinationFolder, output_type: str, document_generation_data: List[DocGenDocumentGenerationDataV2025R0], *, file_version: Optional[FileVersionBaseV2025R0] = None, box_version: BoxVersionHeaderV2025R0 = BoxVersionHeaderV2025R0._2025_0, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> DocGenBatchBaseV2025R0: + """ + Generates a document using a Box Doc Gen template. + :param input_source: Source of input. The value has to be `api` for all the API-based document generation requests. + :type input_source: str + :param output_type: Type of the output file. + :type output_type: str + :param box_version: Version header, defaults to BoxVersionHeaderV2025R0._2025_0 + :type box_version: BoxVersionHeaderV2025R0, 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 = {'file': file, 'file_version': file_version, 'input_source': input_source, 'destination_folder': destination_folder, 'output_type': output_type, 'document_generation_data': document_generation_data} + 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/docgen_batches']), 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, DocGenBatchBaseV2025R0) \ No newline at end of file diff --git a/box_sdk_gen/managers/docgen_template.py b/box_sdk_gen/managers/docgen_template.py new file mode 100644 index 000000000..fbabd3027 --- /dev/null +++ b/box_sdk_gen/managers/docgen_template.py @@ -0,0 +1,175 @@ +from typing import Optional + +from typing import Dict + +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.v2025_r0.file_reference_v2025_r0 import FileReferenceV2025R0 + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.v2025_r0.doc_gen_template_base_v2025_r0 import DocGenTemplateBaseV2025R0 + +from box_sdk_gen.schemas.v2025_r0.client_error_v2025_r0 import ClientErrorV2025R0 + +from box_sdk_gen.parameters.v2025_r0.box_version_header_v2025_r0 import BoxVersionHeaderV2025R0 + +from box_sdk_gen.schemas.v2025_r0.doc_gen_template_create_request_v2025_r0 import DocGenTemplateCreateRequestV2025R0 + +from box_sdk_gen.schemas.v2025_r0.doc_gen_templates_v2025_r0 import DocGenTemplatesV2025R0 + +from box_sdk_gen.schemas.v2025_r0.doc_gen_template_v2025_r0 import DocGenTemplateV2025R0 + +from box_sdk_gen.schemas.v2025_r0.doc_gen_tags_v2025_r0 import DocGenTagsV2025R0 + +from box_sdk_gen.schemas.v2025_r0.doc_gen_tags_processing_message_v2025_r0 import DocGenTagsProcessingMessageV2025R0 + +from box_sdk_gen.schemas.v2025_r0.doc_gen_jobs_v2025_r0 import DocGenJobsV2025R0 + +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 DocgenTemplateManager: + 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_docgen_template_v2025_r0(self, file: FileReferenceV2025R0, *, box_version: BoxVersionHeaderV2025R0 = BoxVersionHeaderV2025R0._2025_0, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> DocGenTemplateBaseV2025R0: + """ + Marks a file as a Box Doc Gen template. + :param box_version: Version header, defaults to BoxVersionHeaderV2025R0._2025_0 + :type box_version: BoxVersionHeaderV2025R0, 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 = {'file': file} + 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/docgen_templates']), 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, DocGenTemplateBaseV2025R0) + def get_docgen_templates_v2025_r0(self, *, marker: Optional[str] = None, limit: Optional[int] = None, box_version: BoxVersionHeaderV2025R0 = BoxVersionHeaderV2025R0._2025_0, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> DocGenTemplatesV2025R0: + """ + Lists Box Doc Gen templates on which the user is a collaborator. + :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 limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], optional + :param box_version: Version header, defaults to BoxVersionHeaderV2025R0._2025_0 + :type box_version: BoxVersionHeaderV2025R0, 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({'marker': to_string(marker), 'limit': to_string(limit)}) + 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/docgen_templates']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, DocGenTemplatesV2025R0) + def delete_docgen_template_by_id_v2025_r0(self, template_id: str, *, box_version: BoxVersionHeaderV2025R0 = BoxVersionHeaderV2025R0._2025_0, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Unmarks file as Box Doc Gen template + :param template_id: ID of the file which will no longer be marked as a Box Doc Gen template. +Example: "123" + :type template_id: str + :param box_version: Version header, defaults to BoxVersionHeaderV2025R0._2025_0 + :type box_version: BoxVersionHeaderV2025R0, 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 = {} + 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/docgen_templates/', to_string(template_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None + def get_docgen_template_by_id_v2025_r0(self, template_id: str, *, box_version: BoxVersionHeaderV2025R0 = BoxVersionHeaderV2025R0._2025_0, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> DocGenTemplateV2025R0: + """ + Lists details of a specific Box Doc Gen template. + :param template_id: The ID of a Box Doc Gen template. +Example: 123 + :type template_id: str + :param box_version: Version header, defaults to BoxVersionHeaderV2025R0._2025_0 + :type box_version: BoxVersionHeaderV2025R0, 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 = {} + 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/docgen_templates/', to_string(template_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, DocGenTemplateV2025R0) + def get_docgen_template_tags_v2025_r0(self, template_id: str, *, template_version_id: Optional[str] = None, marker: Optional[str] = None, limit: Optional[int] = None, box_version: BoxVersionHeaderV2025R0 = BoxVersionHeaderV2025R0._2025_0, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> DocGenTagsV2025R0: + """ + Lists all tags in a Box Doc Gen template. + :param template_id: ID of template. +Example: 123 + :type template_id: str + :param template_version_id: Id of template version., defaults to None + :type template_version_id: Optional[str], 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 limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], optional + :param box_version: Version header, defaults to BoxVersionHeaderV2025R0._2025_0 + :type box_version: BoxVersionHeaderV2025R0, 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({'template_version_id': to_string(template_version_id), 'marker': to_string(marker), 'limit': to_string(limit)}) + 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/docgen_templates/', to_string(template_id), '/tags']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, DocGenTagsV2025R0) + def get_docgen_template_job_by_id_v2025_r0(self, template_id: str, *, marker: Optional[str] = None, limit: Optional[int] = None, box_version: BoxVersionHeaderV2025R0 = BoxVersionHeaderV2025R0._2025_0, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> DocGenJobsV2025R0: + """ + Lists the users jobs which use this template. + :param template_id: Id of template to fetch jobs for. +Example: 123 + :type template_id: str + :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 limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], optional + :param box_version: Version header, defaults to BoxVersionHeaderV2025R0._2025_0 + :type box_version: BoxVersionHeaderV2025R0, 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({'marker': to_string(marker), 'limit': to_string(limit)}) + 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/docgen_template_jobs/', to_string(template_id)]), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, DocGenJobsV2025R0) \ No newline at end of file diff --git a/box_sdk_gen/managers/downloads.py b/box_sdk_gen/managers/downloads.py new file mode 100644 index 000000000..39e13dfc7 --- /dev/null +++ b/box_sdk_gen/managers/downloads.py @@ -0,0 +1,169 @@ +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.client_error import ClientError + +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.internal.utils import write_input_stream_to_output_stream + +from box_sdk_gen.internal.utils import OutputStream + +class DownloadsManager: + 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_download_file_url(self, file_id: str, *, version: Optional[str] = None, access_token: Optional[str] = None, range: Optional[str] = None, boxapi: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> str: + """ + Returns the contents of a file in binary format. + :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 version: The file version to download, defaults to None + :type version: Optional[str], optional + :param access_token: An optional access token that can be used to pre-authenticate this request, which means that a download link can be shared with a browser or a third party service without them needing to know how to handle the authentication. +When using this parameter, please make sure that the access token is sufficiently scoped down to only allow read access to that file and no other files or folders., defaults to None + :type access_token: Optional[str], optional + :param range: The byte range of the content to download. + +The format `bytes={start_byte}-{end_byte}` can be used to specify +what section of the file to download., defaults to None + :type range: Optional[str], optional + :param boxapi: The URL, and optional password, for the shared link of this item. + +This header can be used to access items that have not been +explicitly shared with a user. + +Use the format `shared_link=[link]` or if a password is required then +use `shared_link=[link]&shared_link_password=[password]`. + +This header can be used on the file or folder shared, as well as on any files +or folders nested within the item., defaults to None + :type boxapi: 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({'version': to_string(version), 'access_token': to_string(access_token)}) + headers_map: Dict[str, str] = prepare_params({'range': to_string(range), 'boxapi': to_string(boxapi), **extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/content']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session, follow_redirects=False)) + if 'location' in response.headers: + return response.headers.get('location') + if 'Location' in response.headers: + return response.headers.get('Location') + raise BoxSDKError(message='No location header in response') + def download_file(self, file_id: str, *, version: Optional[str] = None, access_token: Optional[str] = None, range: Optional[str] = None, boxapi: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Optional[ByteStream]: + """ + Returns the contents of a file in binary format. + :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 version: The file version to download, defaults to None + :type version: Optional[str], optional + :param access_token: An optional access token that can be used to pre-authenticate this request, which means that a download link can be shared with a browser or a third party service without them needing to know how to handle the authentication. +When using this parameter, please make sure that the access token is sufficiently scoped down to only allow read access to that file and no other files or folders., defaults to None + :type access_token: Optional[str], optional + :param range: The byte range of the content to download. + +The format `bytes={start_byte}-{end_byte}` can be used to specify +what section of the file to download., defaults to None + :type range: Optional[str], optional + :param boxapi: The URL, and optional password, for the shared link of this item. + +This header can be used to access items that have not been +explicitly shared with a user. + +Use the format `shared_link=[link]` or if a password is required then +use `shared_link=[link]&shared_link_password=[password]`. + +This header can be used on the file or folder shared, as well as on any files +or folders nested within the item., defaults to None + :type boxapi: 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({'version': to_string(version), 'access_token': to_string(access_token)}) + headers_map: Dict[str, str] = prepare_params({'range': to_string(range), 'boxapi': to_string(boxapi), **extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/content']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.BINARY, auth=self.auth, network_session=self.network_session)) + if to_string(response.status) == '202': + return None + return response.content + def download_file_to_output_stream(self, file_id: str, output_stream: OutputStream, *, version: Optional[str] = None, access_token: Optional[str] = None, range: Optional[str] = None, boxapi: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + :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 output_stream: Download file to a given output stream + :type output_stream: OutputStream + :param version: The file version to download, defaults to None + :type version: Optional[str], optional + :param access_token: An optional access token that can be used to pre-authenticate this request, which means that a download link can be shared with a browser or a third party service without them needing to know how to handle the authentication. +When using this parameter, please make sure that the access token is sufficiently scoped down to only allow read access to that file and no other files or folders., defaults to None + :type access_token: Optional[str], optional + :param range: The byte range of the content to download. + +The format `bytes={start_byte}-{end_byte}` can be used to specify +what section of the file to download., defaults to None + :type range: Optional[str], optional + :param boxapi: The URL, and optional password, for the shared link of this item. + +This header can be used to access items that have not been +explicitly shared with a user. + +Use the format `shared_link=[link]` or if a password is required then +use `shared_link=[link]&shared_link_password=[password]`. + +This header can be used on the file or folder shared, as well as on any files +or folders nested within the item., defaults to None + :type boxapi: 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 = {} + download_stream: ByteStream = self.download_file(file_id, version=version, access_token=access_token, range=range, boxapi=boxapi, extra_headers=extra_headers) + write_input_stream_to_output_stream(download_stream, output_stream) \ No newline at end of file diff --git a/box_sdk_gen/managers/email_aliases.py b/box_sdk_gen/managers/email_aliases.py new file mode 100644 index 000000000..a2e0a0978 --- /dev/null +++ b/box_sdk_gen/managers/email_aliases.py @@ -0,0 +1,101 @@ +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.email_aliases import EmailAliases + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.email_alias import EmailAlias + +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 EmailAliasesManager: + 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_user_email_aliases(self, user_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> EmailAliases: + """ + Retrieves all email aliases for a user. The collection + + does not include the primary login for the user. + + :param user_id: The ID of the user. +Example: "12345" + :type user_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/users/', to_string(user_id), '/email_aliases']), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, EmailAliases) + def create_user_email_alias(self, user_id: str, email: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> EmailAlias: + """ + Adds a new email alias to a user account.. + :param user_id: The ID of the user. +Example: "12345" + :type user_id: str + :param email: The email address to add to the account as an alias. + +Note: The domain of the email alias needs to be registered + to your enterprise. +See the [domain verification guide]( + https://support.box.com/hc/en-us/articles/4408619650579-Domain-Verification + ) for steps to add a new domain. + :type email: str + :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 = {'email': email} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/users/', to_string(user_id), '/email_aliases']), 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, EmailAlias) + def delete_user_email_alias_by_id(self, user_id: str, email_alias_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Removes an email alias from a user. + :param user_id: The ID of the user. +Example: "12345" + :type user_id: str + :param email_alias_id: The ID of the email alias. +Example: "23432" + :type email_alias_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/users/', to_string(user_id), '/email_aliases/', to_string(email_alias_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/events.py b/box_sdk_gen/managers/events.py new file mode 100644 index 000000000..f546f1f0d --- /dev/null +++ b/box_sdk_gen/managers/events.py @@ -0,0 +1,333 @@ +from enum import Enum + +from typing import Optional + +from typing import Dict + +from box_sdk_gen.serialization.json import deserialize + +from typing import List + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.realtime_servers import RealtimeServers + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.events import Events + +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 SerializedData + +from box_sdk_gen.internal.utils import DateTime + +from box_sdk_gen.serialization.json import sd_to_json + +class GetEventsStreamType(str, Enum): + ALL = 'all' + CHANGES = 'changes' + SYNC = 'sync' + ADMIN_LOGS = 'admin_logs' + ADMIN_LOGS_STREAMING = 'admin_logs_streaming' + +class GetEventsEventType(str, Enum): + ACCESS_GRANTED = 'ACCESS_GRANTED' + ACCESS_REVOKED = 'ACCESS_REVOKED' + ADD_DEVICE_ASSOCIATION = 'ADD_DEVICE_ASSOCIATION' + ADD_LOGIN_ACTIVITY_DEVICE = 'ADD_LOGIN_ACTIVITY_DEVICE' + ADMIN_LOGIN = 'ADMIN_LOGIN' + APPLICATION_CREATED = 'APPLICATION_CREATED' + APPLICATION_PUBLIC_KEY_ADDED = 'APPLICATION_PUBLIC_KEY_ADDED' + APPLICATION_PUBLIC_KEY_DELETED = 'APPLICATION_PUBLIC_KEY_DELETED' + CHANGE_ADMIN_ROLE = 'CHANGE_ADMIN_ROLE' + CHANGE_FOLDER_PERMISSION = 'CHANGE_FOLDER_PERMISSION' + COLLABORATION_ACCEPT = 'COLLABORATION_ACCEPT' + COLLABORATION_EXPIRATION = 'COLLABORATION_EXPIRATION' + COLLABORATION_INVITE = 'COLLABORATION_INVITE' + COLLABORATION_REMOVE = 'COLLABORATION_REMOVE' + COLLABORATION_ROLE_CHANGE = 'COLLABORATION_ROLE_CHANGE' + COMMENT_CREATE = 'COMMENT_CREATE' + COMMENT_DELETE = 'COMMENT_DELETE' + CONTENT_WORKFLOW_ABNORMAL_DOWNLOAD_ACTIVITY = 'CONTENT_WORKFLOW_ABNORMAL_DOWNLOAD_ACTIVITY' + CONTENT_WORKFLOW_AUTOMATION_ADD = 'CONTENT_WORKFLOW_AUTOMATION_ADD' + CONTENT_WORKFLOW_AUTOMATION_DELETE = 'CONTENT_WORKFLOW_AUTOMATION_DELETE' + CONTENT_WORKFLOW_POLICY_ADD = 'CONTENT_WORKFLOW_POLICY_ADD' + CONTENT_WORKFLOW_SHARING_POLICY_VIOLATION = 'CONTENT_WORKFLOW_SHARING_POLICY_VIOLATION' + CONTENT_WORKFLOW_UPLOAD_POLICY_VIOLATION = 'CONTENT_WORKFLOW_UPLOAD_POLICY_VIOLATION' + COPY = 'COPY' + DATA_RETENTION_CREATE_RETENTION = 'DATA_RETENTION_CREATE_RETENTION' + DATA_RETENTION_REMOVE_RETENTION = 'DATA_RETENTION_REMOVE_RETENTION' + DELETE = 'DELETE' + DELETE_USER = 'DELETE_USER' + DEVICE_TRUST_CHECK_FAILED = 'DEVICE_TRUST_CHECK_FAILED' + DOWNLOAD = 'DOWNLOAD' + EDIT = 'EDIT' + EDIT_USER = 'EDIT_USER' + EMAIL_ALIAS_CONFIRM = 'EMAIL_ALIAS_CONFIRM' + EMAIL_ALIAS_REMOVE = 'EMAIL_ALIAS_REMOVE' + ENTERPRISE_APP_AUTHORIZATION_UPDATE = 'ENTERPRISE_APP_AUTHORIZATION_UPDATE' + EXTERNAL_COLLAB_SECURITY_SETTINGS = 'EXTERNAL_COLLAB_SECURITY_SETTINGS' + FAILED_LOGIN = 'FAILED_LOGIN' + FILE_MARKED_MALICIOUS = 'FILE_MARKED_MALICIOUS' + FILE_WATERMARKED_DOWNLOAD = 'FILE_WATERMARKED_DOWNLOAD' + GROUP_ADD_ITEM = 'GROUP_ADD_ITEM' + GROUP_ADD_USER = 'GROUP_ADD_USER' + GROUP_CREATION = 'GROUP_CREATION' + GROUP_DELETION = 'GROUP_DELETION' + GROUP_EDITED = 'GROUP_EDITED' + GROUP_REMOVE_ITEM = 'GROUP_REMOVE_ITEM' + GROUP_REMOVE_USER = 'GROUP_REMOVE_USER' + ITEM_EMAIL_SEND = 'ITEM_EMAIL_SEND' + ITEM_MODIFY = 'ITEM_MODIFY' + ITEM_OPEN = 'ITEM_OPEN' + ITEM_SHARED_UPDATE = 'ITEM_SHARED_UPDATE' + ITEM_SYNC = 'ITEM_SYNC' + ITEM_UNSYNC = 'ITEM_UNSYNC' + LEGAL_HOLD_ASSIGNMENT_CREATE = 'LEGAL_HOLD_ASSIGNMENT_CREATE' + LEGAL_HOLD_ASSIGNMENT_DELETE = 'LEGAL_HOLD_ASSIGNMENT_DELETE' + LEGAL_HOLD_POLICY_CREATE = 'LEGAL_HOLD_POLICY_CREATE' + LEGAL_HOLD_POLICY_DELETE = 'LEGAL_HOLD_POLICY_DELETE' + LEGAL_HOLD_POLICY_UPDATE = 'LEGAL_HOLD_POLICY_UPDATE' + LOCK = 'LOCK' + LOGIN = 'LOGIN' + METADATA_INSTANCE_CREATE = 'METADATA_INSTANCE_CREATE' + METADATA_INSTANCE_DELETE = 'METADATA_INSTANCE_DELETE' + METADATA_INSTANCE_UPDATE = 'METADATA_INSTANCE_UPDATE' + METADATA_TEMPLATE_CREATE = 'METADATA_TEMPLATE_CREATE' + METADATA_TEMPLATE_DELETE = 'METADATA_TEMPLATE_DELETE' + METADATA_TEMPLATE_UPDATE = 'METADATA_TEMPLATE_UPDATE' + MOVE = 'MOVE' + NEW_USER = 'NEW_USER' + OAUTH2_ACCESS_TOKEN_REVOKE = 'OAUTH2_ACCESS_TOKEN_REVOKE' + PREVIEW = 'PREVIEW' + REMOVE_DEVICE_ASSOCIATION = 'REMOVE_DEVICE_ASSOCIATION' + REMOVE_LOGIN_ACTIVITY_DEVICE = 'REMOVE_LOGIN_ACTIVITY_DEVICE' + RENAME = 'RENAME' + RETENTION_POLICY_ASSIGNMENT_ADD = 'RETENTION_POLICY_ASSIGNMENT_ADD' + SHARE = 'SHARE' + SHARED_LINK_SEND = 'SHARED_LINK_SEND' + SHARE_EXPIRATION = 'SHARE_EXPIRATION' + SHIELD_ALERT = 'SHIELD_ALERT' + SHIELD_EXTERNAL_COLLAB_ACCESS_BLOCKED = 'SHIELD_EXTERNAL_COLLAB_ACCESS_BLOCKED' + SHIELD_EXTERNAL_COLLAB_ACCESS_BLOCKED_MISSING_JUSTIFICATION = 'SHIELD_EXTERNAL_COLLAB_ACCESS_BLOCKED_MISSING_JUSTIFICATION' + SHIELD_EXTERNAL_COLLAB_INVITE_BLOCKED = 'SHIELD_EXTERNAL_COLLAB_INVITE_BLOCKED' + SHIELD_EXTERNAL_COLLAB_INVITE_BLOCKED_MISSING_JUSTIFICATION = 'SHIELD_EXTERNAL_COLLAB_INVITE_BLOCKED_MISSING_JUSTIFICATION' + SHIELD_JUSTIFICATION_APPROVAL = 'SHIELD_JUSTIFICATION_APPROVAL' + SHIELD_SHARED_LINK_ACCESS_BLOCKED = 'SHIELD_SHARED_LINK_ACCESS_BLOCKED' + SHIELD_SHARED_LINK_STATUS_RESTRICTED_ON_CREATE = 'SHIELD_SHARED_LINK_STATUS_RESTRICTED_ON_CREATE' + SHIELD_SHARED_LINK_STATUS_RESTRICTED_ON_UPDATE = 'SHIELD_SHARED_LINK_STATUS_RESTRICTED_ON_UPDATE' + SIGN_DOCUMENT_ASSIGNED = 'SIGN_DOCUMENT_ASSIGNED' + SIGN_DOCUMENT_CANCELLED = 'SIGN_DOCUMENT_CANCELLED' + SIGN_DOCUMENT_COMPLETED = 'SIGN_DOCUMENT_COMPLETED' + SIGN_DOCUMENT_CONVERTED = 'SIGN_DOCUMENT_CONVERTED' + SIGN_DOCUMENT_CREATED = 'SIGN_DOCUMENT_CREATED' + SIGN_DOCUMENT_DECLINED = 'SIGN_DOCUMENT_DECLINED' + SIGN_DOCUMENT_EXPIRED = 'SIGN_DOCUMENT_EXPIRED' + SIGN_DOCUMENT_SIGNED = 'SIGN_DOCUMENT_SIGNED' + SIGN_DOCUMENT_VIEWED_BY_SIGNED = 'SIGN_DOCUMENT_VIEWED_BY_SIGNED' + SIGNER_DOWNLOADED = 'SIGNER_DOWNLOADED' + SIGNER_FORWARDED = 'SIGNER_FORWARDED' + STORAGE_EXPIRATION = 'STORAGE_EXPIRATION' + TASK_ASSIGNMENT_CREATE = 'TASK_ASSIGNMENT_CREATE' + TASK_ASSIGNMENT_DELETE = 'TASK_ASSIGNMENT_DELETE' + TASK_ASSIGNMENT_UPDATE = 'TASK_ASSIGNMENT_UPDATE' + TASK_CREATE = 'TASK_CREATE' + TASK_UPDATE = 'TASK_UPDATE' + TERMS_OF_SERVICE_ACCEPT = 'TERMS_OF_SERVICE_ACCEPT' + TERMS_OF_SERVICE_REJECT = 'TERMS_OF_SERVICE_REJECT' + UNDELETE = 'UNDELETE' + UNLOCK = 'UNLOCK' + UNSHARE = 'UNSHARE' + UPDATE_COLLABORATION_EXPIRATION = 'UPDATE_COLLABORATION_EXPIRATION' + UPDATE_SHARE_EXPIRATION = 'UPDATE_SHARE_EXPIRATION' + UPLOAD = 'UPLOAD' + USER_AUTHENTICATE_OAUTH2_ACCESS_TOKEN_CREATE = 'USER_AUTHENTICATE_OAUTH2_ACCESS_TOKEN_CREATE' + WATERMARK_LABEL_CREATE = 'WATERMARK_LABEL_CREATE' + WATERMARK_LABEL_DELETE = 'WATERMARK_LABEL_DELETE' + +class EventsManager: + 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_events_with_long_polling(self, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> RealtimeServers: + """ + Returns a list of real-time servers that can be used for long-polling updates + + to the [event stream](#get-events). + + + Long polling is the concept where a HTTP request is kept open until the + + + server sends a response, then repeating the process over and over to receive + + + updated responses. + + + Long polling the event stream can only be used for user events, not for + + + enterprise events. + + + To use long polling, first use this endpoint to retrieve a list of long poll + + + URLs. Next, make a long poll request to any of the provided URLs. + + + When an event occurs in monitored account a response with the value + + + `new_change` will be sent. The response contains no other details as + + + it only serves as a prompt to take further action such as sending a + + + request to the [events endpoint](#get-events) with the last known + + + `stream_position`. + + + After the server sends this response it closes the connection. You must now + + + repeat the long poll process to begin listening for events again. + + + If no events occur for a while and the connection times out you will + + + receive a response with the value `reconnect`. When you receive this response + + + you’ll make another call to this endpoint to restart the process. + + + If you receive no events in `retry_timeout` seconds then you will need to + + + make another request to the real-time server (one of the URLs in the response + + + for this endpoint). This might be necessary due to network errors. + + + Finally, if you receive a `max_retries` error when making a request to the + + + real-time server, you should start over by making a call to this endpoint + + + first. + + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/events']), method='OPTIONS', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, RealtimeServers) + def get_events(self, *, stream_type: Optional[GetEventsStreamType] = None, stream_position: Optional[str] = None, limit: Optional[int] = None, event_type: Optional[List[GetEventsEventType]] = None, created_after: Optional[DateTime] = None, created_before: Optional[DateTime] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Events: + """ + Returns up to a year of past events for a given user + + or for the entire enterprise. + + + By default this returns events for the authenticated user. To retrieve events + + + for the entire enterprise, set the `stream_type` to `admin_logs_streaming` + + + for live monitoring of new events, or `admin_logs` for querying across + + + historical events. The user making the API call will + + + need to have admin privileges, and the application will need to have the + + + scope `manage enterprise properties` checked. + + :param stream_type: Defines the type of events that are returned + +* `all` returns everything for a user and is the default +* `changes` returns events that may cause file tree changes + such as file updates or collaborations. +* `sync` is similar to `changes` but only applies to synced folders +* `admin_logs` returns all events for an entire enterprise and + requires the user making the API call to have admin permissions. This + stream type is for programmatically pulling from a 1 year history of + events across all users within the enterprise and within a + `created_after` and `created_before` time frame. The complete history + of events will be returned in chronological order based on the event + time, but latency will be much higher than `admin_logs_streaming`. +* `admin_logs_streaming` returns all events for an entire enterprise and + requires the user making the API call to have admin permissions. This + stream type is for polling for recent events across all users within + the enterprise. Latency will be much lower than `admin_logs`, but + events will not be returned in chronological order and may + contain duplicates., defaults to None + :type stream_type: Optional[GetEventsStreamType], optional + :param stream_position: The location in the event stream to start receiving events from. + +* `now` will return an empty list events and +the latest stream position for initialization. +* `0` or `null` will return all events., defaults to None + :type stream_position: Optional[str], optional + :param limit: Limits the number of events returned + +Note: Sometimes, the events less than the limit requested can be returned +even when there may be more events remaining. This is primarily done in +the case where a number of events have already been retrieved and these +retrieved events are returned rather than delaying for an unknown amount +of time to see if there are any more results., defaults to None + :type limit: Optional[int], optional + :param event_type: A comma-separated list of events to filter by. This can only be used when +requesting the events with a `stream_type` of `admin_logs` or +`adming_logs_streaming`. For any other `stream_type` this value will be +ignored., defaults to None + :type event_type: Optional[List[GetEventsEventType]], optional + :param created_after: The lower bound date and time to return events for. This can only be used +when requesting the events with a `stream_type` of `admin_logs`. For any +other `stream_type` this value will be ignored., defaults to None + :type created_after: Optional[DateTime], optional + :param created_before: The upper bound date and time to return events for. This can only be used +when requesting the events with a `stream_type` of `admin_logs`. For any +other `stream_type` this value will be ignored., defaults to None + :type created_before: Optional[DateTime], 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({'stream_type': to_string(stream_type), 'stream_position': to_string(stream_position), 'limit': to_string(limit), 'event_type': to_string(event_type), 'created_after': to_string(created_after), 'created_before': to_string(created_before)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/events']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Events) \ No newline at end of file diff --git a/box_sdk_gen/managers/file_classifications.py b/box_sdk_gen/managers/file_classifications.py new file mode 100644 index 000000000..daa180713 --- /dev/null +++ b/box_sdk_gen/managers/file_classifications.py @@ -0,0 +1,207 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from typing import List + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.classification import Classification + +from box_sdk_gen.schemas.client_error import ClientError + +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 UpdateClassificationOnFileRequestBodyOpField(str, Enum): + REPLACE = 'replace' + +class UpdateClassificationOnFileRequestBodyPathField(str, Enum): + _BOX__SECURITY__CLASSIFICATION__KEY = '/Box__Security__Classification__Key' + +class UpdateClassificationOnFileRequestBody(BaseObject): + def __init__(self, value: str, *, op: UpdateClassificationOnFileRequestBodyOpField = UpdateClassificationOnFileRequestBodyOpField.REPLACE, path: UpdateClassificationOnFileRequestBodyPathField = UpdateClassificationOnFileRequestBodyPathField._BOX__SECURITY__CLASSIFICATION__KEY, **kwargs): + """ + :param value: The name of the classification to apply to this file. + +To list the available classifications in an enterprise, +use the classification API to retrieve the +[classification template](e://get_metadata_templates_enterprise_securityClassification-6VMVochwUWo_schema) +which lists all available classification keys. + :type value: str + :param op: `replace`, defaults to UpdateClassificationOnFileRequestBodyOpField.REPLACE + :type op: UpdateClassificationOnFileRequestBodyOpField, optional + :param path: Defines classifications +available in the enterprise., defaults to UpdateClassificationOnFileRequestBodyPathField._BOX__SECURITY__CLASSIFICATION__KEY + :type path: UpdateClassificationOnFileRequestBodyPathField, optional + """ + super().__init__(**kwargs) + self.value = value + self.op = op + self.path = path + +class FileClassificationsManager: + 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_classification_on_file(self, file_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Classification: + """ + Retrieves the classification metadata instance that + + has been applied to a file. + + + This API can also be called by including the enterprise ID in the + + + URL explicitly, for example + + + `/files/:id//enterprise_12345/securityClassification-6VMVochwUWo`. + + :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 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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/metadata/enterprise/securityClassification-6VMVochwUWo']), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Classification) + def add_classification_to_file(self, file_id: str, *, box_security_classification_key: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Classification: + """ + Adds a classification to a file by specifying the label of the + + classification to add. + + + This API can also be called by including the enterprise ID in the + + + URL explicitly, for example + + + `/files/:id//enterprise_12345/securityClassification-6VMVochwUWo`. + + :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 box_security_classification_key: The name of the classification to apply to this file. + +To list the available classifications in an enterprise, +use the classification API to retrieve the +[classification template](e://get_metadata_templates_enterprise_securityClassification-6VMVochwUWo_schema) +which lists all available classification keys., defaults to None + :type box_security_classification_key: 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 = {} + request_body: Dict = {'Box__Security__Classification__Key': box_security_classification_key} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/metadata/enterprise/securityClassification-6VMVochwUWo']), 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, Classification) + def update_classification_on_file(self, file_id: str, request_body: List[UpdateClassificationOnFileRequestBody], *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Classification: + """ + Updates a classification on a file. + + The classification can only be updated if a classification has already been + + + applied to the file before. When editing classifications, only values are + + + defined for the enterprise will be accepted. + + :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 request_body: Request body of updateClassificationOnFile method + :type request_body: List[UpdateClassificationOnFileRequestBody] + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/metadata/enterprise/securityClassification-6VMVochwUWo']), method='PUT', headers=headers_map, data=serialize(request_body), content_type='application/json-patch+json', response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Classification) + def delete_classification_from_file(self, file_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Removes any classifications from a file. + + This API can also be called by including the enterprise ID in the + + + URL explicitly, for example + + + `/files/:id//enterprise_12345/securityClassification-6VMVochwUWo`. + + :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 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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/metadata/enterprise/securityClassification-6VMVochwUWo']), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/file_metadata.py b/box_sdk_gen/managers/file_metadata.py new file mode 100644 index 000000000..2d016b1a1 --- /dev/null +++ b/box_sdk_gen/managers/file_metadata.py @@ -0,0 +1,258 @@ +from enum import Enum + +from typing import Optional + +from typing import Dict + +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 deserialize + +from box_sdk_gen.serialization.json import serialize + +from typing import List + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.metadatas import Metadatas + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.metadata_full import MetadataFull + +from box_sdk_gen.schemas.metadata_instance_value import MetadataInstanceValue + +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 GetFileMetadataByIdScope(str, Enum): + GLOBAL = 'global' + ENTERPRISE = 'enterprise' + +class CreateFileMetadataByIdScope(str, Enum): + GLOBAL = 'global' + ENTERPRISE = 'enterprise' + +class UpdateFileMetadataByIdScope(str, Enum): + GLOBAL = 'global' + ENTERPRISE = 'enterprise' + +class UpdateFileMetadataByIdRequestBodyOpField(str, Enum): + ADD = 'add' + REPLACE = 'replace' + REMOVE = 'remove' + TEST = 'test' + MOVE = 'move' + COPY = 'copy' + +class UpdateFileMetadataByIdRequestBody(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'from_': 'from', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'from': 'from_', **BaseObject._json_to_fields_mapping} + def __init__(self, *, op: Optional[UpdateFileMetadataByIdRequestBodyOpField] = None, path: Optional[str] = None, value: Optional[MetadataInstanceValue] = None, from_: Optional[str] = None, **kwargs): + """ + :param op: The type of change to perform on the template. Some +of these are hazardous as they will change existing templates., defaults to None + :type op: Optional[UpdateFileMetadataByIdRequestBodyOpField], optional + :param path: The location in the metadata JSON object +to apply the changes to, in the format of a +[JSON-Pointer](https://tools.ietf.org/html/rfc6901). + +The path must always be prefixed with a `/` to represent the root +of the template. The characters `~` and `/` are reserved +characters and must be escaped in the key., defaults to None + :type path: Optional[str], optional + :param from_: The location in the metadata JSON object to move or copy a value +from. Required for `move` or `copy` operations and must be in the +format of a [JSON-Pointer](https://tools.ietf.org/html/rfc6901)., defaults to None + :type from_: Optional[str], optional + """ + super().__init__(**kwargs) + self.op = op + self.path = path + self.value = value + self.from_ = from_ + +class DeleteFileMetadataByIdScope(str, Enum): + GLOBAL = 'global' + ENTERPRISE = 'enterprise' + +class FileMetadataManager: + 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_metadata(self, file_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Metadatas: + """ + Retrieves all metadata for a given file. + :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 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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/metadata']), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Metadatas) + def get_file_metadata_by_id(self, file_id: str, scope: GetFileMetadataByIdScope, template_key: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> MetadataFull: + """ + Retrieves the instance of a metadata template that has been applied to a + + file. + + :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 scope: The scope of the metadata template +Example: "global" + :type scope: GetFileMetadataByIdScope + :param template_key: The name of the metadata template +Example: "properties" + :type template_key: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/metadata/', to_string(scope), '/', to_string(template_key)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, MetadataFull) + def create_file_metadata_by_id(self, file_id: str, scope: CreateFileMetadataByIdScope, template_key: str, request_body: Dict, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> MetadataFull: + """ + Applies an instance of a metadata template to a file. + + In most cases only values that are present in the metadata template + + + will be accepted, except for the `global.properties` template which accepts + + + any key-value pair. + + :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 scope: The scope of the metadata template +Example: "global" + :type scope: CreateFileMetadataByIdScope + :param template_key: The name of the metadata template +Example: "properties" + :type template_key: str + :param request_body: Request body of createFileMetadataById method + :type request_body: Dict + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/metadata/', to_string(scope), '/', to_string(template_key)]), 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, MetadataFull) + def update_file_metadata_by_id(self, file_id: str, scope: UpdateFileMetadataByIdScope, template_key: str, request_body: List[UpdateFileMetadataByIdRequestBody], *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> MetadataFull: + """ + Updates a piece of metadata on a file. + + The metadata instance can only be updated if the template has already been + + + applied to the file before. When editing metadata, only values that match + + + the metadata template schema will be accepted. + + + The update is applied atomically. If any errors occur during the + + + application of the operations, the metadata instance will not be changed. + + :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 scope: The scope of the metadata template +Example: "global" + :type scope: UpdateFileMetadataByIdScope + :param template_key: The name of the metadata template +Example: "properties" + :type template_key: str + :param request_body: Request body of updateFileMetadataById method + :type request_body: List[UpdateFileMetadataByIdRequestBody] + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/metadata/', to_string(scope), '/', to_string(template_key)]), method='PUT', headers=headers_map, data=serialize(request_body), content_type='application/json-patch+json', response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, MetadataFull) + def delete_file_metadata_by_id(self, file_id: str, scope: DeleteFileMetadataByIdScope, template_key: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Deletes a piece of file metadata. + :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 scope: The scope of the metadata template +Example: "global" + :type scope: DeleteFileMetadataByIdScope + :param template_key: The name of the metadata template +Example: "properties" + :type template_key: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/metadata/', to_string(scope), '/', to_string(template_key)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/file_requests.py b/box_sdk_gen/managers/file_requests.py new file mode 100644 index 000000000..21ae1344b --- /dev/null +++ b/box_sdk_gen/managers/file_requests.py @@ -0,0 +1,261 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.internal.utils import DateTime + +from box_sdk_gen.schemas.file_request import FileRequest + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.file_request_update_request import FileRequestUpdateRequest + +from box_sdk_gen.schemas.file_request_copy_request import FileRequestCopyRequest + +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 UpdateFileRequestByIdStatus(str, Enum): + ACTIVE = 'active' + INACTIVE = 'inactive' + +class CreateFileRequestCopyFolderTypeField(str, Enum): + FOLDER = 'folder' + +class CreateFileRequestCopyFolder(BaseObject): + _discriminator = 'type', {'folder'} + def __init__(self, id: str, *, type: Optional[CreateFileRequestCopyFolderTypeField] = None, **kwargs): + """ + :param id: The ID of the folder to associate the new +file request to. + :type id: str + :param type: `folder`, defaults to None + :type type: Optional[CreateFileRequestCopyFolderTypeField], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class CreateFileRequestCopyStatus(str, Enum): + ACTIVE = 'active' + INACTIVE = 'inactive' + +class FileRequestsManager: + 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_request_by_id(self, file_request_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FileRequest: + """ + Retrieves the information about a file request. + :param file_request_id: The unique identifier that represent a file request. + +The ID for any file request can be determined +by visiting a file request builder in the web application +and copying the ID from the URL. For example, +for the URL `https://*.app.box.com/filerequest/123` +the `file_request_id` is `123`. +Example: "123" + :type file_request_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/file_requests/', to_string(file_request_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, FileRequest) + def update_file_request_by_id(self, file_request_id: str, *, title: Optional[str] = None, description: Optional[str] = None, status: Optional[UpdateFileRequestByIdStatus] = None, is_email_required: Optional[bool] = None, is_description_required: Optional[bool] = None, expires_at: Optional[DateTime] = None, if_match: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FileRequest: + """ + Updates a file request. This can be used to activate or + + deactivate a file request. + + :param file_request_id: The unique identifier that represent a file request. + +The ID for any file request can be determined +by visiting a file request builder in the web application +and copying the ID from the URL. For example, +for the URL `https://*.app.box.com/filerequest/123` +the `file_request_id` is `123`. +Example: "123" + :type file_request_id: str + :param title: An optional new title for the file request. This can be +used to change the title of the file request. + +This will default to the value on the existing file request., defaults to None + :type title: Optional[str], optional + :param description: An optional new description for the file request. This can be +used to change the description of the file request. + +This will default to the value on the existing file request., defaults to None + :type description: Optional[str], optional + :param status: An optional new status of the file request. + +When the status is set to `inactive`, the file request +will no longer accept new submissions, and any visitor +to the file request URL will receive a `HTTP 404` status +code. + +This will default to the value on the existing file request., defaults to None + :type status: Optional[UpdateFileRequestByIdStatus], optional + :param is_email_required: Whether a file request submitter is required to provide +their email address. + +When this setting is set to true, the Box UI will show +an email field on the file request form. + +This will default to the value on the existing file request., defaults to None + :type is_email_required: Optional[bool], optional + :param is_description_required: Whether a file request submitter is required to provide +a description of the files they are submitting. + +When this setting is set to true, the Box UI will show +a description field on the file request form. + +This will default to the value on the existing file request., defaults to None + :type is_description_required: Optional[bool], optional + :param expires_at: The date after which a file request will no longer accept new +submissions. + +After this date, the `status` will automatically be set to +`inactive`. + +This will default to the value on the existing file request., defaults to None + :type expires_at: Optional[DateTime], optional + :param if_match: Ensures this item hasn't recently changed before +making changes. + +Pass in the item's last observed `etag` value +into this header and the endpoint will fail +with a `412 Precondition Failed` if it +has changed since., defaults to None + :type if_match: 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 = {} + request_body: Dict = {'title': title, 'description': description, 'status': status, 'is_email_required': is_email_required, 'is_description_required': is_description_required, 'expires_at': expires_at} + headers_map: Dict[str, str] = prepare_params({'if-match': to_string(if_match), **extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/file_requests/', to_string(file_request_id)]), method='PUT', 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, FileRequest) + def delete_file_request_by_id(self, file_request_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Deletes a file request permanently. + :param file_request_id: The unique identifier that represent a file request. + +The ID for any file request can be determined +by visiting a file request builder in the web application +and copying the ID from the URL. For example, +for the URL `https://*.app.box.com/filerequest/123` +the `file_request_id` is `123`. +Example: "123" + :type file_request_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/file_requests/', to_string(file_request_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None + def create_file_request_copy(self, file_request_id: str, folder: CreateFileRequestCopyFolder, *, title: Optional[str] = None, description: Optional[str] = None, status: Optional[CreateFileRequestCopyStatus] = None, is_email_required: Optional[bool] = None, is_description_required: Optional[bool] = None, expires_at: Optional[DateTime] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FileRequest: + """ + Copies an existing file request that is already present on one folder, + + and applies it to another folder. + + :param file_request_id: The unique identifier that represent a file request. + +The ID for any file request can be determined +by visiting a file request builder in the web application +and copying the ID from the URL. For example, +for the URL `https://*.app.box.com/filerequest/123` +the `file_request_id` is `123`. +Example: "123" + :type file_request_id: str + :param folder: The folder to associate the new file request to. + :type folder: CreateFileRequestCopyFolder + :param title: An optional new title for the file request. This can be +used to change the title of the file request. + +This will default to the value on the existing file request., defaults to None + :type title: Optional[str], optional + :param description: An optional new description for the file request. This can be +used to change the description of the file request. + +This will default to the value on the existing file request., defaults to None + :type description: Optional[str], optional + :param status: An optional new status of the file request. + +When the status is set to `inactive`, the file request +will no longer accept new submissions, and any visitor +to the file request URL will receive a `HTTP 404` status +code. + +This will default to the value on the existing file request., defaults to None + :type status: Optional[CreateFileRequestCopyStatus], optional + :param is_email_required: Whether a file request submitter is required to provide +their email address. + +When this setting is set to true, the Box UI will show +an email field on the file request form. + +This will default to the value on the existing file request., defaults to None + :type is_email_required: Optional[bool], optional + :param is_description_required: Whether a file request submitter is required to provide +a description of the files they are submitting. + +When this setting is set to true, the Box UI will show +a description field on the file request form. + +This will default to the value on the existing file request., defaults to None + :type is_description_required: Optional[bool], optional + :param expires_at: The date after which a file request will no longer accept new +submissions. + +After this date, the `status` will automatically be set to +`inactive`. + +This will default to the value on the existing file request., defaults to None + :type expires_at: Optional[DateTime], 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 = {'folder': folder, 'title': title, 'description': description, 'status': status, 'is_email_required': is_email_required, 'is_description_required': is_description_required, 'expires_at': expires_at} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/file_requests/', to_string(file_request_id), '/copy']), 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, FileRequest) \ No newline at end of file diff --git a/box_sdk_gen/managers/file_version_legal_holds.py b/box_sdk_gen/managers/file_version_legal_holds.py new file mode 100644 index 000000000..8d43fd7c6 --- /dev/null +++ b/box_sdk_gen/managers/file_version_legal_holds.py @@ -0,0 +1,123 @@ +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.file_version_legal_hold import FileVersionLegalHold + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.file_version_legal_holds import FileVersionLegalHolds + +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 FileVersionLegalHoldsManager: + 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_version_legal_hold_by_id(self, file_version_legal_hold_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FileVersionLegalHold: + """ + Retrieves information about the legal hold policies + + assigned to a file version. + + :param file_version_legal_hold_id: The ID of the file version legal hold +Example: "2348213" + :type file_version_legal_hold_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/file_version_legal_holds/', to_string(file_version_legal_hold_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, FileVersionLegalHold) + def get_file_version_legal_holds(self, policy_id: str, *, marker: Optional[str] = None, limit: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FileVersionLegalHolds: + """ + Get a list of file versions on legal hold for a legal hold + + assignment. + + + Due to ongoing re-architecture efforts this API might not return all file + + + versions for this policy ID. + + + Instead, this API will only return file versions held in the legacy + + + architecture. Two new endpoints will available to request any file versions + + + held in the new architecture. + + + For file versions held in the new architecture, the `GET + + + /legal_hold_policy_assignments/:id/file_versions_on_hold` API can be used to + + + return all past file versions available for this policy assignment, and the + + + `GET /legal_hold_policy_assignments/:id/files_on_hold` API can be used to + + + return any current (latest) versions of a file under legal hold. + + + The `GET /legal_hold_policy_assignments?policy_id={id}` API can be used to + + + find a list of policy assignments for a given policy ID. + + + Once the re-architecture is completed this API will be deprecated. + + :param policy_id: The ID of the legal hold policy to get the file version legal +holds for. + :type policy_id: str + :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 limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], 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({'policy_id': to_string(policy_id), 'marker': to_string(marker), 'limit': to_string(limit)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/file_version_legal_holds']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, FileVersionLegalHolds) \ No newline at end of file diff --git a/box_sdk_gen/managers/file_version_retentions.py b/box_sdk_gen/managers/file_version_retentions.py new file mode 100644 index 000000000..5586d2d56 --- /dev/null +++ b/box_sdk_gen/managers/file_version_retentions.py @@ -0,0 +1,120 @@ +from enum import Enum + +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.file_version_retentions import FileVersionRetentions + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.file_version_retention import FileVersionRetention + +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 GetFileVersionRetentionsDispositionAction(str, Enum): + PERMANENTLY_DELETE = 'permanently_delete' + REMOVE_RETENTION = 'remove_retention' + +class FileVersionRetentionsManager: + 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_version_retentions(self, *, file_id: Optional[str] = None, file_version_id: Optional[str] = None, policy_id: Optional[str] = None, disposition_action: Optional[GetFileVersionRetentionsDispositionAction] = None, disposition_before: Optional[str] = None, disposition_after: Optional[str] = None, limit: Optional[int] = None, marker: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FileVersionRetentions: + """ + Retrieves all file version retentions for the given enterprise. + + **Note**: + + + File retention API is now **deprecated**. + + + To get information about files and file versions under retention, + + + see [files under retention](e://get-retention-policy-assignments-id-files-under-retention) or [file versions under retention](e://get-retention-policy-assignments-id-file-versions-under-retention) endpoints. + + :param file_id: Filters results by files with this ID., defaults to None + :type file_id: Optional[str], optional + :param file_version_id: Filters results by file versions with this ID., defaults to None + :type file_version_id: Optional[str], optional + :param policy_id: Filters results by the retention policy with this ID., defaults to None + :type policy_id: Optional[str], optional + :param disposition_action: Filters results by the retention policy with this disposition +action., defaults to None + :type disposition_action: Optional[GetFileVersionRetentionsDispositionAction], optional + :param disposition_before: Filters results by files that will have their disposition +come into effect before this date., defaults to None + :type disposition_before: Optional[str], optional + :param disposition_after: Filters results by files that will have their disposition +come into effect after this date., defaults to None + :type disposition_after: Optional[str], optional + :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 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({'file_id': to_string(file_id), 'file_version_id': to_string(file_version_id), 'policy_id': to_string(policy_id), 'disposition_action': to_string(disposition_action), 'disposition_before': to_string(disposition_before), 'disposition_after': to_string(disposition_after), 'limit': to_string(limit), 'marker': to_string(marker)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/file_version_retentions']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, FileVersionRetentions) + def get_file_version_retention_by_id(self, file_version_retention_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FileVersionRetention: + """ + Returns information about a file version retention. + + **Note**: + + + File retention API is now **deprecated**. + + + To get information about files and file versions under retention, + + + see [files under retention](e://get-retention-policy-assignments-id-files-under-retention) or [file versions under retention](e://get-retention-policy-assignments-id-file-versions-under-retention) endpoints. + + :param file_version_retention_id: The ID of the file version retention +Example: "3424234" + :type file_version_retention_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/file_version_retentions/', to_string(file_version_retention_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, FileVersionRetention) \ No newline at end of file diff --git a/box_sdk_gen/managers/file_versions.py b/box_sdk_gen/managers/file_versions.py new file mode 100644 index 000000000..b2ad66015 --- /dev/null +++ b/box_sdk_gen/managers/file_versions.py @@ -0,0 +1,276 @@ +from enum import Enum + +from typing import Optional + +from typing import List + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.internal.null_value import NullValue + +from typing import Union + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.file_versions import FileVersions + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.file_version_full import FileVersionFull + +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 PromoteFileVersionType(str, Enum): + FILE_VERSION = 'file_version' + +class FileVersionsManager: + 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_versions(self, file_id: str, *, fields: Optional[List[str]] = None, limit: Optional[int] = None, offset: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FileVersions: + """ + Retrieve a list of the past versions for a file. + + Versions are only tracked by Box users with premium accounts. To fetch the ID + + + of the current version of a file, use the `GET /file/:id` API. + + :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 fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[str]], optional + :param limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], optional + :param offset: The offset of the item at which to begin the response. + +Queries with offset parameter value +exceeding 10000 will be rejected +with a 400 response., defaults to None + :type offset: Optional[int], 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({'fields': to_string(fields), 'limit': to_string(limit), 'offset': to_string(offset)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/versions']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, FileVersions) + def get_file_version_by_id(self, file_id: str, file_version_id: str, *, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FileVersionFull: + """ + Retrieve a specific version of a file. + + Versions are only tracked for Box users with premium accounts. + + :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 file_version_id: The ID of the file version +Example: "1234" + :type file_version_id: str + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/versions/', to_string(file_version_id)]), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, FileVersionFull) + def delete_file_version_by_id(self, file_id: str, file_version_id: str, *, if_match: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Move a file version to the trash. + + Versions are only tracked for Box users with premium accounts. + + :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 file_version_id: The ID of the file version +Example: "1234" + :type file_version_id: str + :param if_match: Ensures this item hasn't recently changed before +making changes. + +Pass in the item's last observed `etag` value +into this header and the endpoint will fail +with a `412 Precondition Failed` if it +has changed since., defaults to None + :type if_match: 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 = {} + headers_map: Dict[str, str] = prepare_params({'if-match': to_string(if_match), **extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/versions/', to_string(file_version_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None + def update_file_version_by_id(self, file_id: str, file_version_id: str, *, trashed_at: Union[Optional[str], NullValue] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FileVersionFull: + """ + Restores a specific version of a file after it was deleted. + + Don't use this endpoint to restore Box Notes, + + + as it works with file formats such as PDF, DOC, + + + PPTX or similar. + + :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 file_version_id: The ID of the file version +Example: "1234" + :type file_version_id: str + :param trashed_at: Set this to `null` to clear +the date and restore the file., defaults to None + :type trashed_at: Union[Optional[str], NullValue], 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 = {'trashed_at': trashed_at} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/versions/', to_string(file_version_id)]), method='PUT', 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, FileVersionFull) + def promote_file_version(self, file_id: str, *, id: Optional[str] = None, type: Optional[PromoteFileVersionType] = None, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FileVersionFull: + """ + Promote a specific version of a file. + + If previous versions exist, this method can be used to + + + promote one of the older versions to the top of the version history. + + + This creates a new copy of the old version and puts it at the + + + top of the versions history. The file will have the exact same contents + + + as the older version, with the the same hash digest, `etag`, and + + + name as the original. + + + Other properties such as comments do not get updated to their + + + former values. + + + Don't use this endpoint to restore Box Notes, + + + as it works with file formats such as PDF, DOC, + + + PPTX or similar. + + :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 id: The file version ID, defaults to None + :type id: Optional[str], optional + :param type: The type to promote, defaults to None + :type type: Optional[PromoteFileVersionType], optional + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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 = {} + request_body: Dict = {'id': id, 'type': type} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/versions/current']), method='POST', params=query_params_map, 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, FileVersionFull) \ No newline at end of file diff --git a/box_sdk_gen/managers/file_watermarks.py b/box_sdk_gen/managers/file_watermarks.py new file mode 100644 index 000000000..093260782 --- /dev/null +++ b/box_sdk_gen/managers/file_watermarks.py @@ -0,0 +1,123 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.watermark import Watermark + +from box_sdk_gen.schemas.client_error import ClientError + +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 UpdateFileWatermarkWatermarkImprintField(str, Enum): + DEFAULT = 'default' + +class UpdateFileWatermarkWatermark(BaseObject): + def __init__(self, *, imprint: UpdateFileWatermarkWatermarkImprintField = UpdateFileWatermarkWatermarkImprintField.DEFAULT, **kwargs): + """ + :param imprint: The type of watermark to apply. + +Currently only supports one option., defaults to UpdateFileWatermarkWatermarkImprintField.DEFAULT + :type imprint: UpdateFileWatermarkWatermarkImprintField, optional + """ + super().__init__(**kwargs) + self.imprint = imprint + +class FileWatermarksManager: + 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_watermark(self, file_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Watermark: + """ + Retrieve the watermark for a file. + :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 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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/watermark']), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Watermark) + def update_file_watermark(self, file_id: str, watermark: UpdateFileWatermarkWatermark, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Watermark: + """ + Applies or update a watermark on a file. + :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 watermark: The watermark to imprint on the file + :type watermark: UpdateFileWatermarkWatermark + :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 = {'watermark': watermark} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/watermark']), method='PUT', 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, Watermark) + def delete_file_watermark(self, file_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Removes the watermark from a file. + :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 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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/watermark']), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/files.py b/box_sdk_gen/managers/files.py new file mode 100644 index 000000000..86793fa1d --- /dev/null +++ b/box_sdk_gen/managers/files.py @@ -0,0 +1,537 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from enum import Enum + +from typing import List + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.internal.null_value import NullValue + +from typing import Union + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.client_error import ClientError + +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 + +from box_sdk_gen.internal.utils import DateTime + +class UpdateFileByIdParent(BaseObject): + def __init__(self, *, id: Optional[str] = None, user_id: Optional[str] = None, **kwargs): + """ + :param id: The ID of parent item, defaults to None + :type id: Optional[str], optional + :param user_id: The input for `user_id` is optional. Moving to non-root folder is not allowed when `user_id` is present. Parent folder id should be zero when `user_id` is provided., defaults to None + :type user_id: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.user_id = user_id + +class UpdateFileByIdSharedLinkAccessField(str, Enum): + OPEN = 'open' + COMPANY = 'company' + COLLABORATORS = 'collaborators' + +class UpdateFileByIdSharedLinkPermissionsField(BaseObject): + def __init__(self, *, can_download: Optional[bool] = None, **kwargs): + """ + :param can_download: If the shared link allows for downloading of files. +This can only be set when `access` is set to +`open` or `company`., defaults to None + :type can_download: Optional[bool], optional + """ + super().__init__(**kwargs) + self.can_download = can_download + +class UpdateFileByIdSharedLink(BaseObject): + def __init__(self, *, access: Optional[UpdateFileByIdSharedLinkAccessField] = None, password: Optional[str] = None, vanity_name: Optional[str] = None, unshared_at: Optional[DateTime] = None, permissions: Optional[UpdateFileByIdSharedLinkPermissionsField] = None, **kwargs): + """ + :param access: The level of access for the shared link. This can be +restricted to anyone with the link (`open`), only people +within the company (`company`) and only those who +have been invited to the folder (`collaborators`). + +If not set, this field defaults to the access level specified +by the enterprise admin. To create a shared link with this +default setting pass the `shared_link` object with +no `access` field, for example `{ "shared_link": {} }`. + +The `company` access level is only available to paid +accounts., defaults to None + :type access: Optional[UpdateFileByIdSharedLinkAccessField], optional + :param password: The password required to access the shared link. Set the +password to `null` to remove it. +Passwords must now be at least eight characters +long and include a number, upper case letter, or +a non-numeric or non-alphabetic character. +A password can only be set when `access` is set to `open`., defaults to None + :type password: Optional[str], optional + :param vanity_name: Defines a custom vanity name to use in the shared link URL, +for example `https://app.box.com/v/my-shared-link`. + +Custom URLs should not be used when sharing sensitive content +as vanity URLs are a lot easier to guess than regular shared links., defaults to None + :type vanity_name: Optional[str], optional + :param unshared_at: The timestamp at which this shared link will +expire. This field can only be set by +users with paid accounts., defaults to None + :type unshared_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.access = access + self.password = password + self.vanity_name = vanity_name + self.unshared_at = unshared_at + self.permissions = permissions + +class UpdateFileByIdLockAccessField(str, Enum): + LOCK = 'lock' + +class UpdateFileByIdLock(BaseObject): + def __init__(self, *, access: Optional[UpdateFileByIdLockAccessField] = None, expires_at: Optional[DateTime] = None, is_download_prevented: Optional[bool] = None, **kwargs): + """ + :param access: The type of this object., defaults to None + :type access: Optional[UpdateFileByIdLockAccessField], optional + :param expires_at: Defines the time at which the lock expires., defaults to None + :type expires_at: Optional[DateTime], optional + :param is_download_prevented: Defines if the file can be downloaded while it is locked., defaults to None + :type is_download_prevented: Optional[bool], optional + """ + super().__init__(**kwargs) + self.access = access + self.expires_at = expires_at + self.is_download_prevented = is_download_prevented + +class UpdateFileByIdPermissionsCanDownloadField(str, Enum): + OPEN = 'open' + COMPANY = 'company' + +class UpdateFileByIdPermissions(BaseObject): + def __init__(self, *, can_download: Optional[UpdateFileByIdPermissionsCanDownloadField] = None, **kwargs): + """ + :param can_download: Defines who is allowed to download this file. The possible +values are either `open` for everyone or `company` for +the other members of the user's enterprise. + +This setting overrides the download permissions that are +normally part of the `role` of a collaboration. When set to +`company`, this essentially removes the download option for +external users with `viewer` or `editor` a roles., defaults to None + :type can_download: Optional[UpdateFileByIdPermissionsCanDownloadField], optional + """ + super().__init__(**kwargs) + self.can_download = can_download + +class UpdateFileByIdCollections(BaseObject): + def __init__(self, *, id: Optional[str] = None, type: Optional[str] = None, **kwargs): + """ + :param id: The unique identifier for this object, defaults to None + :type id: Optional[str], optional + :param type: The type for this object, defaults to None + :type type: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class CopyFileParent(BaseObject): + def __init__(self, id: str, **kwargs): + """ + :param id: The ID of folder to copy the file to. + :type id: str + """ + super().__init__(**kwargs) + self.id = id + +class GetFileThumbnailUrlExtension(str, Enum): + PNG = 'png' + JPG = 'jpg' + +class GetFileThumbnailByIdExtension(str, Enum): + PNG = 'png' + JPG = 'jpg' + +class FilesManager: + 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_by_id(self, file_id: str, *, fields: Optional[List[str]] = None, if_none_match: Optional[str] = None, boxapi: Optional[str] = None, x_rep_hints: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FileFull: + """ + Retrieves the details about a file. + :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 fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested. + +Additionally this field can be used to query any metadata +applied to the file by specifying the `metadata` field as well +as the scope and key of the template to retrieve, for example +`?fields=metadata.enterprise_12345.contractTemplate`., defaults to None + :type fields: Optional[List[str]], optional + :param if_none_match: Ensures an item is only returned if it has changed. + +Pass in the item's last observed `etag` value +into this header and the endpoint will fail +with a `304 Not Modified` if the item has not +changed since., defaults to None + :type if_none_match: Optional[str], optional + :param boxapi: The URL, and optional password, for the shared link of this item. + +This header can be used to access items that have not been +explicitly shared with a user. + +Use the format `shared_link=[link]` or if a password is required then +use `shared_link=[link]&shared_link_password=[password]`. + +This header can be used on the file or folder shared, as well as on any files +or folders nested within the item., defaults to None + :type boxapi: Optional[str], optional + :param x_rep_hints: A header required to request specific `representations` +of a file. Use this in combination with the `fields` query +parameter to request a specific file representation. + +The general format for these representations is +`X-Rep-Hints: [...]` where `[...]` is one or many +hints in the format `[fileType?query]`. + +For example, to request a `png` representation in `32x32` +as well as `64x64` pixel dimensions provide the following +hints. + +`x-rep-hints: [jpg?dimensions=32x32][jpg?dimensions=64x64]` + +Additionally, a `text` representation is available for all +document file types in Box using the `[extracted_text]` +representation. + +`x-rep-hints: [extracted_text]`, defaults to None + :type x_rep_hints: 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({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({'if-none-match': to_string(if_none_match), 'boxapi': to_string(boxapi), 'x-rep-hints': to_string(x_rep_hints), **extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id)]), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, FileFull) + def update_file_by_id(self, file_id: str, *, name: Optional[str] = None, description: Optional[str] = None, parent: Optional[UpdateFileByIdParent] = None, shared_link: Union[Optional[UpdateFileByIdSharedLink], NullValue] = None, lock: Union[Optional[UpdateFileByIdLock], NullValue] = None, disposition_at: Optional[DateTime] = None, permissions: Optional[UpdateFileByIdPermissions] = None, collections: Union[Optional[List[UpdateFileByIdCollections]], NullValue] = None, tags: Optional[List[str]] = None, fields: Optional[List[str]] = None, if_match: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FileFull: + """ + Updates a file. This can be used to rename or move a file, + + create a shared link, or lock a file. + + :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 name: An optional different name for the file. This can be used to +rename the file. + +File names must be unique within their parent folder. The name check is case-insensitive, so a file +named `New File` cannot be created in a parent folder that already contains a folder named `new file`., defaults to None + :type name: Optional[str], optional + :param description: The description for a file. This can be seen in the right-hand sidebar panel +when viewing a file in the Box web app. Additionally, this index is used in +the search index of the file, allowing users to find the file by the content +in the description., defaults to None + :type description: Optional[str], optional + :param lock: Defines a lock on an item. This prevents the item from being +moved, renamed, or otherwise changed by anyone other than the user +who created the lock. + +Set this to `null` to remove the lock., defaults to None + :type lock: Union[Optional[UpdateFileByIdLock], NullValue], optional + :param disposition_at: The retention expiration timestamp for the given file. This +date cannot be shortened once set on a file., defaults to None + :type disposition_at: Optional[DateTime], optional + :param permissions: Defines who can download a file., defaults to None + :type permissions: Optional[UpdateFileByIdPermissions], optional + :param collections: An array of collections to make this file +a member of. Currently +we only support the `favorites` collection. + +To get the ID for a collection, use the +[List all collections][1] endpoint. + +Passing an empty array `[]` or `null` will remove +the file from all collections. + +[1]: e://get-collections, defaults to None + :type collections: Union[Optional[List[UpdateFileByIdCollections]], NullValue], optional + :param tags: The tags for this item. These tags are shown in +the Box web app and mobile apps next to an item. + +To add or remove a tag, retrieve the item's current tags, +modify them, and then update this field. + +There is a limit of 100 tags per item, and 10,000 +unique tags per enterprise., defaults to None + :type tags: Optional[List[str]], optional + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[str]], optional + :param if_match: Ensures this item hasn't recently changed before +making changes. + +Pass in the item's last observed `etag` value +into this header and the endpoint will fail +with a `412 Precondition Failed` if it +has changed since., defaults to None + :type if_match: 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 = {} + request_body: Dict = {'name': name, 'description': description, 'parent': parent, 'shared_link': shared_link, 'lock': lock, 'disposition_at': disposition_at, 'permissions': permissions, 'collections': collections, 'tags': tags} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({'if-match': to_string(if_match), **extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id)]), method='PUT', params=query_params_map, 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, FileFull) + def delete_file_by_id(self, file_id: str, *, if_match: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Deletes a file, either permanently or by moving it to + + the trash. + + + The the enterprise settings determine whether the item will + + + be permanently deleted from Box or moved to the trash. + + :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 if_match: Ensures this item hasn't recently changed before +making changes. + +Pass in the item's last observed `etag` value +into this header and the endpoint will fail +with a `412 Precondition Failed` if it +has changed since., defaults to None + :type if_match: 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 = {} + headers_map: Dict[str, str] = prepare_params({'if-match': to_string(if_match), **extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None + def copy_file(self, file_id: str, parent: CopyFileParent, *, name: Optional[str] = None, version: Optional[str] = None, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FileFull: + r""" + Creates a copy of a file. + :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 parent: The destination folder to copy the file to. + :type parent: CopyFileParent + :param name: An optional new name for the copied file. + +There are some restrictions to the file name. Names containing +non-printable ASCII characters, forward and backward slashes +(`/`, `\`), and protected names like `.` and `..` are +automatically sanitized by removing the non-allowed +characters., defaults to None + :type name: Optional[str], optional + :param version: An optional ID of the specific file version to copy., defaults to None + :type version: Optional[str], optional + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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 = {} + request_body: Dict = {'name': name, 'version': version, 'parent': parent} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/copy']), method='POST', params=query_params_map, 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, FileFull) + def get_file_thumbnail_url(self, file_id: str, extension: GetFileThumbnailUrlExtension, *, min_height: Optional[int] = None, min_width: Optional[int] = None, max_height: Optional[int] = None, max_width: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> str: + """ + Retrieves a thumbnail, or smaller image representation, of a file. + + Sizes of `32x32`,`64x64`, `128x128`, and `256x256` can be returned in + + + the `.png` format and sizes of `32x32`, `160x160`, and `320x320` + + + can be returned in the `.jpg` format. + + + Thumbnails can be generated for the image and video file formats listed + + + [found on our community site][1]. + + + [1]: https://community.box.com/t5/Migrating-and-Previewing-Content/File-Types-and-Fonts-Supported-in-Box-Content-Preview/ta-p/327 + + :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 extension: The file format for the thumbnail +Example: "png" + :type extension: GetFileThumbnailUrlExtension + :param min_height: The minimum height of the thumbnail, defaults to None + :type min_height: Optional[int], optional + :param min_width: The minimum width of the thumbnail, defaults to None + :type min_width: Optional[int], optional + :param max_height: The maximum height of the thumbnail, defaults to None + :type max_height: Optional[int], optional + :param max_width: The maximum width of the thumbnail, defaults to None + :type max_width: Optional[int], 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({'min_height': to_string(min_height), 'min_width': to_string(min_width), 'max_height': to_string(max_height), 'max_width': to_string(max_width)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/thumbnail.', to_string(extension)]), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session, follow_redirects=False)) + if 'location' in response.headers: + return response.headers.get('location') + if 'Location' in response.headers: + return response.headers.get('Location') + raise BoxSDKError(message='No location header in response') + def get_file_thumbnail_by_id(self, file_id: str, extension: GetFileThumbnailByIdExtension, *, min_height: Optional[int] = None, min_width: Optional[int] = None, max_height: Optional[int] = None, max_width: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Optional[ByteStream]: + """ + Retrieves a thumbnail, or smaller image representation, of a file. + + Sizes of `32x32`,`64x64`, `128x128`, and `256x256` can be returned in + + + the `.png` format and sizes of `32x32`, `160x160`, and `320x320` + + + can be returned in the `.jpg` format. + + + Thumbnails can be generated for the image and video file formats listed + + + [found on our community site][1]. + + + [1]: https://community.box.com/t5/Migrating-and-Previewing-Content/File-Types-and-Fonts-Supported-in-Box-Content-Preview/ta-p/327 + + :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 extension: The file format for the thumbnail +Example: "png" + :type extension: GetFileThumbnailByIdExtension + :param min_height: The minimum height of the thumbnail, defaults to None + :type min_height: Optional[int], optional + :param min_width: The minimum width of the thumbnail, defaults to None + :type min_width: Optional[int], optional + :param max_height: The maximum height of the thumbnail, defaults to None + :type max_height: Optional[int], optional + :param max_width: The maximum width of the thumbnail, defaults to None + :type max_width: Optional[int], 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({'min_height': to_string(min_height), 'min_width': to_string(min_width), 'max_height': to_string(max_height), 'max_width': to_string(max_width)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/thumbnail.', to_string(extension)]), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.BINARY, auth=self.auth, network_session=self.network_session)) + if to_string(response.status) == '202': + return None + return response.content \ No newline at end of file diff --git a/box_sdk_gen/managers/folder_classifications.py b/box_sdk_gen/managers/folder_classifications.py new file mode 100644 index 000000000..0afde3acf --- /dev/null +++ b/box_sdk_gen/managers/folder_classifications.py @@ -0,0 +1,219 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from typing import List + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.classification import Classification + +from box_sdk_gen.schemas.client_error import ClientError + +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 UpdateClassificationOnFolderRequestBodyOpField(str, Enum): + REPLACE = 'replace' + +class UpdateClassificationOnFolderRequestBodyPathField(str, Enum): + _BOX__SECURITY__CLASSIFICATION__KEY = '/Box__Security__Classification__Key' + +class UpdateClassificationOnFolderRequestBody(BaseObject): + def __init__(self, value: str, *, op: UpdateClassificationOnFolderRequestBodyOpField = UpdateClassificationOnFolderRequestBodyOpField.REPLACE, path: UpdateClassificationOnFolderRequestBodyPathField = UpdateClassificationOnFolderRequestBodyPathField._BOX__SECURITY__CLASSIFICATION__KEY, **kwargs): + """ + :param value: The name of the classification to apply to this folder. + +To list the available classifications in an enterprise, +use the classification API to retrieve the +[classification template](e://get_metadata_templates_enterprise_securityClassification-6VMVochwUWo_schema) +which lists all available classification keys. + :type value: str + :param op: `replace`, defaults to UpdateClassificationOnFolderRequestBodyOpField.REPLACE + :type op: UpdateClassificationOnFolderRequestBodyOpField, optional + :param path: Defines classifications +available in the enterprise., defaults to UpdateClassificationOnFolderRequestBodyPathField._BOX__SECURITY__CLASSIFICATION__KEY + :type path: UpdateClassificationOnFolderRequestBodyPathField, optional + """ + super().__init__(**kwargs) + self.value = value + self.op = op + self.path = path + +class FolderClassificationsManager: + 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_classification_on_folder(self, folder_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Classification: + """ + Retrieves the classification metadata instance that + + has been applied to a folder. + + + This API can also be called by including the enterprise ID in the + + + URL explicitly, for example + + + `/folders/:id/enterprise_12345/securityClassification-6VMVochwUWo`. + + :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 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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders/', to_string(folder_id), '/metadata/enterprise/securityClassification-6VMVochwUWo']), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Classification) + def add_classification_to_folder(self, folder_id: str, *, box_security_classification_key: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Classification: + """ + Adds a classification to a folder by specifying the label of the + + classification to add. + + + This API can also be called by including the enterprise ID in the + + + URL explicitly, for example + + + `/folders/:id/enterprise_12345/securityClassification-6VMVochwUWo`. + + :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 box_security_classification_key: The name of the classification to apply to this folder. + +To list the available classifications in an enterprise, +use the classification API to retrieve the +[classification template](e://get_metadata_templates_enterprise_securityClassification-6VMVochwUWo_schema) +which lists all available classification keys., defaults to None + :type box_security_classification_key: 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 = {} + request_body: Dict = {'Box__Security__Classification__Key': box_security_classification_key} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders/', to_string(folder_id), '/metadata/enterprise/securityClassification-6VMVochwUWo']), 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, Classification) + def update_classification_on_folder(self, folder_id: str, request_body: List[UpdateClassificationOnFolderRequestBody], *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Classification: + """ + Updates a classification on a folder. + + The classification can only be updated if a classification has already been + + + applied to the folder before. When editing classifications, only values are + + + defined for the enterprise will be accepted. + + :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 request_body: Request body of updateClassificationOnFolder method + :type request_body: List[UpdateClassificationOnFolderRequestBody] + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders/', to_string(folder_id), '/metadata/enterprise/securityClassification-6VMVochwUWo']), method='PUT', headers=headers_map, data=serialize(request_body), content_type='application/json-patch+json', response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Classification) + def delete_classification_from_folder(self, folder_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Removes any classifications from a folder. + + This API can also be called by including the enterprise ID in the + + + URL explicitly, for example + + + `/folders/:id/enterprise_12345/securityClassification-6VMVochwUWo`. + + :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 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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders/', to_string(folder_id), '/metadata/enterprise/securityClassification-6VMVochwUWo']), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/folder_locks.py b/box_sdk_gen/managers/folder_locks.py new file mode 100644 index 000000000..220e94363 --- /dev/null +++ b/box_sdk_gen/managers/folder_locks.py @@ -0,0 +1,147 @@ +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.folder_locks import FolderLocks + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.folder_lock import FolderLock + +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 CreateFolderLockLockedOperations(BaseObject): + def __init__(self, move: bool, delete: bool, **kwargs): + """ + :param move: Whether moving the folder should be locked. + :type move: bool + :param delete: Whether deleting the folder should be locked. + :type delete: bool + """ + super().__init__(**kwargs) + self.move = move + self.delete = delete + +class CreateFolderLockFolder(BaseObject): + def __init__(self, type: str, id: str, **kwargs): + """ + :param type: The content type the lock is being applied to. Only `folder` +is supported. + :type type: str + :param id: The ID of the folder. + :type id: str + """ + super().__init__(**kwargs) + self.type = type + self.id = id + +class FolderLocksManager: + 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_folder_locks(self, folder_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FolderLocks: + """ + Retrieves folder lock details for a given folder. + + You must be authenticated as the owner or co-owner of the folder to + + + use this endpoint. + + :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`. + :type folder_id: str + :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({'folder_id': to_string(folder_id)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folder_locks']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, FolderLocks) + def create_folder_lock(self, folder: CreateFolderLockFolder, *, locked_operations: Optional[CreateFolderLockLockedOperations] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FolderLock: + """ + Creates a folder lock on a folder, preventing it from being moved and/or + + deleted. + + + You must be authenticated as the owner or co-owner of the folder to + + + use this endpoint. + + :param folder: The folder to apply the lock to. + :type folder: CreateFolderLockFolder + :param locked_operations: The operations to lock for the folder. If `locked_operations` is +included in the request, both `move` and `delete` must also be +included and both set to `true`., defaults to None + :type locked_operations: Optional[CreateFolderLockLockedOperations], 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 = {'locked_operations': locked_operations, 'folder': folder} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folder_locks']), 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, FolderLock) + def delete_folder_lock_by_id(self, folder_lock_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Deletes a folder lock on a given folder. + + You must be authenticated as the owner or co-owner of the folder to + + + use this endpoint. + + :param folder_lock_id: The ID of the folder lock. +Example: "12345" + :type folder_lock_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folder_locks/', to_string(folder_lock_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/folder_metadata.py b/box_sdk_gen/managers/folder_metadata.py new file mode 100644 index 000000000..07f33126f --- /dev/null +++ b/box_sdk_gen/managers/folder_metadata.py @@ -0,0 +1,285 @@ +from enum import Enum + +from typing import Optional + +from typing import Dict + +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 deserialize + +from box_sdk_gen.serialization.json import serialize + +from typing import List + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.metadatas import Metadatas + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.metadata_full import MetadataFull + +from box_sdk_gen.schemas.metadata_instance_value import MetadataInstanceValue + +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 GetFolderMetadataByIdScope(str, Enum): + GLOBAL = 'global' + ENTERPRISE = 'enterprise' + +class CreateFolderMetadataByIdScope(str, Enum): + GLOBAL = 'global' + ENTERPRISE = 'enterprise' + +class UpdateFolderMetadataByIdScope(str, Enum): + GLOBAL = 'global' + ENTERPRISE = 'enterprise' + +class UpdateFolderMetadataByIdRequestBodyOpField(str, Enum): + ADD = 'add' + REPLACE = 'replace' + REMOVE = 'remove' + TEST = 'test' + MOVE = 'move' + COPY = 'copy' + +class UpdateFolderMetadataByIdRequestBody(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'from_': 'from', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'from': 'from_', **BaseObject._json_to_fields_mapping} + def __init__(self, *, op: Optional[UpdateFolderMetadataByIdRequestBodyOpField] = None, path: Optional[str] = None, value: Optional[MetadataInstanceValue] = None, from_: Optional[str] = None, **kwargs): + """ + :param op: The type of change to perform on the template. Some +of these are hazardous as they will change existing templates., defaults to None + :type op: Optional[UpdateFolderMetadataByIdRequestBodyOpField], optional + :param path: The location in the metadata JSON object +to apply the changes to, in the format of a +[JSON-Pointer](https://tools.ietf.org/html/rfc6901). + +The path must always be prefixed with a `/` to represent the root +of the template. The characters `~` and `/` are reserved +characters and must be escaped in the key., defaults to None + :type path: Optional[str], optional + :param from_: The location in the metadata JSON object to move or copy a value +from. Required for `move` or `copy` operations and must be in the +format of a [JSON-Pointer](https://tools.ietf.org/html/rfc6901)., defaults to None + :type from_: Optional[str], optional + """ + super().__init__(**kwargs) + self.op = op + self.path = path + self.value = value + self.from_ = from_ + +class DeleteFolderMetadataByIdScope(str, Enum): + GLOBAL = 'global' + ENTERPRISE = 'enterprise' + +class FolderMetadataManager: + 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_folder_metadata(self, folder_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Metadatas: + """ + Retrieves all metadata for a given folder. This can not be used on the root + + folder with ID `0`. + + :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 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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders/', to_string(folder_id), '/metadata']), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Metadatas) + def get_folder_metadata_by_id(self, folder_id: str, scope: GetFolderMetadataByIdScope, template_key: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> MetadataFull: + """ + Retrieves the instance of a metadata template that has been applied to a + + folder. This can not be used on the root folder with ID `0`. + + :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 scope: The scope of the metadata template +Example: "global" + :type scope: GetFolderMetadataByIdScope + :param template_key: The name of the metadata template +Example: "properties" + :type template_key: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders/', to_string(folder_id), '/metadata/', to_string(scope), '/', to_string(template_key)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, MetadataFull) + def create_folder_metadata_by_id(self, folder_id: str, scope: CreateFolderMetadataByIdScope, template_key: str, request_body: Dict, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> MetadataFull: + """ + Applies an instance of a metadata template to a folder. + + In most cases only values that are present in the metadata template + + + will be accepted, except for the `global.properties` template which accepts + + + any key-value pair. + + + To display the metadata template in the Box web app the enterprise needs to be + + + configured to enable **Cascading Folder Level Metadata** for the user in the + + + admin console. + + :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 scope: The scope of the metadata template +Example: "global" + :type scope: CreateFolderMetadataByIdScope + :param template_key: The name of the metadata template +Example: "properties" + :type template_key: str + :param request_body: Request body of createFolderMetadataById method + :type request_body: Dict + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders/', to_string(folder_id), '/metadata/', to_string(scope), '/', to_string(template_key)]), 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, MetadataFull) + def update_folder_metadata_by_id(self, folder_id: str, scope: UpdateFolderMetadataByIdScope, template_key: str, request_body: List[UpdateFolderMetadataByIdRequestBody], *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> MetadataFull: + """ + Updates a piece of metadata on a folder. + + The metadata instance can only be updated if the template has already been + + + applied to the folder before. When editing metadata, only values that match + + + the metadata template schema will be accepted. + + + The update is applied atomically. If any errors occur during the + + + application of the operations, the metadata instance will not be changed. + + :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 scope: The scope of the metadata template +Example: "global" + :type scope: UpdateFolderMetadataByIdScope + :param template_key: The name of the metadata template +Example: "properties" + :type template_key: str + :param request_body: Request body of updateFolderMetadataById method + :type request_body: List[UpdateFolderMetadataByIdRequestBody] + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders/', to_string(folder_id), '/metadata/', to_string(scope), '/', to_string(template_key)]), method='PUT', headers=headers_map, data=serialize(request_body), content_type='application/json-patch+json', response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, MetadataFull) + def delete_folder_metadata_by_id(self, folder_id: str, scope: DeleteFolderMetadataByIdScope, template_key: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Deletes a piece of folder metadata. + :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 scope: The scope of the metadata template +Example: "global" + :type scope: DeleteFolderMetadataByIdScope + :param template_key: The name of the metadata template +Example: "properties" + :type template_key: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders/', to_string(folder_id), '/metadata/', to_string(scope), '/', to_string(template_key)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/folder_watermarks.py b/box_sdk_gen/managers/folder_watermarks.py new file mode 100644 index 000000000..ee9122927 --- /dev/null +++ b/box_sdk_gen/managers/folder_watermarks.py @@ -0,0 +1,132 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.watermark import Watermark + +from box_sdk_gen.schemas.client_error import ClientError + +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 UpdateFolderWatermarkWatermarkImprintField(str, Enum): + DEFAULT = 'default' + +class UpdateFolderWatermarkWatermark(BaseObject): + def __init__(self, *, imprint: UpdateFolderWatermarkWatermarkImprintField = UpdateFolderWatermarkWatermarkImprintField.DEFAULT, **kwargs): + """ + :param imprint: The type of watermark to apply. + +Currently only supports one option., defaults to UpdateFolderWatermarkWatermarkImprintField.DEFAULT + :type imprint: UpdateFolderWatermarkWatermarkImprintField, optional + """ + super().__init__(**kwargs) + self.imprint = imprint + +class FolderWatermarksManager: + 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_folder_watermark(self, folder_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Watermark: + """ + Retrieve the watermark for a folder. + :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 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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders/', to_string(folder_id), '/watermark']), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Watermark) + def update_folder_watermark(self, folder_id: str, watermark: UpdateFolderWatermarkWatermark, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Watermark: + """ + Applies or update a watermark on a folder. + :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 watermark: The watermark to imprint on the folder + :type watermark: UpdateFolderWatermarkWatermark + :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 = {'watermark': watermark} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders/', to_string(folder_id), '/watermark']), method='PUT', 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, Watermark) + def delete_folder_watermark(self, folder_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Removes the watermark from a folder. + :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 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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders/', to_string(folder_id), '/watermark']), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/folders.py b/box_sdk_gen/managers/folders.py new file mode 100644 index 000000000..c85e93f31 --- /dev/null +++ b/box_sdk_gen/managers/folders.py @@ -0,0 +1,694 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.internal.null_value import NullValue + +from typing import Union + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.items import Items + +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 + +from box_sdk_gen.internal.utils import DateTime + +class GetFolderByIdSort(str, Enum): + ID = 'id' + NAME = 'name' + DATE = 'date' + SIZE = 'size' + +class GetFolderByIdDirection(str, Enum): + ASC = 'ASC' + DESC = 'DESC' + +class UpdateFolderByIdSyncState(str, Enum): + SYNCED = 'synced' + NOT_SYNCED = 'not_synced' + PARTIALLY_SYNCED = 'partially_synced' + +class UpdateFolderByIdParent(BaseObject): + def __init__(self, *, id: Optional[str] = None, user_id: Optional[str] = None, **kwargs): + """ + :param id: The ID of parent item, defaults to None + :type id: Optional[str], optional + :param user_id: The input for `user_id` is optional. Moving to non-root folder is not allowed when `user_id` is present. Parent folder id should be zero when `user_id` is provided., defaults to None + :type user_id: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.user_id = user_id + +class UpdateFolderByIdSharedLinkAccessField(str, Enum): + OPEN = 'open' + COMPANY = 'company' + COLLABORATORS = 'collaborators' + +class UpdateFolderByIdSharedLinkPermissionsField(BaseObject): + def __init__(self, *, can_download: Optional[bool] = None, **kwargs): + """ + :param can_download: If the shared link allows for downloading of files. +This can only be set when `access` is set to +`open` or `company`., defaults to None + :type can_download: Optional[bool], optional + """ + super().__init__(**kwargs) + self.can_download = can_download + +class UpdateFolderByIdSharedLink(BaseObject): + def __init__(self, *, access: Optional[UpdateFolderByIdSharedLinkAccessField] = None, password: Optional[str] = None, vanity_name: Optional[str] = None, unshared_at: Optional[DateTime] = None, permissions: Optional[UpdateFolderByIdSharedLinkPermissionsField] = None, **kwargs): + """ + :param access: The level of access for the shared link. This can be +restricted to anyone with the link (`open`), only people +within the company (`company`) and only those who +have been invited to the folder (`collaborators`). + +If not set, this field defaults to the access level specified +by the enterprise admin. To create a shared link with this +default setting pass the `shared_link` object with +no `access` field, for example `{ "shared_link": {} }`. + +The `company` access level is only available to paid +accounts., defaults to None + :type access: Optional[UpdateFolderByIdSharedLinkAccessField], optional + :param password: The password required to access the shared link. Set the +password to `null` to remove it. +Passwords must now be at least eight characters +long and include a number, upper case letter, or +a non-numeric or non-alphabetic character. +A password can only be set when `access` is set to `open`., defaults to None + :type password: Optional[str], optional + :param vanity_name: Defines a custom vanity name to use in the shared link URL, +for example `https://app.box.com/v/my-shared-link`. + +Custom URLs should not be used when sharing sensitive content +as vanity URLs are a lot easier to guess than regular shared links., defaults to None + :type vanity_name: Optional[str], optional + :param unshared_at: The timestamp at which this shared link will +expire. This field can only be set by +users with paid accounts., defaults to None + :type unshared_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.access = access + self.password = password + self.vanity_name = vanity_name + self.unshared_at = unshared_at + self.permissions = permissions + +class UpdateFolderByIdFolderUploadEmailAccessField(str, Enum): + OPEN = 'open' + COLLABORATORS = 'collaborators' + +class UpdateFolderByIdFolderUploadEmail(BaseObject): + def __init__(self, *, access: Optional[UpdateFolderByIdFolderUploadEmailAccessField] = None, **kwargs): + """ + :param access: When this parameter has been set, users can email files +to the email address that has been automatically +created for this folder. + +To create an email address, set this property either when +creating or updating the folder. + +When set to `collaborators`, only emails from registered email +addresses for collaborators will be accepted. This includes +any email aliases a user might have registered. + +When set to `open` it will accept emails from any email +address., defaults to None + :type access: Optional[UpdateFolderByIdFolderUploadEmailAccessField], optional + """ + super().__init__(**kwargs) + self.access = access + +class UpdateFolderByIdCollections(BaseObject): + def __init__(self, *, id: Optional[str] = None, type: Optional[str] = None, **kwargs): + """ + :param id: The unique identifier for this object, defaults to None + :type id: Optional[str], optional + :param type: The type for this object, defaults to None + :type type: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class GetFolderItemsSort(str, Enum): + ID = 'id' + NAME = 'name' + DATE = 'date' + SIZE = 'size' + +class GetFolderItemsDirection(str, Enum): + ASC = 'ASC' + DESC = 'DESC' + +class CreateFolderParent(BaseObject): + def __init__(self, id: str, **kwargs): + """ + :param id: The ID of parent folder + :type id: str + """ + super().__init__(**kwargs) + self.id = id + +class CreateFolderFolderUploadEmailAccessField(str, Enum): + OPEN = 'open' + COLLABORATORS = 'collaborators' + +class CreateFolderFolderUploadEmail(BaseObject): + def __init__(self, *, access: Optional[CreateFolderFolderUploadEmailAccessField] = None, **kwargs): + """ + :param access: When this parameter has been set, users can email files +to the email address that has been automatically +created for this folder. + +To create an email address, set this property either when +creating or updating the folder. + +When set to `collaborators`, only emails from registered email +addresses for collaborators will be accepted. This includes +any email aliases a user might have registered. + +When set to `open` it will accept emails from any email +address., defaults to None + :type access: Optional[CreateFolderFolderUploadEmailAccessField], optional + """ + super().__init__(**kwargs) + self.access = access + +class CreateFolderSyncState(str, Enum): + SYNCED = 'synced' + NOT_SYNCED = 'not_synced' + PARTIALLY_SYNCED = 'partially_synced' + +class CopyFolderParent(BaseObject): + def __init__(self, id: str, **kwargs): + """ + :param id: The ID of parent folder + :type id: str + """ + super().__init__(**kwargs) + self.id = id + +class FoldersManager: + 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_folder_by_id(self, folder_id: str, *, fields: Optional[List[str]] = None, sort: Optional[GetFolderByIdSort] = None, direction: Optional[GetFolderByIdDirection] = None, offset: Optional[int] = None, limit: Optional[int] = None, if_none_match: Optional[str] = None, boxapi: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FolderFull: + """ + Retrieves details for a folder, including the first 100 entries + + in the folder. + + + Passing `sort`, `direction`, `offset`, and `limit` + + + parameters in query allows you to manage the + + + list of returned + + + [folder items](r://folder--full#param-item-collection). + + + To fetch more items within the folder, use the + + + [Get items in a folder](e://get-folders-id-items) endpoint. + + :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 fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested. + +Additionally this field can be used to query any metadata +applied to the file by specifying the `metadata` field as well +as the scope and key of the template to retrieve, for example +`?fields=metadata.enterprise_12345.contractTemplate`., defaults to None + :type fields: Optional[List[str]], optional + :param sort: Defines the **second** attribute by which items +are sorted. + +The folder type affects the way the items +are sorted: + + * **Standard folder**: + Items are always sorted by + their `type` first, with + folders listed before files, + and files listed + before web links. + + * **Root folder**: + This parameter is not supported + for marker-based pagination + on the root folder + + (the folder with an `id` of `0`). + + * **Shared folder with parent path + to the associated folder visible to + the collaborator**: + Items are always sorted by + their `type` first, with + folders listed before files, + and files listed + before web links., defaults to None + :type sort: Optional[GetFolderByIdSort], optional + :param direction: The direction to sort results in. This can be either in alphabetical ascending +(`ASC`) or descending (`DESC`) order., defaults to None + :type direction: Optional[GetFolderByIdDirection], optional + :param offset: The offset of the item at which to begin the response. + +Queries with offset parameter value +exceeding 10000 will be rejected +with a 400 response., defaults to None + :type offset: Optional[int], optional + :param limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], optional + :param if_none_match: Ensures an item is only returned if it has changed. + +Pass in the item's last observed `etag` value +into this header and the endpoint will fail +with a `304 Not Modified` if the item has not +changed since., defaults to None + :type if_none_match: Optional[str], optional + :param boxapi: The URL, and optional password, for the shared link of this item. + +This header can be used to access items that have not been +explicitly shared with a user. + +Use the format `shared_link=[link]` or if a password is required then +use `shared_link=[link]&shared_link_password=[password]`. + +This header can be used on the file or folder shared, as well as on any files +or folders nested within the item., defaults to None + :type boxapi: 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({'fields': to_string(fields), 'sort': to_string(sort), 'direction': to_string(direction), 'offset': to_string(offset), 'limit': to_string(limit)}) + headers_map: Dict[str, str] = prepare_params({'if-none-match': to_string(if_none_match), 'boxapi': to_string(boxapi), **extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders/', to_string(folder_id)]), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, FolderFull) + def update_folder_by_id(self, folder_id: str, *, name: Optional[str] = None, description: Optional[str] = None, sync_state: Optional[UpdateFolderByIdSyncState] = None, can_non_owners_invite: Optional[bool] = None, parent: Optional[UpdateFolderByIdParent] = None, shared_link: Optional[UpdateFolderByIdSharedLink] = None, folder_upload_email: Union[Optional[UpdateFolderByIdFolderUploadEmail], NullValue] = None, tags: Optional[List[str]] = None, is_collaboration_restricted_to_enterprise: Optional[bool] = None, collections: Union[Optional[List[UpdateFolderByIdCollections]], NullValue] = None, can_non_owners_view_collaborators: Optional[bool] = None, fields: Optional[List[str]] = None, if_match: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FolderFull: + r""" + Updates a folder. This can be also be used to move the folder, + + create shared links, update collaborations, and more. + + :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 name: The optional new name for this folder. + +The following restrictions to folder names apply: names containing +non-printable ASCII characters, forward and backward slashes +(`/`, `\`), names with trailing spaces, and names `.` and `..` are +not allowed. + +Folder names must be unique within their parent folder. The name check is case-insensitive, +so a folder named `New Folder` cannot be created in a parent folder that already contains +a folder named `new folder`., defaults to None + :type name: Optional[str], optional + :param description: The optional description of this folder, defaults to None + :type description: Optional[str], optional + :param sync_state: Specifies whether a folder should be synced to a +user's device or not. This is used by Box Sync +(discontinued) and is not used by Box Drive., defaults to None + :type sync_state: Optional[UpdateFolderByIdSyncState], optional + :param can_non_owners_invite: Specifies if users who are not the owner +of the folder can invite new collaborators to the folder., defaults to None + :type can_non_owners_invite: Optional[bool], optional + :param tags: The tags for this item. These tags are shown in +the Box web app and mobile apps next to an item. + +To add or remove a tag, retrieve the item's current tags, +modify them, and then update this field. + +There is a limit of 100 tags per item, and 10,000 +unique tags per enterprise., defaults to None + :type tags: Optional[List[str]], optional + :param is_collaboration_restricted_to_enterprise: Specifies if new invites to this folder are restricted to users +within the enterprise. This does not affect existing +collaborations., defaults to None + :type is_collaboration_restricted_to_enterprise: Optional[bool], optional + :param collections: An array of collections to make this folder +a member of. Currently +we only support the `favorites` collection. + +To get the ID for a collection, use the +[List all collections][1] endpoint. + +Passing an empty array `[]` or `null` will remove +the folder from all collections. + +[1]: e://get-collections, defaults to None + :type collections: Union[Optional[List[UpdateFolderByIdCollections]], NullValue], optional + :param can_non_owners_view_collaborators: Restricts collaborators who are not the owner of +this folder from viewing other collaborations on +this folder. + +It also restricts non-owners from inviting new +collaborators. + +When setting this field to `false`, it is required +to also set `can_non_owners_invite_collaborators` to +`false` if it has not already been set., defaults to None + :type can_non_owners_view_collaborators: Optional[bool], optional + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[str]], optional + :param if_match: Ensures this item hasn't recently changed before +making changes. + +Pass in the item's last observed `etag` value +into this header and the endpoint will fail +with a `412 Precondition Failed` if it +has changed since., defaults to None + :type if_match: 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 = {} + request_body: Dict = {'name': name, 'description': description, 'sync_state': sync_state, 'can_non_owners_invite': can_non_owners_invite, 'parent': parent, 'shared_link': shared_link, 'folder_upload_email': folder_upload_email, 'tags': tags, 'is_collaboration_restricted_to_enterprise': is_collaboration_restricted_to_enterprise, 'collections': collections, 'can_non_owners_view_collaborators': can_non_owners_view_collaborators} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({'if-match': to_string(if_match), **extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders/', to_string(folder_id)]), method='PUT', params=query_params_map, 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, FolderFull) + def delete_folder_by_id(self, folder_id: str, *, recursive: Optional[bool] = None, if_match: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Deletes a folder, either permanently or by moving it to + + the trash. + + :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 recursive: Delete a folder that is not empty by recursively deleting the +folder and all of its content., defaults to None + :type recursive: Optional[bool], optional + :param if_match: Ensures this item hasn't recently changed before +making changes. + +Pass in the item's last observed `etag` value +into this header and the endpoint will fail +with a `412 Precondition Failed` if it +has changed since., defaults to None + :type if_match: 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({'recursive': to_string(recursive)}) + headers_map: Dict[str, str] = prepare_params({'if-match': to_string(if_match), **extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders/', to_string(folder_id)]), method='DELETE', params=query_params_map, headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None + def get_folder_items(self, folder_id: str, *, fields: Optional[List[str]] = None, usemarker: Optional[bool] = None, marker: Optional[str] = None, offset: Optional[int] = None, limit: Optional[int] = None, sort: Optional[GetFolderItemsSort] = None, direction: Optional[GetFolderItemsDirection] = None, boxapi: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Items: + """ + Retrieves a page of items in a folder. These items can be files, + + folders, and web links. + + + To request more information about the folder itself, like its size, + + + use the [Get a folder](#get-folders-id) endpoint instead. + + :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 fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested. + +Additionally this field can be used to query any metadata +applied to the file by specifying the `metadata` field as well +as the scope and key of the template to retrieve, for example +`?fields=metadata.enterprise_12345.contractTemplate`., defaults to None + :type fields: Optional[List[str]], optional + :param usemarker: Specifies whether to use marker-based pagination instead of +offset-based pagination. Only one pagination method can +be used at a time. + +By setting this value to true, the API will return a `marker` field +that can be passed as a parameter to this endpoint to get the next +page of the response., defaults to None + :type usemarker: Optional[bool], 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 offset: The offset of the item at which to begin the response. + +Queries with offset parameter value +exceeding 10000 will be rejected +with a 400 response., defaults to None + :type offset: Optional[int], optional + :param limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], optional + :param sort: Defines the **second** attribute by which items +are sorted. + +The folder type affects the way the items +are sorted: + + * **Standard folder**: + Items are always sorted by + their `type` first, with + folders listed before files, + and files listed + before web links. + + * **Root folder**: + This parameter is not supported + for marker-based pagination + on the root folder + + (the folder with an `id` of `0`). + + * **Shared folder with parent path + to the associated folder visible to + the collaborator**: + Items are always sorted by + their `type` first, with + folders listed before files, + and files listed + before web links., defaults to None + :type sort: Optional[GetFolderItemsSort], optional + :param direction: The direction to sort results in. This can be either in alphabetical ascending +(`ASC`) or descending (`DESC`) order., defaults to None + :type direction: Optional[GetFolderItemsDirection], optional + :param boxapi: The URL, and optional password, for the shared link of this item. + +This header can be used to access items that have not been +explicitly shared with a user. + +Use the format `shared_link=[link]` or if a password is required then +use `shared_link=[link]&shared_link_password=[password]`. + +This header can be used on the file or folder shared, as well as on any files +or folders nested within the item., defaults to None + :type boxapi: 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({'fields': to_string(fields), 'usemarker': to_string(usemarker), 'marker': to_string(marker), 'offset': to_string(offset), 'limit': to_string(limit), 'sort': to_string(sort), 'direction': to_string(direction)}) + headers_map: Dict[str, str] = prepare_params({'boxapi': to_string(boxapi), **extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders/', to_string(folder_id), '/items']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Items) + def create_folder(self, name: str, parent: CreateFolderParent, *, folder_upload_email: Optional[CreateFolderFolderUploadEmail] = None, sync_state: Optional[CreateFolderSyncState] = None, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FolderFull: + r""" + Creates a new empty folder within the specified parent folder. + :param name: The name for the new folder. + +The following restrictions to folder names apply: names containing +non-printable ASCII characters, forward and backward slashes +(`/`, `\`), names with trailing spaces, and names `.` and `..` are +not allowed. + +Folder names must be unique within their parent folder. The name check is case-insensitive, +so a folder named `New Folder` cannot be created in a parent folder that already contains +a folder named `new folder`. + :type name: str + :param parent: The parent folder to create the new folder within. + :type parent: CreateFolderParent + :param sync_state: Specifies whether a folder should be synced to a +user's device or not. This is used by Box Sync +(discontinued) and is not used by Box Drive., defaults to None + :type sync_state: Optional[CreateFolderSyncState], optional + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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 = {} + request_body: Dict = {'name': name, 'parent': parent, 'folder_upload_email': folder_upload_email, 'sync_state': sync_state} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders']), method='POST', params=query_params_map, 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, FolderFull) + def copy_folder(self, folder_id: str, parent: CopyFolderParent, *, name: Optional[str] = None, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FolderFull: + r""" + Creates a copy of a folder within a destination folder. + + The original folder will not be changed. + + :param folder_id: The unique identifier of the folder to copy. + +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 with the ID `0` can not be copied. +Example: "0" + :type folder_id: str + :param parent: The destination folder to copy the folder to. + :type parent: CopyFolderParent + :param name: An optional new name for the copied folder. + +There are some restrictions to the file name. Names containing +non-printable ASCII characters, forward and backward slashes +(`/`, `\`), as well as names with trailing spaces are +prohibited. + +Additionally, the names `.` and `..` are +not allowed either., defaults to None + :type name: Optional[str], optional + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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 = {} + request_body: Dict = {'name': name, 'parent': parent} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders/', to_string(folder_id), '/copy']), method='POST', params=query_params_map, 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, FolderFull) \ No newline at end of file diff --git a/box_sdk_gen/managers/groups.py b/box_sdk_gen/managers/groups.py new file mode 100644 index 000000000..4754bf6a5 --- /dev/null +++ b/box_sdk_gen/managers/groups.py @@ -0,0 +1,302 @@ +from enum import Enum + +from typing import Optional + +from typing import List + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.groups import Groups + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.group_full import GroupFull + +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 CreateGroupInvitabilityLevel(str, Enum): + ADMINS_ONLY = 'admins_only' + ADMINS_AND_MEMBERS = 'admins_and_members' + ALL_MANAGED_USERS = 'all_managed_users' + +class CreateGroupMemberViewabilityLevel(str, Enum): + ADMINS_ONLY = 'admins_only' + ADMINS_AND_MEMBERS = 'admins_and_members' + ALL_MANAGED_USERS = 'all_managed_users' + +class UpdateGroupByIdInvitabilityLevel(str, Enum): + ADMINS_ONLY = 'admins_only' + ADMINS_AND_MEMBERS = 'admins_and_members' + ALL_MANAGED_USERS = 'all_managed_users' + +class UpdateGroupByIdMemberViewabilityLevel(str, Enum): + ADMINS_ONLY = 'admins_only' + ADMINS_AND_MEMBERS = 'admins_and_members' + ALL_MANAGED_USERS = 'all_managed_users' + +class GroupsManager: + 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_groups(self, *, filter_term: Optional[str] = None, fields: Optional[List[str]] = None, limit: Optional[int] = None, offset: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Groups: + """ + Retrieves all of the groups for a given enterprise. The user + + must have admin permissions to inspect enterprise's groups. + + :param filter_term: Limits the results to only groups whose `name` starts +with the search term., defaults to None + :type filter_term: Optional[str], optional + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[str]], optional + :param limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], optional + :param offset: The offset of the item at which to begin the response. + +Queries with offset parameter value +exceeding 10000 will be rejected +with a 400 response., defaults to None + :type offset: Optional[int], 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({'filter_term': to_string(filter_term), 'fields': to_string(fields), 'limit': to_string(limit), 'offset': to_string(offset)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/groups']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Groups) + def create_group(self, name: str, *, provenance: Optional[str] = None, external_sync_identifier: Optional[str] = None, description: Optional[str] = None, invitability_level: Optional[CreateGroupInvitabilityLevel] = None, member_viewability_level: Optional[CreateGroupMemberViewabilityLevel] = None, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> GroupFull: + """ + Creates a new group of users in an enterprise. Only users with admin + + permissions can create new groups. + + :param name: The name of the new group to be created. This name must be unique +within the enterprise. + :type name: str + :param provenance: Keeps track of which external source this group is +coming, for example `Active Directory`, or `Okta`. + +Setting this will also prevent Box admins from editing +the group name and its members directly via the Box +web application. + +This is desirable for one-way syncing of groups., defaults to None + :type provenance: Optional[str], optional + :param external_sync_identifier: An arbitrary identifier that can be used by +external group sync tools to link this Box Group to +an external group. + +Example values of this field +could be an **Active Directory Object ID** or a **Google +Group ID**. + +We recommend you use of this field in +order to avoid issues when group names are updated in +either Box or external systems., defaults to None + :type external_sync_identifier: Optional[str], optional + :param description: A human readable description of the group., defaults to None + :type description: Optional[str], optional + :param invitability_level: Specifies who can invite the group to collaborate +on folders. + +When set to `admins_only` the enterprise admin, co-admins, +and the group's admin can invite the group. + +When set to `admins_and_members` all the admins listed +above and group members can invite the group. + +When set to `all_managed_users` all managed users in the +enterprise can invite the group., defaults to None + :type invitability_level: Optional[CreateGroupInvitabilityLevel], optional + :param member_viewability_level: Specifies who can see the members of the group. + +* `admins_only` - the enterprise admin, co-admins, group's + group admin +* `admins_and_members` - all admins and group members +* `all_managed_users` - all managed users in the + enterprise, defaults to None + :type member_viewability_level: Optional[CreateGroupMemberViewabilityLevel], optional + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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 = {} + request_body: Dict = {'name': name, 'provenance': provenance, 'external_sync_identifier': external_sync_identifier, 'description': description, 'invitability_level': invitability_level, 'member_viewability_level': member_viewability_level} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/groups']), method='POST', params=query_params_map, 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, GroupFull) + def get_group_by_id(self, group_id: str, *, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> GroupFull: + """ + Retrieves information about a group. Only members of this + + group or users with admin-level permissions will be able to + + + use this API. + + :param group_id: The ID of the group. +Example: "57645" + :type group_id: str + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/groups/', to_string(group_id)]), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, GroupFull) + def update_group_by_id(self, group_id: str, *, name: Optional[str] = None, provenance: Optional[str] = None, external_sync_identifier: Optional[str] = None, description: Optional[str] = None, invitability_level: Optional[UpdateGroupByIdInvitabilityLevel] = None, member_viewability_level: Optional[UpdateGroupByIdMemberViewabilityLevel] = None, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> GroupFull: + """ + Updates a specific group. Only admins of this + + group or users with admin-level permissions will be able to + + + use this API. + + :param group_id: The ID of the group. +Example: "57645" + :type group_id: str + :param name: The name of the new group to be created. Must be unique within the +enterprise., defaults to None + :type name: Optional[str], optional + :param provenance: Keeps track of which external source this group is +coming, for example `Active Directory`, or `Okta`. + +Setting this will also prevent Box admins from editing +the group name and its members directly via the Box +web application. + +This is desirable for one-way syncing of groups., defaults to None + :type provenance: Optional[str], optional + :param external_sync_identifier: An arbitrary identifier that can be used by +external group sync tools to link this Box Group to +an external group. + +Example values of this field +could be an **Active Directory Object ID** or a **Google +Group ID**. + +We recommend you use of this field in +order to avoid issues when group names are updated in +either Box or external systems., defaults to None + :type external_sync_identifier: Optional[str], optional + :param description: A human readable description of the group., defaults to None + :type description: Optional[str], optional + :param invitability_level: Specifies who can invite the group to collaborate +on folders. + +When set to `admins_only` the enterprise admin, co-admins, +and the group's admin can invite the group. + +When set to `admins_and_members` all the admins listed +above and group members can invite the group. + +When set to `all_managed_users` all managed users in the +enterprise can invite the group., defaults to None + :type invitability_level: Optional[UpdateGroupByIdInvitabilityLevel], optional + :param member_viewability_level: Specifies who can see the members of the group. + +* `admins_only` - the enterprise admin, co-admins, group's + group admin +* `admins_and_members` - all admins and group members +* `all_managed_users` - all managed users in the + enterprise, defaults to None + :type member_viewability_level: Optional[UpdateGroupByIdMemberViewabilityLevel], optional + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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 = {} + request_body: Dict = {'name': name, 'provenance': provenance, 'external_sync_identifier': external_sync_identifier, 'description': description, 'invitability_level': invitability_level, 'member_viewability_level': member_viewability_level} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/groups/', to_string(group_id)]), method='PUT', params=query_params_map, 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, GroupFull) + def delete_group_by_id(self, group_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Permanently deletes a group. Only users with + + admin-level permissions will be able to use this API. + + :param group_id: The ID of the group. +Example: "57645" + :type group_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/groups/', to_string(group_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/integration_mappings.py b/box_sdk_gen/managers/integration_mappings.py new file mode 100644 index 000000000..9fab685bf --- /dev/null +++ b/box_sdk_gen/managers/integration_mappings.py @@ -0,0 +1,268 @@ +from enum import Enum + +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.integration_mapping_partner_item_slack import IntegrationMappingPartnerItemSlack + +from box_sdk_gen.schemas.integration_mapping_partner_item_teams_create_request import IntegrationMappingPartnerItemTeamsCreateRequest + +from box_sdk_gen.schemas.integration_mappings import IntegrationMappings + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.integration_mapping import IntegrationMapping + +from box_sdk_gen.schemas.integration_mapping_slack_create_request import IntegrationMappingSlackCreateRequest + +from box_sdk_gen.schemas.integration_mapping_box_item_slack import IntegrationMappingBoxItemSlack + +from box_sdk_gen.schemas.integration_mapping_slack_options import IntegrationMappingSlackOptions + +from box_sdk_gen.schemas.integration_mappings_teams import IntegrationMappingsTeams + +from box_sdk_gen.schemas.integration_mapping_teams import IntegrationMappingTeams + +from box_sdk_gen.schemas.integration_mapping_teams_create_request import IntegrationMappingTeamsCreateRequest + +from box_sdk_gen.schemas.folder_reference import FolderReference + +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 GetSlackIntegrationMappingPartnerItemType(str, Enum): + CHANNEL = 'channel' + +class GetSlackIntegrationMappingBoxItemType(str, Enum): + FOLDER = 'folder' + +class GetTeamsIntegrationMappingPartnerItemType(str, Enum): + CHANNEL = 'channel' + TEAM = 'team' + +class GetTeamsIntegrationMappingBoxItemType(str, Enum): + FOLDER = 'folder' + +class IntegrationMappingsManager: + 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_slack_integration_mapping(self, *, marker: Optional[str] = None, limit: Optional[int] = None, partner_item_type: Optional[GetSlackIntegrationMappingPartnerItemType] = None, partner_item_id: Optional[str] = None, box_item_id: Optional[str] = None, box_item_type: Optional[GetSlackIntegrationMappingBoxItemType] = None, is_manually_created: Optional[bool] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> IntegrationMappings: + """ + Lists [Slack integration mappings](https://support.box.com/hc/en-us/articles/4415585987859-Box-as-the-Content-Layer-for-Slack) in a users' enterprise. + + You need Admin or Co-Admin role to + + + use this endpoint. + + :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 limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], optional + :param partner_item_type: Mapped item type, for which the mapping should be returned, defaults to None + :type partner_item_type: Optional[GetSlackIntegrationMappingPartnerItemType], optional + :param partner_item_id: ID of the mapped item, for which the mapping should be returned, defaults to None + :type partner_item_id: Optional[str], optional + :param box_item_id: Box item ID, for which the mappings should be returned, defaults to None + :type box_item_id: Optional[str], optional + :param box_item_type: Box item type, for which the mappings should be returned, defaults to None + :type box_item_type: Optional[GetSlackIntegrationMappingBoxItemType], optional + :param is_manually_created: Whether the mapping has been manually created, defaults to None + :type is_manually_created: Optional[bool], 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({'marker': to_string(marker), 'limit': to_string(limit), 'partner_item_type': to_string(partner_item_type), 'partner_item_id': to_string(partner_item_id), 'box_item_id': to_string(box_item_id), 'box_item_type': to_string(box_item_type), 'is_manually_created': to_string(is_manually_created)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/integration_mappings/slack']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, IntegrationMappings) + def create_slack_integration_mapping(self, partner_item: IntegrationMappingPartnerItemSlack, box_item: IntegrationMappingBoxItemSlack, *, options: Optional[IntegrationMappingSlackOptions] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> IntegrationMapping: + """ + Creates a [Slack integration mapping](https://support.box.com/hc/en-us/articles/4415585987859-Box-as-the-Content-Layer-for-Slack) + + by mapping a Slack channel to a Box item. + + + You need Admin or Co-Admin role to + + + use this endpoint. + + :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 = {'partner_item': partner_item, 'box_item': box_item, 'options': options} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/integration_mappings/slack']), 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, IntegrationMapping) + def update_slack_integration_mapping_by_id(self, integration_mapping_id: str, *, box_item: Optional[IntegrationMappingBoxItemSlack] = None, options: Optional[IntegrationMappingSlackOptions] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> IntegrationMapping: + """ + Updates a [Slack integration mapping](https://support.box.com/hc/en-us/articles/4415585987859-Box-as-the-Content-Layer-for-Slack). + + Supports updating the Box folder ID and options. + + + You need Admin or Co-Admin role to + + + use this endpoint. + + :param integration_mapping_id: An ID of an integration mapping +Example: "11235432" + :type integration_mapping_id: str + :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 = {'box_item': box_item, 'options': options} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/integration_mappings/slack/', to_string(integration_mapping_id)]), method='PUT', 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, IntegrationMapping) + def delete_slack_integration_mapping_by_id(self, integration_mapping_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Deletes a [Slack integration mapping](https://support.box.com/hc/en-us/articles/4415585987859-Box-as-the-Content-Layer-for-Slack). + + You need Admin or Co-Admin role to + + + use this endpoint. + + :param integration_mapping_id: An ID of an integration mapping +Example: "11235432" + :type integration_mapping_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/integration_mappings/slack/', to_string(integration_mapping_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None + def get_teams_integration_mapping(self, *, partner_item_type: Optional[GetTeamsIntegrationMappingPartnerItemType] = None, partner_item_id: Optional[str] = None, box_item_id: Optional[str] = None, box_item_type: Optional[GetTeamsIntegrationMappingBoxItemType] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> IntegrationMappingsTeams: + """ + Lists [Teams integration mappings](https://support.box.com/hc/en-us/articles/360044681474-Using-Box-for-Teams) in a users' enterprise. + + You need Admin or Co-Admin role to + + + use this endpoint. + + :param partner_item_type: Mapped item type, for which the mapping should be returned, defaults to None + :type partner_item_type: Optional[GetTeamsIntegrationMappingPartnerItemType], optional + :param partner_item_id: ID of the mapped item, for which the mapping should be returned, defaults to None + :type partner_item_id: Optional[str], optional + :param box_item_id: Box item ID, for which the mappings should be returned, defaults to None + :type box_item_id: Optional[str], optional + :param box_item_type: Box item type, for which the mappings should be returned, defaults to None + :type box_item_type: Optional[GetTeamsIntegrationMappingBoxItemType], 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({'partner_item_type': to_string(partner_item_type), 'partner_item_id': to_string(partner_item_id), 'box_item_id': to_string(box_item_id), 'box_item_type': to_string(box_item_type)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/integration_mappings/teams']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, IntegrationMappingsTeams) + def create_teams_integration_mapping(self, partner_item: IntegrationMappingPartnerItemTeamsCreateRequest, box_item: FolderReference, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> IntegrationMappingTeams: + """ + Creates a [Teams integration mapping](https://support.box.com/hc/en-us/articles/360044681474-Using-Box-for-Teams) + + by mapping a Teams channel to a Box item. + + + You need Admin or Co-Admin role to + + + use this endpoint. + + :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 = {'partner_item': partner_item, 'box_item': box_item} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/integration_mappings/teams']), 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, IntegrationMappingTeams) + def update_teams_integration_mapping_by_id(self, integration_mapping_id: str, *, box_item: Optional[FolderReference] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> IntegrationMappingTeams: + """ + Updates a [Teams integration mapping](https://support.box.com/hc/en-us/articles/360044681474-Using-Box-for-Teams). + + Supports updating the Box folder ID and options. + + + You need Admin or Co-Admin role to + + + use this endpoint. + + :param integration_mapping_id: An ID of an integration mapping +Example: "11235432" + :type integration_mapping_id: str + :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 = {'box_item': box_item} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/integration_mappings/teams/', to_string(integration_mapping_id)]), method='PUT', 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, IntegrationMappingTeams) + def delete_teams_integration_mapping_by_id(self, integration_mapping_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Deletes a [Teams integration mapping](https://support.box.com/hc/en-us/articles/360044681474-Using-Box-for-Teams). + + You need Admin or Co-Admin role to + + + use this endpoint. + + :param integration_mapping_id: An ID of an integration mapping +Example: "11235432" + :type integration_mapping_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/integration_mappings/teams/', to_string(integration_mapping_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/invites.py b/box_sdk_gen/managers/invites.py new file mode 100644 index 000000000..fc6c14ab3 --- /dev/null +++ b/box_sdk_gen/managers/invites.py @@ -0,0 +1,134 @@ +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Optional + +from typing import List + +from typing import Dict + +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.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.invite import Invite + +from box_sdk_gen.schemas.client_error import ClientError + +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 CreateInviteEnterprise(BaseObject): + def __init__(self, id: str, **kwargs): + """ + :param id: The ID of the enterprise + :type id: str + """ + super().__init__(**kwargs) + self.id = id + +class CreateInviteActionableBy(BaseObject): + def __init__(self, *, login: Optional[str] = None, **kwargs): + """ + :param login: The login of the invited user, defaults to None + :type login: Optional[str], optional + """ + super().__init__(**kwargs) + self.login = login + +class InvitesManager: + 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_invite(self, enterprise: CreateInviteEnterprise, actionable_by: CreateInviteActionableBy, *, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Invite: + """ + Invites an existing external user to join an enterprise. + + The existing user can not be part of another enterprise and + + + must already have a Box account. Once invited, the user will receive an + + + email and are prompted to accept the invitation within the + + + Box web application. + + + This method requires the "Manage An Enterprise" scope enabled for + + + the application, which can be enabled within the developer console. + + :param enterprise: The enterprise to invite the user to + :type enterprise: CreateInviteEnterprise + :param actionable_by: The user to invite + :type actionable_by: CreateInviteActionableBy + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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 = {} + request_body: Dict = {'enterprise': enterprise, 'actionable_by': actionable_by} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/invites']), method='POST', params=query_params_map, 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, Invite) + def get_invite_by_id(self, invite_id: str, *, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Invite: + """ + Returns the status of a user invite. + :param invite_id: The ID of an invite. +Example: "213723" + :type invite_id: str + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/invites/', to_string(invite_id)]), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Invite) \ No newline at end of file diff --git a/box_sdk_gen/managers/legal_hold_policies.py b/box_sdk_gen/managers/legal_hold_policies.py new file mode 100644 index 000000000..a17691831 --- /dev/null +++ b/box_sdk_gen/managers/legal_hold_policies.py @@ -0,0 +1,187 @@ +from typing import Optional + +from typing import List + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.legal_hold_policies import LegalHoldPolicies + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.legal_hold_policy import LegalHoldPolicy + +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 + +from box_sdk_gen.internal.utils import DateTime + +class LegalHoldPoliciesManager: + 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_legal_hold_policies(self, *, policy_name: Optional[str] = None, fields: Optional[List[str]] = None, marker: Optional[str] = None, limit: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> LegalHoldPolicies: + """ + Retrieves a list of legal hold policies that belong to + + an enterprise. + + :param policy_name: Limits results to policies for which the names start with +this search term. This is a case-insensitive prefix., defaults to None + :type policy_name: Optional[str], optional + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[str]], 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 limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], 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({'policy_name': to_string(policy_name), 'fields': to_string(fields), 'marker': to_string(marker), 'limit': to_string(limit)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/legal_hold_policies']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, LegalHoldPolicies) + def create_legal_hold_policy(self, policy_name: str, *, description: Optional[str] = None, filter_started_at: Optional[DateTime] = None, filter_ended_at: Optional[DateTime] = None, is_ongoing: Optional[bool] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> LegalHoldPolicy: + """ + Create a new legal hold policy. + :param policy_name: The name of the policy. + :type policy_name: str + :param description: A description for the policy., defaults to None + :type description: Optional[str], optional + :param filter_started_at: The filter start date. + +When this policy is applied using a `custodian` legal +hold assignments, it will only apply to file versions +created or uploaded inside of the +date range. Other assignment types, such as folders and +files, will ignore the date filter. + +Required if `is_ongoing` is set to `false`., defaults to None + :type filter_started_at: Optional[DateTime], optional + :param filter_ended_at: The filter end date. + +When this policy is applied using a `custodian` legal +hold assignments, it will only apply to file versions +created or uploaded inside of the +date range. Other assignment types, such as folders and +files, will ignore the date filter. + +Required if `is_ongoing` is set to `false`., defaults to None + :type filter_ended_at: Optional[DateTime], optional + :param is_ongoing: Whether new assignments under this policy should +continue applying to files even after initialization. + +When this policy is applied using a legal hold assignment, +it will continue applying the policy to any new file versions +even after it has been applied. + +For example, if a legal hold assignment is placed on a user +today, and that user uploads a file tomorrow, that file will +get held. This will continue until the policy is retired. + +Required if no filter dates are set., defaults to None + :type is_ongoing: Optional[bool], 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 = {'policy_name': policy_name, 'description': description, 'filter_started_at': filter_started_at, 'filter_ended_at': filter_ended_at, 'is_ongoing': is_ongoing} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/legal_hold_policies']), 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, LegalHoldPolicy) + def get_legal_hold_policy_by_id(self, legal_hold_policy_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> LegalHoldPolicy: + """ + Retrieve a legal hold policy. + :param legal_hold_policy_id: The ID of the legal hold policy +Example: "324432" + :type legal_hold_policy_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/legal_hold_policies/', to_string(legal_hold_policy_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, LegalHoldPolicy) + def update_legal_hold_policy_by_id(self, legal_hold_policy_id: str, *, policy_name: Optional[str] = None, description: Optional[str] = None, release_notes: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> LegalHoldPolicy: + """ + Update legal hold policy. + :param legal_hold_policy_id: The ID of the legal hold policy +Example: "324432" + :type legal_hold_policy_id: str + :param policy_name: The name of the policy., defaults to None + :type policy_name: Optional[str], optional + :param description: A description for the policy., defaults to None + :type description: Optional[str], optional + :param release_notes: Notes around why the policy was released., defaults to None + :type release_notes: 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 = {} + request_body: Dict = {'policy_name': policy_name, 'description': description, 'release_notes': release_notes} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/legal_hold_policies/', to_string(legal_hold_policy_id)]), method='PUT', 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, LegalHoldPolicy) + def delete_legal_hold_policy_by_id(self, legal_hold_policy_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Delete an existing legal hold policy. + + This is an asynchronous process. The policy will not be + + + fully deleted yet when the response returns. + + :param legal_hold_policy_id: The ID of the legal hold policy +Example: "324432" + :type legal_hold_policy_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/legal_hold_policies/', to_string(legal_hold_policy_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/legal_hold_policy_assignments.py b/box_sdk_gen/managers/legal_hold_policy_assignments.py new file mode 100644 index 000000000..4545a138d --- /dev/null +++ b/box_sdk_gen/managers/legal_hold_policy_assignments.py @@ -0,0 +1,242 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Optional + +from typing import List + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.legal_hold_policy_assignments import LegalHoldPolicyAssignments + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.legal_hold_policy_assignment import LegalHoldPolicyAssignment + +from box_sdk_gen.schemas.files_on_hold import FilesOnHold + +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 GetLegalHoldPolicyAssignmentsAssignToType(str, Enum): + FILE = 'file' + FILE_VERSION = 'file_version' + FOLDER = 'folder' + USER = 'user' + OWNERSHIP = 'ownership' + INTERACTIONS = 'interactions' + +class CreateLegalHoldPolicyAssignmentAssignToTypeField(str, Enum): + FILE = 'file' + FILE_VERSION = 'file_version' + FOLDER = 'folder' + USER = 'user' + OWNERSHIP = 'ownership' + INTERACTION = 'interaction' + +class CreateLegalHoldPolicyAssignmentAssignTo(BaseObject): + _discriminator = 'type', {'file', 'file_version', 'folder', 'user', 'ownership', 'interaction'} + def __init__(self, type: CreateLegalHoldPolicyAssignmentAssignToTypeField, id: str, **kwargs): + """ + :param type: The type of item to assign the policy to + :type type: CreateLegalHoldPolicyAssignmentAssignToTypeField + :param id: The ID of item to assign the policy to + :type id: str + """ + super().__init__(**kwargs) + self.type = type + self.id = id + +class LegalHoldPolicyAssignmentsManager: + 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_legal_hold_policy_assignments(self, policy_id: str, *, assign_to_type: Optional[GetLegalHoldPolicyAssignmentsAssignToType] = None, assign_to_id: Optional[str] = None, marker: Optional[str] = None, limit: Optional[int] = None, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> LegalHoldPolicyAssignments: + """ + Retrieves a list of items a legal hold policy has been assigned to. + :param policy_id: The ID of the legal hold policy + :type policy_id: str + :param assign_to_type: Filters the results by the type of item the +policy was applied to., defaults to None + :type assign_to_type: Optional[GetLegalHoldPolicyAssignmentsAssignToType], optional + :param assign_to_id: Filters the results by the ID of item the +policy was applied to., defaults to None + :type assign_to_id: Optional[str], 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 limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], optional + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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({'policy_id': to_string(policy_id), 'assign_to_type': to_string(assign_to_type), 'assign_to_id': to_string(assign_to_id), 'marker': to_string(marker), 'limit': to_string(limit), 'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/legal_hold_policy_assignments']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, LegalHoldPolicyAssignments) + def create_legal_hold_policy_assignment(self, policy_id: str, assign_to: CreateLegalHoldPolicyAssignmentAssignTo, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> LegalHoldPolicyAssignment: + """ + Assign a legal hold to a file, file version, folder, or user. + :param policy_id: The ID of the policy to assign. + :type policy_id: str + :param assign_to: The item to assign the policy to + :type assign_to: CreateLegalHoldPolicyAssignmentAssignTo + :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 = {'policy_id': policy_id, 'assign_to': assign_to} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/legal_hold_policy_assignments']), 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, LegalHoldPolicyAssignment) + def get_legal_hold_policy_assignment_by_id(self, legal_hold_policy_assignment_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> LegalHoldPolicyAssignment: + """ + Retrieve a legal hold policy assignment. + :param legal_hold_policy_assignment_id: The ID of the legal hold policy assignment +Example: "753465" + :type legal_hold_policy_assignment_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/legal_hold_policy_assignments/', to_string(legal_hold_policy_assignment_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, LegalHoldPolicyAssignment) + def delete_legal_hold_policy_assignment_by_id(self, legal_hold_policy_assignment_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Remove a legal hold from an item. + + This is an asynchronous process. The policy will not be + + + fully removed yet when the response returns. + + :param legal_hold_policy_assignment_id: The ID of the legal hold policy assignment +Example: "753465" + :type legal_hold_policy_assignment_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/legal_hold_policy_assignments/', to_string(legal_hold_policy_assignment_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None + def get_legal_hold_policy_assignment_file_on_hold(self, legal_hold_policy_assignment_id: str, *, marker: Optional[str] = None, limit: Optional[int] = None, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FilesOnHold: + """ + Get a list of files with current file versions for a legal hold + + assignment. + + + In some cases you may want to get previous file versions instead. In these + + + cases, use the `GET /legal_hold_policy_assignments/:id/file_versions_on_hold` + + + API instead to return any previous versions of a file for this legal hold + + + policy assignment. + + + Due to ongoing re-architecture efforts this API might not return all file + + + versions held for this policy ID. Instead, this API will only return the + + + latest file version held in the newly developed architecture. The `GET + + + /file_version_legal_holds` API can be used to fetch current and past versions + + + of files held within the legacy architecture. + + + This endpoint does not support returning any content that is on hold due to + + + a Custodian collaborating on a Hub. + + + The `GET /legal_hold_policy_assignments?policy_id={id}` API can be used to + + + find a list of policy assignments for a given policy ID. + + :param legal_hold_policy_assignment_id: The ID of the legal hold policy assignment +Example: "753465" + :type legal_hold_policy_assignment_id: str + :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 limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], optional + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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({'marker': to_string(marker), 'limit': to_string(limit), 'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/legal_hold_policy_assignments/', to_string(legal_hold_policy_assignment_id), '/files_on_hold']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, FilesOnHold) \ No newline at end of file diff --git a/box_sdk_gen/managers/list_collaborations.py b/box_sdk_gen/managers/list_collaborations.py new file mode 100644 index 000000000..8777f6409 --- /dev/null +++ b/box_sdk_gen/managers/list_collaborations.py @@ -0,0 +1,201 @@ +from enum import Enum + +from typing import Optional + +from typing import List + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.collaborations import Collaborations + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.collaborations_offset_paginated import CollaborationsOffsetPaginated + +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 GetCollaborationsStatus(str, Enum): + PENDING = 'pending' + +class ListCollaborationsManager: + 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_collaborations(self, file_id: str, *, fields: Optional[List[str]] = None, limit: Optional[int] = None, marker: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Collaborations: + """ + Retrieves a list of pending and active collaborations for a + + file. This returns all the users that have access to the file + + + or have been invited to the file. + + :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 fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[str]], optional + :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 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({'fields': to_string(fields), 'limit': to_string(limit), 'marker': to_string(marker)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/collaborations']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Collaborations) + def get_folder_collaborations(self, folder_id: str, *, fields: Optional[List[str]] = None, limit: Optional[int] = None, marker: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Collaborations: + """ + Retrieves a list of pending and active collaborations for a + + folder. This returns all the users that have access to the folder + + + or have been invited to the folder. + + :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`. +Example: "12345" + :type folder_id: str + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[str]], optional + :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 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({'fields': to_string(fields), 'limit': to_string(limit), 'marker': to_string(marker)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders/', to_string(folder_id), '/collaborations']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Collaborations) + def get_collaborations(self, status: GetCollaborationsStatus, *, fields: Optional[List[str]] = None, offset: Optional[int] = None, limit: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> CollaborationsOffsetPaginated: + """ + Retrieves all pending collaboration invites for this user. + :param status: The status of the collaborations to retrieve + :type status: GetCollaborationsStatus + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[str]], optional + :param offset: The offset of the item at which to begin the response. + +Queries with offset parameter value +exceeding 10000 will be rejected +with a 400 response., defaults to None + :type offset: Optional[int], optional + :param limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], 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({'status': to_string(status), 'fields': to_string(fields), 'offset': to_string(offset), 'limit': to_string(limit)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/collaborations']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, CollaborationsOffsetPaginated) + def get_group_collaborations(self, group_id: str, *, limit: Optional[int] = None, offset: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> CollaborationsOffsetPaginated: + """ + Retrieves all the collaborations for a group. The user + + must have admin permissions to inspect enterprise's groups. + + + Each collaboration object has details on which files or + + + folders the group has access to and with what role. + + :param group_id: The ID of the group. +Example: "57645" + :type group_id: str + :param limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], optional + :param offset: The offset of the item at which to begin the response. + +Queries with offset parameter value +exceeding 10000 will be rejected +with a 400 response., defaults to None + :type offset: Optional[int], 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), 'offset': to_string(offset)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/groups/', to_string(group_id), '/collaborations']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, CollaborationsOffsetPaginated) \ No newline at end of file diff --git a/box_sdk_gen/managers/memberships.py b/box_sdk_gen/managers/memberships.py new file mode 100644 index 000000000..8ed12a381 --- /dev/null +++ b/box_sdk_gen/managers/memberships.py @@ -0,0 +1,277 @@ +from box_sdk_gen.internal.base_object import BaseObject + +from enum import Enum + +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.internal.null_value import NullValue + +from typing import Union + +from typing import List + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.group_memberships import GroupMemberships + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.group_membership import GroupMembership + +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 CreateGroupMembershipUser(BaseObject): + def __init__(self, id: str, **kwargs): + """ + :param id: The ID of the user to add to the group + :type id: str + """ + super().__init__(**kwargs) + self.id = id + +class CreateGroupMembershipGroup(BaseObject): + def __init__(self, id: str, **kwargs): + """ + :param id: The ID of the group to add the user to + :type id: str + """ + super().__init__(**kwargs) + self.id = id + +class CreateGroupMembershipRole(str, Enum): + MEMBER = 'member' + ADMIN = 'admin' + +class UpdateGroupMembershipByIdRole(str, Enum): + MEMBER = 'member' + ADMIN = 'admin' + +class MembershipsManager: + 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_user_memberships(self, user_id: str, *, limit: Optional[int] = None, offset: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> GroupMemberships: + """ + Retrieves all the groups for a user. Only members of this + + group or users with admin-level permissions will be able to + + + use this API. + + :param user_id: The ID of the user. +Example: "12345" + :type user_id: str + :param limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], optional + :param offset: The offset of the item at which to begin the response. + +Queries with offset parameter value +exceeding 10000 will be rejected +with a 400 response., defaults to None + :type offset: Optional[int], 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), 'offset': to_string(offset)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/users/', to_string(user_id), '/memberships']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, GroupMemberships) + def get_group_memberships(self, group_id: str, *, limit: Optional[int] = None, offset: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> GroupMemberships: + """ + Retrieves all the members for a group. Only members of this + + group or users with admin-level permissions will be able to + + + use this API. + + :param group_id: The ID of the group. +Example: "57645" + :type group_id: str + :param limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], optional + :param offset: The offset of the item at which to begin the response. + +Queries with offset parameter value +exceeding 10000 will be rejected +with a 400 response., defaults to None + :type offset: Optional[int], 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), 'offset': to_string(offset)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/groups/', to_string(group_id), '/memberships']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, GroupMemberships) + def create_group_membership(self, user: CreateGroupMembershipUser, group: CreateGroupMembershipGroup, *, role: Optional[CreateGroupMembershipRole] = None, configurable_permissions: Union[Optional[Dict[str, bool]], NullValue] = None, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> GroupMembership: + """ + Creates a group membership. Only users with + + admin-level permissions will be able to use this API. + + :param user: The user to add to the group. + :type user: CreateGroupMembershipUser + :param group: The group to add the user to. + :type group: CreateGroupMembershipGroup + :param role: The role of the user in the group., defaults to None + :type role: Optional[CreateGroupMembershipRole], optional + :param configurable_permissions: Custom configuration for the permissions an admin +if a group will receive. This option has no effect +on members with a role of `member`. + +Setting these permissions overwrites the default +access levels of an admin. + +Specifying a value of `null` for this object will disable +all configurable permissions. Specifying permissions will set +them accordingly, omitted permissions will be enabled by default., defaults to None + :type configurable_permissions: Union[Optional[Dict[str, bool]], NullValue], optional + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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 = {} + request_body: Dict = {'user': user, 'group': group, 'role': role, 'configurable_permissions': configurable_permissions} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/group_memberships']), method='POST', params=query_params_map, 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, GroupMembership) + def get_group_membership_by_id(self, group_membership_id: str, *, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> GroupMembership: + """ + Retrieves a specific group membership. Only admins of this + + group or users with admin-level permissions will be able to + + + use this API. + + :param group_membership_id: The ID of the group membership. +Example: "434534" + :type group_membership_id: str + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/group_memberships/', to_string(group_membership_id)]), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, GroupMembership) + def update_group_membership_by_id(self, group_membership_id: str, *, role: Optional[UpdateGroupMembershipByIdRole] = None, configurable_permissions: Union[Optional[Dict[str, bool]], NullValue] = None, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> GroupMembership: + """ + Updates a user's group membership. Only admins of this + + group or users with admin-level permissions will be able to + + + use this API. + + :param group_membership_id: The ID of the group membership. +Example: "434534" + :type group_membership_id: str + :param role: The role of the user in the group., defaults to None + :type role: Optional[UpdateGroupMembershipByIdRole], optional + :param configurable_permissions: Custom configuration for the permissions an admin +if a group will receive. This option has no effect +on members with a role of `member`. + +Setting these permissions overwrites the default +access levels of an admin. + +Specifying a value of `null` for this object will disable +all configurable permissions. Specifying permissions will set +them accordingly, omitted permissions will be enabled by default., defaults to None + :type configurable_permissions: Union[Optional[Dict[str, bool]], NullValue], optional + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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 = {} + request_body: Dict = {'role': role, 'configurable_permissions': configurable_permissions} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/group_memberships/', to_string(group_membership_id)]), method='PUT', params=query_params_map, 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, GroupMembership) + def delete_group_membership_by_id(self, group_membership_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Deletes a specific group membership. Only admins of this + + group or users with admin-level permissions will be able to + + + use this API. + + :param group_membership_id: The ID of the group membership. +Example: "434534" + :type group_membership_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/group_memberships/', to_string(group_membership_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/metadata_cascade_policies.py b/box_sdk_gen/managers/metadata_cascade_policies.py new file mode 100644 index 000000000..a3b121444 --- /dev/null +++ b/box_sdk_gen/managers/metadata_cascade_policies.py @@ -0,0 +1,199 @@ +from enum import Enum + +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.metadata_cascade_policies import MetadataCascadePolicies + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.metadata_cascade_policy import MetadataCascadePolicy + +from box_sdk_gen.schemas.conflict_error import ConflictError + +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 CreateMetadataCascadePolicyScope(str, Enum): + GLOBAL = 'global' + ENTERPRISE = 'enterprise' + +class ApplyMetadataCascadePolicyConflictResolution(str, Enum): + NONE = 'none' + OVERWRITE = 'overwrite' + +class MetadataCascadePoliciesManager: + 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_metadata_cascade_policies(self, folder_id: str, *, owner_enterprise_id: Optional[str] = None, marker: Optional[str] = None, offset: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> MetadataCascadePolicies: + """ + Retrieves a list of all the metadata cascade policies + + that are applied to a given folder. This can not be used on the root + + + folder with ID `0`. + + :param folder_id: Specifies which folder to return policies for. This can not be used on the +root folder with ID `0`. + :type folder_id: str + :param owner_enterprise_id: The ID of the enterprise ID for which to find metadata +cascade policies. If not specified, it defaults to the +current enterprise., defaults to None + :type owner_enterprise_id: Optional[str], 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 offset: The offset of the item at which to begin the response. + +Queries with offset parameter value +exceeding 10000 will be rejected +with a 400 response., defaults to None + :type offset: Optional[int], 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({'folder_id': to_string(folder_id), 'owner_enterprise_id': to_string(owner_enterprise_id), 'marker': to_string(marker), 'offset': to_string(offset)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/metadata_cascade_policies']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, MetadataCascadePolicies) + def create_metadata_cascade_policy(self, folder_id: str, scope: CreateMetadataCascadePolicyScope, template_key: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> MetadataCascadePolicy: + """ + Creates a new metadata cascade policy that applies a given + + metadata template to a given folder and automatically + + + cascades it down to any files within that folder. + + + In order for the policy to be applied a metadata instance must first + + + be applied to the folder the policy is to be applied to. + + :param folder_id: The ID of the folder to apply the policy to. This folder will +need to already have an instance of the targeted metadata +template applied to it. + :type folder_id: str + :param scope: The scope of the targeted metadata template. This template will +need to already have an instance applied to the targeted folder. + :type scope: CreateMetadataCascadePolicyScope + :param template_key: The key of the targeted metadata template. This template will +need to already have an instance applied to the targeted folder. + +In many cases the template key is automatically derived +of its display name, for example `Contract Template` would +become `contractTemplate`. In some cases the creator of the +template will have provided its own template key. + +Please [list the templates for an enterprise][list], or +get all instances on a [file][file] or [folder][folder] +to inspect a template's key. + +[list]: e://get-metadata-templates-enterprise +[file]: e://get-files-id-metadata +[folder]: e://get-folders-id-metadata + :type template_key: str + :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 = {'folder_id': folder_id, 'scope': scope, 'templateKey': template_key} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/metadata_cascade_policies']), 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, MetadataCascadePolicy) + def get_metadata_cascade_policy_by_id(self, metadata_cascade_policy_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> MetadataCascadePolicy: + """ + Retrieve a specific metadata cascade policy assigned to a folder. + :param metadata_cascade_policy_id: The ID of the metadata cascade policy. +Example: "6fd4ff89-8fc1-42cf-8b29-1890dedd26d7" + :type metadata_cascade_policy_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/metadata_cascade_policies/', to_string(metadata_cascade_policy_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, MetadataCascadePolicy) + def delete_metadata_cascade_policy_by_id(self, metadata_cascade_policy_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Deletes a metadata cascade policy. + :param metadata_cascade_policy_id: The ID of the metadata cascade policy. +Example: "6fd4ff89-8fc1-42cf-8b29-1890dedd26d7" + :type metadata_cascade_policy_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/metadata_cascade_policies/', to_string(metadata_cascade_policy_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None + def apply_metadata_cascade_policy(self, metadata_cascade_policy_id: str, conflict_resolution: ApplyMetadataCascadePolicyConflictResolution, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Force the metadata on a folder with a metadata cascade policy to be applied to + + all of its children. This can be used after creating a new cascade policy to + + + enforce the metadata to be cascaded down to all existing files within that + + + folder. + + :param metadata_cascade_policy_id: The ID of the cascade policy to force-apply. +Example: "6fd4ff89-8fc1-42cf-8b29-1890dedd26d7" + :type metadata_cascade_policy_id: str + :param conflict_resolution: Describes the desired behavior when dealing with the conflict +where a metadata template already has an instance applied +to a child. + +* `none` will preserve the existing value on the file +* `overwrite` will force-apply the templates values over + any existing values. + :type conflict_resolution: ApplyMetadataCascadePolicyConflictResolution + :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 = {'conflict_resolution': conflict_resolution} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/metadata_cascade_policies/', to_string(metadata_cascade_policy_id), '/apply']), method='POST', headers=headers_map, data=serialize(request_body), content_type='application/json', response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/metadata_templates.py b/box_sdk_gen/managers/metadata_templates.py new file mode 100644 index 000000000..533b08cec --- /dev/null +++ b/box_sdk_gen/managers/metadata_templates.py @@ -0,0 +1,369 @@ +from enum import Enum + +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 deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.metadata_templates import MetadataTemplates + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.metadata_template import MetadataTemplate + +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 GetMetadataTemplateScope(str, Enum): + GLOBAL = 'global' + ENTERPRISE = 'enterprise' + +class UpdateMetadataTemplateScope(str, Enum): + GLOBAL = 'global' + ENTERPRISE = 'enterprise' + +class UpdateMetadataTemplateRequestBodyOpField(str, Enum): + EDITTEMPLATE = 'editTemplate' + ADDFIELD = 'addField' + REORDERFIELDS = 'reorderFields' + ADDENUMOPTION = 'addEnumOption' + REORDERENUMOPTIONS = 'reorderEnumOptions' + REORDERMULTISELECTOPTIONS = 'reorderMultiSelectOptions' + ADDMULTISELECTOPTION = 'addMultiSelectOption' + EDITFIELD = 'editField' + REMOVEFIELD = 'removeField' + EDITENUMOPTION = 'editEnumOption' + REMOVEENUMOPTION = 'removeEnumOption' + EDITMULTISELECTOPTION = 'editMultiSelectOption' + REMOVEMULTISELECTOPTION = 'removeMultiSelectOption' + +class UpdateMetadataTemplateRequestBody(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'field_key': 'fieldKey', 'field_keys': 'fieldKeys', 'enum_option_key': 'enumOptionKey', 'enum_option_keys': 'enumOptionKeys', 'multi_select_option_key': 'multiSelectOptionKey', 'multi_select_option_keys': 'multiSelectOptionKeys', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'fieldKey': 'field_key', 'fieldKeys': 'field_keys', 'enumOptionKey': 'enum_option_key', 'enumOptionKeys': 'enum_option_keys', 'multiSelectOptionKey': 'multi_select_option_key', 'multiSelectOptionKeys': 'multi_select_option_keys', **BaseObject._json_to_fields_mapping} + def __init__(self, op: UpdateMetadataTemplateRequestBodyOpField, *, data: Optional[Dict] = None, field_key: Optional[str] = None, field_keys: Optional[List[str]] = None, enum_option_key: Optional[str] = None, enum_option_keys: Optional[List[str]] = None, multi_select_option_key: Optional[str] = None, multi_select_option_keys: Optional[List[str]] = None, **kwargs): + """ + :param op: The type of change to perform on the template. Some +of these are hazardous as they will change existing templates. + :type op: UpdateMetadataTemplateRequestBodyOpField + :param data: The data for the operation. This will vary depending on the +operation being performed., defaults to None + :type data: Optional[Dict], optional + :param field_key: For operations that affect a single field this defines the key of +the field that is affected., defaults to None + :type field_key: Optional[str], optional + :param field_keys: For operations that affect multiple fields this defines the keys +of the fields that are affected., defaults to None + :type field_keys: Optional[List[str]], optional + :param enum_option_key: For operations that affect a single `enum` option this defines +the key of the option that is affected., defaults to None + :type enum_option_key: Optional[str], optional + :param enum_option_keys: For operations that affect multiple `enum` options this defines +the keys of the options that are affected., defaults to None + :type enum_option_keys: Optional[List[str]], optional + :param multi_select_option_key: For operations that affect a single multi select option this +defines the key of the option that is affected., defaults to None + :type multi_select_option_key: Optional[str], optional + :param multi_select_option_keys: For operations that affect multiple multi select options this +defines the keys of the options that are affected., defaults to None + :type multi_select_option_keys: Optional[List[str]], optional + """ + super().__init__(**kwargs) + self.op = op + self.data = data + self.field_key = field_key + self.field_keys = field_keys + self.enum_option_key = enum_option_key + self.enum_option_keys = enum_option_keys + self.multi_select_option_key = multi_select_option_key + self.multi_select_option_keys = multi_select_option_keys + +class DeleteMetadataTemplateScope(str, Enum): + GLOBAL = 'global' + ENTERPRISE = 'enterprise' + +class CreateMetadataTemplateFieldsTypeField(str, Enum): + STRING = 'string' + FLOAT = 'float' + DATE = 'date' + ENUM = 'enum' + MULTISELECT = 'multiSelect' + +class CreateMetadataTemplateFieldsOptionsField(BaseObject): + def __init__(self, key: str, **kwargs): + """ + :param key: The text value of the option. This represents both the display name of the +option and the internal key used when updating templates. + :type key: str + """ + super().__init__(**kwargs) + self.key = key + +class CreateMetadataTemplateFields(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'display_name': 'displayName', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'displayName': 'display_name', **BaseObject._json_to_fields_mapping} + _discriminator = 'type', {'string', 'float', 'date', 'enum', 'multiSelect'} + def __init__(self, type: CreateMetadataTemplateFieldsTypeField, key: str, display_name: str, *, description: Optional[str] = None, hidden: Optional[bool] = None, options: Optional[List[CreateMetadataTemplateFieldsOptionsField]] = None, **kwargs): + """ + :param type: The type of field. The basic fields are a `string` field for text, a +`float` field for numbers, and a `date` fields to present the user with a +date-time picker. + +Additionally, metadata templates support an `enum` field for a basic list +of items, and ` multiSelect` field for a similar list of items where the +user can select more than one value. + :type type: CreateMetadataTemplateFieldsTypeField + :param key: A unique identifier for the field. The identifier must +be unique within the template to which it belongs. + :type key: str + :param display_name: The display name of the field as it is shown to the user in the web and +mobile apps. + :type display_name: str + :param description: A description of the field. This is not shown to the user., defaults to None + :type description: Optional[str], optional + :param hidden: Whether this field is hidden in the UI for the user and can only be set +through the API instead., defaults to None + :type hidden: Optional[bool], optional + :param options: A list of options for this field. This is used in combination with the +`enum` and `multiSelect` field types., defaults to None + :type options: Optional[List[CreateMetadataTemplateFieldsOptionsField]], optional + """ + super().__init__(**kwargs) + self.type = type + self.key = key + self.display_name = display_name + self.description = description + self.hidden = hidden + self.options = options + +class MetadataTemplatesManager: + 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_metadata_templates_by_instance_id(self, metadata_instance_id: str, *, marker: Optional[str] = None, limit: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> MetadataTemplates: + """ + Finds a metadata template by searching for the ID of an instance of the + + template. + + :param metadata_instance_id: The ID of an instance of the metadata template to find. + :type metadata_instance_id: str + :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 limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], 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({'metadata_instance_id': to_string(metadata_instance_id), 'marker': to_string(marker), 'limit': to_string(limit)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/metadata_templates']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, MetadataTemplates) + def get_metadata_template(self, scope: GetMetadataTemplateScope, template_key: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> MetadataTemplate: + """ + Retrieves a metadata template by its `scope` and `templateKey` values. + + To find the `scope` and `templateKey` for a template, list all templates for + + + an enterprise or globally, or list all templates applied to a file or folder. + + :param scope: The scope of the metadata template +Example: "global" + :type scope: GetMetadataTemplateScope + :param template_key: The name of the metadata template +Example: "properties" + :type template_key: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/metadata_templates/', to_string(scope), '/', to_string(template_key), '/schema']), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, MetadataTemplate) + def update_metadata_template(self, scope: UpdateMetadataTemplateScope, template_key: str, request_body: List[UpdateMetadataTemplateRequestBody], *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> MetadataTemplate: + """ + Updates a metadata template. + + The metadata template can only be updated if the template + + + already exists. + + + The update is applied atomically. If any errors occur during the + + + application of the operations, the metadata template will not be changed. + + :param scope: The scope of the metadata template +Example: "global" + :type scope: UpdateMetadataTemplateScope + :param template_key: The name of the metadata template +Example: "properties" + :type template_key: str + :param request_body: Request body of updateMetadataTemplate method + :type request_body: List[UpdateMetadataTemplateRequestBody] + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/metadata_templates/', to_string(scope), '/', to_string(template_key), '/schema']), method='PUT', headers=headers_map, data=serialize(request_body), content_type='application/json-patch+json', response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, MetadataTemplate) + def delete_metadata_template(self, scope: DeleteMetadataTemplateScope, template_key: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Delete a metadata template and its instances. + + This deletion is permanent and can not be reversed. + + :param scope: The scope of the metadata template +Example: "global" + :type scope: DeleteMetadataTemplateScope + :param template_key: The name of the metadata template +Example: "properties" + :type template_key: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/metadata_templates/', to_string(scope), '/', to_string(template_key), '/schema']), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None + def get_metadata_template_by_id(self, template_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> MetadataTemplate: + """ + Retrieves a metadata template by its ID. + :param template_id: The ID of the template +Example: "f7a9891f" + :type template_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/metadata_templates/', to_string(template_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, MetadataTemplate) + def get_global_metadata_templates(self, *, marker: Optional[str] = None, limit: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> MetadataTemplates: + """ + Used to retrieve all generic, global metadata templates available to all + + enterprises using Box. + + :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 limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], 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({'marker': to_string(marker), 'limit': to_string(limit)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/metadata_templates/global']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, MetadataTemplates) + def get_enterprise_metadata_templates(self, *, marker: Optional[str] = None, limit: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> MetadataTemplates: + """ + Used to retrieve all metadata templates created to be used specifically within + + the user's enterprise + + :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 limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], 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({'marker': to_string(marker), 'limit': to_string(limit)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/metadata_templates/enterprise']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, MetadataTemplates) + def create_metadata_template(self, scope: str, display_name: str, *, template_key: Optional[str] = None, hidden: Optional[bool] = None, fields: Optional[List[CreateMetadataTemplateFields]] = None, copy_instance_on_item_copy: Optional[bool] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> MetadataTemplate: + """ + Creates a new metadata template that can be applied to + + files and folders. + + :param scope: The scope of the metadata template to create. Applications can +only create templates for use within the authenticated user's +enterprise. + +This value needs to be set to `enterprise`, as `global` scopes can +not be created by applications. + :type scope: str + :param display_name: The display name of the template. + :type display_name: str + :param template_key: A unique identifier for the template. This identifier needs to be +unique across the enterprise for which the metadata template is +being created. + +When not provided, the API will create a unique `templateKey` +based on the value of the `displayName`., defaults to None + :type template_key: Optional[str], optional + :param hidden: Defines if this template is visible in the Box web app UI, or if +it is purely intended for usage through the API., defaults to None + :type hidden: Optional[bool], optional + :param fields: An ordered list of template fields which are part of the template. +Each field can be a regular text field, date field, number field, +as well as a single or multi-select list., defaults to None + :type fields: Optional[List[CreateMetadataTemplateFields]], optional + :param copy_instance_on_item_copy: Whether or not to copy any metadata attached to a file or folder +when it is copied. By default, metadata is not copied along with a +file or folder when it is copied., defaults to None + :type copy_instance_on_item_copy: Optional[bool], 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 = {'scope': scope, 'templateKey': template_key, 'displayName': display_name, 'hidden': hidden, 'fields': fields, 'copyInstanceOnItemCopy': copy_instance_on_item_copy} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/metadata_templates/schema']), 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, MetadataTemplate) \ No newline at end of file diff --git a/box_sdk_gen/managers/recent_items.py b/box_sdk_gen/managers/recent_items.py new file mode 100644 index 000000000..cee6ec104 --- /dev/null +++ b/box_sdk_gen/managers/recent_items.py @@ -0,0 +1,77 @@ +from typing import Optional + +from typing import List + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.recent_items import RecentItems + +from box_sdk_gen.schemas.client_error import ClientError + +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 RecentItemsManager: + 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_recent_items(self, *, fields: Optional[List[str]] = None, limit: Optional[int] = None, marker: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> RecentItems: + """ + Returns information about the recent items accessed + + by a user, either in the last 90 days or up to the last + + + 1000 items accessed. + + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[str]], optional + :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 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({'fields': to_string(fields), 'limit': to_string(limit), 'marker': to_string(marker)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/recent_items']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, RecentItems) \ No newline at end of file diff --git a/box_sdk_gen/managers/retention_policies.py b/box_sdk_gen/managers/retention_policies.py new file mode 100644 index 000000000..ce15251ff --- /dev/null +++ b/box_sdk_gen/managers/retention_policies.py @@ -0,0 +1,276 @@ +from enum import Enum + +from typing import Optional + +from typing import List + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.internal.null_value import NullValue + +from typing import Union + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.retention_policies import RetentionPolicies + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.retention_policy import RetentionPolicy + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.schemas.user_base import UserBase + +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 GetRetentionPoliciesPolicyType(str, Enum): + FINITE = 'finite' + INDEFINITE = 'indefinite' + +class CreateRetentionPolicyPolicyType(str, Enum): + FINITE = 'finite' + INDEFINITE = 'indefinite' + +class CreateRetentionPolicyDispositionAction(str, Enum): + PERMANENTLY_DELETE = 'permanently_delete' + REMOVE_RETENTION = 'remove_retention' + +class CreateRetentionPolicyRetentionType(str, Enum): + MODIFIABLE = 'modifiable' + NON_MODIFIABLE = 'non_modifiable' + +class RetentionPoliciesManager: + 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_retention_policies(self, *, policy_name: Optional[str] = None, policy_type: Optional[GetRetentionPoliciesPolicyType] = None, created_by_user_id: Optional[str] = None, fields: Optional[List[str]] = None, limit: Optional[int] = None, marker: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> RetentionPolicies: + """ + Retrieves all of the retention policies for an enterprise. + :param policy_name: Filters results by a case sensitive prefix of the name of +retention policies., defaults to None + :type policy_name: Optional[str], optional + :param policy_type: Filters results by the type of retention policy., defaults to None + :type policy_type: Optional[GetRetentionPoliciesPolicyType], optional + :param created_by_user_id: Filters results by the ID of the user who created policy., defaults to None + :type created_by_user_id: Optional[str], optional + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[str]], optional + :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., defaults to None + :type marker: 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({'policy_name': to_string(policy_name), 'policy_type': to_string(policy_type), 'created_by_user_id': to_string(created_by_user_id), 'fields': to_string(fields), 'limit': to_string(limit), 'marker': to_string(marker)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/retention_policies']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, RetentionPolicies) + def create_retention_policy(self, policy_name: str, policy_type: CreateRetentionPolicyPolicyType, disposition_action: CreateRetentionPolicyDispositionAction, *, description: Optional[str] = None, retention_length: Optional[str] = None, retention_type: Optional[CreateRetentionPolicyRetentionType] = None, can_owner_extend_retention: Optional[bool] = None, are_owners_notified: Optional[bool] = None, custom_notification_recipients: Optional[List[UserMini]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> RetentionPolicy: + """ + Creates a retention policy. + :param policy_name: The name for the retention policy + :type policy_name: str + :param policy_type: The type of the retention policy. A retention +policy type can either be `finite`, where a +specific amount of time to retain the content is known +upfront, or `indefinite`, where the amount of time +to retain the content is still unknown. + :type policy_type: CreateRetentionPolicyPolicyType + :param disposition_action: The disposition action of the retention policy. +`permanently_delete` deletes the content +retained by the policy permanently. +`remove_retention` lifts retention policy +from the content, allowing it to be deleted +by users once the retention policy has expired. + :type disposition_action: CreateRetentionPolicyDispositionAction + :param description: The additional text description of the retention policy., defaults to None + :type description: Optional[str], optional + :param retention_length: The length of the retention policy. This value +specifies the duration in days that the retention +policy will be active for after being assigned to +content. If the policy has a `policy_type` of +`indefinite`, the `retention_length` will also be +`indefinite`., defaults to None + :type retention_length: Optional[str], optional + :param retention_type: Specifies the retention type: + +* `modifiable`: You can modify the retention policy. For example, +you can add or remove folders, shorten or lengthen +the policy duration, or delete the assignment. +Use this type if your retention policy +is not related to any regulatory purposes. + +* `non_modifiable`: You can modify the retention policy +only in a limited way: add a folder, lengthen the duration, +retire the policy, change the disposition action +or notification settings. You cannot perform other actions, +such as deleting the assignment or shortening the +policy duration. Use this type to ensure +compliance with regulatory retention policies., defaults to None + :type retention_type: Optional[CreateRetentionPolicyRetentionType], optional + :param can_owner_extend_retention: Whether the owner of a file will be allowed to +extend the retention., defaults to None + :type can_owner_extend_retention: Optional[bool], optional + :param are_owners_notified: Whether owner and co-owners of a file are notified +when the policy nears expiration., defaults to None + :type are_owners_notified: Optional[bool], optional + :param custom_notification_recipients: A list of users notified when +the retention policy duration is about to end., defaults to None + :type custom_notification_recipients: Optional[List[UserMini]], 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 = {'policy_name': policy_name, 'description': description, 'policy_type': policy_type, 'disposition_action': disposition_action, 'retention_length': retention_length, 'retention_type': retention_type, 'can_owner_extend_retention': can_owner_extend_retention, 'are_owners_notified': are_owners_notified, 'custom_notification_recipients': custom_notification_recipients} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/retention_policies']), 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, RetentionPolicy) + def get_retention_policy_by_id(self, retention_policy_id: str, *, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> RetentionPolicy: + """ + Retrieves a retention policy. + :param retention_policy_id: The ID of the retention policy. +Example: "982312" + :type retention_policy_id: str + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/retention_policies/', to_string(retention_policy_id)]), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, RetentionPolicy) + def update_retention_policy_by_id(self, retention_policy_id: str, *, policy_name: Union[Optional[str], NullValue] = None, description: Union[Optional[str], NullValue] = None, disposition_action: Optional[str] = None, retention_type: Union[Optional[str], NullValue] = None, retention_length: Optional[str] = None, status: Union[Optional[str], NullValue] = None, can_owner_extend_retention: Union[Optional[bool], NullValue] = None, are_owners_notified: Union[Optional[bool], NullValue] = None, custom_notification_recipients: Union[Optional[List[UserBase]], NullValue] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> RetentionPolicy: + """ + Updates a retention policy. + :param retention_policy_id: The ID of the retention policy. +Example: "982312" + :type retention_policy_id: str + :param policy_name: The name for the retention policy, defaults to None + :type policy_name: Union[Optional[str], NullValue], optional + :param description: The additional text description of the retention policy., defaults to None + :type description: Union[Optional[str], NullValue], optional + :param disposition_action: The disposition action of the retention policy. +This action can be `permanently_delete`, which +will cause the content retained by the policy +to be permanently deleted, or `remove_retention`, +which will lift the retention policy from the content, +allowing it to be deleted by users, +once the retention policy has expired. +You can use `null` if you don't want to change `disposition_action`., defaults to None + :type disposition_action: Optional[str], optional + :param retention_type: Specifies the retention type: + +* `modifiable`: You can modify the retention policy. For example, +you can add or remove folders, shorten or lengthen +the policy duration, or delete the assignment. +Use this type if your retention policy +is not related to any regulatory purposes. +* `non-modifiable`: You can modify the retention policy +only in a limited way: add a folder, lengthen the duration, +retire the policy, change the disposition action +or notification settings. You cannot perform other actions, +such as deleting the assignment or shortening the +policy duration. Use this type to ensure +compliance with regulatory retention policies. + +When updating a retention policy, you can use +`non-modifiable` type only. You can convert a +`modifiable` policy to `non-modifiable`, but +not the other way around., defaults to None + :type retention_type: Union[Optional[str], NullValue], optional + :param retention_length: The length of the retention policy. This value +specifies the duration in days that the retention +policy will be active for after being assigned to +content. If the policy has a `policy_type` of +`indefinite`, the `retention_length` will also be +`indefinite`., defaults to None + :type retention_length: Optional[str], optional + :param status: Used to retire a retention policy. + +If not retiring a policy, do not include this parameter +or set it to `null`., defaults to None + :type status: Union[Optional[str], NullValue], optional + :param can_owner_extend_retention: Determines if the owner of items under the policy +can extend the retention when the original retention +duration is about to end., defaults to None + :type can_owner_extend_retention: Union[Optional[bool], NullValue], optional + :param are_owners_notified: Determines if owners and co-owners of items +under the policy are notified when +the retention duration is about to end., defaults to None + :type are_owners_notified: Union[Optional[bool], NullValue], optional + :param custom_notification_recipients: A list of users notified when the retention duration is about to end., defaults to None + :type custom_notification_recipients: Union[Optional[List[UserBase]], NullValue], 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 = {'policy_name': policy_name, 'description': description, 'disposition_action': disposition_action, 'retention_type': retention_type, 'retention_length': retention_length, 'status': status, 'can_owner_extend_retention': can_owner_extend_retention, 'are_owners_notified': are_owners_notified, 'custom_notification_recipients': custom_notification_recipients} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/retention_policies/', to_string(retention_policy_id)]), method='PUT', 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, RetentionPolicy) + def delete_retention_policy_by_id(self, retention_policy_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Permanently deletes a retention policy. + :param retention_policy_id: The ID of the retention policy. +Example: "982312" + :type retention_policy_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/retention_policies/', to_string(retention_policy_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/retention_policy_assignments.py b/box_sdk_gen/managers/retention_policy_assignments.py new file mode 100644 index 000000000..efba7551c --- /dev/null +++ b/box_sdk_gen/managers/retention_policy_assignments.py @@ -0,0 +1,215 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.retention_policy_assignments import RetentionPolicyAssignments + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.retention_policy_assignment import RetentionPolicyAssignment + +from box_sdk_gen.schemas.files_under_retention import FilesUnderRetention + +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 GetRetentionPolicyAssignmentsType(str, Enum): + FOLDER = 'folder' + ENTERPRISE = 'enterprise' + METADATA_TEMPLATE = 'metadata_template' + +class CreateRetentionPolicyAssignmentAssignToTypeField(str, Enum): + ENTERPRISE = 'enterprise' + FOLDER = 'folder' + METADATA_TEMPLATE = 'metadata_template' + +class CreateRetentionPolicyAssignmentAssignTo(BaseObject): + _discriminator = 'type', {'enterprise', 'folder', 'metadata_template'} + def __init__(self, type: CreateRetentionPolicyAssignmentAssignToTypeField, *, id: Optional[str] = None, **kwargs): + """ + :param type: The type of item to assign the policy to. + :type type: CreateRetentionPolicyAssignmentAssignToTypeField + :param id: The ID of item to assign the policy to. +Set to `null` or omit when `type` is set to +`enterprise`., defaults to None + :type id: Optional[str], optional + """ + super().__init__(**kwargs) + self.type = type + self.id = id + +class CreateRetentionPolicyAssignmentFilterFields(BaseObject): + def __init__(self, *, field: Optional[str] = None, value: Optional[str] = None, **kwargs): + """ + :param field: The metadata attribute key id., defaults to None + :type field: Optional[str], optional + :param value: The metadata attribute field id. For value, only +enum and multiselect types are supported., defaults to None + :type value: Optional[str], optional + """ + super().__init__(**kwargs) + self.field = field + self.value = value + +class RetentionPolicyAssignmentsManager: + 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_retention_policy_assignments(self, retention_policy_id: str, *, type: Optional[GetRetentionPolicyAssignmentsType] = None, fields: Optional[List[str]] = None, marker: Optional[str] = None, limit: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> RetentionPolicyAssignments: + """ + Returns a list of all retention policy assignments associated with a specified + + retention policy. + + :param retention_policy_id: The ID of the retention policy. +Example: "982312" + :type retention_policy_id: str + :param type: The type of the retention policy assignment to retrieve., defaults to None + :type type: Optional[GetRetentionPolicyAssignmentsType], optional + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[str]], optional + :param marker: Defines the position marker at which to begin returning results. This is +used when paginating using marker-based pagination., defaults to None + :type marker: Optional[str], optional + :param limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], 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({'type': to_string(type), 'fields': to_string(fields), 'marker': to_string(marker), 'limit': to_string(limit)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/retention_policies/', to_string(retention_policy_id), '/assignments']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, RetentionPolicyAssignments) + def create_retention_policy_assignment(self, policy_id: str, assign_to: CreateRetentionPolicyAssignmentAssignTo, *, filter_fields: Optional[List[CreateRetentionPolicyAssignmentFilterFields]] = None, start_date_field: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> RetentionPolicyAssignment: + """ + Assigns a retention policy to an item. + :param policy_id: The ID of the retention policy to assign + :type policy_id: str + :param assign_to: The item to assign the policy to + :type assign_to: CreateRetentionPolicyAssignmentAssignTo + :param filter_fields: If the `assign_to` type is `metadata_template`, +then optionally add the `filter_fields` parameter which will +require an array of objects with a field entry and a value entry. +Currently only one object of `field` and `value` is supported., defaults to None + :type filter_fields: Optional[List[CreateRetentionPolicyAssignmentFilterFields]], optional + :param start_date_field: The date the retention policy assignment begins. + +If the `assigned_to` type is `metadata_template`, +this field can be a date field's metadata attribute key id., defaults to None + :type start_date_field: 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 = {} + request_body: Dict = {'policy_id': policy_id, 'assign_to': assign_to, 'filter_fields': filter_fields, 'start_date_field': start_date_field} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/retention_policy_assignments']), 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, RetentionPolicyAssignment) + def get_retention_policy_assignment_by_id(self, retention_policy_assignment_id: str, *, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> RetentionPolicyAssignment: + """ + Retrieves a retention policy assignment + :param retention_policy_assignment_id: The ID of the retention policy assignment. +Example: "1233123" + :type retention_policy_assignment_id: str + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/retention_policy_assignments/', to_string(retention_policy_assignment_id)]), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, RetentionPolicyAssignment) + def delete_retention_policy_assignment_by_id(self, retention_policy_assignment_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Removes a retention policy assignment + + applied to content. + + :param retention_policy_assignment_id: The ID of the retention policy assignment. +Example: "1233123" + :type retention_policy_assignment_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/retention_policy_assignments/', to_string(retention_policy_assignment_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None + def get_files_under_retention_policy_assignment(self, retention_policy_assignment_id: str, *, marker: Optional[str] = None, limit: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FilesUnderRetention: + """ + Returns a list of files under retention for a retention policy assignment. + :param retention_policy_assignment_id: The ID of the retention policy assignment. +Example: "1233123" + :type retention_policy_assignment_id: str + :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 limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], 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({'marker': to_string(marker), 'limit': to_string(limit)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/retention_policy_assignments/', to_string(retention_policy_assignment_id), '/files_under_retention']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, FilesUnderRetention) \ No newline at end of file diff --git a/box_sdk_gen/managers/search.py b/box_sdk_gen/managers/search.py new file mode 100644 index 000000000..38a51235e --- /dev/null +++ b/box_sdk_gen/managers/search.py @@ -0,0 +1,438 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Dict + +from typing import List + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.internal.utils import to_string + +from typing import Union + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.metadata_query_results import MetadataQueryResults + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.metadata_query import MetadataQuery + +from box_sdk_gen.schemas.search_results import SearchResults + +from box_sdk_gen.schemas.search_results_with_shared_links import SearchResultsWithSharedLinks + +from box_sdk_gen.schemas.metadata_filter import MetadataFilter + +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 SerializedData + +from box_sdk_gen.serialization.json import sd_to_json + +class SearchByMetadataQueryOrderByDirectionField(str, Enum): + ASC = 'ASC' + DESC = 'DESC' + +class SearchByMetadataQueryOrderBy(BaseObject): + def __init__(self, *, field_key: Optional[str] = None, direction: Optional[SearchByMetadataQueryOrderByDirectionField] = None, **kwargs): + """ + :param field_key: The metadata template field to order by. + +The `field_key` represents the `key` value of a field from the +metadata template being searched for., defaults to None + :type field_key: Optional[str], optional + :param direction: The direction to order by, either ascending or descending. + +The `ordering` direction must be the same for each item in the +array., defaults to None + :type direction: Optional[SearchByMetadataQueryOrderByDirectionField], optional + """ + super().__init__(**kwargs) + self.field_key = field_key + self.direction = direction + +class SearchForContentScope(str, Enum): + USER_CONTENT = 'user_content' + ENTERPRISE_CONTENT = 'enterprise_content' + +class SearchForContentContentTypes(str, Enum): + NAME = 'name' + DESCRIPTION = 'description' + FILE_CONTENT = 'file_content' + COMMENTS = 'comments' + TAG = 'tag' + +class SearchForContentType(str, Enum): + FILE = 'file' + FOLDER = 'folder' + WEB_LINK = 'web_link' + +class SearchForContentTrashContent(str, Enum): + NON_TRASHED_ONLY = 'non_trashed_only' + TRASHED_ONLY = 'trashed_only' + ALL_ITEMS = 'all_items' + +class SearchForContentSort(str, Enum): + MODIFIED_AT = 'modified_at' + RELEVANCE = 'relevance' + +class SearchForContentDirection(str, Enum): + DESC = 'DESC' + ASC = 'ASC' + +class SearchManager: + 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 search_by_metadata_query(self, from_: str, ancestor_folder_id: str, *, query: Optional[str] = None, query_params: Optional[Dict] = None, order_by: Optional[List[SearchByMetadataQueryOrderBy]] = None, limit: Optional[int] = None, marker: Optional[str] = None, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> MetadataQueryResults: + """ + Create a search using SQL-like syntax to return items that match specific + + metadata. + + + By default, this endpoint returns only the most basic info about the items for + + + which the query matches. To get additional fields for each item, including any + + + of the metadata, use the `fields` attribute in the query. + + :param from_: Specifies the template used in the query. Must be in the form +`scope.templateKey`. Not all templates can be used in this field, +most notably the built-in, Box-provided classification templates +can not be used in a query. + :type from_: str + :param ancestor_folder_id: The ID of the folder that you are restricting the query to. A +value of zero will return results from all folders you have access +to. A non-zero value will only return results found in the folder +corresponding to the ID or in any of its subfolders. + :type ancestor_folder_id: str + :param query: The query to perform. A query is a logical expression that is very similar +to a SQL `SELECT` statement. Values in the search query can be turned into +parameters specified in the `query_param` arguments list to prevent having +to manually insert search values into the query string. + +For example, a value of `:amount` would represent the `amount` value in +`query_params` object., defaults to None + :type query: Optional[str], optional + :param query_params: Set of arguments corresponding to the parameters specified in the +`query`. The type of each parameter used in the `query_params` must match +the type of the corresponding metadata template field., defaults to None + :type query_params: Optional[Dict], optional + :param order_by: A list of template fields and directions to sort the metadata query +results by. + +The ordering `direction` must be the same for each item in the array., defaults to None + :type order_by: Optional[List[SearchByMetadataQueryOrderBy]], optional + :param limit: A value between 0 and 100 that indicates the maximum number of results +to return for a single request. This only specifies a maximum +boundary and will not guarantee the minimum number of results +returned., defaults to None + :type limit: Optional[int], optional + :param marker: Marker to use for requesting the next page., defaults to None + :type marker: Optional[str], optional + :param fields: By default, this endpoint returns only the most basic info about the items for +which the query matches. This attribute can be used to specify a list of +additional attributes to return for any item, including its metadata. + +This attribute takes a list of item fields, metadata template identifiers, +or metadata template field identifiers. + +For example: + +* `created_by` will add the details of the user who created the item to +the response. +* `metadata..` will return the mini-representation +of the metadata instance identified by the `scope` and `templateKey`. +* `metadata...` will return all the mini-representation +of the metadata instance identified by the `scope` and `templateKey` plus +the field specified by the `field` name. Multiple fields for the same +`scope` and `templateKey` can be defined., defaults to None + :type fields: Optional[List[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 = {} + request_body: Dict = {'from': from_, 'query': query, 'query_params': query_params, 'ancestor_folder_id': ancestor_folder_id, 'order_by': order_by, 'limit': limit, 'marker': marker, 'fields': fields} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/metadata_queries/execute_read']), 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, MetadataQueryResults) + def search_for_content(self, *, query: Optional[str] = None, scope: Optional[SearchForContentScope] = None, file_extensions: Optional[List[str]] = None, created_at_range: Optional[List[str]] = None, updated_at_range: Optional[List[str]] = None, size_range: Optional[List[int]] = None, owner_user_ids: Optional[List[str]] = None, recent_updater_user_ids: Optional[List[str]] = None, ancestor_folder_ids: Optional[List[str]] = None, content_types: Optional[List[SearchForContentContentTypes]] = None, type: Optional[SearchForContentType] = None, trash_content: Optional[SearchForContentTrashContent] = None, mdfilters: Optional[List[MetadataFilter]] = None, sort: Optional[SearchForContentSort] = None, direction: Optional[SearchForContentDirection] = None, limit: Optional[int] = None, include_recent_shared_links: Optional[bool] = None, fields: Optional[List[str]] = None, offset: Optional[int] = None, deleted_user_ids: Optional[List[str]] = None, deleted_at_range: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Union[SearchResults, SearchResultsWithSharedLinks]: + """ + Searches for files, folders, web links, and shared files across the + + users content or across the entire enterprise. + + :param query: The string to search for. This query is matched against item names, +descriptions, text content of files, and various other fields of +the different item types. + +This parameter supports a variety of operators to further refine +the results returns. + +* `""` - by wrapping a query in double quotes only exact matches are + returned by the API. Exact searches do not return search matches + based on specific character sequences. Instead, they return + matches based on phrases, that is, word sequences. For example: + A search for `"Blue-Box"` may return search results including + the sequence `"blue.box"`, `"Blue Box"`, and `"Blue-Box"`; + any item containing the words `Blue` and `Box` consecutively, in + the order specified. +* `AND` - returns items that contain both the search terms. For + example, a search for `marketing AND BoxWorks` returns items + that have both `marketing` and `BoxWorks` within its text in any order. + It does not return a result that only has `BoxWorks` in its text. +* `OR` - returns items that contain either of the search terms. For + example, a search for `marketing OR BoxWorks` returns a result that + has either `marketing` or `BoxWorks` within its text. Using this + operator is not necessary as we implicitly interpret multi-word + queries as `OR` unless another supported boolean term is used. +* `NOT` - returns items that do not contain the search term provided. + For example, a search for `marketing AND NOT BoxWorks` returns a result + that has only `marketing` within its text. Results containing + `BoxWorks` are omitted. + +We do not support lower case (that is, +`and`, `or`, and `not`) or mixed case (that is, `And`, `Or`, and `Not`) +operators. + +This field is required unless the `mdfilters` parameter is defined., defaults to None + :type query: Optional[str], optional + :param scope: Limits the search results to either the files that the user has +access to, or to files available to the entire enterprise. + +The scope defaults to `user_content`, which limits the search +results to content that is available to the currently authenticated +user. + +The `enterprise_content` can be requested by an admin through our +support channels. Once this scope has been enabled for a user, it +will allow that use to query for content across the entire +enterprise and not only the content that they have access to., defaults to None + :type scope: Optional[SearchForContentScope], optional + :param file_extensions: Limits the search results to any files that match any of the provided +file extensions. This list is a comma-separated list of file extensions +without the dots., defaults to None + :type file_extensions: Optional[List[str]], optional + :param created_at_range: Limits the search results to any items created within +a given date range. + +Date ranges are defined as comma separated RFC3339 +timestamps. + +If the the start date is omitted (`,2014-05-17T13:35:01-07:00`) +anything created before the end date will be returned. + +If the end date is omitted (`2014-05-15T13:35:01-07:00,`) the +current date will be used as the end date instead., defaults to None + :type created_at_range: Optional[List[str]], optional + :param updated_at_range: Limits the search results to any items updated within +a given date range. + +Date ranges are defined as comma separated RFC3339 +timestamps. + +If the start date is omitted (`,2014-05-17T13:35:01-07:00`) +anything updated before the end date will be returned. + +If the end date is omitted (`2014-05-15T13:35:01-07:00,`) the +current date will be used as the end date instead., defaults to None + :type updated_at_range: Optional[List[str]], optional + :param size_range: Limits the search results to any items with a size within +a given file size range. This applied to files and folders. + +Size ranges are defined as comma separated list of a lower +and upper byte size limit (inclusive). + +The upper and lower bound can be omitted to create open ranges., defaults to None + :type size_range: Optional[List[int]], optional + :param owner_user_ids: Limits the search results to any items that are owned +by the given list of owners, defined as a list of comma separated +user IDs. + +The items still need to be owned or shared with +the currently authenticated user for them to show up in the search +results. If the user does not have access to any files owned by any of +the users an empty result set will be returned. + +To search across an entire enterprise, we recommend using the +`enterprise_content` scope parameter which can be requested with our +support team., defaults to None + :type owner_user_ids: Optional[List[str]], optional + :param recent_updater_user_ids: Limits the search results to any items that have been updated +by the given list of users, defined as a list of comma separated +user IDs. + +The items still need to be owned or shared with +the currently authenticated user for them to show up in the search +results. If the user does not have access to any files owned by any of +the users an empty result set will be returned. + +This feature only searches back to the last 10 versions of an item., defaults to None + :type recent_updater_user_ids: Optional[List[str]], optional + :param ancestor_folder_ids: Limits the search results to items within the given +list of folders, defined as a comma separated lists +of folder IDs. + +Search results will also include items within any subfolders +of those ancestor folders. + +The folders still need to be owned or shared with +the currently authenticated user. If the folder is not accessible by this +user, or it does not exist, a `HTTP 404` error code will be returned +instead. + +To search across an entire enterprise, we recommend using the +`enterprise_content` scope parameter which can be requested with our +support team., defaults to None + :type ancestor_folder_ids: Optional[List[str]], optional + :param content_types: Limits the search results to any items that match the search query +for a specific part of the file, for example the file description. + +Content types are defined as a comma separated lists +of Box recognized content types. The allowed content types are as follows. + +* `name` - The name of the item, as defined by its `name` field. +* `description` - The description of the item, as defined by its + `description` field. +* `file_content` - The actual content of the file. +* `comments` - The content of any of the comments on a file or + folder. +* `tags` - Any tags that are applied to an item, as defined by its + `tags` field., defaults to None + :type content_types: Optional[List[SearchForContentContentTypes]], optional + :param type: Limits the search results to any items of this type. This +parameter only takes one value. By default the API returns +items that match any of these types. + +* `file` - Limits the search results to files +* `folder` - Limits the search results to folders +* `web_link` - Limits the search results to web links, also known + as bookmarks, defaults to None + :type type: Optional[SearchForContentType], optional + :param trash_content: Determines if the search should look in the trash for items. + +By default, this API only returns search results for items +not currently in the trash (`non_trashed_only`). + +* `trashed_only` - Only searches for items currently in the trash +* `non_trashed_only` - Only searches for items currently not in + the trash +* `all_items` - Searches for both trashed and non-trashed items., defaults to None + :type trash_content: Optional[SearchForContentTrashContent], optional + :param mdfilters: Limits the search results to any items for which the metadata matches the provided filter. +This parameter is a list that specifies exactly **one** metadata template used to filter the search results. +The parameter is required unless the `query` parameter is provided., defaults to None + :type mdfilters: Optional[List[MetadataFilter]], optional + :param sort: Defines the order in which search results are returned. This API +defaults to returning items by relevance unless this parameter is +explicitly specified. + +* `relevance` (default) returns the results sorted by relevance to the +query search term. The relevance is based on the occurrence of the search +term in the items name, description, content, and additional properties. +* `modified_at` returns the results ordered in descending order by date +at which the item was last modified., defaults to None + :type sort: Optional[SearchForContentSort], optional + :param direction: Defines the direction in which search results are ordered. This API +defaults to returning items in descending (`DESC`) order unless this +parameter is explicitly specified. + +When results are sorted by `relevance` the ordering is locked to returning +items in descending order of relevance, and this parameter is ignored., defaults to None + :type direction: Optional[SearchForContentDirection], optional + :param limit: Defines the maximum number of items to return as part of a page of +results., defaults to None + :type limit: Optional[int], optional + :param include_recent_shared_links: Defines whether the search results should include any items +that the user recently accessed through a shared link. + +When this parameter has been set to true, +the format of the response of this API changes to return +a list of [Search Results with +Shared Links](r://search_results_with_shared_links), defaults to None + :type include_recent_shared_links: Optional[bool], optional + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[str]], optional + :param offset: The offset of the item at which to begin the response. + +Queries with offset parameter value +exceeding 10000 will be rejected +with a 400 response., defaults to None + :type offset: Optional[int], optional + :param deleted_user_ids: Limits the search results to items that were deleted by the given +list of users, defined as a list of comma separated user IDs. + +The `trash_content` parameter needs to be set to `trashed_only`. + +If searching in trash is not performed, an empty result set +is returned. The items need to be owned or shared with +the currently authenticated user for them to show up in the search +results. + +If the user does not have access to any files owned by +any of the users, an empty result set is returned. + +Data available from 2023-02-01 onwards., defaults to None + :type deleted_user_ids: Optional[List[str]], optional + :param deleted_at_range: Limits the search results to any items deleted within a given +date range. + +Date ranges are defined as comma separated RFC3339 timestamps. + +If the the start date is omitted (`2014-05-17T13:35:01-07:00`), +anything deleted before the end date will be returned. + +If the end date is omitted (`2014-05-15T13:35:01-07:00`), +the current date will be used as the end date instead. + +The `trash_content` parameter needs to be set to `trashed_only`. + +If searching in trash is not performed, then an empty result +is returned. + +Data available from 2023-02-01 onwards., defaults to None + :type deleted_at_range: Optional[List[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({'query': to_string(query), 'scope': to_string(scope), 'file_extensions': to_string(file_extensions), 'created_at_range': to_string(created_at_range), 'updated_at_range': to_string(updated_at_range), 'size_range': to_string(size_range), 'owner_user_ids': to_string(owner_user_ids), 'recent_updater_user_ids': to_string(recent_updater_user_ids), 'ancestor_folder_ids': to_string(ancestor_folder_ids), 'content_types': to_string(content_types), 'type': to_string(type), 'trash_content': to_string(trash_content), 'mdfilters': to_string(mdfilters), 'sort': to_string(sort), 'direction': to_string(direction), 'limit': to_string(limit), 'include_recent_shared_links': to_string(include_recent_shared_links), 'fields': to_string(fields), 'offset': to_string(offset), 'deleted_user_ids': to_string(deleted_user_ids), 'deleted_at_range': to_string(deleted_at_range)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/search']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Union[SearchResults, SearchResultsWithSharedLinks]) \ No newline at end of file diff --git a/box_sdk_gen/managers/session_termination.py b/box_sdk_gen/managers/session_termination.py new file mode 100644 index 000000000..5eb4ac619 --- /dev/null +++ b/box_sdk_gen/managers/session_termination.py @@ -0,0 +1,88 @@ +from typing import Optional + +from typing import List + +from typing import Dict + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.session_termination_message import SessionTerminationMessage + +from box_sdk_gen.schemas.client_error import ClientError + +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 SerializedData + +class SessionTerminationManager: + 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 terminate_users_sessions(self, user_ids: List[str], user_logins: List[str], *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> SessionTerminationMessage: + """ + Validates the roles and permissions of the user, + + and creates asynchronous jobs + + + to terminate the user's sessions. + + + Returns the status for the POST request. + + :param user_ids: A list of user IDs + :type user_ids: List[str] + :param user_logins: A list of user logins + :type user_logins: List[str] + :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 = {'user_ids': user_ids, 'user_logins': user_logins} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/users/terminate_sessions']), 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, SessionTerminationMessage) + def terminate_groups_sessions(self, group_ids: List[str], *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> SessionTerminationMessage: + """ + Validates the roles and permissions of the group, + + and creates asynchronous jobs + + + to terminate the group's sessions. + + + Returns the status for the POST request. + + :param group_ids: A list of group IDs + :type group_ids: List[str] + :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 = {'group_ids': group_ids} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/groups/terminate_sessions']), 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, SessionTerminationMessage) \ No newline at end of file diff --git a/box_sdk_gen/managers/shared_links_app_items.py b/box_sdk_gen/managers/shared_links_app_items.py new file mode 100644 index 000000000..edf30299f --- /dev/null +++ b/box_sdk_gen/managers/shared_links_app_items.py @@ -0,0 +1,59 @@ +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.app_item import AppItem + +from box_sdk_gen.schemas.client_error import ClientError + +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 SharedLinksAppItemsManager: + 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 find_app_item_for_shared_link(self, boxapi: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> AppItem: + """ + Returns the app item represented by a shared link. + + The link can originate from the current enterprise or another. + + :param boxapi: A header containing the shared link and optional password for the +shared link. + +The format for this header is `shared_link=[link]&shared_link_password=[password]` + :type boxapi: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({'boxapi': to_string(boxapi), **extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/shared_items#app_items']), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, AppItem) \ No newline at end of file diff --git a/box_sdk_gen/managers/shared_links_files.py b/box_sdk_gen/managers/shared_links_files.py new file mode 100644 index 000000000..6bcd49070 --- /dev/null +++ b/box_sdk_gen/managers/shared_links_files.py @@ -0,0 +1,362 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.internal.null_value import NullValue + +from typing import Union + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.client_error import ClientError + +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 + +from box_sdk_gen.internal.utils import DateTime + +class AddShareLinkToFileSharedLinkAccessField(str, Enum): + OPEN = 'open' + COMPANY = 'company' + COLLABORATORS = 'collaborators' + +class AddShareLinkToFileSharedLinkPermissionsField(BaseObject): + def __init__(self, *, can_download: Optional[bool] = None, can_preview: Optional[bool] = None, can_edit: Optional[bool] = None, **kwargs): + """ + :param can_download: If the shared link allows for downloading of files. +This can only be set when `access` is set to +`open` or `company`., defaults to None + :type can_download: Optional[bool], optional + :param can_preview: If the shared link allows for previewing of files. +This value is always `true`. For shared links on folders +this also applies to any items in the folder., defaults to None + :type can_preview: Optional[bool], optional + :param can_edit: If the shared link allows for editing of files. +This can only be set when `access` is set to +`open` or `company`. +This value can only be `true` is `can_download` is +also `true`., defaults to None + :type can_edit: Optional[bool], optional + """ + super().__init__(**kwargs) + self.can_download = can_download + self.can_preview = can_preview + self.can_edit = can_edit + +class AddShareLinkToFileSharedLink(BaseObject): + def __init__(self, *, access: Optional[AddShareLinkToFileSharedLinkAccessField] = None, password: Optional[str] = None, vanity_name: Optional[str] = None, unshared_at: Optional[DateTime] = None, permissions: Optional[AddShareLinkToFileSharedLinkPermissionsField] = None, **kwargs): + """ + :param access: The level of access for the shared link. This can be +restricted to anyone with the link (`open`), only people +within the company (`company`) and only those who +have been invited to the file (`collaborators`). + +If not set, this field defaults to the access level specified +by the enterprise admin. To create a shared link with this +default setting pass the `shared_link` object with +no `access` field, for example `{ "shared_link": {} }`. + +The `company` access level is only available to paid +accounts., defaults to None + :type access: Optional[AddShareLinkToFileSharedLinkAccessField], optional + :param password: The password required to access the shared link. Set the +password to `null` to remove it. +Passwords must now be at least eight characters +long and include a number, upper case letter, or +a non-numeric or non-alphabetic character. +A password can only be set when `access` is set to `open`., defaults to None + :type password: Optional[str], optional + :param vanity_name: Defines a custom vanity name to use in the shared link URL, +for example `https://app.box.com/v/my-shared-link`. + +Custom URLs should not be used when sharing sensitive content +as vanity URLs are a lot easier to guess than regular shared +links., defaults to None + :type vanity_name: Optional[str], optional + :param unshared_at: The timestamp at which this shared link will +expire. This field can only be set by +users with paid accounts. The value must be greater than the +current date and time., defaults to None + :type unshared_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.access = access + self.password = password + self.vanity_name = vanity_name + self.unshared_at = unshared_at + self.permissions = permissions + +class UpdateSharedLinkOnFileSharedLinkAccessField(str, Enum): + OPEN = 'open' + COMPANY = 'company' + COLLABORATORS = 'collaborators' + +class UpdateSharedLinkOnFileSharedLinkPermissionsField(BaseObject): + def __init__(self, *, can_download: Optional[bool] = None, can_preview: Optional[bool] = None, can_edit: Optional[bool] = None, **kwargs): + """ + :param can_download: If the shared link allows for downloading of files. +This can only be set when `access` is set to +`open` or `company`., defaults to None + :type can_download: Optional[bool], optional + :param can_preview: If the shared link allows for previewing of files. +This value is always `true`. For shared links on folders +this also applies to any items in the folder., defaults to None + :type can_preview: Optional[bool], optional + :param can_edit: If the shared link allows for editing of files. +This can only be set when `access` is set to +`open` or `company`. +This value can only be `true` is `can_download` is +also `true`., defaults to None + :type can_edit: Optional[bool], optional + """ + super().__init__(**kwargs) + self.can_download = can_download + self.can_preview = can_preview + self.can_edit = can_edit + +class UpdateSharedLinkOnFileSharedLink(BaseObject): + def __init__(self, *, access: Optional[UpdateSharedLinkOnFileSharedLinkAccessField] = None, password: Optional[str] = None, vanity_name: Optional[str] = None, unshared_at: Optional[DateTime] = None, permissions: Optional[UpdateSharedLinkOnFileSharedLinkPermissionsField] = None, **kwargs): + """ + :param access: The level of access for the shared link. This can be +restricted to anyone with the link (`open`), only people +within the company (`company`) and only those who +have been invited to the folder (`collaborators`). + +If not set, this field defaults to the access level specified +by the enterprise admin. To create a shared link with this +default setting pass the `shared_link` object with +no `access` field, for example `{ "shared_link": {} }`. + +The `company` access level is only available to paid +accounts., defaults to None + :type access: Optional[UpdateSharedLinkOnFileSharedLinkAccessField], optional + :param password: The password required to access the shared link. Set the +password to `null` to remove it. +Passwords must now be at least eight characters +long and include a number, upper case letter, or +a non-numeric or non-alphabetic character. +A password can only be set when `access` is set to `open`., defaults to None + :type password: Optional[str], optional + :param vanity_name: Defines a custom vanity name to use in the shared link URL, +for example `https://app.box.com/v/my-shared-link`. + +Custom URLs should not be used when sharing sensitive content +as vanity URLs are a lot easier to guess than regular shared +links., defaults to None + :type vanity_name: Optional[str], optional + :param unshared_at: The timestamp at which this shared link will +expire. This field can only be set by +users with paid accounts. The value must be greater than the +current date and time., defaults to None + :type unshared_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.access = access + self.password = password + self.vanity_name = vanity_name + self.unshared_at = unshared_at + self.permissions = permissions + +class RemoveSharedLinkFromFileSharedLink(BaseObject): + def __init__(self, **kwargs): + super().__init__(**kwargs) + +class SharedLinksFilesManager: + 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 find_file_for_shared_link(self, boxapi: str, *, fields: Optional[List[str]] = None, if_none_match: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FileFull: + """ + Returns the file represented by a shared link. + + A shared file can be represented by a shared link, + + + which can originate within the current enterprise or within another. + + + This endpoint allows an application to retrieve information about a + + + shared file when only given a shared link. + + + The `shared_link_permission_options` array field can be returned + + + by requesting it in the `fields` query parameter. + + :param boxapi: A header containing the shared link and optional password for the +shared link. + +The format for this header is as follows. + +`shared_link=[link]&shared_link_password=[password]` + :type boxapi: str + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[str]], optional + :param if_none_match: Ensures an item is only returned if it has changed. + +Pass in the item's last observed `etag` value +into this header and the endpoint will fail +with a `304 Not Modified` if the item has not +changed since., defaults to None + :type if_none_match: 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({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({'if-none-match': to_string(if_none_match), 'boxapi': to_string(boxapi), **extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/shared_items']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, FileFull) + def get_shared_link_for_file(self, file_id: str, fields: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FileFull: + """ + Gets the information for a shared link on a file. + :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 fields: Explicitly request the `shared_link` fields +to be returned for this item. + :type fields: str + :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({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '#get_shared_link']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, FileFull) + def add_share_link_to_file(self, file_id: str, fields: str, *, shared_link: Optional[AddShareLinkToFileSharedLink] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FileFull: + """ + Adds a shared link to a file. + :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 fields: Explicitly request the `shared_link` fields +to be returned for this item. + :type fields: str + :param shared_link: The settings for the shared link to create on the file. +Use an empty object (`{}`) to use the default settings for shared +links., defaults to None + :type shared_link: Optional[AddShareLinkToFileSharedLink], 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 = {'shared_link': shared_link} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '#add_shared_link']), method='PUT', params=query_params_map, 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, FileFull) + def update_shared_link_on_file(self, file_id: str, fields: str, *, shared_link: Optional[UpdateSharedLinkOnFileSharedLink] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FileFull: + """ + Updates a shared link on a file. + :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 fields: Explicitly request the `shared_link` fields +to be returned for this item. + :type fields: str + :param shared_link: The settings for the shared link to update., defaults to None + :type shared_link: Optional[UpdateSharedLinkOnFileSharedLink], 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 = {'shared_link': shared_link} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '#update_shared_link']), method='PUT', params=query_params_map, 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, FileFull) + def remove_shared_link_from_file(self, file_id: str, fields: str, *, shared_link: Union[Optional[RemoveSharedLinkFromFileSharedLink], NullValue] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FileFull: + """ + Removes a shared link from a file. + :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 fields: Explicitly request the `shared_link` fields +to be returned for this item. + :type fields: str + :param shared_link: By setting this value to `null`, the shared link +is removed from the file., defaults to None + :type shared_link: Union[Optional[RemoveSharedLinkFromFileSharedLink], NullValue], 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 = {'shared_link': shared_link} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '#remove_shared_link']), method='PUT', params=query_params_map, 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, FileFull) \ No newline at end of file diff --git a/box_sdk_gen/managers/shared_links_folders.py b/box_sdk_gen/managers/shared_links_folders.py new file mode 100644 index 000000000..123dccfdf --- /dev/null +++ b/box_sdk_gen/managers/shared_links_folders.py @@ -0,0 +1,363 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.internal.null_value import NullValue + +from typing import Union + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.schemas.client_error import ClientError + +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 + +from box_sdk_gen.internal.utils import DateTime + +class AddShareLinkToFolderSharedLinkAccessField(str, Enum): + OPEN = 'open' + COMPANY = 'company' + COLLABORATORS = 'collaborators' + +class AddShareLinkToFolderSharedLinkPermissionsField(BaseObject): + def __init__(self, *, can_download: Optional[bool] = None, can_preview: Optional[bool] = None, can_edit: Optional[bool] = None, **kwargs): + """ + :param can_download: If the shared link allows for downloading of files. +This can only be set when `access` is set to +`open` or `company`., defaults to None + :type can_download: Optional[bool], optional + :param can_preview: If the shared link allows for previewing of files. +This value is always `true`. For shared links on folders +this also applies to any items in the folder., defaults to None + :type can_preview: Optional[bool], optional + :param can_edit: This value can only be `false` for items +with a `type` of `folder`., defaults to None + :type can_edit: Optional[bool], optional + """ + super().__init__(**kwargs) + self.can_download = can_download + self.can_preview = can_preview + self.can_edit = can_edit + +class AddShareLinkToFolderSharedLink(BaseObject): + def __init__(self, *, access: Optional[AddShareLinkToFolderSharedLinkAccessField] = None, password: Optional[str] = None, vanity_name: Optional[str] = None, unshared_at: Optional[DateTime] = None, permissions: Optional[AddShareLinkToFolderSharedLinkPermissionsField] = None, **kwargs): + """ + :param access: The level of access for the shared link. This can be +restricted to anyone with the link (`open`), only people +within the company (`company`) and only those who +have been invited to the folder (`collaborators`). + +If not set, this field defaults to the access level specified +by the enterprise admin. To create a shared link with this +default setting pass the `shared_link` object with +no `access` field, for example `{ "shared_link": {} }`. + +The `company` access level is only available to paid +accounts., defaults to None + :type access: Optional[AddShareLinkToFolderSharedLinkAccessField], optional + :param password: The password required to access the shared link. Set the +password to `null` to remove it. +Passwords must now be at least eight characters +long and include a number, upper case letter, or +a non-numeric or non-alphabetic character. +A password can only be set when `access` is set to `open`., defaults to None + :type password: Optional[str], optional + :param vanity_name: Defines a custom vanity name to use in the shared link URL, +for example `https://app.box.com/v/my-shared-link`. + +Custom URLs should not be used when sharing sensitive content +as vanity URLs are a lot easier to guess than regular shared +links., defaults to None + :type vanity_name: Optional[str], optional + :param unshared_at: The timestamp at which this shared link will +expire. This field can only be set by +users with paid accounts. The value must be greater than the +current date and time., defaults to None + :type unshared_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.access = access + self.password = password + self.vanity_name = vanity_name + self.unshared_at = unshared_at + self.permissions = permissions + +class UpdateSharedLinkOnFolderSharedLinkAccessField(str, Enum): + OPEN = 'open' + COMPANY = 'company' + COLLABORATORS = 'collaborators' + +class UpdateSharedLinkOnFolderSharedLinkPermissionsField(BaseObject): + def __init__(self, *, can_download: Optional[bool] = None, can_preview: Optional[bool] = None, can_edit: Optional[bool] = None, **kwargs): + """ + :param can_download: If the shared link allows for downloading of files. +This can only be set when `access` is set to +`open` or `company`., defaults to None + :type can_download: Optional[bool], optional + :param can_preview: If the shared link allows for previewing of files. +This value is always `true`. For shared links on folders +this also applies to any items in the folder., defaults to None + :type can_preview: Optional[bool], optional + :param can_edit: This value can only be `false` for items +with a `type` of `folder`., defaults to None + :type can_edit: Optional[bool], optional + """ + super().__init__(**kwargs) + self.can_download = can_download + self.can_preview = can_preview + self.can_edit = can_edit + +class UpdateSharedLinkOnFolderSharedLink(BaseObject): + def __init__(self, *, access: Optional[UpdateSharedLinkOnFolderSharedLinkAccessField] = None, password: Optional[str] = None, vanity_name: Optional[str] = None, unshared_at: Optional[DateTime] = None, permissions: Optional[UpdateSharedLinkOnFolderSharedLinkPermissionsField] = None, **kwargs): + """ + :param access: The level of access for the shared link. This can be +restricted to anyone with the link (`open`), only people +within the company (`company`) and only those who +have been invited to the folder (`collaborators`). + +If not set, this field defaults to the access level specified +by the enterprise admin. To create a shared link with this +default setting pass the `shared_link` object with +no `access` field, for example `{ "shared_link": {} }`. + +The `company` access level is only available to paid +accounts., defaults to None + :type access: Optional[UpdateSharedLinkOnFolderSharedLinkAccessField], optional + :param password: The password required to access the shared link. Set the +password to `null` to remove it. +Passwords must now be at least eight characters +long and include a number, upper case letter, or +a non-numeric or non-alphabetic character. +A password can only be set when `access` is set to `open`., defaults to None + :type password: Optional[str], optional + :param vanity_name: Defines a custom vanity name to use in the shared link URL, +for example `https://app.box.com/v/my-shared-link`. + +Custom URLs should not be used when sharing sensitive content +as vanity URLs are a lot easier to guess than regular shared +links., defaults to None + :type vanity_name: Optional[str], optional + :param unshared_at: The timestamp at which this shared link will +expire. This field can only be set by +users with paid accounts. The value must be greater than the +current date and time., defaults to None + :type unshared_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.access = access + self.password = password + self.vanity_name = vanity_name + self.unshared_at = unshared_at + self.permissions = permissions + +class RemoveSharedLinkFromFolderSharedLink(BaseObject): + def __init__(self, **kwargs): + super().__init__(**kwargs) + +class SharedLinksFoldersManager: + 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 find_folder_for_shared_link(self, boxapi: str, *, fields: Optional[List[str]] = None, if_none_match: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FolderFull: + """ + Return the folder represented by a shared link. + + A shared folder can be represented by a shared link, + + + which can originate within the current enterprise or within another. + + + This endpoint allows an application to retrieve information about a + + + shared folder when only given a shared link. + + :param boxapi: A header containing the shared link and optional password for the +shared link. + +The format for this header is as follows. + +`shared_link=[link]&shared_link_password=[password]` + :type boxapi: str + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[str]], optional + :param if_none_match: Ensures an item is only returned if it has changed. + +Pass in the item's last observed `etag` value +into this header and the endpoint will fail +with a `304 Not Modified` if the item has not +changed since., defaults to None + :type if_none_match: 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({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({'if-none-match': to_string(if_none_match), 'boxapi': to_string(boxapi), **extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/shared_items#folders']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, FolderFull) + def get_shared_link_for_folder(self, folder_id: str, fields: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FolderFull: + """ + Gets the information for a shared link on a folder. + :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 fields: Explicitly request the `shared_link` fields +to be returned for this item. + :type fields: str + :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({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders/', to_string(folder_id), '#get_shared_link']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, FolderFull) + def add_share_link_to_folder(self, folder_id: str, fields: str, *, shared_link: Optional[AddShareLinkToFolderSharedLink] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FolderFull: + """ + Adds a shared link to a folder. + :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 fields: Explicitly request the `shared_link` fields +to be returned for this item. + :type fields: str + :param shared_link: The settings for the shared link to create on the folder. + +Use an empty object (`{}`) to use the default settings for shared +links., defaults to None + :type shared_link: Optional[AddShareLinkToFolderSharedLink], 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 = {'shared_link': shared_link} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders/', to_string(folder_id), '#add_shared_link']), method='PUT', params=query_params_map, 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, FolderFull) + def update_shared_link_on_folder(self, folder_id: str, fields: str, *, shared_link: Optional[UpdateSharedLinkOnFolderSharedLink] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FolderFull: + """ + Updates a shared link on a folder. + :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 fields: Explicitly request the `shared_link` fields +to be returned for this item. + :type fields: str + :param shared_link: The settings for the shared link to update., defaults to None + :type shared_link: Optional[UpdateSharedLinkOnFolderSharedLink], 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 = {'shared_link': shared_link} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders/', to_string(folder_id), '#update_shared_link']), method='PUT', params=query_params_map, 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, FolderFull) + def remove_shared_link_from_folder(self, folder_id: str, fields: str, *, shared_link: Union[Optional[RemoveSharedLinkFromFolderSharedLink], NullValue] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FolderFull: + """ + Removes a shared link from a folder. + :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 fields: Explicitly request the `shared_link` fields +to be returned for this item. + :type fields: str + :param shared_link: By setting this value to `null`, the shared link +is removed from the folder., defaults to None + :type shared_link: Union[Optional[RemoveSharedLinkFromFolderSharedLink], NullValue], 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 = {'shared_link': shared_link} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders/', to_string(folder_id), '#remove_shared_link']), method='PUT', params=query_params_map, 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, FolderFull) \ No newline at end of file diff --git a/box_sdk_gen/managers/shared_links_web_links.py b/box_sdk_gen/managers/shared_links_web_links.py new file mode 100644 index 000000000..3b2e4cc18 --- /dev/null +++ b/box_sdk_gen/managers/shared_links_web_links.py @@ -0,0 +1,325 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.internal.null_value import NullValue + +from typing import Union + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.web_link import WebLink + +from box_sdk_gen.schemas.client_error import ClientError + +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 + +from box_sdk_gen.internal.utils import DateTime + +class AddShareLinkToWebLinkSharedLinkAccessField(str, Enum): + OPEN = 'open' + COMPANY = 'company' + COLLABORATORS = 'collaborators' + +class AddShareLinkToWebLinkSharedLinkPermissionsField(BaseObject): + def __init__(self, *, can_download: Optional[bool] = None, can_preview: Optional[bool] = None, can_edit: Optional[bool] = None, **kwargs): + """ + :param can_download: If the shared link allows for downloading of files. +This can only be set when `access` is set to +`open` or `company`., defaults to None + :type can_download: Optional[bool], optional + :param can_preview: If the shared link allows for previewing of files. +This value is always `true`. For shared links on folders +this also applies to any items in the folder., defaults to None + :type can_preview: Optional[bool], optional + :param can_edit: This value can only be `true` is `type` is `file`., defaults to None + :type can_edit: Optional[bool], optional + """ + super().__init__(**kwargs) + self.can_download = can_download + self.can_preview = can_preview + self.can_edit = can_edit + +class AddShareLinkToWebLinkSharedLink(BaseObject): + def __init__(self, *, access: Optional[AddShareLinkToWebLinkSharedLinkAccessField] = None, password: Optional[str] = None, vanity_name: Optional[str] = None, unshared_at: Optional[DateTime] = None, permissions: Optional[AddShareLinkToWebLinkSharedLinkPermissionsField] = None, **kwargs): + """ + :param access: The level of access for the shared link. This can be +restricted to anyone with the link (`open`), only people +within the company (`company`) and only those who +have been invited to the file (`collaborators`). + +If not set, this field defaults to the access level specified +by the enterprise admin. To create a shared link with this +default setting pass the `shared_link` object with +no `access` field, for example `{ "shared_link": {} }`. + +The `company` access level is only available to paid +accounts., defaults to None + :type access: Optional[AddShareLinkToWebLinkSharedLinkAccessField], optional + :param password: The password required to access the shared link. Set the +password to `null` to remove it. +Passwords must now be at least eight characters +long and include a number, upper case letter, or +a non-numeric or non-alphabetic character. +A password can only be set when `access` is set to `open`., defaults to None + :type password: Optional[str], optional + :param vanity_name: Defines a custom vanity name to use in the shared link URL, +for example `https://app.box.com/v/my-shared-link`. + +Custom URLs should not be used when sharing sensitive content +as vanity URLs are a lot easier to guess than regular shared +links., defaults to None + :type vanity_name: Optional[str], optional + :param unshared_at: The timestamp at which this shared link will +expire. This field can only be set by +users with paid accounts. The value must be greater than the +current date and time., defaults to None + :type unshared_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.access = access + self.password = password + self.vanity_name = vanity_name + self.unshared_at = unshared_at + self.permissions = permissions + +class UpdateSharedLinkOnWebLinkSharedLinkAccessField(str, Enum): + OPEN = 'open' + COMPANY = 'company' + COLLABORATORS = 'collaborators' + +class UpdateSharedLinkOnWebLinkSharedLinkPermissionsField(BaseObject): + def __init__(self, *, can_download: Optional[bool] = None, can_preview: Optional[bool] = None, can_edit: Optional[bool] = None, **kwargs): + """ + :param can_download: If the shared link allows for downloading of files. +This can only be set when `access` is set to +`open` or `company`., defaults to None + :type can_download: Optional[bool], optional + :param can_preview: If the shared link allows for previewing of files. +This value is always `true`. For shared links on folders +this also applies to any items in the folder., defaults to None + :type can_preview: Optional[bool], optional + :param can_edit: This value can only be `true` is `type` is `file`., defaults to None + :type can_edit: Optional[bool], optional + """ + super().__init__(**kwargs) + self.can_download = can_download + self.can_preview = can_preview + self.can_edit = can_edit + +class UpdateSharedLinkOnWebLinkSharedLink(BaseObject): + def __init__(self, *, access: Optional[UpdateSharedLinkOnWebLinkSharedLinkAccessField] = None, password: Optional[str] = None, vanity_name: Optional[str] = None, unshared_at: Optional[DateTime] = None, permissions: Optional[UpdateSharedLinkOnWebLinkSharedLinkPermissionsField] = None, **kwargs): + """ + :param access: The level of access for the shared link. This can be +restricted to anyone with the link (`open`), only people +within the company (`company`) and only those who +have been invited to the folder (`collaborators`). + +If not set, this field defaults to the access level specified +by the enterprise admin. To create a shared link with this +default setting pass the `shared_link` object with +no `access` field, for example `{ "shared_link": {} }`. + +The `company` access level is only available to paid +accounts., defaults to None + :type access: Optional[UpdateSharedLinkOnWebLinkSharedLinkAccessField], optional + :param password: The password required to access the shared link. Set the +password to `null` to remove it. +Passwords must now be at least eight characters +long and include a number, upper case letter, or +a non-numeric or non-alphabetic character. +A password can only be set when `access` is set to `open`., defaults to None + :type password: Optional[str], optional + :param vanity_name: Defines a custom vanity name to use in the shared link URL, +for example `https://app.box.com/v/my-shared-link`. + +Custom URLs should not be used when sharing sensitive content +as vanity URLs are a lot easier to guess than regular shared +links., defaults to None + :type vanity_name: Optional[str], optional + :param unshared_at: The timestamp at which this shared link will +expire. This field can only be set by +users with paid accounts. The value must be greater than the +current date and time., defaults to None + :type unshared_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.access = access + self.password = password + self.vanity_name = vanity_name + self.unshared_at = unshared_at + self.permissions = permissions + +class RemoveSharedLinkFromWebLinkSharedLink(BaseObject): + def __init__(self, **kwargs): + super().__init__(**kwargs) + +class SharedLinksWebLinksManager: + 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 find_web_link_for_shared_link(self, boxapi: str, *, fields: Optional[List[str]] = None, if_none_match: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> WebLink: + """ + Returns the web link represented by a shared link. + + A shared web link can be represented by a shared link, + + + which can originate within the current enterprise or within another. + + + This endpoint allows an application to retrieve information about a + + + shared web link when only given a shared link. + + :param boxapi: A header containing the shared link and optional password for the +shared link. + +The format for this header is as follows. + +`shared_link=[link]&shared_link_password=[password]` + :type boxapi: str + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[str]], optional + :param if_none_match: Ensures an item is only returned if it has changed. + +Pass in the item's last observed `etag` value +into this header and the endpoint will fail +with a `304 Not Modified` if the item has not +changed since., defaults to None + :type if_none_match: 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({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({'if-none-match': to_string(if_none_match), 'boxapi': to_string(boxapi), **extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/shared_items#web_links']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, WebLink) + def get_shared_link_for_web_link(self, web_link_id: str, fields: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> WebLink: + """ + Gets the information for a shared link on a web link. + :param web_link_id: The ID of the web link. +Example: "12345" + :type web_link_id: str + :param fields: Explicitly request the `shared_link` fields +to be returned for this item. + :type fields: str + :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({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/web_links/', to_string(web_link_id), '#get_shared_link']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, WebLink) + def add_share_link_to_web_link(self, web_link_id: str, fields: str, *, shared_link: Optional[AddShareLinkToWebLinkSharedLink] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> WebLink: + """ + Adds a shared link to a web link. + :param web_link_id: The ID of the web link. +Example: "12345" + :type web_link_id: str + :param fields: Explicitly request the `shared_link` fields +to be returned for this item. + :type fields: str + :param shared_link: The settings for the shared link to create on the web link. + +Use an empty object (`{}`) to use the default settings for shared +links., defaults to None + :type shared_link: Optional[AddShareLinkToWebLinkSharedLink], 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 = {'shared_link': shared_link} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/web_links/', to_string(web_link_id), '#add_shared_link']), method='PUT', params=query_params_map, 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, WebLink) + def update_shared_link_on_web_link(self, web_link_id: str, fields: str, *, shared_link: Optional[UpdateSharedLinkOnWebLinkSharedLink] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> WebLink: + """ + Updates a shared link on a web link. + :param web_link_id: The ID of the web link. +Example: "12345" + :type web_link_id: str + :param fields: Explicitly request the `shared_link` fields +to be returned for this item. + :type fields: str + :param shared_link: The settings for the shared link to update., defaults to None + :type shared_link: Optional[UpdateSharedLinkOnWebLinkSharedLink], 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 = {'shared_link': shared_link} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/web_links/', to_string(web_link_id), '#update_shared_link']), method='PUT', params=query_params_map, 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, WebLink) + def remove_shared_link_from_web_link(self, web_link_id: str, fields: str, *, shared_link: Union[Optional[RemoveSharedLinkFromWebLinkSharedLink], NullValue] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> WebLink: + """ + Removes a shared link from a web link. + :param web_link_id: The ID of the web link. +Example: "12345" + :type web_link_id: str + :param fields: Explicitly request the `shared_link` fields +to be returned for this item. + :type fields: str + :param shared_link: By setting this value to `null`, the shared link +is removed from the web link., defaults to None + :type shared_link: Union[Optional[RemoveSharedLinkFromWebLinkSharedLink], NullValue], 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 = {'shared_link': shared_link} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/web_links/', to_string(web_link_id), '#remove_shared_link']), method='PUT', params=query_params_map, 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, WebLink) \ No newline at end of file diff --git a/box_sdk_gen/managers/shield_information_barrier_reports.py b/box_sdk_gen/managers/shield_information_barrier_reports.py new file mode 100644 index 000000000..93c9262e9 --- /dev/null +++ b/box_sdk_gen/managers/shield_information_barrier_reports.py @@ -0,0 +1,95 @@ +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.shield_information_barrier_base import ShieldInformationBarrierBase + +from box_sdk_gen.schemas.shield_information_barrier_reports import ShieldInformationBarrierReports + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.shield_information_barrier_report import ShieldInformationBarrierReport + +from box_sdk_gen.schemas.shield_information_barrier_reference import ShieldInformationBarrierReference + +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 ShieldInformationBarrierReportsManager: + 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_shield_information_barrier_reports(self, shield_information_barrier_id: str, *, marker: Optional[str] = None, limit: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ShieldInformationBarrierReports: + """ + Lists shield information barrier reports. + :param shield_information_barrier_id: The ID of the shield information barrier. + :type shield_information_barrier_id: str + :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 limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], 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({'shield_information_barrier_id': to_string(shield_information_barrier_id), 'marker': to_string(marker), 'limit': to_string(limit)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/shield_information_barrier_reports']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, ShieldInformationBarrierReports) + def create_shield_information_barrier_report(self, *, shield_information_barrier: Optional[ShieldInformationBarrierBase] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ShieldInformationBarrierReport: + """ + Creates a shield information barrier report for a given barrier. + :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 = {'shield_information_barrier': shield_information_barrier} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/shield_information_barrier_reports']), 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, ShieldInformationBarrierReport) + def get_shield_information_barrier_report_by_id(self, shield_information_barrier_report_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ShieldInformationBarrierReport: + """ + Retrieves a shield information barrier report by its ID. + :param shield_information_barrier_report_id: The ID of the shield information barrier Report. +Example: "3423" + :type shield_information_barrier_report_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/shield_information_barrier_reports/', to_string(shield_information_barrier_report_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, ShieldInformationBarrierReport) \ No newline at end of file diff --git a/box_sdk_gen/managers/shield_information_barrier_segment_members.py b/box_sdk_gen/managers/shield_information_barrier_segment_members.py new file mode 100644 index 000000000..99cb372af --- /dev/null +++ b/box_sdk_gen/managers/shield_information_barrier_segment_members.py @@ -0,0 +1,149 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.shield_information_barrier_segment_member import ShieldInformationBarrierSegmentMember + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.shield_information_barrier_segment_members import ShieldInformationBarrierSegmentMembers + +from box_sdk_gen.schemas.shield_information_barrier_base import ShieldInformationBarrierBase + +from box_sdk_gen.schemas.user_base import UserBase + +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 CreateShieldInformationBarrierSegmentMemberType(str, Enum): + SHIELD_INFORMATION_BARRIER_SEGMENT_MEMBER = 'shield_information_barrier_segment_member' + +class CreateShieldInformationBarrierSegmentMemberShieldInformationBarrierSegmentTypeField(str, Enum): + SHIELD_INFORMATION_BARRIER_SEGMENT = 'shield_information_barrier_segment' + +class CreateShieldInformationBarrierSegmentMemberShieldInformationBarrierSegment(BaseObject): + _discriminator = 'type', {'shield_information_barrier_segment'} + def __init__(self, *, id: Optional[str] = None, type: Optional[CreateShieldInformationBarrierSegmentMemberShieldInformationBarrierSegmentTypeField] = None, **kwargs): + """ + :param id: The ID reference of the +requesting shield information barrier segment., defaults to None + :type id: Optional[str], optional + :param type: The type of the shield barrier segment for this member., defaults to None + :type type: Optional[CreateShieldInformationBarrierSegmentMemberShieldInformationBarrierSegmentTypeField], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class ShieldInformationBarrierSegmentMembersManager: + 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_shield_information_barrier_segment_member_by_id(self, shield_information_barrier_segment_member_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ShieldInformationBarrierSegmentMember: + """ + Retrieves a shield information barrier + + segment member by its ID. + + :param shield_information_barrier_segment_member_id: The ID of the shield information barrier segment Member. +Example: "7815" + :type shield_information_barrier_segment_member_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/shield_information_barrier_segment_members/', to_string(shield_information_barrier_segment_member_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, ShieldInformationBarrierSegmentMember) + def delete_shield_information_barrier_segment_member_by_id(self, shield_information_barrier_segment_member_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Deletes a shield information barrier + + segment member based on provided ID. + + :param shield_information_barrier_segment_member_id: The ID of the shield information barrier segment Member. +Example: "7815" + :type shield_information_barrier_segment_member_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/shield_information_barrier_segment_members/', to_string(shield_information_barrier_segment_member_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None + def get_shield_information_barrier_segment_members(self, shield_information_barrier_segment_id: str, *, marker: Optional[str] = None, limit: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ShieldInformationBarrierSegmentMembers: + """ + Lists shield information barrier segment members + + based on provided segment IDs. + + :param shield_information_barrier_segment_id: The ID of the shield information barrier segment. + :type shield_information_barrier_segment_id: str + :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 limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], 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({'shield_information_barrier_segment_id': to_string(shield_information_barrier_segment_id), 'marker': to_string(marker), 'limit': to_string(limit)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/shield_information_barrier_segment_members']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, ShieldInformationBarrierSegmentMembers) + def create_shield_information_barrier_segment_member(self, shield_information_barrier_segment: CreateShieldInformationBarrierSegmentMemberShieldInformationBarrierSegment, user: UserBase, *, type: Optional[CreateShieldInformationBarrierSegmentMemberType] = None, shield_information_barrier: Optional[ShieldInformationBarrierBase] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ShieldInformationBarrierSegmentMember: + """ + Creates a new shield information barrier segment member. + :param shield_information_barrier_segment: The `type` and `id` of the +requested shield information barrier segment. + :type shield_information_barrier_segment: CreateShieldInformationBarrierSegmentMemberShieldInformationBarrierSegment + :param user: User to which restriction will be applied. + :type user: UserBase + :param type: -| A type of the shield barrier segment member., defaults to None + :type type: Optional[CreateShieldInformationBarrierSegmentMemberType], 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 = {'type': type, 'shield_information_barrier': shield_information_barrier, 'shield_information_barrier_segment': shield_information_barrier_segment, 'user': user} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/shield_information_barrier_segment_members']), 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, ShieldInformationBarrierSegmentMember) \ No newline at end of file diff --git a/box_sdk_gen/managers/shield_information_barrier_segment_restrictions.py b/box_sdk_gen/managers/shield_information_barrier_segment_restrictions.py new file mode 100644 index 000000000..cc6132a8b --- /dev/null +++ b/box_sdk_gen/managers/shield_information_barrier_segment_restrictions.py @@ -0,0 +1,170 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.shield_information_barrier_segment_restriction import ShieldInformationBarrierSegmentRestriction + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.shield_information_barrier_segment_restrictions import ShieldInformationBarrierSegmentRestrictions + +from box_sdk_gen.schemas.shield_information_barrier_base import ShieldInformationBarrierBase + +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 CreateShieldInformationBarrierSegmentRestrictionType(str, Enum): + SHIELD_INFORMATION_BARRIER_SEGMENT_RESTRICTION = 'shield_information_barrier_segment_restriction' + +class CreateShieldInformationBarrierSegmentRestrictionShieldInformationBarrierSegmentTypeField(str, Enum): + SHIELD_INFORMATION_BARRIER_SEGMENT = 'shield_information_barrier_segment' + +class CreateShieldInformationBarrierSegmentRestrictionShieldInformationBarrierSegment(BaseObject): + _discriminator = 'type', {'shield_information_barrier_segment'} + def __init__(self, *, id: Optional[str] = None, type: Optional[CreateShieldInformationBarrierSegmentRestrictionShieldInformationBarrierSegmentTypeField] = None, **kwargs): + """ + :param id: The ID reference of the requesting +shield information barrier segment., defaults to None + :type id: Optional[str], optional + :param type: The type of the shield barrier segment for this member., defaults to None + :type type: Optional[CreateShieldInformationBarrierSegmentRestrictionShieldInformationBarrierSegmentTypeField], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class CreateShieldInformationBarrierSegmentRestrictionRestrictedSegmentTypeField(str, Enum): + SHIELD_INFORMATION_BARRIER_SEGMENT = 'shield_information_barrier_segment' + +class CreateShieldInformationBarrierSegmentRestrictionRestrictedSegment(BaseObject): + _discriminator = 'type', {'shield_information_barrier_segment'} + def __init__(self, *, id: Optional[str] = None, type: Optional[CreateShieldInformationBarrierSegmentRestrictionRestrictedSegmentTypeField] = None, **kwargs): + """ + :param id: The ID reference of the restricted +shield information barrier segment., defaults to None + :type id: Optional[str], optional + :param type: The type of the restricted shield +information barrier segment., defaults to None + :type type: Optional[CreateShieldInformationBarrierSegmentRestrictionRestrictedSegmentTypeField], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class ShieldInformationBarrierSegmentRestrictionsManager: + 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_shield_information_barrier_segment_restriction_by_id(self, shield_information_barrier_segment_restriction_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ShieldInformationBarrierSegmentRestriction: + """ + Retrieves a shield information barrier segment + + restriction based on provided ID. + + :param shield_information_barrier_segment_restriction_id: The ID of the shield information barrier segment Restriction. +Example: "4563" + :type shield_information_barrier_segment_restriction_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/shield_information_barrier_segment_restrictions/', to_string(shield_information_barrier_segment_restriction_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, ShieldInformationBarrierSegmentRestriction) + def delete_shield_information_barrier_segment_restriction_by_id(self, shield_information_barrier_segment_restriction_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Delete shield information barrier segment restriction + + based on provided ID. + + :param shield_information_barrier_segment_restriction_id: The ID of the shield information barrier segment Restriction. +Example: "4563" + :type shield_information_barrier_segment_restriction_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/shield_information_barrier_segment_restrictions/', to_string(shield_information_barrier_segment_restriction_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None + def get_shield_information_barrier_segment_restrictions(self, shield_information_barrier_segment_id: str, *, marker: Optional[str] = None, limit: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ShieldInformationBarrierSegmentRestrictions: + """ + Lists shield information barrier segment restrictions + + based on provided segment ID. + + :param shield_information_barrier_segment_id: The ID of the shield information barrier segment. + :type shield_information_barrier_segment_id: str + :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 limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], 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({'shield_information_barrier_segment_id': to_string(shield_information_barrier_segment_id), 'marker': to_string(marker), 'limit': to_string(limit)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/shield_information_barrier_segment_restrictions']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, ShieldInformationBarrierSegmentRestrictions) + def create_shield_information_barrier_segment_restriction(self, shield_information_barrier_segment: CreateShieldInformationBarrierSegmentRestrictionShieldInformationBarrierSegment, restricted_segment: CreateShieldInformationBarrierSegmentRestrictionRestrictedSegment, *, type: CreateShieldInformationBarrierSegmentRestrictionType = CreateShieldInformationBarrierSegmentRestrictionType.SHIELD_INFORMATION_BARRIER_SEGMENT_RESTRICTION, shield_information_barrier: Optional[ShieldInformationBarrierBase] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ShieldInformationBarrierSegmentRestriction: + """ + Creates a shield information barrier + + segment restriction object. + + :param shield_information_barrier_segment: The `type` and `id` of the requested +shield information barrier segment. + :type shield_information_barrier_segment: CreateShieldInformationBarrierSegmentRestrictionShieldInformationBarrierSegment + :param restricted_segment: The `type` and `id` of the restricted +shield information barrier segment. + :type restricted_segment: CreateShieldInformationBarrierSegmentRestrictionRestrictedSegment + :param type: The type of the shield barrier segment +restriction for this member., defaults to CreateShieldInformationBarrierSegmentRestrictionType.SHIELD_INFORMATION_BARRIER_SEGMENT_RESTRICTION + :type type: CreateShieldInformationBarrierSegmentRestrictionType, 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 = {'type': type, 'shield_information_barrier': shield_information_barrier, 'shield_information_barrier_segment': shield_information_barrier_segment, 'restricted_segment': restricted_segment} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/shield_information_barrier_segment_restrictions']), 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, ShieldInformationBarrierSegmentRestriction) \ No newline at end of file diff --git a/box_sdk_gen/managers/shield_information_barrier_segments.py b/box_sdk_gen/managers/shield_information_barrier_segments.py new file mode 100644 index 000000000..91a753b91 --- /dev/null +++ b/box_sdk_gen/managers/shield_information_barrier_segments.py @@ -0,0 +1,141 @@ +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.internal.null_value import NullValue + +from typing import Union + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.shield_information_barrier_segment import ShieldInformationBarrierSegment + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.shield_information_barrier_segments import ShieldInformationBarrierSegments + +from box_sdk_gen.schemas.shield_information_barrier_base import ShieldInformationBarrierBase + +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 ShieldInformationBarrierSegmentsManager: + 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_shield_information_barrier_segment_by_id(self, shield_information_barrier_segment_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ShieldInformationBarrierSegment: + """ + Retrieves shield information barrier segment based on provided ID.. + :param shield_information_barrier_segment_id: The ID of the shield information barrier segment. +Example: "3423" + :type shield_information_barrier_segment_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/shield_information_barrier_segments/', to_string(shield_information_barrier_segment_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, ShieldInformationBarrierSegment) + def delete_shield_information_barrier_segment_by_id(self, shield_information_barrier_segment_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Deletes the shield information barrier segment + + based on provided ID. + + :param shield_information_barrier_segment_id: The ID of the shield information barrier segment. +Example: "3423" + :type shield_information_barrier_segment_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/shield_information_barrier_segments/', to_string(shield_information_barrier_segment_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None + def update_shield_information_barrier_segment_by_id(self, shield_information_barrier_segment_id: str, *, name: Optional[str] = None, description: Union[Optional[str], NullValue] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ShieldInformationBarrierSegment: + """ + Updates the shield information barrier segment based on provided ID.. + :param shield_information_barrier_segment_id: The ID of the shield information barrier segment. +Example: "3423" + :type shield_information_barrier_segment_id: str + :param name: The updated name for the shield information barrier segment., defaults to None + :type name: Optional[str], optional + :param description: The updated description for +the shield information barrier segment., defaults to None + :type description: Union[Optional[str], NullValue], 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 = {'name': name, 'description': description} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/shield_information_barrier_segments/', to_string(shield_information_barrier_segment_id)]), method='PUT', 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, ShieldInformationBarrierSegment) + def get_shield_information_barrier_segments(self, shield_information_barrier_id: str, *, marker: Optional[str] = None, limit: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ShieldInformationBarrierSegments: + """ + Retrieves a list of shield information barrier segment objects + + for the specified Information Barrier ID. + + :param shield_information_barrier_id: The ID of the shield information barrier. + :type shield_information_barrier_id: str + :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 limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], 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({'shield_information_barrier_id': to_string(shield_information_barrier_id), 'marker': to_string(marker), 'limit': to_string(limit)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/shield_information_barrier_segments']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, ShieldInformationBarrierSegments) + def create_shield_information_barrier_segment(self, shield_information_barrier: ShieldInformationBarrierBase, name: str, *, description: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ShieldInformationBarrierSegment: + """ + Creates a shield information barrier segment. + :param name: Name of the shield information barrier segment + :type name: str + :param description: Description of the shield information barrier segment, defaults to None + :type description: 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 = {} + request_body: Dict = {'shield_information_barrier': shield_information_barrier, 'name': name, 'description': description} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/shield_information_barrier_segments']), 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, ShieldInformationBarrierSegment) \ No newline at end of file diff --git a/box_sdk_gen/managers/shield_information_barriers.py b/box_sdk_gen/managers/shield_information_barriers.py new file mode 100644 index 000000000..36ad1869e --- /dev/null +++ b/box_sdk_gen/managers/shield_information_barriers.py @@ -0,0 +1,122 @@ +from enum import Enum + +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.shield_information_barrier import ShieldInformationBarrier + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.shield_information_barriers import ShieldInformationBarriers + +from box_sdk_gen.schemas.enterprise_base import EnterpriseBase + +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 UpdateShieldInformationBarrierStatusStatus(str, Enum): + PENDING = 'pending' + DISABLED = 'disabled' + +class ShieldInformationBarriersManager: + 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_shield_information_barrier_by_id(self, shield_information_barrier_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ShieldInformationBarrier: + """ + Get shield information barrier based on provided ID. + :param shield_information_barrier_id: The ID of the shield information barrier. +Example: "1910967" + :type shield_information_barrier_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/shield_information_barriers/', to_string(shield_information_barrier_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, ShieldInformationBarrier) + def update_shield_information_barrier_status(self, id: str, status: UpdateShieldInformationBarrierStatusStatus, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ShieldInformationBarrier: + """ + Change status of shield information barrier with the specified ID. + :param id: The ID of the shield information barrier. + :type id: str + :param status: The desired status for the shield information barrier. + :type status: UpdateShieldInformationBarrierStatusStatus + :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 = {'id': id, 'status': status} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/shield_information_barriers/change_status']), 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, ShieldInformationBarrier) + def get_shield_information_barriers(self, *, marker: Optional[str] = None, limit: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ShieldInformationBarriers: + """ + Retrieves a list of shield information barrier objects + + for the enterprise of JWT. + + :param marker: Defines the position marker at which to begin returning results. This is +used when paginating using marker-based pagination., defaults to None + :type marker: Optional[str], optional + :param limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], 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({'marker': to_string(marker), 'limit': to_string(limit)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/shield_information_barriers']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, ShieldInformationBarriers) + def create_shield_information_barrier(self, enterprise: EnterpriseBase, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ShieldInformationBarrier: + """ + Creates a shield information barrier to + + separate individuals/groups within the same + + + firm and prevents confidential information passing between them. + + :param enterprise: The `type` and `id` of enterprise this barrier is under. + :type enterprise: EnterpriseBase + :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 = {'enterprise': enterprise} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/shield_information_barriers']), 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, ShieldInformationBarrier) \ No newline at end of file diff --git a/box_sdk_gen/managers/sign_requests.py b/box_sdk_gen/managers/sign_requests.py new file mode 100644 index 000000000..af5863ac3 --- /dev/null +++ b/box_sdk_gen/managers/sign_requests.py @@ -0,0 +1,193 @@ +from enum import Enum + +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from typing import List + +from box_sdk_gen.internal.null_value import NullValue + +from typing import Union + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.file_base import FileBase + +from box_sdk_gen.schemas.sign_request_create_signer import SignRequestCreateSigner + +from box_sdk_gen.schemas.folder_mini import FolderMini + +from box_sdk_gen.schemas.sign_request_prefill_tag import SignRequestPrefillTag + +from box_sdk_gen.schemas.sign_request import SignRequest + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.sign_requests import SignRequests + +from box_sdk_gen.schemas.sign_request_create_request import SignRequestCreateRequest + +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 CreateSignRequestSignatureColor(str, Enum): + BLUE = 'blue' + BLACK = 'black' + RED = 'red' + +class SignRequestsManager: + 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 cancel_sign_request(self, sign_request_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> SignRequest: + """ + Cancels a sign request. + :param sign_request_id: The ID of the signature request +Example: "33243242" + :type sign_request_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/sign_requests/', to_string(sign_request_id), '/cancel']), method='POST', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, SignRequest) + def resend_sign_request(self, sign_request_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Resends a signature request email to all outstanding signers. + :param sign_request_id: The ID of the signature request +Example: "33243242" + :type sign_request_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/sign_requests/', to_string(sign_request_id), '/resend']), method='POST', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None + def get_sign_request_by_id(self, sign_request_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> SignRequest: + """ + Gets a sign request by ID. + :param sign_request_id: The ID of the signature request +Example: "33243242" + :type sign_request_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/sign_requests/', to_string(sign_request_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, SignRequest) + def get_sign_requests(self, *, marker: Optional[str] = None, limit: Optional[int] = None, senders: Optional[List[str]] = None, shared_requests: Optional[bool] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> SignRequests: + """ + Gets signature requests created by a user. If the `sign_files` and/or + + `parent_folder` are deleted, the signature request will not return in the list. + + :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 limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], optional + :param senders: A list of sender emails to filter the signature requests by sender. +If provided, `shared_requests` must be set to `true`., defaults to None + :type senders: Optional[List[str]], optional + :param shared_requests: If set to `true`, only includes requests that user is not an owner, +but user is a collaborator. Collaborator access is determined by the +user access level of the sign files of the request. +Default is `false`. Must be set to `true` if `senders` are provided., defaults to None + :type shared_requests: Optional[bool], 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({'marker': to_string(marker), 'limit': to_string(limit), 'senders': to_string(senders), 'shared_requests': to_string(shared_requests)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/sign_requests']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, SignRequests) + def create_sign_request(self, signers: List[SignRequestCreateSigner], *, source_files: Union[Optional[List[FileBase]], NullValue] = None, signature_color: Union[Optional[CreateSignRequestSignatureColor], NullValue] = None, parent_folder: Optional[FolderMini] = None, is_document_preparation_needed: Optional[bool] = None, redirect_url: Union[Optional[str], NullValue] = None, declined_redirect_url: Union[Optional[str], NullValue] = None, are_text_signatures_enabled: Optional[bool] = None, email_subject: Union[Optional[str], NullValue] = None, email_message: Union[Optional[str], NullValue] = None, are_reminders_enabled: Optional[bool] = None, name: Optional[str] = None, prefill_tags: Optional[List[SignRequestPrefillTag]] = None, days_valid: Union[Optional[int], NullValue] = None, external_id: Union[Optional[str], NullValue] = None, template_id: Union[Optional[str], NullValue] = None, external_system_name: Union[Optional[str], NullValue] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> SignRequest: + """ + Creates a signature request. This involves preparing a document for signing and + + sending the signature request to signers. + + :param signers: Array of signers for the signature request. 35 is the +max number of signers permitted. + +**Note**: It may happen that some signers belong to conflicting [segments](r://shield-information-barrier-segment-member) (user groups). +This means that due to the security policies, users are assigned to segments to prevent exchanges or communication that could lead to ethical conflicts. +In such a case, an attempt to send the sign request will result in an error. + +Read more about [segments and ethical walls](https://support.box.com/hc/en-us/articles/9920431507603-Understanding-Information-Barriers#h_01GFVJEHQA06N7XEZ4GCZ9GFAQ). + :type signers: List[SignRequestCreateSigner] + :param source_files: List of files to create a signing document from. This is currently limited to ten files. Only the ID and type fields are required for each file., defaults to None + :type source_files: Union[Optional[List[FileBase]], NullValue], optional + :param signature_color: Force a specific color for the signature (blue, black, or red), defaults to None + :type signature_color: Union[Optional[CreateSignRequestSignatureColor], NullValue], optional + :param is_document_preparation_needed: Indicates if the sender should receive a `prepare_url` in the response to complete document preparation using the UI., defaults to None + :type is_document_preparation_needed: Optional[bool], optional + :param redirect_url: When specified, the signature request will be redirected to this url when a document is signed., defaults to None + :type redirect_url: Union[Optional[str], NullValue], optional + :param declined_redirect_url: The uri that a signer will be redirected to after declining to sign a document., defaults to None + :type declined_redirect_url: Union[Optional[str], NullValue], optional + :param are_text_signatures_enabled: Disables the usage of signatures generated by typing (text)., defaults to None + :type are_text_signatures_enabled: Optional[bool], optional + :param email_subject: Subject of sign request email. This is cleaned by sign request. If this field is not passed, a default subject will be used., defaults to None + :type email_subject: Union[Optional[str], NullValue], optional + :param email_message: Message to include in sign request email. The field is cleaned through sanitization of specific characters. However, some html tags are allowed. Links included in the message are also converted to hyperlinks in the email. The message may contain the following html tags including `a`, `abbr`, `acronym`, `b`, `blockquote`, `code`, `em`, `i`, `ul`, `li`, `ol`, and `strong`. Be aware that when the text to html ratio is too high, the email may end up in spam filters. Custom styles on these tags are not allowed. If this field is not passed, a default message will be used., defaults to None + :type email_message: Union[Optional[str], NullValue], optional + :param are_reminders_enabled: Reminds signers to sign a document on day 3, 8, 13 and 18. Reminders are only sent to outstanding signers., defaults to None + :type are_reminders_enabled: Optional[bool], optional + :param name: Name of the signature request., defaults to None + :type name: Optional[str], optional + :param prefill_tags: When a document contains sign-related tags in the content, you can prefill them using this `prefill_tags` by referencing the 'id' of the tag as the `external_id` field of the prefill tag., defaults to None + :type prefill_tags: Optional[List[SignRequestPrefillTag]], optional + :param days_valid: Set the number of days after which the created signature request will automatically expire if not completed. By default, we do not apply any expiration date on signature requests, and the signature request does not expire., defaults to None + :type days_valid: Union[Optional[int], NullValue], optional + :param external_id: This can be used to reference an ID in an external system that the sign request is related to., defaults to None + :type external_id: Union[Optional[str], NullValue], optional + :param template_id: When a signature request is created from a template this field will indicate the id of that template., defaults to None + :type template_id: Union[Optional[str], NullValue], optional + :param external_system_name: Used as an optional system name to appear in the signature log next to the signers who have been assigned the `embed_url_external_id`., defaults to None + :type external_system_name: Union[Optional[str], NullValue], 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 = {'source_files': source_files, 'signature_color': signature_color, 'signers': signers, 'parent_folder': parent_folder, 'is_document_preparation_needed': is_document_preparation_needed, 'redirect_url': redirect_url, 'declined_redirect_url': declined_redirect_url, 'are_text_signatures_enabled': are_text_signatures_enabled, 'email_subject': email_subject, 'email_message': email_message, 'are_reminders_enabled': are_reminders_enabled, 'name': name, 'prefill_tags': prefill_tags, 'days_valid': days_valid, 'external_id': external_id, 'template_id': template_id, 'external_system_name': external_system_name} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/sign_requests']), 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, SignRequest) \ No newline at end of file diff --git a/box_sdk_gen/managers/sign_templates.py b/box_sdk_gen/managers/sign_templates.py new file mode 100644 index 000000000..49e397a11 --- /dev/null +++ b/box_sdk_gen/managers/sign_templates.py @@ -0,0 +1,75 @@ +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.sign_templates import SignTemplates + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.sign_template import SignTemplate + +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 SignTemplatesManager: + 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_sign_templates(self, *, marker: Optional[str] = None, limit: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> SignTemplates: + """ + Gets Box Sign templates created by a user. + :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 limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], 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({'marker': to_string(marker), 'limit': to_string(limit)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/sign_templates']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, SignTemplates) + def get_sign_template_by_id(self, template_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> SignTemplate: + """ + Fetches details of a specific Box Sign template. + :param template_id: The ID of a Box Sign template. +Example: "123075213-7d117509-8f05-42e4-a5ef-5190a319d41d" + :type template_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/sign_templates/', to_string(template_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, SignTemplate) \ No newline at end of file diff --git a/box_sdk_gen/managers/skills.py b/box_sdk_gen/managers/skills.py new file mode 100644 index 000000000..283361fbd --- /dev/null +++ b/box_sdk_gen/managers/skills.py @@ -0,0 +1,254 @@ +from enum import Enum + +from typing import Optional + +from typing import Union + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.skill_cards_metadata import SkillCardsMetadata + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.keyword_skill_card import KeywordSkillCard + +from box_sdk_gen.schemas.timeline_skill_card import TimelineSkillCard + +from box_sdk_gen.schemas.transcript_skill_card import TranscriptSkillCard + +from box_sdk_gen.schemas.status_skill_card import StatusSkillCard + +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 UpdateBoxSkillCardsOnFileRequestBodyOpField(str, Enum): + REPLACE = 'replace' + +class UpdateBoxSkillCardsOnFileRequestBody(BaseObject): + def __init__(self, *, op: Optional[UpdateBoxSkillCardsOnFileRequestBodyOpField] = None, path: Optional[str] = None, value: Optional[Union[KeywordSkillCard, TimelineSkillCard, TranscriptSkillCard, StatusSkillCard]] = None, **kwargs): + """ + :param op: `replace`, defaults to None + :type op: Optional[UpdateBoxSkillCardsOnFileRequestBodyOpField], optional + :param path: The JSON Path that represents the card to replace. In most cases +this will be in the format `/cards/{index}` where `index` is the +zero-indexed position of the card in the list of cards., defaults to None + :type path: Optional[str], optional + """ + super().__init__(**kwargs) + self.op = op + self.path = path + self.value = value + +class UpdateAllSkillCardsOnFileStatus(str, Enum): + INVOKED = 'invoked' + PROCESSING = 'processing' + SUCCESS = 'success' + TRANSIENT_FAILURE = 'transient_failure' + PERMANENT_FAILURE = 'permanent_failure' + +class UpdateAllSkillCardsOnFileMetadata(BaseObject): + def __init__(self, *, cards: Optional[List[Union[KeywordSkillCard, TimelineSkillCard, TranscriptSkillCard, StatusSkillCard]]] = None, **kwargs): + """ + :param cards: A list of Box Skill cards to apply to this file., defaults to None + :type cards: Optional[List[Union[KeywordSkillCard, TimelineSkillCard, TranscriptSkillCard, StatusSkillCard]]], optional + """ + super().__init__(**kwargs) + self.cards = cards + +class UpdateAllSkillCardsOnFileFileTypeField(str, Enum): + FILE = 'file' + +class UpdateAllSkillCardsOnFileFile(BaseObject): + _discriminator = 'type', {'file'} + def __init__(self, *, type: Optional[UpdateAllSkillCardsOnFileFileTypeField] = None, id: Optional[str] = None, **kwargs): + """ + :param type: `file`, defaults to None + :type type: Optional[UpdateAllSkillCardsOnFileFileTypeField], optional + :param id: The ID of the file, defaults to None + :type id: Optional[str], optional + """ + super().__init__(**kwargs) + self.type = type + self.id = id + +class UpdateAllSkillCardsOnFileFileVersionTypeField(str, Enum): + FILE_VERSION = 'file_version' + +class UpdateAllSkillCardsOnFileFileVersion(BaseObject): + _discriminator = 'type', {'file_version'} + def __init__(self, *, type: Optional[UpdateAllSkillCardsOnFileFileVersionTypeField] = None, id: Optional[str] = None, **kwargs): + """ + :param type: `file_version`, defaults to None + :type type: Optional[UpdateAllSkillCardsOnFileFileVersionTypeField], optional + :param id: The ID of the file version, defaults to None + :type id: Optional[str], optional + """ + super().__init__(**kwargs) + self.type = type + self.id = id + +class UpdateAllSkillCardsOnFileUsage(BaseObject): + def __init__(self, *, unit: Optional[str] = None, value: Optional[float] = None, **kwargs): + """ + :param unit: `file`, defaults to None + :type unit: Optional[str], optional + :param value: `1`, defaults to None + :type value: Optional[float], optional + """ + super().__init__(**kwargs) + self.unit = unit + self.value = value + +class SkillsManager: + 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_box_skill_cards_on_file(self, file_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> SkillCardsMetadata: + """ + List the Box Skills metadata cards that are attached to a file. + :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 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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/metadata/global/boxSkillsCards']), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, SkillCardsMetadata) + def create_box_skill_cards_on_file(self, file_id: str, cards: List[Union[KeywordSkillCard, TimelineSkillCard, TranscriptSkillCard, StatusSkillCard]], *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> SkillCardsMetadata: + """ + Applies one or more Box Skills metadata cards to a file. + :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 cards: A list of Box Skill cards to apply to this file. + :type cards: List[Union[KeywordSkillCard, TimelineSkillCard, TranscriptSkillCard, StatusSkillCard]] + :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 = {'cards': cards} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/metadata/global/boxSkillsCards']), 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, SkillCardsMetadata) + def update_box_skill_cards_on_file(self, file_id: str, request_body: List[UpdateBoxSkillCardsOnFileRequestBody], *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> SkillCardsMetadata: + """ + Updates one or more Box Skills metadata cards to a file. + :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 request_body: Request body of updateBoxSkillCardsOnFile method + :type request_body: List[UpdateBoxSkillCardsOnFileRequestBody] + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/metadata/global/boxSkillsCards']), method='PUT', headers=headers_map, data=serialize(request_body), content_type='application/json-patch+json', response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, SkillCardsMetadata) + def delete_box_skill_cards_from_file(self, file_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Removes any Box Skills cards metadata from a file. + :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 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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/metadata/global/boxSkillsCards']), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None + def update_all_skill_cards_on_file(self, skill_id: str, status: UpdateAllSkillCardsOnFileStatus, metadata: UpdateAllSkillCardsOnFileMetadata, file: UpdateAllSkillCardsOnFileFile, *, file_version: Optional[UpdateAllSkillCardsOnFileFileVersion] = None, usage: Optional[UpdateAllSkillCardsOnFileUsage] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + An alternative method that can be used to overwrite and update all Box Skill + + metadata cards on a file. + + :param skill_id: The ID of the skill to apply this metadata for. +Example: "33243242" + :type skill_id: str + :param status: Defines the status of this invocation. Set this to `success` when setting Skill cards. + :type status: UpdateAllSkillCardsOnFileStatus + :param metadata: The metadata to set for this skill. This is a list of +Box Skills cards. These cards will overwrite any existing Box +skill cards on the file. + :type metadata: UpdateAllSkillCardsOnFileMetadata + :param file: The file to assign the cards to. + :type file: UpdateAllSkillCardsOnFileFile + :param file_version: The optional file version to assign the cards to., defaults to None + :type file_version: Optional[UpdateAllSkillCardsOnFileFileVersion], optional + :param usage: A descriptor that defines what items are affected by this call. + +Set this to the default values when setting a card to a `success` +state, and leave it out in most other situations., defaults to None + :type usage: Optional[UpdateAllSkillCardsOnFileUsage], 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 = {'status': status, 'metadata': metadata, 'file': file, 'file_version': file_version, 'usage': usage} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/skill_invocations/', to_string(skill_id)]), method='PUT', headers=headers_map, data=serialize(request_body), content_type='application/json', response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/storage_policies.py b/box_sdk_gen/managers/storage_policies.py new file mode 100644 index 000000000..2bef519a1 --- /dev/null +++ b/box_sdk_gen/managers/storage_policies.py @@ -0,0 +1,87 @@ +from typing import Optional + +from typing import List + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.storage_policies import StoragePolicies + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.storage_policy import StoragePolicy + +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 StoragePoliciesManager: + 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_storage_policies(self, *, fields: Optional[List[str]] = None, marker: Optional[str] = None, limit: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> StoragePolicies: + """ + Fetches all the storage policies in the enterprise. + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[str]], 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 limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], 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({'fields': to_string(fields), 'marker': to_string(marker), 'limit': to_string(limit)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/storage_policies']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, StoragePolicies) + def get_storage_policy_by_id(self, storage_policy_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> StoragePolicy: + """ + Fetches a specific storage policy. + :param storage_policy_id: The ID of the storage policy. +Example: "34342" + :type storage_policy_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/storage_policies/', to_string(storage_policy_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, StoragePolicy) \ No newline at end of file diff --git a/box_sdk_gen/managers/storage_policy_assignments.py b/box_sdk_gen/managers/storage_policy_assignments.py new file mode 100644 index 000000000..b53f18942 --- /dev/null +++ b/box_sdk_gen/managers/storage_policy_assignments.py @@ -0,0 +1,201 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.storage_policy_assignments import StoragePolicyAssignments + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.storage_policy_assignment import StoragePolicyAssignment + +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 GetStoragePolicyAssignmentsResolvedForType(str, Enum): + USER = 'user' + ENTERPRISE = 'enterprise' + +class CreateStoragePolicyAssignmentStoragePolicyTypeField(str, Enum): + STORAGE_POLICY = 'storage_policy' + +class CreateStoragePolicyAssignmentStoragePolicy(BaseObject): + _discriminator = 'type', {'storage_policy'} + def __init__(self, id: str, *, type: CreateStoragePolicyAssignmentStoragePolicyTypeField = CreateStoragePolicyAssignmentStoragePolicyTypeField.STORAGE_POLICY, **kwargs): + """ + :param id: The ID of the storage policy to assign. + :type id: str + :param type: The type to assign., defaults to CreateStoragePolicyAssignmentStoragePolicyTypeField.STORAGE_POLICY + :type type: CreateStoragePolicyAssignmentStoragePolicyTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class CreateStoragePolicyAssignmentAssignedToTypeField(str, Enum): + USER = 'user' + ENTERPRISE = 'enterprise' + +class CreateStoragePolicyAssignmentAssignedTo(BaseObject): + _discriminator = 'type', {'user', 'enterprise'} + def __init__(self, type: CreateStoragePolicyAssignmentAssignedToTypeField, id: str, **kwargs): + """ + :param type: The type to assign the policy to. + :type type: CreateStoragePolicyAssignmentAssignedToTypeField + :param id: The ID of the user or enterprise + :type id: str + """ + super().__init__(**kwargs) + self.type = type + self.id = id + +class UpdateStoragePolicyAssignmentByIdStoragePolicyTypeField(str, Enum): + STORAGE_POLICY = 'storage_policy' + +class UpdateStoragePolicyAssignmentByIdStoragePolicy(BaseObject): + _discriminator = 'type', {'storage_policy'} + def __init__(self, id: str, *, type: UpdateStoragePolicyAssignmentByIdStoragePolicyTypeField = UpdateStoragePolicyAssignmentByIdStoragePolicyTypeField.STORAGE_POLICY, **kwargs): + """ + :param id: The ID of the storage policy to assign. + :type id: str + :param type: The type to assign., defaults to UpdateStoragePolicyAssignmentByIdStoragePolicyTypeField.STORAGE_POLICY + :type type: UpdateStoragePolicyAssignmentByIdStoragePolicyTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class StoragePolicyAssignmentsManager: + 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_storage_policy_assignments(self, resolved_for_type: GetStoragePolicyAssignmentsResolvedForType, resolved_for_id: str, *, marker: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> StoragePolicyAssignments: + """ + Fetches all the storage policy assignment for an enterprise or user. + :param resolved_for_type: The target type to return assignments for + :type resolved_for_type: GetStoragePolicyAssignmentsResolvedForType + :param resolved_for_id: The ID of the user or enterprise to return assignments for + :type resolved_for_id: str + :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 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({'marker': to_string(marker), 'resolved_for_type': to_string(resolved_for_type), 'resolved_for_id': to_string(resolved_for_id)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/storage_policy_assignments']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, StoragePolicyAssignments) + def create_storage_policy_assignment(self, storage_policy: CreateStoragePolicyAssignmentStoragePolicy, assigned_to: CreateStoragePolicyAssignmentAssignedTo, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> StoragePolicyAssignment: + """ + Creates a storage policy assignment for an enterprise or user. + :param storage_policy: The storage policy to assign to the user or +enterprise + :type storage_policy: CreateStoragePolicyAssignmentStoragePolicy + :param assigned_to: The user or enterprise to assign the storage +policy to. + :type assigned_to: CreateStoragePolicyAssignmentAssignedTo + :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 = {'storage_policy': storage_policy, 'assigned_to': assigned_to} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/storage_policy_assignments']), 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, StoragePolicyAssignment) + def get_storage_policy_assignment_by_id(self, storage_policy_assignment_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> StoragePolicyAssignment: + """ + Fetches a specific storage policy assignment. + :param storage_policy_assignment_id: The ID of the storage policy assignment. +Example: "932483" + :type storage_policy_assignment_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/storage_policy_assignments/', to_string(storage_policy_assignment_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, StoragePolicyAssignment) + def update_storage_policy_assignment_by_id(self, storage_policy_assignment_id: str, storage_policy: UpdateStoragePolicyAssignmentByIdStoragePolicy, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> StoragePolicyAssignment: + """ + Updates a specific storage policy assignment. + :param storage_policy_assignment_id: The ID of the storage policy assignment. +Example: "932483" + :type storage_policy_assignment_id: str + :param storage_policy: The storage policy to assign to the user or +enterprise + :type storage_policy: UpdateStoragePolicyAssignmentByIdStoragePolicy + :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 = {'storage_policy': storage_policy} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/storage_policy_assignments/', to_string(storage_policy_assignment_id)]), method='PUT', 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, StoragePolicyAssignment) + def delete_storage_policy_assignment_by_id(self, storage_policy_assignment_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Delete a storage policy assignment. + + Deleting a storage policy assignment on a user + + + will have the user inherit the enterprise's default + + + storage policy. + + + There is a rate limit for calling this endpoint of only + + + twice per user in a 24 hour time frame. + + :param storage_policy_assignment_id: The ID of the storage policy assignment. +Example: "932483" + :type storage_policy_assignment_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/storage_policy_assignments/', to_string(storage_policy_assignment_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/task_assignments.py b/box_sdk_gen/managers/task_assignments.py new file mode 100644 index 000000000..76a420a28 --- /dev/null +++ b/box_sdk_gen/managers/task_assignments.py @@ -0,0 +1,178 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.task_assignments import TaskAssignments + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.task_assignment import TaskAssignment + +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 CreateTaskAssignmentTaskTypeField(str, Enum): + TASK = 'task' + +class CreateTaskAssignmentTask(BaseObject): + _discriminator = 'type', {'task'} + def __init__(self, id: str, *, type: CreateTaskAssignmentTaskTypeField = CreateTaskAssignmentTaskTypeField.TASK, **kwargs): + """ + :param id: The ID of the task + :type id: str + :param type: The type of the item to assign., defaults to CreateTaskAssignmentTaskTypeField.TASK + :type type: CreateTaskAssignmentTaskTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class CreateTaskAssignmentAssignTo(BaseObject): + def __init__(self, *, id: Optional[str] = None, login: Optional[str] = None, **kwargs): + """ + :param id: The ID of the user to assign to the +task. + +To specify a user by their email +address use the `login` parameter., defaults to None + :type id: Optional[str], optional + :param login: The email address of the user to assign to the task. +To specify a user by their user ID please use the `id` parameter., defaults to None + :type login: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.login = login + +class UpdateTaskAssignmentByIdResolutionState(str, Enum): + COMPLETED = 'completed' + INCOMPLETE = 'incomplete' + APPROVED = 'approved' + REJECTED = 'rejected' + +class TaskAssignmentsManager: + 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_task_assignments(self, task_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> TaskAssignments: + """ + Lists all of the assignments for a given task. + :param task_id: The ID of the task. +Example: "12345" + :type task_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/tasks/', to_string(task_id), '/assignments']), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, TaskAssignments) + def create_task_assignment(self, task: CreateTaskAssignmentTask, assign_to: CreateTaskAssignmentAssignTo, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> TaskAssignment: + """ + Assigns a task to a user. + + A task can be assigned to more than one user by creating multiple + + + assignments. + + :param task: The task to assign to a user. + :type task: CreateTaskAssignmentTask + :param assign_to: The user to assign the task to. + :type assign_to: CreateTaskAssignmentAssignTo + :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 = {'task': task, 'assign_to': assign_to} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/task_assignments']), 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, TaskAssignment) + def get_task_assignment_by_id(self, task_assignment_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> TaskAssignment: + """ + Retrieves information about a task assignment. + :param task_assignment_id: The ID of the task assignment. +Example: "12345" + :type task_assignment_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/task_assignments/', to_string(task_assignment_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, TaskAssignment) + def update_task_assignment_by_id(self, task_assignment_id: str, *, message: Optional[str] = None, resolution_state: Optional[UpdateTaskAssignmentByIdResolutionState] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> TaskAssignment: + """ + Updates a task assignment. This endpoint can be + + used to update the state of a task assigned to a user. + + :param task_assignment_id: The ID of the task assignment. +Example: "12345" + :type task_assignment_id: str + :param message: An optional message by the assignee that can be added to the task., defaults to None + :type message: Optional[str], optional + :param resolution_state: The state of the task assigned to the user. + +* For a task with an `action` value of `complete` this can be +`incomplete` or `completed`. +* For a task with an `action` of `review` this can be +`incomplete`, `approved`, or `rejected`., defaults to None + :type resolution_state: Optional[UpdateTaskAssignmentByIdResolutionState], 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 = {'message': message, 'resolution_state': resolution_state} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/task_assignments/', to_string(task_assignment_id)]), method='PUT', 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, TaskAssignment) + def delete_task_assignment_by_id(self, task_assignment_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Deletes a specific task assignment. + :param task_assignment_id: The ID of the task assignment. +Example: "12345" + :type task_assignment_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/task_assignments/', to_string(task_assignment_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/tasks.py b/box_sdk_gen/managers/tasks.py new file mode 100644 index 000000000..10ff938ad --- /dev/null +++ b/box_sdk_gen/managers/tasks.py @@ -0,0 +1,205 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.tasks import Tasks + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.task import Task + +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 + +from box_sdk_gen.internal.utils import DateTime + +class CreateTaskItemTypeField(str, Enum): + FILE = 'file' + +class CreateTaskItem(BaseObject): + _discriminator = 'type', {'file'} + def __init__(self, *, id: Optional[str] = None, type: Optional[CreateTaskItemTypeField] = None, **kwargs): + """ + :param id: The ID of the file, defaults to None + :type id: Optional[str], optional + :param type: `file`, defaults to None + :type type: Optional[CreateTaskItemTypeField], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class CreateTaskAction(str, Enum): + REVIEW = 'review' + COMPLETE = 'complete' + +class CreateTaskCompletionRule(str, Enum): + ALL_ASSIGNEES = 'all_assignees' + ANY_ASSIGNEE = 'any_assignee' + +class UpdateTaskByIdAction(str, Enum): + REVIEW = 'review' + COMPLETE = 'complete' + +class UpdateTaskByIdCompletionRule(str, Enum): + ALL_ASSIGNEES = 'all_assignees' + ANY_ASSIGNEE = 'any_assignee' + +class TasksManager: + 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_tasks(self, file_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Tasks: + """ + Retrieves a list of all the tasks for a file. This + + endpoint does not support pagination. + + :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 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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/tasks']), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Tasks) + def create_task(self, item: CreateTaskItem, *, action: Optional[CreateTaskAction] = None, message: Optional[str] = None, due_at: Optional[DateTime] = None, completion_rule: Optional[CreateTaskCompletionRule] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Task: + """ + Creates a single task on a file. This task is not assigned to any user and + + will need to be assigned separately. + + :param item: The file to attach the task to. + :type item: CreateTaskItem + :param action: The action the task assignee will be prompted to do. Must be + +* `review` defines an approval task that can be approved or +rejected +* `complete` defines a general task which can be completed, defaults to None + :type action: Optional[CreateTaskAction], optional + :param message: An optional message to include with the task., defaults to None + :type message: Optional[str], optional + :param due_at: Defines when the task is due. Defaults to `null` if not +provided., defaults to None + :type due_at: Optional[DateTime], optional + :param completion_rule: Defines which assignees need to complete this task before the task +is considered completed. + +* `all_assignees` (default) requires all assignees to review or +approve the the task in order for it to be considered completed. +* `any_assignee` accepts any one assignee to review or +approve the the task in order for it to be considered completed., defaults to None + :type completion_rule: Optional[CreateTaskCompletionRule], 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 = {'item': item, 'action': action, 'message': message, 'due_at': due_at, 'completion_rule': completion_rule} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/tasks']), 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, Task) + def get_task_by_id(self, task_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Task: + """ + Retrieves information about a specific task. + :param task_id: The ID of the task. +Example: "12345" + :type task_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/tasks/', to_string(task_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Task) + def update_task_by_id(self, task_id: str, *, action: Optional[UpdateTaskByIdAction] = None, message: Optional[str] = None, due_at: Optional[DateTime] = None, completion_rule: Optional[UpdateTaskByIdCompletionRule] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Task: + """ + Updates a task. This can be used to update a task's configuration, or to + + update its completion state. + + :param task_id: The ID of the task. +Example: "12345" + :type task_id: str + :param action: The action the task assignee will be prompted to do. Must be + +* `review` defines an approval task that can be approved or +rejected +* `complete` defines a general task which can be completed, defaults to None + :type action: Optional[UpdateTaskByIdAction], optional + :param message: The message included with the task., defaults to None + :type message: Optional[str], optional + :param due_at: When the task is due at., defaults to None + :type due_at: Optional[DateTime], optional + :param completion_rule: Defines which assignees need to complete this task before the task +is considered completed. + +* `all_assignees` (default) requires all assignees to review or +approve the the task in order for it to be considered completed. +* `any_assignee` accepts any one assignee to review or +approve the the task in order for it to be considered completed., defaults to None + :type completion_rule: Optional[UpdateTaskByIdCompletionRule], 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 = {'action': action, 'message': message, 'due_at': due_at, 'completion_rule': completion_rule} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/tasks/', to_string(task_id)]), method='PUT', 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, Task) + def delete_task_by_id(self, task_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Removes a task from a file. + :param task_id: The ID of the task. +Example: "12345" + :type task_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/tasks/', to_string(task_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/terms_of_service_user_statuses.py b/box_sdk_gen/managers/terms_of_service_user_statuses.py new file mode 100644 index 000000000..b1fbd7df2 --- /dev/null +++ b/box_sdk_gen/managers/terms_of_service_user_statuses.py @@ -0,0 +1,137 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.terms_of_service_user_statuses import TermsOfServiceUserStatuses + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.terms_of_service_user_status import TermsOfServiceUserStatus + +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 CreateTermsOfServiceStatusForUserTosTypeField(str, Enum): + TERMS_OF_SERVICE = 'terms_of_service' + +class CreateTermsOfServiceStatusForUserTos(BaseObject): + _discriminator = 'type', {'terms_of_service'} + def __init__(self, id: str, *, type: CreateTermsOfServiceStatusForUserTosTypeField = CreateTermsOfServiceStatusForUserTosTypeField.TERMS_OF_SERVICE, **kwargs): + """ + :param id: The ID of terms of service + :type id: str + :param type: The type of object., defaults to CreateTermsOfServiceStatusForUserTosTypeField.TERMS_OF_SERVICE + :type type: CreateTermsOfServiceStatusForUserTosTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class CreateTermsOfServiceStatusForUserUserTypeField(str, Enum): + USER = 'user' + +class CreateTermsOfServiceStatusForUserUser(BaseObject): + _discriminator = 'type', {'user'} + def __init__(self, id: str, *, type: CreateTermsOfServiceStatusForUserUserTypeField = CreateTermsOfServiceStatusForUserUserTypeField.USER, **kwargs): + """ + :param id: The ID of user + :type id: str + :param type: The type of object., defaults to CreateTermsOfServiceStatusForUserUserTypeField.USER + :type type: CreateTermsOfServiceStatusForUserUserTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class TermsOfServiceUserStatusesManager: + 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_terms_of_service_user_statuses(self, tos_id: str, *, user_id: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> TermsOfServiceUserStatuses: + """ + Retrieves an overview of users and their status for a + + terms of service, including Whether they have accepted + + + the terms and when. + + :param tos_id: The ID of the terms of service. + :type tos_id: str + :param user_id: Limits results to the given user ID., defaults to None + :type user_id: 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({'tos_id': to_string(tos_id), 'user_id': to_string(user_id)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/terms_of_service_user_statuses']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, TermsOfServiceUserStatuses) + def create_terms_of_service_status_for_user(self, tos: CreateTermsOfServiceStatusForUserTos, user: CreateTermsOfServiceStatusForUserUser, is_accepted: bool, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> TermsOfServiceUserStatus: + """ + Sets the status for a terms of service for a user. + :param tos: The terms of service to set the status for. + :type tos: CreateTermsOfServiceStatusForUserTos + :param user: The user to set the status for. + :type user: CreateTermsOfServiceStatusForUserUser + :param is_accepted: Whether the user has accepted the terms. + :type is_accepted: bool + :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 = {'tos': tos, 'user': user, 'is_accepted': is_accepted} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/terms_of_service_user_statuses']), 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, TermsOfServiceUserStatus) + def update_terms_of_service_status_for_user_by_id(self, terms_of_service_user_status_id: str, is_accepted: bool, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> TermsOfServiceUserStatus: + """ + Updates the status for a terms of service for a user. + :param terms_of_service_user_status_id: The ID of the terms of service status. +Example: "324234" + :type terms_of_service_user_status_id: str + :param is_accepted: Whether the user has accepted the terms. + :type is_accepted: bool + :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 = {'is_accepted': is_accepted} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/terms_of_service_user_statuses/', to_string(terms_of_service_user_status_id)]), method='PUT', 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, TermsOfServiceUserStatus) \ No newline at end of file diff --git a/box_sdk_gen/managers/terms_of_services.py b/box_sdk_gen/managers/terms_of_services.py new file mode 100644 index 000000000..f18f15793 --- /dev/null +++ b/box_sdk_gen/managers/terms_of_services.py @@ -0,0 +1,138 @@ +from enum import Enum + +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.terms_of_services import TermsOfServices + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.terms_of_service import TermsOfService + +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 GetTermsOfServiceTosType(str, Enum): + EXTERNAL = 'external' + MANAGED = 'managed' + +class CreateTermsOfServiceStatus(str, Enum): + ENABLED = 'enabled' + DISABLED = 'disabled' + +class CreateTermsOfServiceTosType(str, Enum): + EXTERNAL = 'external' + MANAGED = 'managed' + +class UpdateTermsOfServiceByIdStatus(str, Enum): + ENABLED = 'enabled' + DISABLED = 'disabled' + +class TermsOfServicesManager: + 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_terms_of_service(self, *, tos_type: Optional[GetTermsOfServiceTosType] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> TermsOfServices: + """ + Returns the current terms of service text and settings + + for the enterprise. + + :param tos_type: Limits the results to the terms of service of the given type., defaults to None + :type tos_type: Optional[GetTermsOfServiceTosType], 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({'tos_type': to_string(tos_type)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/terms_of_services']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, TermsOfServices) + def create_terms_of_service(self, status: CreateTermsOfServiceStatus, text: str, *, tos_type: Optional[CreateTermsOfServiceTosType] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> TermsOfService: + """ + Creates a terms of service for a given enterprise + + and type of user. + + :param status: Whether this terms of service is active. + :type status: CreateTermsOfServiceStatus + :param text: The terms of service text to display to users. + +The text can be set to empty if the `status` is set to `disabled`. + :type text: str + :param tos_type: The type of user to set the terms of +service for., defaults to None + :type tos_type: Optional[CreateTermsOfServiceTosType], 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 = {'status': status, 'tos_type': tos_type, 'text': text} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/terms_of_services']), 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, TermsOfService) + def get_terms_of_service_by_id(self, terms_of_service_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> TermsOfService: + """ + Fetches a specific terms of service. + :param terms_of_service_id: The ID of the terms of service. +Example: "324234" + :type terms_of_service_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/terms_of_services/', to_string(terms_of_service_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, TermsOfService) + def update_terms_of_service_by_id(self, terms_of_service_id: str, status: UpdateTermsOfServiceByIdStatus, text: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> TermsOfService: + """ + Updates a specific terms of service. + :param terms_of_service_id: The ID of the terms of service. +Example: "324234" + :type terms_of_service_id: str + :param status: Whether this terms of service is active. + :type status: UpdateTermsOfServiceByIdStatus + :param text: The terms of service text to display to users. + +The text can be set to empty if the `status` is set to `disabled`. + :type text: str + :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 = {'status': status, 'text': text} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/terms_of_services/', to_string(terms_of_service_id)]), method='PUT', 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, TermsOfService) \ No newline at end of file diff --git a/box_sdk_gen/managers/transfer.py b/box_sdk_gen/managers/transfer.py new file mode 100644 index 000000000..8ecfba66f --- /dev/null +++ b/box_sdk_gen/managers/transfer.py @@ -0,0 +1,156 @@ +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Optional + +from typing import List + +from typing import Dict + +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.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.schemas.client_error import ClientError + +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 TransferOwnedFolderOwnedBy(BaseObject): + def __init__(self, id: str, **kwargs): + """ + :param id: The ID of the user who the folder will be +transferred to + :type id: str + """ + super().__init__(**kwargs) + self.id = id + +class TransferManager: + 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 transfer_owned_folder(self, user_id: str, owned_by: TransferOwnedFolderOwnedBy, *, fields: Optional[List[str]] = None, notify: Optional[bool] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> FolderFull: + """ + Move all of the items (files, folders and workflows) owned by a user into + + another user's account + + + Only the root folder (`0`) can be transferred. + + + Folders can only be moved across users by users with administrative + + + permissions. + + + All existing shared links and folder-level collaborations are transferred + + + during the operation. Please note that while collaborations at the individual + + + file-level are transferred during the operation, the collaborations are + + + deleted when the original user is deleted. + + + If the user has a large number of items across all folders, the call will + + + be run asynchronously. If the operation is not completed within 10 minutes, + + + the user will receive a 200 OK response, and the operation will continue running. + + + If the destination path has a metadata cascade policy attached to any of + + + the parent folders, a metadata cascade operation will be kicked off + + + asynchronously. + + + There is currently no way to check for when this operation is finished. + + + The destination folder's name will be in the format `{User}'s Files and + + + Folders`, where `{User}` is the display name of the user. + + + To make this API call your application will need to have the "Read and write + + + all files and folders stored in Box" scope enabled. + + + Please make sure the destination user has access to `Relay` or `Relay Lite`, + + + and has access to the files and folders involved in the workflows being + + + transferred. + + + Admins will receive an email when the operation is completed. + + :param user_id: The ID of the user. +Example: "12345" + :type user_id: str + :param owned_by: The user who the folder will be transferred to + :type owned_by: TransferOwnedFolderOwnedBy + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[str]], optional + :param notify: Determines if users should receive email notification +for the action performed., defaults to None + :type notify: Optional[bool], 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 = {'owned_by': owned_by} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields), 'notify': to_string(notify)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/users/', to_string(user_id), '/folders/0']), method='PUT', params=query_params_map, 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, FolderFull) \ No newline at end of file diff --git a/box_sdk_gen/managers/trashed_files.py b/box_sdk_gen/managers/trashed_files.py new file mode 100644 index 000000000..7d42d3ca9 --- /dev/null +++ b/box_sdk_gen/managers/trashed_files.py @@ -0,0 +1,175 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from typing import Dict + +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.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.trash_file_restored import TrashFileRestored + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.trash_file import TrashFile + +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 RestoreFileFromTrashParent(BaseObject): + def __init__(self, *, id: Optional[str] = None, **kwargs): + """ + :param id: The ID of parent item, defaults to None + :type id: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + +class TrashedFilesManager: + 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 restore_file_from_trash(self, file_id: str, *, name: Optional[str] = None, parent: Optional[RestoreFileFromTrashParent] = None, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> TrashFileRestored: + """ + Restores a file that has been moved to the trash. + + An optional new parent ID can be provided to restore the file to in case the + + + original folder has been deleted. + + :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 name: An optional new name for the file., defaults to None + :type name: Optional[str], optional + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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 = {} + request_body: Dict = {'name': name, 'parent': parent} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id)]), method='POST', params=query_params_map, 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, TrashFileRestored) + def get_trashed_file_by_id(self, file_id: str, *, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> TrashFile: + """ + Retrieves a file that has been moved to the trash. + + Please note that only if the file itself has been moved to the + + + trash can it be retrieved with this API call. If instead one of + + + its parent folders was moved to the trash, only that folder + + + can be inspected using the + + + [`GET /folders/:id/trash`](e://get_folders_id_trash) API. + + + To list all items that have been moved to the trash, please + + + use the [`GET /folders/trash/items`](e://get-folders-trash-items/) + + + API. + + :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 fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/trash']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, TrashFile) + def delete_trashed_file_by_id(self, file_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Permanently deletes a file that is in the trash. + + This action cannot be undone. + + :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 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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/', to_string(file_id), '/trash']), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/trashed_folders.py b/box_sdk_gen/managers/trashed_folders.py new file mode 100644 index 000000000..13a9a50f0 --- /dev/null +++ b/box_sdk_gen/managers/trashed_folders.py @@ -0,0 +1,199 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from typing import Dict + +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.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.trash_folder_restored import TrashFolderRestored + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.trash_folder import TrashFolder + +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 RestoreFolderFromTrashParent(BaseObject): + def __init__(self, *, id: Optional[str] = None, **kwargs): + """ + :param id: The ID of parent item, defaults to None + :type id: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + +class TrashedFoldersManager: + 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 restore_folder_from_trash(self, folder_id: str, *, name: Optional[str] = None, parent: Optional[RestoreFolderFromTrashParent] = None, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> TrashFolderRestored: + """ + Restores a folder that has been moved to the trash. + + An optional new parent ID can be provided to restore the folder to in case the + + + original folder has been deleted. + + + During this operation, part of the file tree will be locked, mainly + + + the source folder and all of its descendants, as well as the destination + + + folder. + + + For the duration of the operation, no other move, copy, delete, or restore + + + operation can performed on any of the locked folders. + + :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 name: An optional new name for the folder., defaults to None + :type name: Optional[str], optional + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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 = {} + request_body: Dict = {'name': name, 'parent': parent} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders/', to_string(folder_id)]), method='POST', params=query_params_map, 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, TrashFolderRestored) + def get_trashed_folder_by_id(self, folder_id: str, *, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> TrashFolder: + """ + Retrieves a folder that has been moved to the trash. + + Please note that only if the folder itself has been moved to the + + + trash can it be retrieved with this API call. If instead one of + + + its parent folders was moved to the trash, only that folder + + + can be inspected using the + + + [`GET /folders/:id/trash`](e://get_folders_id_trash) API. + + + To list all items that have been moved to the trash, please + + + use the [`GET /folders/trash/items`](e://get-folders-trash-items/) + + + API. + + :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 fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders/', to_string(folder_id), '/trash']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, TrashFolder) + def delete_trashed_folder_by_id(self, folder_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Permanently deletes a folder that is in the trash. + + This action cannot be undone. + + :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 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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders/', to_string(folder_id), '/trash']), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/trashed_items.py b/box_sdk_gen/managers/trashed_items.py new file mode 100644 index 000000000..35c416445 --- /dev/null +++ b/box_sdk_gen/managers/trashed_items.py @@ -0,0 +1,126 @@ +from enum import Enum + +from typing import Optional + +from typing import List + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.items import Items + +from box_sdk_gen.schemas.client_error import ClientError + +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 GetTrashedItemsDirection(str, Enum): + ASC = 'ASC' + DESC = 'DESC' + +class GetTrashedItemsSort(str, Enum): + NAME = 'name' + DATE = 'date' + SIZE = 'size' + +class TrashedItemsManager: + 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_trashed_items(self, *, fields: Optional[List[str]] = None, limit: Optional[int] = None, offset: Optional[int] = None, usemarker: Optional[bool] = None, marker: Optional[str] = None, direction: Optional[GetTrashedItemsDirection] = None, sort: Optional[GetTrashedItemsSort] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Items: + """ + Retrieves the files and folders that have been moved + + to the trash. + + + Any attribute in the full files or folders objects can be passed + + + in with the `fields` parameter to retrieve those specific + + + attributes that are not returned by default. + + + This endpoint defaults to use offset-based pagination, yet also supports + + + marker-based pagination using the `marker` parameter. + + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[str]], optional + :param limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], optional + :param offset: The offset of the item at which to begin the response. + +Queries with offset parameter value +exceeding 10000 will be rejected +with a 400 response., defaults to None + :type offset: Optional[int], optional + :param usemarker: Specifies whether to use marker-based pagination instead of +offset-based pagination. Only one pagination method can +be used at a time. + +By setting this value to true, the API will return a `marker` field +that can be passed as a parameter to this endpoint to get the next +page of the response., defaults to None + :type usemarker: Optional[bool], 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 direction: The direction to sort results in. This can be either in alphabetical ascending +(`ASC`) or descending (`DESC`) order., defaults to None + :type direction: Optional[GetTrashedItemsDirection], optional + :param sort: Defines the **second** attribute by which items +are sorted. + +Items are always sorted by their `type` first, with +folders listed before files, and files listed +before web links. + +This parameter is not supported when using marker-based pagination., defaults to None + :type sort: Optional[GetTrashedItemsSort], 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({'fields': to_string(fields), 'limit': to_string(limit), 'offset': to_string(offset), 'usemarker': to_string(usemarker), 'marker': to_string(marker), 'direction': to_string(direction), 'sort': to_string(sort)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/folders/trash/items']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Items) \ No newline at end of file diff --git a/box_sdk_gen/managers/trashed_web_links.py b/box_sdk_gen/managers/trashed_web_links.py new file mode 100644 index 000000000..97406ff4d --- /dev/null +++ b/box_sdk_gen/managers/trashed_web_links.py @@ -0,0 +1,133 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from typing import Dict + +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.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.trash_web_link_restored import TrashWebLinkRestored + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.trash_web_link import TrashWebLink + +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 RestoreWeblinkFromTrashParent(BaseObject): + def __init__(self, *, id: Optional[str] = None, **kwargs): + """ + :param id: The ID of parent item, defaults to None + :type id: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + +class TrashedWebLinksManager: + 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 restore_weblink_from_trash(self, web_link_id: str, *, name: Optional[str] = None, parent: Optional[RestoreWeblinkFromTrashParent] = None, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> TrashWebLinkRestored: + """ + Restores a web link that has been moved to the trash. + + An optional new parent ID can be provided to restore the web link to in case + + + the original folder has been deleted. + + :param web_link_id: The ID of the web link. +Example: "12345" + :type web_link_id: str + :param name: An optional new name for the web link., defaults to None + :type name: Optional[str], optional + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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 = {} + request_body: Dict = {'name': name, 'parent': parent} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/web_links/', to_string(web_link_id)]), method='POST', params=query_params_map, 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, TrashWebLinkRestored) + def get_trashed_web_link_by_id(self, web_link_id: str, *, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> TrashWebLink: + """ + Retrieves a web link that has been moved to the trash. + :param web_link_id: The ID of the web link. +Example: "12345" + :type web_link_id: str + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/web_links/', to_string(web_link_id), '/trash']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, TrashWebLink) + def delete_trashed_web_link_by_id(self, web_link_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Permanently deletes a web link that is in the trash. + + This action cannot be undone. + + :param web_link_id: The ID of the web link. +Example: "12345" + :type web_link_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/web_links/', to_string(web_link_id), '/trash']), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/uploads.py b/box_sdk_gen/managers/uploads.py new file mode 100644 index 000000000..731902944 --- /dev/null +++ b/box_sdk_gen/managers/uploads.py @@ -0,0 +1,357 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from typing import Dict + +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.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.files import Files + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.upload_url import UploadUrl + +from box_sdk_gen.schemas.conflict_error import ConflictError + +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.internal.utils import DateTime + +from box_sdk_gen.serialization.json import sd_to_json + +from box_sdk_gen.networking.fetch_options import MultipartItem + +from box_sdk_gen.serialization.json import SerializedData + +class UploadFileVersionAttributes(BaseObject): + def __init__(self, name: str, *, content_modified_at: Optional[DateTime] = None, **kwargs): + """ + :param name: An optional new name for the file. If specified, the file +will be renamed when the new version is uploaded. + :type name: str + :param content_modified_at: Defines the time the file was last modified at. + +If not set, the upload time will be used., defaults to None + :type content_modified_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.name = name + self.content_modified_at = content_modified_at + +class PreflightFileUploadCheckParent(BaseObject): + def __init__(self, *, id: Optional[str] = None, **kwargs): + """ + :param id: The ID of parent item, defaults to None + :type id: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + +class UploadFileAttributesParentField(BaseObject): + def __init__(self, id: str, **kwargs): + """ + :param id: The id of the parent folder. Use +`0` for the user's root folder. + :type id: str + """ + super().__init__(**kwargs) + self.id = id + +class UploadFileAttributes(BaseObject): + def __init__(self, name: str, parent: UploadFileAttributesParentField, *, content_created_at: Optional[DateTime] = None, content_modified_at: Optional[DateTime] = None, **kwargs): + """ + :param name: The name of the file. + +File names must be unique within their parent folder. The name check is case-insensitive, so a file +named `New File` cannot be created in a parent folder that already contains a folder named `new file`. + :type name: str + :param parent: The parent folder to upload the file to + :type parent: UploadFileAttributesParentField + :param content_created_at: Defines the time the file was originally created at. + +If not set, the upload time will be used., defaults to None + :type content_created_at: Optional[DateTime], optional + :param content_modified_at: Defines the time the file was last modified at. + +If not set, the upload time will be used., defaults to None + :type content_modified_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.name = name + self.parent = parent + self.content_created_at = content_created_at + self.content_modified_at = content_modified_at + +class UploadWithPreflightCheckAttributesParentField(BaseObject): + def __init__(self, id: str, **kwargs): + """ + :param id: The id of the parent folder. Use +`0` for the user's root folder. + :type id: str + """ + super().__init__(**kwargs) + self.id = id + +class UploadWithPreflightCheckAttributes(BaseObject): + def __init__(self, name: str, parent: UploadWithPreflightCheckAttributesParentField, size: int, *, content_created_at: Optional[DateTime] = None, content_modified_at: Optional[DateTime] = None, **kwargs): + """ + :param name: The name of the file. + +File names must be unique within their parent folder. The name check is case-insensitive, so a file +named `New File` cannot be created in a parent folder that already contains a folder named `new file`. + :type name: str + :param parent: The parent folder to upload the file to + :type parent: UploadWithPreflightCheckAttributesParentField + :param size: The size of the file in bytes + :type size: int + :param content_created_at: Defines the time the file was originally created at. + +If not set, the upload time will be used., defaults to None + :type content_created_at: Optional[DateTime], optional + :param content_modified_at: Defines the time the file was last modified at. + +If not set, the upload time will be used., defaults to None + :type content_modified_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.name = name + self.parent = parent + self.size = size + self.content_created_at = content_created_at + self.content_modified_at = content_modified_at + +class UploadsManager: + 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 upload_file_version(self, file_id: str, attributes: UploadFileVersionAttributes, file: ByteStream, *, file_file_name: Optional[str] = None, file_content_type: Optional[str] = None, fields: Optional[List[str]] = None, if_match: Optional[str] = None, content_md_5: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Files: + """ + Update a file's content. For file sizes over 50MB we recommend + + using the Chunk Upload APIs. + + + The `attributes` part of the body must come **before** the + + + `file` part. Requests that do not follow this format when + + + uploading the file will receive a HTTP `400` error with a + + + `metadata_after_file_contents` error code. + + :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 attributes: The additional attributes of the file being uploaded. Mainly the +name and the parent folder. These attributes are part of the multi +part request body and are in JSON format. + + + + The `attributes` part of the body must come **before** the + `file` part. Requests that do not follow this format when + uploading the file will receive a HTTP `400` error with a + `metadata_after_file_contents` error code. + + + :type attributes: UploadFileVersionAttributes + :param file: The content of the file to upload to Box. + + + + The `attributes` part of the body must come **before** the + `file` part. Requests that do not follow this format when + uploading the file will receive a HTTP `400` error with a + `metadata_after_file_contents` error code. + + + :type file: ByteStream + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[str]], optional + :param if_match: Ensures this item hasn't recently changed before +making changes. + +Pass in the item's last observed `etag` value +into this header and the endpoint will fail +with a `412 Precondition Failed` if it +has changed since., defaults to None + :type if_match: Optional[str], optional + :param content_md_5: An optional header containing the SHA1 hash of the file to +ensure that the file was not corrupted in transit., defaults to None + :type content_md_5: 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 = {} + request_body: Dict = {'attributes': attributes, 'file': file, 'file_file_name': file_file_name, 'file_content_type': file_content_type} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({'if-match': to_string(if_match), 'content-md5': to_string(content_md_5), **extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.upload_url, '/2.0/files/', to_string(file_id), '/content']), method='POST', params=query_params_map, headers=headers_map, multipart_data=[MultipartItem(part_name='attributes', data=serialize(attributes)), MultipartItem(part_name='file', file_stream=file, file_name=file_file_name, content_type=file_content_type)], content_type='multipart/form-data', response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Files) + def preflight_file_upload_check(self, *, name: Optional[str] = None, size: Optional[int] = None, parent: Optional[PreflightFileUploadCheckParent] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> UploadUrl: + """ + Performs a check to verify that a file will be accepted by Box + + before you upload the entire file. + + :param name: The name for the file, defaults to None + :type name: Optional[str], optional + :param size: The size of the file in bytes, defaults to None + :type size: Optional[int], 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 = {'name': name, 'size': size, 'parent': parent} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/files/content']), method='OPTIONS', 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, UploadUrl) + def upload_file(self, attributes: UploadFileAttributes, file: ByteStream, *, file_file_name: Optional[str] = None, file_content_type: Optional[str] = None, fields: Optional[List[str]] = None, content_md_5: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Files: + """ + Uploads a small file to Box. For file sizes over 50MB we recommend + + using the Chunk Upload APIs. + + + The `attributes` part of the body must come **before** the + + + `file` part. Requests that do not follow this format when + + + uploading the file will receive a HTTP `400` error with a + + + `metadata_after_file_contents` error code. + + :param attributes: The additional attributes of the file being uploaded. Mainly the +name and the parent folder. These attributes are part of the multi +part request body and are in JSON format. + + + + The `attributes` part of the body must come **before** the + `file` part. Requests that do not follow this format when + uploading the file will receive a HTTP `400` error with a + `metadata_after_file_contents` error code. + + + :type attributes: UploadFileAttributes + :param file: The content of the file to upload to Box. + + + + The `attributes` part of the body must come **before** the + `file` part. Requests that do not follow this format when + uploading the file will receive a HTTP `400` error with a + `metadata_after_file_contents` error code. + + + :type file: ByteStream + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[str]], optional + :param content_md_5: An optional header containing the SHA1 hash of the file to +ensure that the file was not corrupted in transit., defaults to None + :type content_md_5: 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 = {} + request_body: Dict = {'attributes': attributes, 'file': file, 'file_file_name': file_file_name, 'file_content_type': file_content_type} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({'content-md5': to_string(content_md_5), **extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.upload_url, '/2.0/files/content']), method='POST', params=query_params_map, headers=headers_map, multipart_data=[MultipartItem(part_name='attributes', data=serialize(attributes)), MultipartItem(part_name='file', file_stream=file, file_name=file_file_name, content_type=file_content_type)], content_type='multipart/form-data', response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Files) + def upload_with_preflight_check(self, attributes: UploadWithPreflightCheckAttributes, file: ByteStream, *, file_file_name: Optional[str] = None, file_content_type: Optional[str] = None, fields: Optional[List[str]] = None, content_md_5: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Files: + """ + Upload a file with a preflight check + :param file: The content of the file to upload to Box. + + + + The `attributes` part of the body must come **before** the + `file` part. Requests that do not follow this format when + uploading the file will receive a HTTP `400` error with a + `metadata_after_file_contents` error code. + + + :type file: ByteStream + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[str]], optional + :param content_md_5: An optional header containing the SHA1 hash of the file to +ensure that the file was not corrupted in transit., defaults to None + :type content_md_5: 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 = {} + request_body: Dict = {'attributes': attributes, 'file': file, 'file_file_name': file_file_name, 'file_content_type': file_content_type} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({'content-md5': to_string(content_md_5), **extra_headers}) + preflight_upload_url: UploadUrl = self.preflight_file_upload_check(name=attributes.name, size=attributes.size, parent=PreflightFileUploadCheckParent(id=attributes.parent.id), extra_headers=extra_headers) + if preflight_upload_url.upload_url == None or not 'http' in preflight_upload_url.upload_url: + raise BoxSDKError(message='Unable to get preflight upload URL') + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=preflight_upload_url.upload_url, method='POST', params=query_params_map, headers=headers_map, multipart_data=[MultipartItem(part_name='attributes', data=serialize(attributes)), MultipartItem(part_name='file', file_stream=file, file_name=file_file_name, content_type=file_content_type)], content_type='multipart/form-data', response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Files) \ No newline at end of file diff --git a/box_sdk_gen/managers/user_collaborations.py b/box_sdk_gen/managers/user_collaborations.py new file mode 100644 index 000000000..80202005a --- /dev/null +++ b/box_sdk_gen/managers/user_collaborations.py @@ -0,0 +1,305 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.collaboration import Collaboration + +from box_sdk_gen.schemas.client_error import ClientError + +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 + +from box_sdk_gen.internal.utils import DateTime + +class UpdateCollaborationByIdRole(str, Enum): + EDITOR = 'editor' + VIEWER = 'viewer' + PREVIEWER = 'previewer' + UPLOADER = 'uploader' + PREVIEWER_UPLOADER = 'previewer uploader' + VIEWER_UPLOADER = 'viewer uploader' + CO_OWNER = 'co-owner' + OWNER = 'owner' + +class UpdateCollaborationByIdStatus(str, Enum): + PENDING = 'pending' + ACCEPTED = 'accepted' + REJECTED = 'rejected' + +class CreateCollaborationItemTypeField(str, Enum): + FILE = 'file' + FOLDER = 'folder' + +class CreateCollaborationItem(BaseObject): + _discriminator = 'type', {'file', 'folder'} + def __init__(self, *, type: Optional[CreateCollaborationItemTypeField] = None, id: Optional[str] = None, **kwargs): + """ + :param type: The type of the item that this collaboration will be +granted access to, defaults to None + :type type: Optional[CreateCollaborationItemTypeField], optional + :param id: The ID of the item that will be granted access to, defaults to None + :type id: Optional[str], optional + """ + super().__init__(**kwargs) + self.type = type + self.id = id + +class CreateCollaborationAccessibleByTypeField(str, Enum): + USER = 'user' + GROUP = 'group' + +class CreateCollaborationAccessibleBy(BaseObject): + _discriminator = 'type', {'user', 'group'} + def __init__(self, type: CreateCollaborationAccessibleByTypeField, *, id: Optional[str] = None, login: Optional[str] = None, **kwargs): + """ + :param type: The type of collaborator to invite. + :type type: CreateCollaborationAccessibleByTypeField + :param id: The ID of the user or group. + +Alternatively, use `login` to specify a user by email +address., defaults to None + :type id: Optional[str], optional + :param login: The email address of the user to grant access to the item. + +Alternatively, use `id` to specify a user by user ID., defaults to None + :type login: Optional[str], optional + """ + super().__init__(**kwargs) + self.type = type + self.id = id + self.login = login + +class CreateCollaborationRole(str, Enum): + EDITOR = 'editor' + VIEWER = 'viewer' + PREVIEWER = 'previewer' + UPLOADER = 'uploader' + PREVIEWER_UPLOADER = 'previewer uploader' + VIEWER_UPLOADER = 'viewer uploader' + CO_OWNER = 'co-owner' + +class UserCollaborationsManager: + 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_collaboration_by_id(self, collaboration_id: str, *, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Collaboration: + """ + Retrieves a single collaboration. + :param collaboration_id: The ID of the collaboration +Example: "1234" + :type collaboration_id: str + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/collaborations/', to_string(collaboration_id)]), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Collaboration) + def update_collaboration_by_id(self, collaboration_id: str, role: UpdateCollaborationByIdRole, *, status: Optional[UpdateCollaborationByIdStatus] = None, expires_at: Optional[DateTime] = None, can_view_path: Optional[bool] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Optional[Collaboration]: + """ + Updates a collaboration. + + Can be used to change the owner of an item, or to + + + accept collaboration invites. + + :param collaboration_id: The ID of the collaboration +Example: "1234" + :type collaboration_id: str + :param role: The level of access granted. + :type role: UpdateCollaborationByIdRole + :param status: +Set the status of a `pending` collaboration invitation, +effectively accepting, or rejecting the invite., defaults to None + :type status: Optional[UpdateCollaborationByIdStatus], optional + :param expires_at: Update the expiration date for the collaboration. At this date, +the collaboration will be automatically removed from the item. + +This feature will only work if the **Automatically remove invited +collaborators: Allow folder owners to extend the expiry date** +setting has been enabled in the **Enterprise Settings** +of the **Admin Console**. When the setting is not enabled, +collaborations can not have an expiry date and a value for this +field will be result in an error. + +Additionally, a collaboration can only be given an +expiration if it was created after the **Automatically remove +invited collaborator** setting was enabled., defaults to None + :type expires_at: Optional[DateTime], optional + :param can_view_path: Determines if the invited users can see the entire parent path to +the associated folder. The user will not gain privileges in any +parent folder and therefore can not see content the user is not +collaborated on. + +Be aware that this meaningfully increases the time required to load the +invitee's **All Files** page. We recommend you limit the number of +collaborations with `can_view_path` enabled to 1,000 per user. + +Only owner or co-owners can invite collaborators with a `can_view_path` of +`true`. + +`can_view_path` can only be used for folder collaborations., defaults to None + :type can_view_path: Optional[bool], 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 = {'role': role, 'status': status, 'expires_at': expires_at, 'can_view_path': can_view_path} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/collaborations/', to_string(collaboration_id)]), method='PUT', headers=headers_map, data=serialize(request_body), content_type='application/json', response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + if to_string(response.status) == '204': + return None + return deserialize(response.data, Collaboration) + def delete_collaboration_by_id(self, collaboration_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Deletes a single collaboration. + :param collaboration_id: The ID of the collaboration +Example: "1234" + :type collaboration_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/collaborations/', to_string(collaboration_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None + def create_collaboration(self, item: CreateCollaborationItem, accessible_by: CreateCollaborationAccessibleBy, role: CreateCollaborationRole, *, is_access_only: Optional[bool] = None, can_view_path: Optional[bool] = None, expires_at: Optional[DateTime] = None, fields: Optional[List[str]] = None, notify: Optional[bool] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Collaboration: + """ + Adds a collaboration for a single user or a single group to a file + + or folder. + + + Collaborations can be created using email address, user IDs, or a + + + group IDs. + + + If a collaboration is being created with a group, access to + + + this endpoint is dependent on the group's ability to be invited. + + + If collaboration is in `pending` status, the following fields + + + are redacted: + + + - `login` and `name` are hidden if a collaboration was created + + + using `user_id`, + + + - `name` is hidden if a collaboration was created using `login`. + + :param item: The item to attach the comment to. + :type item: CreateCollaborationItem + :param accessible_by: The user or group to give access to the item. + :type accessible_by: CreateCollaborationAccessibleBy + :param role: The level of access granted. + :type role: CreateCollaborationRole + :param is_access_only: If set to `true`, collaborators have access to +shared items, but such items won't be visible in the +All Files list. Additionally, collaborators won't +see the the path to the root folder for the +shared item., defaults to None + :type is_access_only: Optional[bool], optional + :param can_view_path: Determines if the invited users can see the entire parent path to +the associated folder. The user will not gain privileges in any +parent folder and therefore can not see content the user is not +collaborated on. + +Be aware that this meaningfully increases the time required to load the +invitee's **All Files** page. We recommend you limit the number of +collaborations with `can_view_path` enabled to 1,000 per user. + +Only owner or co-owners can invite collaborators with a `can_view_path` of +`true`. + +`can_view_path` can only be used for folder collaborations., defaults to None + :type can_view_path: Optional[bool], optional + :param expires_at: Set the expiration date for the collaboration. At this date, the +collaboration will be automatically removed from the item. + +This feature will only work if the **Automatically remove invited +collaborators: Allow folder owners to extend the expiry date** +setting has been enabled in the **Enterprise Settings** +of the **Admin Console**. When the setting is not enabled, +collaborations can not have an expiry date and a value for this +field will be result in an error., defaults to None + :type expires_at: Optional[DateTime], optional + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[str]], optional + :param notify: Determines if users should receive email notification +for the action performed., defaults to None + :type notify: Optional[bool], 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 = {'item': item, 'accessible_by': accessible_by, 'role': role, 'is_access_only': is_access_only, 'can_view_path': can_view_path, 'expires_at': expires_at} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields), 'notify': to_string(notify)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/collaborations']), method='POST', params=query_params_map, 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, Collaboration) \ No newline at end of file diff --git a/box_sdk_gen/managers/users.py b/box_sdk_gen/managers/users.py new file mode 100644 index 000000000..9e27f0d53 --- /dev/null +++ b/box_sdk_gen/managers/users.py @@ -0,0 +1,465 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.internal.null_value import NullValue + +from typing import Union + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.users import Users + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.user_full import UserFull + +from box_sdk_gen.schemas.tracking_code import TrackingCode + +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 GetUsersUserType(str, Enum): + ALL = 'all' + MANAGED = 'managed' + EXTERNAL = 'external' + +class CreateUserRole(str, Enum): + COADMIN = 'coadmin' + USER = 'user' + +class CreateUserStatus(str, Enum): + ACTIVE = 'active' + INACTIVE = 'inactive' + CANNOT_DELETE_EDIT = 'cannot_delete_edit' + CANNOT_DELETE_EDIT_UPLOAD = 'cannot_delete_edit_upload' + +class UpdateUserByIdRole(str, Enum): + COADMIN = 'coadmin' + USER = 'user' + +class UpdateUserByIdStatus(str, Enum): + ACTIVE = 'active' + INACTIVE = 'inactive' + CANNOT_DELETE_EDIT = 'cannot_delete_edit' + CANNOT_DELETE_EDIT_UPLOAD = 'cannot_delete_edit_upload' + +class UpdateUserByIdNotificationEmail(BaseObject): + def __init__(self, *, email: Optional[str] = None, **kwargs): + """ + :param email: The email address to send the notifications to., defaults to None + :type email: Optional[str], optional + """ + super().__init__(**kwargs) + self.email = email + +class UsersManager: + 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_users(self, *, filter_term: Optional[str] = None, user_type: Optional[GetUsersUserType] = None, external_app_user_id: Optional[str] = None, fields: Optional[List[str]] = None, offset: Optional[int] = None, limit: Optional[int] = None, usemarker: Optional[bool] = None, marker: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Users: + """ + Returns a list of all users for the Enterprise along with their `user_id`, + + `public_name`, and `login`. + + + The application and the authenticated user need to + + + have the permission to look up users in the entire + + + enterprise. + + :param filter_term: Limits the results to only users who's `name` or +`login` start with the search term. + +For externally managed users, the search term needs +to completely match the in order to find the user, and +it will only return one user at a time., defaults to None + :type filter_term: Optional[str], optional + :param user_type: Limits the results to the kind of user specified. + +* `all` returns every kind of user for whom the + `login` or `name` partially matches the + `filter_term`. It will only return an external user + if the login matches the `filter_term` completely, + and in that case it will only return that user. +* `managed` returns all managed and app users for whom + the `login` or `name` partially matches the + `filter_term`. +* `external` returns all external users for whom the + `login` matches the `filter_term` exactly., defaults to None + :type user_type: Optional[GetUsersUserType], optional + :param external_app_user_id: Limits the results to app users with the given +`external_app_user_id` value. + +When creating an app user, an +`external_app_user_id` value can be set. This value can +then be used in this endpoint to find any users that +match that `external_app_user_id` value., defaults to None + :type external_app_user_id: Optional[str], optional + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[str]], optional + :param offset: The offset of the item at which to begin the response. + +Queries with offset parameter value +exceeding 10000 will be rejected +with a 400 response., defaults to None + :type offset: Optional[int], optional + :param limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], optional + :param usemarker: Specifies whether to use marker-based pagination instead of +offset-based pagination. Only one pagination method can +be used at a time. + +By setting this value to true, the API will return a `marker` field +that can be passed as a parameter to this endpoint to get the next +page of the response., defaults to None + :type usemarker: Optional[bool], 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 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({'filter_term': to_string(filter_term), 'user_type': to_string(user_type), 'external_app_user_id': to_string(external_app_user_id), 'fields': to_string(fields), 'offset': to_string(offset), 'limit': to_string(limit), 'usemarker': to_string(usemarker), 'marker': to_string(marker)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/users']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Users) + def create_user(self, name: str, *, login: Optional[str] = None, is_platform_access_only: Optional[bool] = None, role: Optional[CreateUserRole] = None, language: Optional[str] = None, is_sync_enabled: Optional[bool] = None, job_title: Optional[str] = None, phone: Optional[str] = None, address: Optional[str] = None, space_amount: Optional[int] = None, tracking_codes: Optional[List[TrackingCode]] = None, can_see_managed_users: Optional[bool] = None, timezone: Optional[str] = None, is_external_collab_restricted: Optional[bool] = None, is_exempt_from_device_limits: Optional[bool] = None, is_exempt_from_login_verification: Optional[bool] = None, status: Optional[CreateUserStatus] = None, external_app_user_id: Optional[str] = None, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> UserFull: + """ + Creates a new managed user in an enterprise. This endpoint + + is only available to users and applications with the right + + + admin permissions. + + :param name: The name of the user + :type name: str + :param login: The email address the user uses to log in + +Required, unless `is_platform_access_only` +is set to `true`., defaults to None + :type login: Optional[str], optional + :param is_platform_access_only: Specifies that the user is an app user., defaults to None + :type is_platform_access_only: Optional[bool], optional + :param role: The user’s enterprise role, defaults to None + :type role: Optional[CreateUserRole], optional + :param language: The language of the user, formatted in modified version of the +[ISO 639-1](/guides/api-calls/language-codes) format., defaults to None + :type language: Optional[str], optional + :param is_sync_enabled: Whether the user can use Box Sync, defaults to None + :type is_sync_enabled: Optional[bool], optional + :param job_title: The user’s job title, defaults to None + :type job_title: Optional[str], optional + :param phone: The user’s phone number, defaults to None + :type phone: Optional[str], optional + :param address: The user’s address, defaults to None + :type address: Optional[str], optional + :param space_amount: The user’s total available space in bytes. Set this to `-1` to +indicate unlimited storage., defaults to None + :type space_amount: Optional[int], optional + :param tracking_codes: Tracking codes allow an admin to generate reports from the +admin console and assign an attribute to a specific group +of users. This setting must be enabled for an enterprise before it +can be used., defaults to None + :type tracking_codes: Optional[List[TrackingCode]], optional + :param can_see_managed_users: Whether the user can see other enterprise users in their +contact list, defaults to None + :type can_see_managed_users: Optional[bool], optional + :param timezone: The user's timezone, defaults to None + :type timezone: Optional[str], optional + :param is_external_collab_restricted: Whether the user is allowed to collaborate with users outside +their enterprise, defaults to None + :type is_external_collab_restricted: Optional[bool], optional + :param is_exempt_from_device_limits: Whether to exempt the user from enterprise device limits, defaults to None + :type is_exempt_from_device_limits: Optional[bool], optional + :param is_exempt_from_login_verification: Whether the user must use two-factor authentication, defaults to None + :type is_exempt_from_login_verification: Optional[bool], optional + :param status: The user's account status, defaults to None + :type status: Optional[CreateUserStatus], optional + :param external_app_user_id: An external identifier for an app user, which can be used to look +up the user. This can be used to tie user IDs from external +identity providers to Box users., defaults to None + :type external_app_user_id: Optional[str], optional + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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 = {} + request_body: Dict = {'name': name, 'login': login, 'is_platform_access_only': is_platform_access_only, 'role': role, 'language': language, 'is_sync_enabled': is_sync_enabled, 'job_title': job_title, 'phone': phone, 'address': address, 'space_amount': space_amount, 'tracking_codes': tracking_codes, 'can_see_managed_users': can_see_managed_users, 'timezone': timezone, 'is_external_collab_restricted': is_external_collab_restricted, 'is_exempt_from_device_limits': is_exempt_from_device_limits, 'is_exempt_from_login_verification': is_exempt_from_login_verification, 'status': status, 'external_app_user_id': external_app_user_id} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/users']), method='POST', params=query_params_map, 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, UserFull) + def get_user_me(self, *, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> UserFull: + """ + Retrieves information about the user who is currently authenticated. + + In the case of a client-side authenticated OAuth 2.0 application + + + this will be the user who authorized the app. + + + In the case of a JWT, server-side authenticated application + + + this will be the service account that belongs to the application + + + by default. + + + Use the `As-User` header to change who this API call is made on behalf of. + + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/users/me']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, UserFull) + def get_user_by_id(self, user_id: str, *, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> UserFull: + """ + Retrieves information about a user in the enterprise. + + The application and the authenticated user need to + + + have the permission to look up users in the entire + + + enterprise. + + + This endpoint also returns a limited set of information + + + for external users who are collaborated on content + + + owned by the enterprise for authenticated users with the + + + right scopes. In this case, disallowed fields will return + + + null instead. + + :param user_id: The ID of the user. +Example: "12345" + :type user_id: str + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/users/', to_string(user_id)]), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, UserFull) + def update_user_by_id(self, user_id: str, *, enterprise: Union[Optional[str], NullValue] = None, notify: Optional[bool] = None, name: Optional[str] = None, login: Optional[str] = None, role: Optional[UpdateUserByIdRole] = None, language: Optional[str] = None, is_sync_enabled: Optional[bool] = None, job_title: Optional[str] = None, phone: Optional[str] = None, address: Optional[str] = None, tracking_codes: Optional[List[TrackingCode]] = None, can_see_managed_users: Optional[bool] = None, timezone: Optional[str] = None, is_external_collab_restricted: Optional[bool] = None, is_exempt_from_device_limits: Optional[bool] = None, is_exempt_from_login_verification: Optional[bool] = None, is_password_reset_required: Optional[bool] = None, status: Optional[UpdateUserByIdStatus] = None, space_amount: Optional[int] = None, notification_email: Union[Optional[UpdateUserByIdNotificationEmail], NullValue] = None, external_app_user_id: Optional[str] = None, fields: Optional[List[str]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> UserFull: + """ + Updates a managed or app user in an enterprise. This endpoint + + is only available to users and applications with the right + + + admin permissions. + + :param user_id: The ID of the user. +Example: "12345" + :type user_id: str + :param enterprise: Set this to `null` to roll the user out of the enterprise +and make them a free user, defaults to None + :type enterprise: Union[Optional[str], NullValue], optional + :param notify: Whether the user should receive an email when they +are rolled out of an enterprise, defaults to None + :type notify: Optional[bool], optional + :param name: The name of the user, defaults to None + :type name: Optional[str], optional + :param login: The email address the user uses to log in + +Note: If the target user's email is not confirmed, then the +primary login address cannot be changed., defaults to None + :type login: Optional[str], optional + :param role: The user’s enterprise role, defaults to None + :type role: Optional[UpdateUserByIdRole], optional + :param language: The language of the user, formatted in modified version of the +[ISO 639-1](/guides/api-calls/language-codes) format., defaults to None + :type language: Optional[str], optional + :param is_sync_enabled: Whether the user can use Box Sync, defaults to None + :type is_sync_enabled: Optional[bool], optional + :param job_title: The user’s job title, defaults to None + :type job_title: Optional[str], optional + :param phone: The user’s phone number, defaults to None + :type phone: Optional[str], optional + :param address: The user’s address, defaults to None + :type address: Optional[str], optional + :param tracking_codes: Tracking codes allow an admin to generate reports from the +admin console and assign an attribute to a specific group +of users. This setting must be enabled for an enterprise before it +can be used., defaults to None + :type tracking_codes: Optional[List[TrackingCode]], optional + :param can_see_managed_users: Whether the user can see other enterprise users in their +contact list, defaults to None + :type can_see_managed_users: Optional[bool], optional + :param timezone: The user's timezone, defaults to None + :type timezone: Optional[str], optional + :param is_external_collab_restricted: Whether the user is allowed to collaborate with users outside +their enterprise, defaults to None + :type is_external_collab_restricted: Optional[bool], optional + :param is_exempt_from_device_limits: Whether to exempt the user from enterprise device limits, defaults to None + :type is_exempt_from_device_limits: Optional[bool], optional + :param is_exempt_from_login_verification: Whether the user must use two-factor authentication, defaults to None + :type is_exempt_from_login_verification: Optional[bool], optional + :param is_password_reset_required: Whether the user is required to reset their password, defaults to None + :type is_password_reset_required: Optional[bool], optional + :param status: The user's account status, defaults to None + :type status: Optional[UpdateUserByIdStatus], optional + :param space_amount: The user’s total available space in bytes. Set this to `-1` to +indicate unlimited storage., defaults to None + :type space_amount: Optional[int], optional + :param notification_email: An alternate notification email address to which email +notifications are sent. When it's confirmed, this will be +the email address to which notifications are sent instead of +to the primary email address. + +Set this value to `null` to remove the notification email., defaults to None + :type notification_email: Union[Optional[UpdateUserByIdNotificationEmail], NullValue], optional + :param external_app_user_id: An external identifier for an app user, which can be used to look +up the user. This can be used to tie user IDs from external +identity providers to Box users. + +Note: In order to update this field, you need to request a token +using the application that created the app user., defaults to None + :type external_app_user_id: Optional[str], optional + :param fields: A comma-separated list of attributes to include in the +response. This can be used to request fields that are +not normally returned in a standard response. + +Be aware that specifying this parameter will have the +effect that none of the standard fields are returned in +the response unless explicitly specified, instead only +fields for the mini representation are returned, additional +to the fields requested., defaults to None + :type fields: Optional[List[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 = {} + request_body: Dict = {'enterprise': enterprise, 'notify': notify, 'name': name, 'login': login, 'role': role, 'language': language, 'is_sync_enabled': is_sync_enabled, 'job_title': job_title, 'phone': phone, 'address': address, 'tracking_codes': tracking_codes, 'can_see_managed_users': can_see_managed_users, 'timezone': timezone, 'is_external_collab_restricted': is_external_collab_restricted, 'is_exempt_from_device_limits': is_exempt_from_device_limits, 'is_exempt_from_login_verification': is_exempt_from_login_verification, 'is_password_reset_required': is_password_reset_required, 'status': status, 'space_amount': space_amount, 'notification_email': notification_email, 'external_app_user_id': external_app_user_id} + query_params_map: Dict[str, str] = prepare_params({'fields': to_string(fields)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/users/', to_string(user_id)]), method='PUT', params=query_params_map, 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, UserFull) + def delete_user_by_id(self, user_id: str, *, notify: Optional[bool] = None, force: Optional[bool] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Deletes a user. By default this will fail if the user + + still owns any content. Move their owned content first + + + before proceeding, or use the `force` field to delete + + + the user and their files. + + :param user_id: The ID of the user. +Example: "12345" + :type user_id: str + :param notify: Whether the user will receive email notification of +the deletion, defaults to None + :type notify: Optional[bool], optional + :param force: Whether the user should be deleted even if this user +still own files, defaults to None + :type force: Optional[bool], 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({'notify': to_string(notify), 'force': to_string(force)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/users/', to_string(user_id)]), method='DELETE', params=query_params_map, headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/web_links.py b/box_sdk_gen/managers/web_links.py new file mode 100644 index 000000000..d43c4fd56 --- /dev/null +++ b/box_sdk_gen/managers/web_links.py @@ -0,0 +1,200 @@ +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Optional + +from enum import Enum + +from typing import Dict + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.web_link import WebLink + +from box_sdk_gen.schemas.client_error import ClientError + +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 SerializedData + +from box_sdk_gen.serialization.json import sd_to_json + +from box_sdk_gen.internal.utils import DateTime + +class CreateWebLinkParent(BaseObject): + def __init__(self, id: str, **kwargs): + """ + :param id: The ID of parent folder + :type id: str + """ + super().__init__(**kwargs) + self.id = id + +class UpdateWebLinkByIdParent(BaseObject): + def __init__(self, *, id: Optional[str] = None, user_id: Optional[str] = None, **kwargs): + """ + :param id: The ID of parent item, defaults to None + :type id: Optional[str], optional + :param user_id: The input for `user_id` is optional. Moving to non-root folder is not allowed when `user_id` is present. Parent folder id should be zero when `user_id` is provided., defaults to None + :type user_id: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.user_id = user_id + +class UpdateWebLinkByIdSharedLinkAccessField(str, Enum): + OPEN = 'open' + COMPANY = 'company' + COLLABORATORS = 'collaborators' + +class UpdateWebLinkByIdSharedLink(BaseObject): + def __init__(self, *, access: Optional[UpdateWebLinkByIdSharedLinkAccessField] = None, password: Optional[str] = None, vanity_name: Optional[str] = None, unshared_at: Optional[DateTime] = None, **kwargs): + """ + :param access: The level of access for the shared link. This can be +restricted to anyone with the link (`open`), only people +within the company (`company`) and only those who +have been invited to the folder (`collaborators`). + +If not set, this field defaults to the access level specified +by the enterprise admin. To create a shared link with this +default setting pass the `shared_link` object with +no `access` field, for example `{ "shared_link": {} }`. + +The `company` access level is only available to paid +accounts., defaults to None + :type access: Optional[UpdateWebLinkByIdSharedLinkAccessField], optional + :param password: The password required to access the shared link. Set the +password to `null` to remove it. +Passwords must now be at least eight characters +long and include a number, upper case letter, or +a non-numeric or non-alphabetic character. +A password can only be set when `access` is set to `open`., defaults to None + :type password: Optional[str], optional + :param vanity_name: Defines a custom vanity name to use in the shared link URL, +for example `https://app.box.com/v/my-shared-link`. + +Custom URLs should not be used when sharing sensitive content +as vanity URLs are a lot easier to guess than regular shared +links., defaults to None + :type vanity_name: Optional[str], optional + :param unshared_at: The timestamp at which this shared link will +expire. This field can only be set by +users with paid accounts. The value must be greater than the +current date and time., defaults to None + :type unshared_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.access = access + self.password = password + self.vanity_name = vanity_name + self.unshared_at = unshared_at + +class WebLinksManager: + 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_web_link(self, url: str, parent: CreateWebLinkParent, *, name: Optional[str] = None, description: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> WebLink: + """ + Creates a web link object within a folder. + :param url: The URL that this web link links to. Must start with +`"http://"` or `"https://"`. + :type url: str + :param parent: The parent folder to create the web link within. + :type parent: CreateWebLinkParent + :param name: Name of the web link. Defaults to the URL if not set., defaults to None + :type name: Optional[str], optional + :param description: Description of the web link., defaults to None + :type description: 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 = {} + request_body: Dict = {'url': url, 'parent': parent, 'name': name, 'description': description} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/web_links']), 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, WebLink) + def get_web_link_by_id(self, web_link_id: str, *, boxapi: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> WebLink: + """ + Retrieve information about a web link. + :param web_link_id: The ID of the web link. +Example: "12345" + :type web_link_id: str + :param boxapi: The URL, and optional password, for the shared link of this item. + +This header can be used to access items that have not been +explicitly shared with a user. + +Use the format `shared_link=[link]` or if a password is required then +use `shared_link=[link]&shared_link_password=[password]`. + +This header can be used on the file or folder shared, as well as on any files +or folders nested within the item., defaults to None + :type boxapi: 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 = {} + headers_map: Dict[str, str] = prepare_params({'boxapi': to_string(boxapi), **extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/web_links/', to_string(web_link_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, WebLink) + def update_web_link_by_id(self, web_link_id: str, *, url: Optional[str] = None, parent: Optional[UpdateWebLinkByIdParent] = None, name: Optional[str] = None, description: Optional[str] = None, shared_link: Optional[UpdateWebLinkByIdSharedLink] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> WebLink: + """ + Updates a web link object. + :param web_link_id: The ID of the web link. +Example: "12345" + :type web_link_id: str + :param url: The new URL that the web link links to. Must start with +`"http://"` or `"https://"`., defaults to None + :type url: Optional[str], optional + :param name: A new name for the web link. Defaults to the URL if not set., defaults to None + :type name: Optional[str], optional + :param description: A new description of the web link., defaults to None + :type description: Optional[str], optional + :param shared_link: The settings for the shared link to update., defaults to None + :type shared_link: Optional[UpdateWebLinkByIdSharedLink], 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 = {'url': url, 'parent': parent, 'name': name, 'description': description, 'shared_link': shared_link} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/web_links/', to_string(web_link_id)]), method='PUT', 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, WebLink) + def delete_web_link_by_id(self, web_link_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Deletes a web link. + :param web_link_id: The ID of the web link. +Example: "12345" + :type web_link_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/web_links/', to_string(web_link_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/webhooks.py b/box_sdk_gen/managers/webhooks.py new file mode 100644 index 000000000..e680706ad --- /dev/null +++ b/box_sdk_gen/managers/webhooks.py @@ -0,0 +1,302 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from typing import List + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.internal.utils import DateTime + +from box_sdk_gen.schemas.webhooks import Webhooks + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.webhook import Webhook + +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 + +from box_sdk_gen.internal.utils import compute_webhook_signature + +from box_sdk_gen.internal.utils import date_time_from_string + +from box_sdk_gen.internal.utils import get_epoch_time_in_seconds + +from box_sdk_gen.internal.utils import date_time_to_epoch_seconds + +class CreateWebhookTargetTypeField(str, Enum): + FILE = 'file' + FOLDER = 'folder' + +class CreateWebhookTarget(BaseObject): + _discriminator = 'type', {'file', 'folder'} + def __init__(self, *, id: Optional[str] = None, type: Optional[CreateWebhookTargetTypeField] = None, **kwargs): + """ + :param id: The ID of the item to trigger a webhook, defaults to None + :type id: Optional[str], optional + :param type: The type of item to trigger a webhook, defaults to None + :type type: Optional[CreateWebhookTargetTypeField], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class CreateWebhookTriggers(str, Enum): + FILE_UPLOADED = 'FILE.UPLOADED' + FILE_PREVIEWED = 'FILE.PREVIEWED' + FILE_DOWNLOADED = 'FILE.DOWNLOADED' + FILE_TRASHED = 'FILE.TRASHED' + FILE_DELETED = 'FILE.DELETED' + FILE_RESTORED = 'FILE.RESTORED' + FILE_COPIED = 'FILE.COPIED' + FILE_MOVED = 'FILE.MOVED' + FILE_LOCKED = 'FILE.LOCKED' + FILE_UNLOCKED = 'FILE.UNLOCKED' + FILE_RENAMED = 'FILE.RENAMED' + COMMENT_CREATED = 'COMMENT.CREATED' + COMMENT_UPDATED = 'COMMENT.UPDATED' + COMMENT_DELETED = 'COMMENT.DELETED' + TASK_ASSIGNMENT_CREATED = 'TASK_ASSIGNMENT.CREATED' + TASK_ASSIGNMENT_UPDATED = 'TASK_ASSIGNMENT.UPDATED' + METADATA_INSTANCE_CREATED = 'METADATA_INSTANCE.CREATED' + METADATA_INSTANCE_UPDATED = 'METADATA_INSTANCE.UPDATED' + METADATA_INSTANCE_DELETED = 'METADATA_INSTANCE.DELETED' + FOLDER_CREATED = 'FOLDER.CREATED' + FOLDER_RENAMED = 'FOLDER.RENAMED' + FOLDER_DOWNLOADED = 'FOLDER.DOWNLOADED' + FOLDER_RESTORED = 'FOLDER.RESTORED' + FOLDER_DELETED = 'FOLDER.DELETED' + FOLDER_COPIED = 'FOLDER.COPIED' + FOLDER_MOVED = 'FOLDER.MOVED' + FOLDER_TRASHED = 'FOLDER.TRASHED' + WEBHOOK_DELETED = 'WEBHOOK.DELETED' + COLLABORATION_CREATED = 'COLLABORATION.CREATED' + COLLABORATION_ACCEPTED = 'COLLABORATION.ACCEPTED' + COLLABORATION_REJECTED = 'COLLABORATION.REJECTED' + COLLABORATION_REMOVED = 'COLLABORATION.REMOVED' + COLLABORATION_UPDATED = 'COLLABORATION.UPDATED' + SHARED_LINK_DELETED = 'SHARED_LINK.DELETED' + SHARED_LINK_CREATED = 'SHARED_LINK.CREATED' + SHARED_LINK_UPDATED = 'SHARED_LINK.UPDATED' + SIGN_REQUEST_COMPLETED = 'SIGN_REQUEST.COMPLETED' + SIGN_REQUEST_DECLINED = 'SIGN_REQUEST.DECLINED' + SIGN_REQUEST_EXPIRED = 'SIGN_REQUEST.EXPIRED' + SIGN_REQUEST_SIGNER_EMAIL_BOUNCED = 'SIGN_REQUEST.SIGNER_EMAIL_BOUNCED' + +class UpdateWebhookByIdTargetTypeField(str, Enum): + FILE = 'file' + FOLDER = 'folder' + +class UpdateWebhookByIdTarget(BaseObject): + _discriminator = 'type', {'file', 'folder'} + def __init__(self, *, id: Optional[str] = None, type: Optional[UpdateWebhookByIdTargetTypeField] = None, **kwargs): + """ + :param id: The ID of the item to trigger a webhook, defaults to None + :type id: Optional[str], optional + :param type: The type of item to trigger a webhook, defaults to None + :type type: Optional[UpdateWebhookByIdTargetTypeField], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class UpdateWebhookByIdTriggers(str, Enum): + FILE_UPLOADED = 'FILE.UPLOADED' + FILE_PREVIEWED = 'FILE.PREVIEWED' + FILE_DOWNLOADED = 'FILE.DOWNLOADED' + FILE_TRASHED = 'FILE.TRASHED' + FILE_DELETED = 'FILE.DELETED' + FILE_RESTORED = 'FILE.RESTORED' + FILE_COPIED = 'FILE.COPIED' + FILE_MOVED = 'FILE.MOVED' + FILE_LOCKED = 'FILE.LOCKED' + FILE_UNLOCKED = 'FILE.UNLOCKED' + FILE_RENAMED = 'FILE.RENAMED' + COMMENT_CREATED = 'COMMENT.CREATED' + COMMENT_UPDATED = 'COMMENT.UPDATED' + COMMENT_DELETED = 'COMMENT.DELETED' + TASK_ASSIGNMENT_CREATED = 'TASK_ASSIGNMENT.CREATED' + TASK_ASSIGNMENT_UPDATED = 'TASK_ASSIGNMENT.UPDATED' + METADATA_INSTANCE_CREATED = 'METADATA_INSTANCE.CREATED' + METADATA_INSTANCE_UPDATED = 'METADATA_INSTANCE.UPDATED' + METADATA_INSTANCE_DELETED = 'METADATA_INSTANCE.DELETED' + FOLDER_CREATED = 'FOLDER.CREATED' + FOLDER_RENAMED = 'FOLDER.RENAMED' + FOLDER_DOWNLOADED = 'FOLDER.DOWNLOADED' + FOLDER_RESTORED = 'FOLDER.RESTORED' + FOLDER_DELETED = 'FOLDER.DELETED' + FOLDER_COPIED = 'FOLDER.COPIED' + FOLDER_MOVED = 'FOLDER.MOVED' + FOLDER_TRASHED = 'FOLDER.TRASHED' + WEBHOOK_DELETED = 'WEBHOOK.DELETED' + COLLABORATION_CREATED = 'COLLABORATION.CREATED' + COLLABORATION_ACCEPTED = 'COLLABORATION.ACCEPTED' + COLLABORATION_REJECTED = 'COLLABORATION.REJECTED' + COLLABORATION_REMOVED = 'COLLABORATION.REMOVED' + COLLABORATION_UPDATED = 'COLLABORATION.UPDATED' + SHARED_LINK_DELETED = 'SHARED_LINK.DELETED' + SHARED_LINK_CREATED = 'SHARED_LINK.CREATED' + SHARED_LINK_UPDATED = 'SHARED_LINK.UPDATED' + SIGN_REQUEST_COMPLETED = 'SIGN_REQUEST.COMPLETED' + SIGN_REQUEST_DECLINED = 'SIGN_REQUEST.DECLINED' + SIGN_REQUEST_EXPIRED = 'SIGN_REQUEST.EXPIRED' + SIGN_REQUEST_SIGNER_EMAIL_BOUNCED = 'SIGN_REQUEST.SIGNER_EMAIL_BOUNCED' + +class WebhooksManager: + 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_webhooks(self, *, marker: Optional[str] = None, limit: Optional[int] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Webhooks: + """ + Returns all defined webhooks for the requesting application. + + This API only returns webhooks that are applied to files or folders that are + + + owned by the authenticated user. This means that an admin can not see webhooks + + + created by a service account unless the admin has access to those folders, and + + + vice versa. + + :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 limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], 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({'marker': to_string(marker), 'limit': to_string(limit)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/webhooks']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Webhooks) + def create_webhook(self, target: CreateWebhookTarget, address: str, triggers: List[CreateWebhookTriggers], *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Webhook: + """ + Creates a webhook. + :param target: The item that will trigger the webhook + :type target: CreateWebhookTarget + :param address: The URL that is notified by this webhook + :type address: str + :param triggers: An array of event names that this webhook is +to be triggered for + :type triggers: List[CreateWebhookTriggers] + :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 = {'target': target, 'address': address, 'triggers': triggers} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/webhooks']), 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, Webhook) + def get_webhook_by_id(self, webhook_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Webhook: + """ + Retrieves a specific webhook + :param webhook_id: The ID of the webhook. +Example: "3321123" + :type webhook_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/webhooks/', to_string(webhook_id)]), method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Webhook) + def update_webhook_by_id(self, webhook_id: str, *, target: Optional[UpdateWebhookByIdTarget] = None, address: Optional[str] = None, triggers: Optional[List[UpdateWebhookByIdTriggers]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Webhook: + """ + Updates a webhook. + :param webhook_id: The ID of the webhook. +Example: "3321123" + :type webhook_id: str + :param target: The item that will trigger the webhook, defaults to None + :type target: Optional[UpdateWebhookByIdTarget], optional + :param address: The URL that is notified by this webhook, defaults to None + :type address: Optional[str], optional + :param triggers: An array of event names that this webhook is +to be triggered for, defaults to None + :type triggers: Optional[List[UpdateWebhookByIdTriggers]], 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 = {'target': target, 'address': address, 'triggers': triggers} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/webhooks/', to_string(webhook_id)]), method='PUT', 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, Webhook) + def delete_webhook_by_id(self, webhook_id: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Deletes a webhook. + :param webhook_id: The ID of the webhook. +Example: "3321123" + :type webhook_id: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/webhooks/', to_string(webhook_id)]), method='DELETE', headers=headers_map, response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None + @staticmethod + def validate_message(body: str, headers: Dict[str, str], primary_key: str, *, secondary_key: Optional[str] = None, max_age: Optional[int] = 600) -> bool: + """ + Validate a webhook message by verifying the signature and the delivery timestamp + :param body: The request body of the webhook message + :type body: str + :param headers: The headers of the webhook message + :type headers: Dict[str, str] + :param primary_key: The primary signature to verify the message with + :type primary_key: str + :param secondary_key: The secondary signature to verify the message with, defaults to None + :type secondary_key: Optional[str], optional + :param max_age: The maximum age of the message in seconds, defaults to 10 minutes, defaults to 600 + :type max_age: Optional[int], optional + """ + delivery_timestamp: DateTime = date_time_from_string(headers.get('box-delivery-timestamp')) + current_epoch: int = get_epoch_time_in_seconds() + if current_epoch - max_age > date_time_to_epoch_seconds(delivery_timestamp) or date_time_to_epoch_seconds(delivery_timestamp) > current_epoch: + return False + if primary_key and compute_webhook_signature(body, headers, primary_key) == headers.get('box-signature-primary'): + return True + if secondary_key and compute_webhook_signature(body, headers, secondary_key) == headers.get('box-signature-secondary'): + return True + return False \ No newline at end of file diff --git a/box_sdk_gen/managers/workflows.py b/box_sdk_gen/managers/workflows.py new file mode 100644 index 000000000..ea4cd1138 --- /dev/null +++ b/box_sdk_gen/managers/workflows.py @@ -0,0 +1,170 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import deserialize + +from typing import List + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.workflows import Workflows + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.outcome import Outcome + +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 StartWorkflowType(str, Enum): + WORKFLOW_PARAMETERS = 'workflow_parameters' + +class StartWorkflowFlow(BaseObject): + def __init__(self, *, type: Optional[str] = None, id: Optional[str] = None, **kwargs): + """ + :param type: The type of the flow object, defaults to None + :type type: Optional[str], optional + :param id: The id of the flow, defaults to None + :type id: Optional[str], optional + """ + super().__init__(**kwargs) + self.type = type + self.id = id + +class StartWorkflowFilesTypeField(str, Enum): + FILE = 'file' + +class StartWorkflowFiles(BaseObject): + _discriminator = 'type', {'file'} + def __init__(self, *, type: Optional[StartWorkflowFilesTypeField] = None, id: Optional[str] = None, **kwargs): + """ + :param type: The type of the file object, defaults to None + :type type: Optional[StartWorkflowFilesTypeField], optional + :param id: The id of the file, defaults to None + :type id: Optional[str], optional + """ + super().__init__(**kwargs) + self.type = type + self.id = id + +class StartWorkflowFolderTypeField(str, Enum): + FOLDER = 'folder' + +class StartWorkflowFolder(BaseObject): + _discriminator = 'type', {'folder'} + def __init__(self, *, type: Optional[StartWorkflowFolderTypeField] = None, id: Optional[str] = None, **kwargs): + """ + :param type: The type of the folder object, defaults to None + :type type: Optional[StartWorkflowFolderTypeField], optional + :param id: The id of the folder, defaults to None + :type id: Optional[str], optional + """ + super().__init__(**kwargs) + self.type = type + self.id = id + +class WorkflowsManager: + 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_workflows(self, folder_id: str, *, trigger_type: Optional[str] = None, limit: Optional[int] = None, marker: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> Workflows: + """ + Returns list of workflows that act on a given `folder ID`, and + + have a flow with a trigger type of `WORKFLOW_MANUAL_START`. + + + You application must be authorized to use the `Manage Box Relay` application + + + scope within the developer console in to use this endpoint. + + :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`. + :type folder_id: str + :param trigger_type: Type of trigger to search for., defaults to None + :type trigger_type: Optional[str], optional + :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 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({'folder_id': to_string(folder_id), 'trigger_type': to_string(trigger_type), 'limit': to_string(limit), 'marker': to_string(marker)}) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/workflows']), method='GET', params=query_params_map, headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, Workflows) + def start_workflow(self, workflow_id: str, flow: StartWorkflowFlow, files: List[StartWorkflowFiles], folder: StartWorkflowFolder, *, type: Optional[StartWorkflowType] = None, outcomes: Optional[List[Outcome]] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> None: + """ + Initiates a flow with a trigger type of `WORKFLOW_MANUAL_START`. + + You application must be authorized to use the `Manage Box Relay` application + + + scope within the developer console. + + :param workflow_id: The ID of the workflow. +Example: "12345" + :type workflow_id: str + :param flow: The flow that will be triggered + :type flow: StartWorkflowFlow + :param files: The array of files for which the workflow should start. All files +must be in the workflow's configured folder. + :type files: List[StartWorkflowFiles] + :param folder: The folder object for which the workflow is configured. + :type folder: StartWorkflowFolder + :param type: The type of the parameters object, defaults to None + :type type: Optional[StartWorkflowType], optional + :param outcomes: A configurable outcome the workflow should complete., defaults to None + :type outcomes: Optional[List[Outcome]], 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 = {'type': type, 'flow': flow, 'files': files, 'folder': folder, 'outcomes': outcomes} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/workflows/', to_string(workflow_id), '/start']), method='POST', headers=headers_map, data=serialize(request_body), content_type='application/json', response_format=ResponseFormat.NO_CONTENT, auth=self.auth, network_session=self.network_session)) + return None \ No newline at end of file diff --git a/box_sdk_gen/managers/zip_downloads.py b/box_sdk_gen/managers/zip_downloads.py new file mode 100644 index 000000000..818a08fea --- /dev/null +++ b/box_sdk_gen/managers/zip_downloads.py @@ -0,0 +1,245 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Optional + +from typing import List + +from typing import Dict + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.zip_download import ZipDownload + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.zip_download_request import ZipDownloadRequest + +from box_sdk_gen.schemas.zip_download_status import ZipDownloadStatus + +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 SerializedData + +from box_sdk_gen.serialization.json import sd_to_json + +class CreateZipDownloadItemsTypeField(str, Enum): + FILE = 'file' + FOLDER = 'folder' + +class CreateZipDownloadItems(BaseObject): + _discriminator = 'type', {'file', 'folder'} + def __init__(self, type: CreateZipDownloadItemsTypeField, id: str, **kwargs): + """ + :param type: The type of the item to add to the archive. + :type type: CreateZipDownloadItemsTypeField + :param id: The identifier of the item to add to the archive. When this item is +a folder then this can not be the root folder with ID `0`. + :type id: str + """ + super().__init__(**kwargs) + self.type = type + self.id = id + +class DownloadZipItemsTypeField(str, Enum): + FILE = 'file' + FOLDER = 'folder' + +class DownloadZipItems(BaseObject): + _discriminator = 'type', {'file', 'folder'} + def __init__(self, type: DownloadZipItemsTypeField, id: str, **kwargs): + """ + :param type: The type of the item to add to the archive. + :type type: DownloadZipItemsTypeField + :param id: The identifier of the item to add to the archive. When this item is +a folder then this can not be the root folder with ID `0`. + :type id: str + """ + super().__init__(**kwargs) + self.type = type + self.id = id + +class ZipDownloadsManager: + 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_zip_download(self, items: List[CreateZipDownloadItems], *, download_file_name: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ZipDownload: + """ + Creates a request to download multiple files and folders as a single `zip` + + archive file. This API does not return the archive but instead performs all + + + the checks to ensure that the user has access to all the items, and then + + + returns a `download_url` and a `status_url` that can be used to download the + + + archive. + + + The limit for an archive is either the Account's upload limit or + + + 10,000 files, whichever is met first. + + + **Note**: Downloading a large file can be + + + affected by various + + + factors such as distance, network latency, + + + bandwidth, and congestion, as well as packet loss + + + ratio and current server load. + + + For these reasons we recommend that a maximum ZIP archive + + + total size does not exceed 25GB. + + :param items: A list of items to add to the `zip` archive. These can +be folders or files. + :type items: List[CreateZipDownloadItems] + :param download_file_name: The optional name of the `zip` archive. This name will be appended by the +`.zip` file extension, for example `January Financials.zip`., defaults to None + :type download_file_name: 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 = {} + request_body: Dict = {'items': items, 'download_file_name': download_file_name} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=''.join([self.network_session.base_urls.base_url, '/2.0/zip_downloads']), 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, ZipDownload) + def get_zip_download_content(self, download_url: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ByteStream: + """ + Returns the contents of a `zip` archive in binary format. This URL does not + + require any form of authentication and could be used in a user's browser to + + + download the archive to a user's device. + + + By default, this URL is only valid for a few seconds from the creation of + + + the request for this archive. Once a download has started it can not be + + + stopped and resumed, instead a new request for a zip archive would need to + + + be created. + + + The URL of this endpoint should not be considered as fixed. Instead, use + + + the [Create zip download](e://post_zip_downloads) API to request to create a + + + `zip` archive, and then follow the `download_url` field in the response to + + + this endpoint. + + :param download_url: The URL that can be used to download created `zip` archive. + Example: `https://dl.boxcloud.com/2.0/zip_downloads/29l00nfxDyHOt7RphI9zT_w==nDnZEDjY2S8iEWWCHEEiptFxwoWojjlibZjJ6geuE5xnXENDTPxzgbks_yY=/content` + :type download_url: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=download_url, method='GET', headers=headers_map, response_format=ResponseFormat.BINARY, auth=self.auth, network_session=self.network_session)) + return response.content + def get_zip_download_status(self, status_url: str, *, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ZipDownloadStatus: + """ + Returns the download status of a `zip` archive, allowing an application to + + inspect the progress of the download as well as the number of items that + + + might have been skipped. + + + This endpoint can only be accessed once the download has started. + + + Subsequently this endpoint is valid for 12 hours from the start of the + + + download. + + + The URL of this endpoint should not be considered as fixed. Instead, use + + + the [Create zip download](e://post_zip_downloads) API to request to create a + + + `zip` archive, and then follow the `status_url` field in the response to + + + this endpoint. + + :param status_url: The URL that can be used to get the status of the `zip` archive being downloaded. + Example: `https://dl.boxcloud.com/2.0/zip_downloads/29l00nfxDyHOt7RphI9zT_w==nDnZEDjY2S8iEWWCHEEiptFxwoWojjlibZjJ6geuE5xnXENDTPxzgbks_yY=/status` + :type status_url: str + :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 = {} + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = self.network_session.network_client.fetch(FetchOptions(url=status_url, method='GET', headers=headers_map, response_format=ResponseFormat.JSON, auth=self.auth, network_session=self.network_session)) + return deserialize(response.data, ZipDownloadStatus) + def download_zip(self, items: List[DownloadZipItems], *, download_file_name: Optional[str] = None, extra_headers: Optional[Dict[str, Optional[str]]] = None) -> ByteStream: + """ + Creates a zip and downloads its content + :param items: A list of items to add to the `zip` archive. These can +be folders or files. + :type items: List[DownloadZipItems] + :param download_file_name: The optional name of the `zip` archive. This name will be appended by the +`.zip` file extension, for example `January Financials.zip`., defaults to None + :type download_file_name: 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 = {} + request_body: Dict = {'items': items, 'download_file_name': download_file_name} + zip_download_session: ZipDownload = self.create_zip_download(items, download_file_name=download_file_name, extra_headers=extra_headers) + return self.get_zip_download_content(zip_download_session.download_url, extra_headers=extra_headers) \ No newline at end of file diff --git a/box_sdk_gen/networking/__init__.py b/box_sdk_gen/networking/__init__.py new file mode 100644 index 000000000..e605f2a2a --- /dev/null +++ b/box_sdk_gen/networking/__init__.py @@ -0,0 +1,19 @@ +from box_sdk_gen.networking.box_network_client import * + +from box_sdk_gen.networking.proxy_config import * + +from box_sdk_gen.networking.network import * + +from box_sdk_gen.networking.auth import * + +from box_sdk_gen.networking.fetch_options import * + +from box_sdk_gen.networking.fetch_response import * + +from box_sdk_gen.networking.network_client import * + +from box_sdk_gen.networking.retries import * + +from box_sdk_gen.networking.base_urls import * + +from box_sdk_gen.networking.version import * \ No newline at end of file diff --git a/box_sdk_gen/networking/auth.py b/box_sdk_gen/networking/auth.py new file mode 100644 index 000000000..3d28d4b55 --- /dev/null +++ b/box_sdk_gen/networking/auth.py @@ -0,0 +1,28 @@ +from typing import Optional + +from abc import abstractmethod + +from typing import List + +from box_sdk_gen.schemas.access_token import AccessToken + +from box_sdk_gen.networking.network import NetworkSession + +class Authentication: + def __init__(self): + pass + @abstractmethod + def retrieve_token(self, *, network_session: Optional[NetworkSession] = None) -> AccessToken: + pass + @abstractmethod + def refresh_token(self, *, network_session: Optional[NetworkSession] = None) -> AccessToken: + pass + @abstractmethod + def retrieve_authorization_header(self, *, network_session: Optional[NetworkSession] = None) -> str: + pass + @abstractmethod + def revoke_token(self, *, network_session: Optional[NetworkSession] = None) -> None: + pass + @abstractmethod + def downscope_token(self, scopes: List[str], *, resource: Optional[str] = None, shared_link: Optional[str] = None, network_session: Optional[NetworkSession] = None) -> AccessToken: + pass \ No newline at end of file diff --git a/box_sdk_gen/networking/base_urls.py b/box_sdk_gen/networking/base_urls.py new file mode 100644 index 000000000..c580cfba8 --- /dev/null +++ b/box_sdk_gen/networking/base_urls.py @@ -0,0 +1,14 @@ +from typing import Dict + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class BaseUrls(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'oauth_2_url': 'oauth2_url', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'oauth2_url': 'oauth_2_url', **BaseObject._json_to_fields_mapping} + def __init__(self, *, base_url: str = 'https://api.box.com', upload_url: str = 'https://upload.box.com/api', oauth_2_url: str = 'https://account.box.com/api/oauth2', **kwargs): + super().__init__(**kwargs) + self.base_url = base_url + self.upload_url = upload_url + self.oauth_2_url = oauth_2_url \ No newline at end of file diff --git a/box_sdk_gen/networking/box_network_client.py b/box_sdk_gen/networking/box_network_client.py new file mode 100644 index 000000000..6735db51a --- /dev/null +++ b/box_sdk_gen/networking/box_network_client.py @@ -0,0 +1,369 @@ +import io + +import time +from collections import OrderedDict +from dataclasses import dataclass +from typing import Optional, Dict, Union +from sys import version_info as py_version + +import requests +from requests import RequestException, Session, Response +from requests_toolbelt import MultipartEncoder + +from ..internal.logging import DataSanitizer +from .retries import BoxRetryStrategy +from ..networking.fetch_options import FetchOptions +from ..networking.fetch_response import FetchResponse +from ..box.errors import BoxAPIError, BoxSDKError, RequestInfo, ResponseInfo +from ..internal.utils import ByteStream, ResponseByteStream +from ..networking.network_client import NetworkClient +from ..serialization.json import ( + sd_to_json, + sd_to_url_params, + json_to_serialized_data, +) +from ..networking.version import __version__ + +SDK_VERSION = __version__ +USER_AGENT_HEADER = f'box-python-generated-sdk-{SDK_VERSION}' +X_BOX_UA_HEADER = ( + f'agent=box-python-generated-sdk/{SDK_VERSION}; ' + f'env=python/{py_version.major}.{py_version.minor}.{py_version.micro}' +) + + +@dataclass +class APIRequest: + method: str + url: str + headers: Dict[str, str] + params: Dict[str, str] + data: Optional[Union[str, ByteStream, MultipartEncoder]] + allow_redirects: bool = True + + +@dataclass +class APIResponse: + network_response: Optional[Response] = None + reauthentication_needed: Optional[bool] = False + raised_exception: Optional[Exception] = None + + def get_header( + self, header_name: str, default_value: Optional[str] = None + ) -> Optional[str]: + try: + return self.network_response.headers[header_name] + except (ValueError, KeyError, AttributeError): + return default_value + + +class BoxNetworkClient(NetworkClient): + def __init__(self, requests_session: Optional[Session] = None): + super().__init__() + self.requests_session = requests_session or requests.Session() + + def fetch(self, options: 'FetchOptions') -> FetchResponse: + retry_strategy = ( + options.network_session.retry_strategy + if options.network_session + else BoxRetryStrategy() + ) + data_sanitizer = ( + options.network_session.data_sanitizer + if options.network_session + else DataSanitizer() + ) + + attempt_nr = 1 + response = APIResponse() + + options_stream_position = self._get_options_stream_position(options) + multipart_streams_positions = self._get_multipart_stream_positions(options) + + while True: + request: APIRequest = self._prepare_request( + options=options, reauthenticate=response.reauthentication_needed + ) + response: APIResponse = self._make_request(request=request) + + # Retry network exception only once + if response.raised_exception and attempt_nr > 1: + break + + if response.network_response is not None: + network_response = response.network_response + + if options.response_format == 'binary': + fetch_response = FetchResponse( + url=network_response.url, + status=network_response.status_code, + headers=dict(response.network_response.headers), + content=ResponseByteStream( + response.network_response.iter_content(chunk_size=1024) + ), + ) + else: + fetch_response = FetchResponse( + url=network_response.url, + status=network_response.status_code, + headers=dict(response.network_response.headers), + data=(self._read_json_body(network_response.text)), + content=io.BytesIO(network_response.content), + ) + + should_retry = retry_strategy.should_retry( + fetch_options=options, + fetch_response=fetch_response, + attempt_number=attempt_nr, + ) + + if should_retry: + time.sleep( + retry_strategy.retry_after( + fetch_options=options, + fetch_response=fetch_response, + attempt_number=attempt_nr, + ) + ) + attempt_nr += 1 + continue + + if 200 <= fetch_response.status < 400: + return fetch_response + + self._raise_on_unsuccessful_request( + request=request, response=response, data_sanitizer=data_sanitizer + ) + + self._reset_options_stream( + options, options_stream_position, response.raised_exception + ) + self._reset_multipart_streams( + options, multipart_streams_positions, response.raised_exception + ) + + attempt_nr += 1 + + self._raise_on_unsuccessful_request( + request=request, response=response, data_sanitizer=data_sanitizer + ) + + def _prepare_request( + self, options: 'FetchOptions', reauthenticate: bool = False + ) -> APIRequest: + headers = self._prepare_headers(options, reauthenticate) + params = options.params or {} + data = self._prepare_body( + options.content_type, options.file_stream or options.data + ) + allow_redirects = options.follow_redirects + + if options.content_type: + if options.content_type == 'multipart/form-data': + fields = OrderedDict() + for part in options.multipart_data: + if part.data: + fields[part.part_name] = sd_to_json(part.data) + else: + fields[part.part_name] = ( + part.file_name or '', + part.file_stream, + part.content_type, + ) + + multipart_stream = MultipartEncoder(fields) + data = multipart_stream + headers['Content-Type'] = multipart_stream.content_type + else: + headers['Content-Type'] = options.content_type + + return APIRequest( + method=options.method, + url=options.url, + headers=headers, + params=params, + data=data, + allow_redirects=allow_redirects, + ) + + @staticmethod + def _prepare_headers( + options: 'FetchOptions', reauthenticate: bool = False + ) -> Dict[str, str]: + headers = {} + if options.network_session: + headers.update(options.network_session.additional_headers) + if options.headers: + headers.update(options.headers) + if options.auth: + if reauthenticate: + options.auth.refresh_token(network_session=options.network_session) + headers['Authorization'] = options.auth.retrieve_authorization_header( + network_session=options.network_session + ) + + headers['User-Agent'] = USER_AGENT_HEADER + headers['X-Box-UA'] = X_BOX_UA_HEADER + return headers + + @staticmethod + def _prepare_body( + content_type: str, data: Union[dict, ByteStream] + ) -> Optional[Union[str, ByteStream]]: + if ( + content_type == 'application/json' + or content_type == 'application/json-patch+json' + ): + return sd_to_json(data) if data else None + if content_type == 'application/x-www-form-urlencoded': + return sd_to_url_params(data) + if ( + content_type == 'multipart/form-data' + or content_type == 'application/octet-stream' + ): + return data + raise + + def _make_request(self, request: APIRequest) -> APIResponse: + raised_exception = None + reauthentication_needed = False + default_timeout = (5, 60) # connect, read timeout + try: + network_response = self.requests_session.request( + method=request.method, + url=request.url, + headers=request.headers, + data=request.data, + params=request.params, + allow_redirects=request.allow_redirects, + stream=True, + timeout=default_timeout, + ) + except RequestException as request_exc: + raised_exception = request_exc + network_response = None + + if 'EOF occurred in violation of protocol' in str(request_exc): + reauthentication_needed = True + + return APIResponse( + network_response=network_response, + reauthentication_needed=reauthentication_needed, + raised_exception=raised_exception, + ) + + @staticmethod + def _raise_on_unsuccessful_request( + request: APIRequest, response: APIResponse, data_sanitizer: DataSanitizer + ) -> None: + if response.raised_exception: + raise BoxSDKError( + message=str(response.raised_exception), error=response.raised_exception + ) + + network_response = response.network_response + response_json = BoxNetworkClient._read_json_body(network_response.text) + + raise BoxAPIError( + message=f'{network_response.status_code} {response_json.get("message", "")}; Request ID: {response_json.get("request_id", "")}', + request_info=RequestInfo( + method=request.method, + url=request.url, + query_params=request.params, + headers=request.headers, + body=request.data, + ), + response_info=ResponseInfo( + status_code=network_response.status_code, + headers=dict(network_response.headers), + body=response_json, + raw_body=network_response.text, + code=response_json.get("code", None), + context_info=response_json.get("context_info", {}), + request_id=response_json.get("request_id", None), + help_url=response_json.get("help_url", None), + ), + data_sanitizer=data_sanitizer, + ) + + @staticmethod + def _get_multipart_stream_positions(options: 'FetchOptions') -> dict: + multipart_streams_positions = {} + if options.multipart_data: + for part in options.multipart_data: + if part.file_stream and part.file_stream.seekable(): + multipart_streams_positions[part.part_name] = ( + part.file_stream.tell() + ) + return multipart_streams_positions + + @staticmethod + def _get_options_stream_position(options: 'FetchOptions') -> int: + filestream_position = 0 + if options.file_stream and options.file_stream.seekable(): + filestream_position = options.file_stream.tell() + return filestream_position + + @staticmethod + def _validate_seekable(stream: ByteStream, raised_exception: Optional[Exception]): + if not stream.seekable(): + raise BoxSDKError( + message='Request with non-seekable stream cannot be retried', + error=raised_exception, + ) + + @staticmethod + def _read_json_body(response_body: str) -> dict: + if not response_body: + return {} + try: + return json_to_serialized_data(response_body) + except (ValueError, TypeError): + return {} + + def _reset_stream( + self, + stream: ByteStream, + original_position: int, + raised_exception: Optional[Exception], + ): + self._validate_seekable(stream, raised_exception) + stream.seek(original_position) + + def _reset_options_stream( + self, + options: 'FetchOptions', + filestream_position: int, + raised_exception: Optional[Exception], + ): + if options.file_stream: + self._reset_stream( + options.file_stream, filestream_position, raised_exception + ) + + def _reset_multipart_streams( + self, + options: 'FetchOptions', + multipart_streams_positions: dict, + raised_exception: Optional[Exception], + ): + if not options.multipart_data: + return + + for part in options.multipart_data: + if not part.file_stream: + continue + + position = multipart_streams_positions.get(part.part_name) + # we didn't get position before sending request hence the stream must be non-seekable + if position is None: + raise BoxSDKError( + message='Request with non-seekable stream cannot be retried', + error=raised_exception, + ) + + self._reset_stream( + part.file_stream, + multipart_streams_positions[part.part_name], + raised_exception, + ) diff --git a/box_sdk_gen/networking/fetch_options.py b/box_sdk_gen/networking/fetch_options.py new file mode 100644 index 000000000..59c0a1cb0 --- /dev/null +++ b/box_sdk_gen/networking/fetch_options.py @@ -0,0 +1,87 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +from enum import Enum + +from typing import Optional + +from typing import Dict + +from typing import List + +if TYPE_CHECKING: + from box_sdk_gen.networking.auth import Authentication + +if TYPE_CHECKING: + from box_sdk_gen.networking.network import NetworkSession + +from box_sdk_gen.serialization.json import SerializedData + +from box_sdk_gen.internal.utils import ByteStream + +class ResponseFormat(str, Enum): + JSON = 'json' + BINARY = 'binary' + NO_CONTENT = 'no_content' + +class MultipartItem: + def __init__(self, part_name: str, *, data: Optional[SerializedData] = None, file_stream: Optional[ByteStream] = None, file_name: Optional[str] = None, content_type: Optional[str] = None): + """ + :param part_name: Name of the part + :type part_name: str + :param data: Data of the part, defaults to None + :type data: Optional[SerializedData], optional + :param file_stream: File stream of the part, defaults to None + :type file_stream: Optional[ByteStream], optional + :param file_name: File name of the part, defaults to None + :type file_name: Optional[str], optional + :param content_type: Content type of the part, defaults to None + :type content_type: Optional[str], optional + """ + self.part_name = part_name + self.data = data + self.file_stream = file_stream + self.file_name = file_name + self.content_type = content_type + +class FetchOptions: + def __init__(self, url: str, method: str, *, params: Optional[Dict[str, str]] = None, headers: Optional[Dict[str, str]] = None, data: Optional[SerializedData] = None, file_stream: Optional[ByteStream] = None, multipart_data: Optional[List[MultipartItem]] = None, content_type: str = 'application/json', response_format: ResponseFormat = ResponseFormat.JSON, auth: Optional[Authentication] = None, network_session: Optional[NetworkSession] = None, follow_redirects: Optional[bool] = True): + """ + :param url: URL of the request + :type url: str + :param method: HTTP verb of the request + :type method: str + :param params: HTTP query parameters, defaults to None + :type params: Optional[Dict[str, str]], optional + :param headers: HTTP headers, defaults to None + :type headers: Optional[Dict[str, str]], optional + :param data: Request body of the request, defaults to None + :type data: Optional[SerializedData], optional + :param file_stream: Stream data of the request, defaults to None + :type file_stream: Optional[ByteStream], optional + :param multipart_data: Multipart data of the request, defaults to None + :type multipart_data: Optional[List[MultipartItem]], optional + :param content_type: Content type of the request body, defaults to 'application/json' + :type content_type: str, optional + :param response_format: Expected response format, defaults to ResponseFormat.JSON + :type response_format: ResponseFormat, optional + :param auth: Authentication object, defaults to None + :type auth: Optional[Authentication], optional + :param network_session: Network session object, defaults to None + :type network_session: Optional[NetworkSession], optional + :param follow_redirects: A boolean value indicate if the request should follow redirects. Defaults to True. Not supported in Browser environment., defaults to True + :type follow_redirects: Optional[bool], optional + """ + self.url = url + self.method = method + self.params = params + self.headers = headers + self.data = data + self.file_stream = file_stream + self.multipart_data = multipart_data + self.content_type = content_type + self.response_format = response_format + self.auth = auth + self.network_session = network_session + self.follow_redirects = follow_redirects \ No newline at end of file diff --git a/box_sdk_gen/networking/fetch_response.py b/box_sdk_gen/networking/fetch_response.py new file mode 100644 index 000000000..96442c39c --- /dev/null +++ b/box_sdk_gen/networking/fetch_response.py @@ -0,0 +1,27 @@ +from typing import Optional + +from typing import Dict + +from box_sdk_gen.serialization.json import SerializedData + +from box_sdk_gen.internal.utils import ByteStream + +class FetchResponse: + def __init__(self, status: int, headers: Dict[str, str], *, url: Optional[str] = None, data: Optional[SerializedData] = None, content: Optional[ByteStream] = None): + """ + :param status: HTTP status code of the response + :type status: int + :param headers: HTTP headers of the response + :type headers: Dict[str, str] + :param url: URL of the response, defaults to None + :type url: Optional[str], optional + :param data: Response body of the response, defaults to None + :type data: Optional[SerializedData], optional + :param content: Streamed content of the response, defaults to None + :type content: Optional[ByteStream], optional + """ + self.status = status + self.headers = headers + self.url = url + self.data = data + self.content = content \ No newline at end of file diff --git a/box_sdk_gen/networking/network.py b/box_sdk_gen/networking/network.py new file mode 100644 index 000000000..c51f8722e --- /dev/null +++ b/box_sdk_gen/networking/network.py @@ -0,0 +1,154 @@ +from typing import Dict + +from ..internal.logging import DataSanitizer +from .network_client import NetworkClient +from .box_network_client import BoxNetworkClient +from .proxy_config import ProxyConfig +from .base_urls import BaseUrls +from .retries import RetryStrategy, BoxRetryStrategy + + +class NetworkSession: + def __init__( + self, + *, + network_client: NetworkClient = None, + retry_strategy: RetryStrategy = None, + additional_headers: Dict[str, str] = None, + base_urls: BaseUrls = None, + proxy_url: str = None, + data_sanitizer: DataSanitizer = None, + ): + if additional_headers is None: + additional_headers = {} + if base_urls is None: + base_urls = BaseUrls() + if retry_strategy is None: + retry_strategy = BoxRetryStrategy() + if network_client is None: + network_client = BoxNetworkClient() + if ( + proxy_url + and hasattr(network_client, 'requests_session') + and network_client.requests_session + ): + network_client.requests_session.proxies = { + 'http': proxy_url, + 'https': proxy_url, + } + if data_sanitizer is None: + data_sanitizer = DataSanitizer() + self.additional_headers = additional_headers + self.base_urls = base_urls + self.proxy_url = proxy_url + self.network_client = network_client + self.retry_strategy = retry_strategy + self.data_sanitizer = data_sanitizer + + def with_additional_headers( + self, additional_headers: Dict[str, str] = None + ) -> 'NetworkSession': + """ + Generate a fresh network session by duplicating the existing configuration and network parameters, + while also including additional headers to be attached to every API call. + :param additional_headers: Dict of headers, which are appended to each API request + :return: a new instance of NetworkSession + """ + return NetworkSession( + network_client=self.network_client, + additional_headers={**self.additional_headers, **additional_headers}, + base_urls=self.base_urls, + proxy_url=self.proxy_url, + retry_strategy=self.retry_strategy, + data_sanitizer=self.data_sanitizer, + ) + + def with_custom_base_urls(self, base_urls: BaseUrls) -> 'NetworkSession': + """ + Generate a fresh network session by duplicating the existing configuration and network parameters, + while also including additional base urls to be used for each API call. + :param base_urls: Dict of base urls, which are appended to each API request + :return: a new instance of NetworkSession + """ + return NetworkSession( + network_client=self.network_client, + additional_headers=self.additional_headers, + base_urls=base_urls, + proxy_url=self.proxy_url, + retry_strategy=self.retry_strategy, + data_sanitizer=self.data_sanitizer, + ) + + def with_proxy(self, config: ProxyConfig) -> 'NetworkSession': + """ + Generate a fresh network session by duplicating the existing configuration and network parameters, + while also including a proxy to be used for each API call. + :param config: ProxyConfig object, which contains the proxy url, username, and password + :return: a new instance of NetworkSession + """ + if not config.url or not config.url.startswith("http"): + raise ValueError("Invalid proxy URL provided") + + proxy_host = config.url.split("//")[1] + proxy_auth = ( + f"{config.username}:{config.password}@" + if config.username and config.password + else "" + ) + proxy_url = f"http://{proxy_auth}{proxy_host}" + return NetworkSession( + network_client=self.network_client, + additional_headers=self.additional_headers, + base_urls=self.base_urls, + proxy_url=proxy_url, + retry_strategy=self.retry_strategy, + data_sanitizer=self.data_sanitizer, + ) + + def with_network_client(self, network_client: NetworkClient) -> 'NetworkSession': + """ + Generate a fresh network session by duplicating the existing configuration and network parameters, + while also including a new network client to be used for each API call. + :param network_client: NetworkClient object, which contains the fetch method + :return: a new instance of NetworkSession + """ + return NetworkSession( + network_client=network_client, + additional_headers=self.additional_headers, + base_urls=self.base_urls, + proxy_url=self.proxy_url, + retry_strategy=self.retry_strategy, + data_sanitizer=self.data_sanitizer, + ) + + def with_retry_strategy(self, retry_strategy: RetryStrategy) -> 'NetworkSession': + """ + Generate a fresh network session by duplicating the existing configuration and network parameters, + while also including a new retry options to be used for each API call. + :param retry_strategy: RetryStrategy object, which contains the retry logic + :return: a new instance of NetworkSession + """ + return NetworkSession( + network_client=self.network_client, + additional_headers=self.additional_headers, + base_urls=self.base_urls, + proxy_url=self.proxy_url, + retry_strategy=retry_strategy, + data_sanitizer=self.data_sanitizer, + ) + + def with_data_sanitizer(self, data_sanitizer: DataSanitizer) -> 'NetworkSession': + """ + Generate a fresh network session by duplicating the existing configuration and network parameters, + while also applying data sanitizer to sanitize sensitive data for logging. + :param data_sanitizer: + :return: + """ + return NetworkSession( + network_client=self.network_client, + additional_headers=self.additional_headers, + base_urls=self.base_urls, + proxy_url=self.proxy_url, + retry_strategy=self.retry_strategy, + data_sanitizer=data_sanitizer, + ) diff --git a/box_sdk_gen/networking/network_client.py b/box_sdk_gen/networking/network_client.py new file mode 100644 index 000000000..15800f80d --- /dev/null +++ b/box_sdk_gen/networking/network_client.py @@ -0,0 +1,12 @@ +from abc import abstractmethod + +from box_sdk_gen.networking.fetch_options import FetchOptions + +from box_sdk_gen.networking.fetch_response import FetchResponse + +class NetworkClient: + def __init__(self): + pass + @abstractmethod + def fetch(self, options: FetchOptions) -> FetchResponse: + pass \ No newline at end of file diff --git a/box_sdk_gen/networking/proxy_config.py b/box_sdk_gen/networking/proxy_config.py new file mode 100644 index 000000000..4fb9f5e2a --- /dev/null +++ b/box_sdk_gen/networking/proxy_config.py @@ -0,0 +1,7 @@ +from typing import Optional + +class ProxyConfig: + def __init__(self, url: str, *, username: Optional[str] = None, password: Optional[str] = None): + self.url = url + self.username = username + self.password = password \ No newline at end of file diff --git a/box_sdk_gen/networking/retries.py b/box_sdk_gen/networking/retries.py new file mode 100644 index 000000000..b32d07d98 --- /dev/null +++ b/box_sdk_gen/networking/retries.py @@ -0,0 +1,49 @@ +from abc import abstractmethod + +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 random + +class RetryStrategy: + def __init__(self): + pass + @abstractmethod + def should_retry(self, fetch_options: FetchOptions, fetch_response: FetchResponse, attempt_number: int) -> bool: + pass + @abstractmethod + def retry_after(self, fetch_options: FetchOptions, fetch_response: FetchResponse, attempt_number: int) -> float: + pass + +class BoxRetryStrategy(RetryStrategy): + def __init__(self, *, max_attempts: int = 5, retry_randomization_factor: float = 0.5, retry_base_interval: float = 1, **kwargs): + super().__init__(**kwargs) + self.max_attempts = max_attempts + self.retry_randomization_factor = retry_randomization_factor + self.retry_base_interval = retry_base_interval + def should_retry(self, fetch_options: FetchOptions, fetch_response: FetchResponse, attempt_number: int) -> bool: + is_successful: bool = fetch_response.status >= 200 and fetch_response.status < 400 + retry_after_header: str = fetch_response.headers.get('Retry-After') + is_accepted_with_retry_after: bool = fetch_response.status == 202 and not retry_after_header == None + if attempt_number >= self.max_attempts: + return False + if is_accepted_with_retry_after: + return True + if fetch_response.status >= 500: + return True + if fetch_response.status == 429: + return True + if fetch_response.status == 401 and not fetch_options.auth == None: + fetch_options.auth.refresh_token(network_session=fetch_options.network_session) + return True + if is_successful: + return False + return False + def retry_after(self, fetch_options: FetchOptions, fetch_response: FetchResponse, attempt_number: int) -> float: + retry_after_header: str = fetch_response.headers.get('Retry-After') + if not retry_after_header == None: + return float(retry_after_header) + randomization: float = random(1 - self.retry_randomization_factor, 1 + self.retry_randomization_factor) + exponential: float = 2 ** attempt_number + return (exponential * self.retry_base_interval) * randomization \ No newline at end of file diff --git a/box_sdk_gen/networking/version.py b/box_sdk_gen/networking/version.py new file mode 100644 index 000000000..541f859dc --- /dev/null +++ b/box_sdk_gen/networking/version.py @@ -0,0 +1 @@ +__version__ = '0.1.0' \ No newline at end of file diff --git a/box_sdk_gen/parameters/__init__.py b/box_sdk_gen/parameters/__init__.py new file mode 100644 index 000000000..dc396edb3 --- /dev/null +++ b/box_sdk_gen/parameters/__init__.py @@ -0,0 +1 @@ +from box_sdk_gen.parameters.v2025_r0 import * \ No newline at end of file diff --git a/box_sdk_gen/parameters/v2025_r0/__init__.py b/box_sdk_gen/parameters/v2025_r0/__init__.py new file mode 100644 index 000000000..d66df409e --- /dev/null +++ b/box_sdk_gen/parameters/v2025_r0/__init__.py @@ -0,0 +1 @@ +from box_sdk_gen.parameters.v2025_r0.box_version_header_v2025_r0 import * \ No newline at end of file diff --git a/box_sdk_gen/parameters/v2025_r0/box_version_header_v2025_r0.py b/box_sdk_gen/parameters/v2025_r0/box_version_header_v2025_r0.py new file mode 100644 index 000000000..23535d46f --- /dev/null +++ b/box_sdk_gen/parameters/v2025_r0/box_version_header_v2025_r0.py @@ -0,0 +1,6 @@ +from enum import Enum + +from box_sdk_gen.box.errors import BoxSDKError + +class BoxVersionHeaderV2025R0(str, Enum): + _2025_0 = '2025.0' \ No newline at end of file diff --git a/box_sdk_gen/schemas/__init__.py b/box_sdk_gen/schemas/__init__.py new file mode 100644 index 000000000..8b12c8d9a --- /dev/null +++ b/box_sdk_gen/schemas/__init__.py @@ -0,0 +1,515 @@ +from box_sdk_gen.schemas.ai_agent_info import * + +from box_sdk_gen.schemas.ai_response import * + +from box_sdk_gen.schemas.ai_agent_reference import * + +from box_sdk_gen.schemas.ai_citation import * + +from box_sdk_gen.schemas.ai_response_full import * + +from box_sdk_gen.schemas.ai_dialogue_history import * + +from box_sdk_gen.schemas.ai_extract_response import * + +from box_sdk_gen.schemas.ai_extract_structured_response import * + +from box_sdk_gen.schemas.ai_item_base import * + +from box_sdk_gen.schemas.ai_item_ask import * + +from box_sdk_gen.schemas.ai_llm_endpoint_params_aws import * + +from box_sdk_gen.schemas.ai_llm_endpoint_params_google import * + +from box_sdk_gen.schemas.ai_llm_endpoint_params_ibm import * + +from box_sdk_gen.schemas.ai_llm_endpoint_params_open_ai import * + +from box_sdk_gen.schemas.ai_llm_endpoint_params import * + +from box_sdk_gen.schemas.ai_agent_basic_text_tool_base import * + +from box_sdk_gen.schemas.ai_agent_basic_text_tool_text_gen import * + +from box_sdk_gen.schemas.ai_agent_long_text_tool_text_gen import * + +from box_sdk_gen.schemas.ai_agent_basic_gen_tool import * + +from box_sdk_gen.schemas.ai_studio_agent_basic_gen_tool import * + +from box_sdk_gen.schemas.ai_studio_agent_text_gen import * + +from box_sdk_gen.schemas.ai_studio_agent_basic_gen_tool_response import * + +from box_sdk_gen.schemas.ai_studio_agent_text_gen_response import * + +from box_sdk_gen.schemas.ai_agent_text_gen import * + +from box_sdk_gen.schemas.ai_text_gen import * + +from box_sdk_gen.schemas.ai_agent_basic_text_tool import * + +from box_sdk_gen.schemas.ai_studio_agent_basic_text_tool import * + +from box_sdk_gen.schemas.ai_studio_agent_basic_text_tool_response import * + +from box_sdk_gen.schemas.ai_agent_long_text_tool import * + +from box_sdk_gen.schemas.ai_studio_agent_long_text_tool import * + +from box_sdk_gen.schemas.ai_studio_agent_long_text_tool_response import * + +from box_sdk_gen.schemas.ai_studio_agent_extract_response import * + +from box_sdk_gen.schemas.ai_studio_agent_ask_response import * + +from box_sdk_gen.schemas.ai_studio_agent_extract import * + +from box_sdk_gen.schemas.ai_studio_agent_ask import * + +from box_sdk_gen.schemas.ai_agent_extract_structured import * + +from box_sdk_gen.schemas.ai_extract_structured import * + +from box_sdk_gen.schemas.ai_agent_extract import * + +from box_sdk_gen.schemas.ai_extract import * + +from box_sdk_gen.schemas.ai_agent_ask import * + +from box_sdk_gen.schemas.ai_ask import * + +from box_sdk_gen.schemas.app_item import * + +from box_sdk_gen.schemas.classification import * + +from box_sdk_gen.schemas.classification_template import * + +from box_sdk_gen.schemas.client_error import * + +from box_sdk_gen.schemas.collaboration_allowlist_entry import * + +from box_sdk_gen.schemas.collaboration_allowlist_entries import * + +from box_sdk_gen.schemas.collaborator_variable import * + +from box_sdk_gen.schemas.collection import * + +from box_sdk_gen.schemas.collections import * + +from box_sdk_gen.schemas.comment_base import * + +from box_sdk_gen.schemas.completion_rule_variable import * + +from box_sdk_gen.schemas.email_alias import * + +from box_sdk_gen.schemas.email_aliases import * + +from box_sdk_gen.schemas.enterprise_base import * + +from box_sdk_gen.schemas.file_base import * + +from box_sdk_gen.schemas.file_request_update_request import * + +from box_sdk_gen.schemas.file_request_copy_request import * + +from box_sdk_gen.schemas.file_version_base import * + +from box_sdk_gen.schemas.file_version_mini import * + +from box_sdk_gen.schemas.file_mini import * + +from box_sdk_gen.schemas.files_under_retention import * + +from box_sdk_gen.schemas.files_on_hold import * + +from box_sdk_gen.schemas.file_conflict import * + +from box_sdk_gen.schemas.conflict_error import * + +from box_sdk_gen.schemas.folder_base import * + +from box_sdk_gen.schemas.folder_mini import * + +from box_sdk_gen.schemas.file_or_folder_scope import * + +from box_sdk_gen.schemas.access_token import * + +from box_sdk_gen.schemas.folder_reference import * + +from box_sdk_gen.schemas.generic_source import * + +from box_sdk_gen.schemas.group_base import * + +from box_sdk_gen.schemas.group_mini import * + +from box_sdk_gen.schemas.group import * + +from box_sdk_gen.schemas.group_full import * + +from box_sdk_gen.schemas.groups import * + +from box_sdk_gen.schemas.integration_mapping_base import * + +from box_sdk_gen.schemas.integration_mapping_box_item_slack import * + +from box_sdk_gen.schemas.integration_mapping_partner_item_slack import * + +from box_sdk_gen.schemas.integration_mapping_partner_item_teams import * + +from box_sdk_gen.schemas.integration_mapping_teams import * + +from box_sdk_gen.schemas.integration_mappings_teams import * + +from box_sdk_gen.schemas.integration_mapping_partner_item_teams_create_request import * + +from box_sdk_gen.schemas.integration_mapping_teams_create_request import * + +from box_sdk_gen.schemas.integration_mapping_slack_options import * + +from box_sdk_gen.schemas.integration_mapping_slack_create_request import * + +from box_sdk_gen.schemas.keyword_skill_card import * + +from box_sdk_gen.schemas.legal_hold_policy_mini import * + +from box_sdk_gen.schemas.legal_hold_policy_assignment_base import * + +from box_sdk_gen.schemas.metadata_base import * + +from box_sdk_gen.schemas.metadata import * + +from box_sdk_gen.schemas.metadatas import * + +from box_sdk_gen.schemas.metadata_full import * + +from box_sdk_gen.schemas.metadata_cascade_policy import * + +from box_sdk_gen.schemas.metadata_cascade_policies import * + +from box_sdk_gen.schemas.metadata_field_filter_date_range import * + +from box_sdk_gen.schemas.metadata_field_filter_float_range import * + +from box_sdk_gen.schemas.metadata_filter import * + +from box_sdk_gen.schemas.metadata_instance_value import * + +from box_sdk_gen.schemas.metadata_query import * + +from box_sdk_gen.schemas.metadata_query_index import * + +from box_sdk_gen.schemas.metadata_template import * + +from box_sdk_gen.schemas.metadata_templates import * + +from box_sdk_gen.schemas.o_auth_2_error import * + +from box_sdk_gen.schemas.post_o_auth_2_revoke import * + +from box_sdk_gen.schemas.post_o_auth_2_token import * + +from box_sdk_gen.schemas.post_o_auth_2_token_refresh_access_token import * + +from box_sdk_gen.schemas.realtime_server import * + +from box_sdk_gen.schemas.realtime_servers import * + +from box_sdk_gen.schemas.retention_policy_base import * + +from box_sdk_gen.schemas.retention_policy_mini import * + +from box_sdk_gen.schemas.file_version_retention import * + +from box_sdk_gen.schemas.file_version_retentions import * + +from box_sdk_gen.schemas.retention_policy_assignment_base import * + +from box_sdk_gen.schemas.role_variable import * + +from box_sdk_gen.schemas.outcome import * + +from box_sdk_gen.schemas.session_termination_message import * + +from box_sdk_gen.schemas.shield_information_barrier_base import * + +from box_sdk_gen.schemas.shield_information_barrier_reference import * + +from box_sdk_gen.schemas.shield_information_barrier_report_base import * + +from box_sdk_gen.schemas.shield_information_barrier_report_details import * + +from box_sdk_gen.schemas.shield_information_barrier_segment_member_base import * + +from box_sdk_gen.schemas.shield_information_barrier_segment_restriction_base import * + +from box_sdk_gen.schemas.shield_information_barrier_segment_restriction_mini import * + +from box_sdk_gen.schemas.sign_request_create_signer import * + +from box_sdk_gen.schemas.sign_request_prefill_tag import * + +from box_sdk_gen.schemas.template_signer_input import * + +from box_sdk_gen.schemas.template_signer import * + +from box_sdk_gen.schemas.sign_template import * + +from box_sdk_gen.schemas.sign_templates import * + +from box_sdk_gen.schemas.sign_request_signer_input import * + +from box_sdk_gen.schemas.sign_request_signer import * + +from box_sdk_gen.schemas.sign_request_base import * + +from box_sdk_gen.schemas.sign_request_create_request import * + +from box_sdk_gen.schemas.sign_request import * + +from box_sdk_gen.schemas.sign_requests import * + +from box_sdk_gen.schemas.status_skill_card import * + +from box_sdk_gen.schemas.storage_policy_mini import * + +from box_sdk_gen.schemas.storage_policy_assignment import * + +from box_sdk_gen.schemas.storage_policy_assignments import * + +from box_sdk_gen.schemas.storage_policy import * + +from box_sdk_gen.schemas.storage_policies import * + +from box_sdk_gen.schemas.terms_of_service_base import * + +from box_sdk_gen.schemas.terms_of_service import * + +from box_sdk_gen.schemas.terms_of_services import * + +from box_sdk_gen.schemas.timeline_skill_card import * + +from box_sdk_gen.schemas.tracking_code import * + +from box_sdk_gen.schemas.transcript_skill_card import * + +from box_sdk_gen.schemas.skill_cards_metadata import * + +from box_sdk_gen.schemas.upload_part_mini import * + +from box_sdk_gen.schemas.upload_part import * + +from box_sdk_gen.schemas.uploaded_part import * + +from box_sdk_gen.schemas.upload_parts import * + +from box_sdk_gen.schemas.upload_session import * + +from box_sdk_gen.schemas.upload_url import * + +from box_sdk_gen.schemas.user_base import * + +from box_sdk_gen.schemas.user_integration_mappings import * + +from box_sdk_gen.schemas.integration_mapping import * + +from box_sdk_gen.schemas.integration_mappings import * + +from box_sdk_gen.schemas.user_mini import * + +from box_sdk_gen.schemas.user import * + +from box_sdk_gen.schemas.user_full import * + +from box_sdk_gen.schemas.users import * + +from box_sdk_gen.schemas.trash_web_link_restored import * + +from box_sdk_gen.schemas.trash_web_link import * + +from box_sdk_gen.schemas.trash_folder_restored import * + +from box_sdk_gen.schemas.trash_folder import * + +from box_sdk_gen.schemas.trash_file_restored import * + +from box_sdk_gen.schemas.trash_file import * + +from box_sdk_gen.schemas.terms_of_service_user_status import * + +from box_sdk_gen.schemas.terms_of_service_user_statuses import * + +from box_sdk_gen.schemas.task_assignment import * + +from box_sdk_gen.schemas.task_assignments import * + +from box_sdk_gen.schemas.task import * + +from box_sdk_gen.schemas.tasks import * + +from box_sdk_gen.schemas.retention_policy_assignment import * + +from box_sdk_gen.schemas.retention_policy_assignments import * + +from box_sdk_gen.schemas.retention_policy import * + +from box_sdk_gen.schemas.retention_policies import * + +from box_sdk_gen.schemas.legal_hold_policy import * + +from box_sdk_gen.schemas.legal_hold_policies import * + +from box_sdk_gen.schemas.invite import * + +from box_sdk_gen.schemas.group_membership import * + +from box_sdk_gen.schemas.group_memberships import * + +from box_sdk_gen.schemas.file_version import * + +from box_sdk_gen.schemas.file_version_full import * + +from box_sdk_gen.schemas.file_versions import * + +from box_sdk_gen.schemas.file_request import * + +from box_sdk_gen.schemas.file import * + +from box_sdk_gen.schemas.file_full import * + +from box_sdk_gen.schemas.files import * + +from box_sdk_gen.schemas.event_source import * + +from box_sdk_gen.schemas.device_pinner import * + +from box_sdk_gen.schemas.device_pinners import * + +from box_sdk_gen.schemas.comment import * + +from box_sdk_gen.schemas.comment_full import * + +from box_sdk_gen.schemas.comments import * + +from box_sdk_gen.schemas.collaboration_allowlist_exempt_target import * + +from box_sdk_gen.schemas.collaboration_allowlist_exempt_targets import * + +from box_sdk_gen.schemas.app_item_event_source import * + +from box_sdk_gen.schemas.user_collaborations import * + +from box_sdk_gen.schemas.shield_information_barrier_segment_restriction import * + +from box_sdk_gen.schemas.shield_information_barrier_segment_restrictions import * + +from box_sdk_gen.schemas.shield_information_barrier_segment_member_mini import * + +from box_sdk_gen.schemas.shield_information_barrier_segment_member import * + +from box_sdk_gen.schemas.shield_information_barrier_segment_members import * + +from box_sdk_gen.schemas.shield_information_barrier_segment import * + +from box_sdk_gen.schemas.shield_information_barrier_segments import * + +from box_sdk_gen.schemas.shield_information_barrier_report import * + +from box_sdk_gen.schemas.shield_information_barrier_reports import * + +from box_sdk_gen.schemas.shield_information_barrier import * + +from box_sdk_gen.schemas.shield_information_barriers import * + +from box_sdk_gen.schemas.folder_lock import * + +from box_sdk_gen.schemas.folder_locks import * + +from box_sdk_gen.schemas.ai_agent_allowed_entity import * + +from box_sdk_gen.schemas.create_ai_agent import * + +from box_sdk_gen.schemas.ai_single_agent_response import * + +from box_sdk_gen.schemas.ai_single_agent_response_full import * + +from box_sdk_gen.schemas.ai_multiple_agent_response import * + +from box_sdk_gen.schemas.user_avatar import * + +from box_sdk_gen.schemas.watermark import * + +from box_sdk_gen.schemas.web_link_base import * + +from box_sdk_gen.schemas.web_link_mini import * + +from box_sdk_gen.schemas.web_link import * + +from box_sdk_gen.schemas.items_offset_paginated import * + +from box_sdk_gen.schemas.items import * + +from box_sdk_gen.schemas.folder import * + +from box_sdk_gen.schemas.legal_hold_policy_assignment import * + +from box_sdk_gen.schemas.legal_hold_policy_assignments import * + +from box_sdk_gen.schemas.file_version_legal_hold import * + +from box_sdk_gen.schemas.file_version_legal_holds import * + +from box_sdk_gen.schemas.folder_full import * + +from box_sdk_gen.schemas.search_results import * + +from box_sdk_gen.schemas.search_result_with_shared_link import * + +from box_sdk_gen.schemas.search_results_with_shared_links import * + +from box_sdk_gen.schemas.recent_item import * + +from box_sdk_gen.schemas.recent_items import * + +from box_sdk_gen.schemas.metadata_query_results import * + +from box_sdk_gen.schemas.event import * + +from box_sdk_gen.schemas.skill_invocation import * + +from box_sdk_gen.schemas.events import * + +from box_sdk_gen.schemas.collaboration import * + +from box_sdk_gen.schemas.collaborations_offset_paginated import * + +from box_sdk_gen.schemas.collaborations import * + +from box_sdk_gen.schemas.app_item_association import * + +from box_sdk_gen.schemas.app_item_associations import * + +from box_sdk_gen.schemas.webhook_mini import * + +from box_sdk_gen.schemas.webhooks import * + +from box_sdk_gen.schemas.webhook import * + +from box_sdk_gen.schemas.webhook_invocation import * + +from box_sdk_gen.schemas.workflow_mini import * + +from box_sdk_gen.schemas.workflow import * + +from box_sdk_gen.schemas.workflows import * + +from box_sdk_gen.schemas.workflow_full import * + +from box_sdk_gen.schemas.zip_download import * + +from box_sdk_gen.schemas.zip_download_request import * + +from box_sdk_gen.schemas.zip_download_status import * + +from box_sdk_gen.schemas.v2025_r0 import * \ No newline at end of file diff --git a/box_sdk_gen/schemas/access_token.py b/box_sdk_gen/schemas/access_token.py new file mode 100644 index 000000000..acb791373 --- /dev/null +++ b/box_sdk_gen/schemas/access_token.py @@ -0,0 +1,45 @@ +from enum import Enum + +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.file_or_folder_scope import FileOrFolderScope + +from box_sdk_gen.box.errors import BoxSDKError + +class AccessTokenTokenTypeField(str, Enum): + BEARER = 'bearer' + +class AccessTokenIssuedTokenTypeField(str, Enum): + URN_IETF_PARAMS_OAUTH_TOKEN_TYPE_ACCESS_TOKEN = 'urn:ietf:params:oauth:token-type:access_token' + +class AccessToken(BaseObject): + def __init__(self, *, access_token: Optional[str] = None, expires_in: Optional[int] = None, token_type: Optional[AccessTokenTokenTypeField] = None, restricted_to: Optional[List[FileOrFolderScope]] = None, refresh_token: Optional[str] = None, issued_token_type: Optional[AccessTokenIssuedTokenTypeField] = None, **kwargs): + """ + :param access_token: The requested access token., defaults to None + :type access_token: Optional[str], optional + :param expires_in: The time in seconds by which this token will expire., defaults to None + :type expires_in: Optional[int], optional + :param token_type: The type of access token returned., defaults to None + :type token_type: Optional[AccessTokenTokenTypeField], optional + :param restricted_to: The permissions that this access token permits, +providing a list of resources (files, folders, etc) +and the scopes permitted for each of those resources., defaults to None + :type restricted_to: Optional[List[FileOrFolderScope]], optional + :param refresh_token: The refresh token for this access token, which can be used +to request a new access token when the current one expires., defaults to None + :type refresh_token: Optional[str], optional + :param issued_token_type: The type of downscoped access token returned. This is only +returned if an access token has been downscoped., defaults to None + :type issued_token_type: Optional[AccessTokenIssuedTokenTypeField], optional + """ + super().__init__(**kwargs) + self.access_token = access_token + self.expires_in = expires_in + self.token_type = token_type + self.restricted_to = restricted_to + self.refresh_token = refresh_token + self.issued_token_type = issued_token_type \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_agent_allowed_entity.py b/box_sdk_gen/schemas/ai_agent_allowed_entity.py new file mode 100644 index 000000000..92f33dd62 --- /dev/null +++ b/box_sdk_gen/schemas/ai_agent_allowed_entity.py @@ -0,0 +1,9 @@ +from typing import Union + +from box_sdk_gen.schemas.user_base import UserBase + +from box_sdk_gen.schemas.group_base import GroupBase + +from box_sdk_gen.box.errors import BoxSDKError + +AiAgentAllowedEntity = Union[UserBase, GroupBase] \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_agent_ask.py b/box_sdk_gen/schemas/ai_agent_ask.py new file mode 100644 index 000000000..458ca2792 --- /dev/null +++ b/box_sdk_gen/schemas/ai_agent_ask.py @@ -0,0 +1,30 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.ai_agent_long_text_tool import AiAgentLongTextTool + +from box_sdk_gen.schemas.ai_agent_basic_text_tool import AiAgentBasicTextTool + +from box_sdk_gen.box.errors import BoxSDKError + +class AiAgentAskTypeField(str, Enum): + AI_AGENT_ASK = 'ai_agent_ask' + +class AiAgentAsk(BaseObject): + _discriminator = 'type', {'ai_agent_ask'} + def __init__(self, *, type: AiAgentAskTypeField = AiAgentAskTypeField.AI_AGENT_ASK, long_text: Optional[AiAgentLongTextTool] = None, basic_text: Optional[AiAgentBasicTextTool] = None, long_text_multi: Optional[AiAgentLongTextTool] = None, basic_text_multi: Optional[AiAgentBasicTextTool] = None, basic_image: Optional[AiAgentBasicTextTool] = None, basic_image_multi: Optional[AiAgentBasicTextTool] = None, **kwargs): + """ + :param type: The type of AI agent used to handle queries., defaults to AiAgentAskTypeField.AI_AGENT_ASK + :type type: AiAgentAskTypeField, optional + """ + super().__init__(**kwargs) + self.type = type + self.long_text = long_text + self.basic_text = basic_text + self.long_text_multi = long_text_multi + self.basic_text_multi = basic_text_multi + self.basic_image = basic_image + self.basic_image_multi = basic_image_multi \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_agent_basic_gen_tool.py b/box_sdk_gen/schemas/ai_agent_basic_gen_tool.py new file mode 100644 index 000000000..03ccef548 --- /dev/null +++ b/box_sdk_gen/schemas/ai_agent_basic_gen_tool.py @@ -0,0 +1,35 @@ +from typing import Optional + +from box_sdk_gen.schemas.ai_llm_endpoint_params import AiLlmEndpointParams + +from box_sdk_gen.schemas.ai_agent_basic_text_tool_base import AiAgentBasicTextToolBase + +from box_sdk_gen.schemas.ai_agent_basic_text_tool_text_gen import AiAgentBasicTextToolTextGen + +from box_sdk_gen.schemas.ai_agent_long_text_tool_text_gen import AiAgentLongTextToolTextGenEmbeddingsField + +from box_sdk_gen.schemas.ai_agent_long_text_tool_text_gen import AiAgentLongTextToolTextGen + +from box_sdk_gen.box.errors import BoxSDKError + +class AiAgentBasicGenTool(AiAgentLongTextToolTextGen): + def __init__(self, *, content_template: Optional[str] = None, embeddings: Optional[AiAgentLongTextToolTextGenEmbeddingsField] = None, system_message: Optional[str] = None, prompt_template: Optional[str] = None, model: Optional[str] = None, num_tokens_for_completion: Optional[int] = None, llm_endpoint_params: Optional[AiLlmEndpointParams] = None, **kwargs): + """ + :param content_template: How the content should be included in a request to the LLM. +Input for `{content}` is optional, depending on the use., defaults to None + :type content_template: Optional[str], optional + :param system_message: System messages aim at helping the LLM understand its role and what it is supposed to do. +The input for `{current_date}` is optional, depending on the use., defaults to None + :type system_message: Optional[str], optional + :param prompt_template: The prompt template contains contextual information of the request and the user prompt. + +When using the `prompt_template` parameter, you **must include** input for `{user_question}`. +Inputs for `{current_date}` and `{content}` are optional, depending on the use., defaults to None + :type prompt_template: Optional[str], optional + :param model: The model used for the AI agent for basic text. For specific model values, see the [available models list](g://box-ai/supported-models)., defaults to None + :type model: Optional[str], optional + :param num_tokens_for_completion: The number of tokens for completion., defaults to None + :type num_tokens_for_completion: Optional[int], optional + """ + super().__init__(embeddings=embeddings, system_message=system_message, prompt_template=prompt_template, model=model, num_tokens_for_completion=num_tokens_for_completion, llm_endpoint_params=llm_endpoint_params, **kwargs) + self.content_template = content_template \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_agent_basic_text_tool.py b/box_sdk_gen/schemas/ai_agent_basic_text_tool.py new file mode 100644 index 000000000..cc7bc46c4 --- /dev/null +++ b/box_sdk_gen/schemas/ai_agent_basic_text_tool.py @@ -0,0 +1,25 @@ +from typing import Optional + +from box_sdk_gen.schemas.ai_llm_endpoint_params import AiLlmEndpointParams + +from box_sdk_gen.schemas.ai_agent_basic_text_tool_base import AiAgentBasicTextToolBase + +from box_sdk_gen.box.errors import BoxSDKError + +class AiAgentBasicTextTool(AiAgentBasicTextToolBase): + def __init__(self, *, system_message: Optional[str] = None, prompt_template: Optional[str] = None, model: Optional[str] = None, num_tokens_for_completion: Optional[int] = None, llm_endpoint_params: Optional[AiLlmEndpointParams] = None, **kwargs): + """ + :param system_message: System messages try to help the LLM "understand" its role and what it is supposed to do., defaults to None + :type system_message: Optional[str], optional + :param prompt_template: The prompt template contains contextual information of the request and the user prompt. +When passing `prompt_template` parameters, you **must include** inputs for `{user_question}` and `{content}`. +`{current_date}` is optional, depending on the use., defaults to None + :type prompt_template: Optional[str], optional + :param model: The model used for the AI agent for basic text. For specific model values, see the [available models list](g://box-ai/supported-models)., defaults to None + :type model: Optional[str], optional + :param num_tokens_for_completion: The number of tokens for completion., defaults to None + :type num_tokens_for_completion: Optional[int], optional + """ + super().__init__(model=model, num_tokens_for_completion=num_tokens_for_completion, llm_endpoint_params=llm_endpoint_params, **kwargs) + self.system_message = system_message + self.prompt_template = prompt_template \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_agent_basic_text_tool_base.py b/box_sdk_gen/schemas/ai_agent_basic_text_tool_base.py new file mode 100644 index 000000000..e283c3113 --- /dev/null +++ b/box_sdk_gen/schemas/ai_agent_basic_text_tool_base.py @@ -0,0 +1,20 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.ai_llm_endpoint_params import AiLlmEndpointParams + +from box_sdk_gen.box.errors import BoxSDKError + +class AiAgentBasicTextToolBase(BaseObject): + def __init__(self, *, model: Optional[str] = None, num_tokens_for_completion: Optional[int] = None, llm_endpoint_params: Optional[AiLlmEndpointParams] = None, **kwargs): + """ + :param model: The model used for the AI agent for basic text. For specific model values, see the [available models list](g://box-ai/supported-models)., defaults to None + :type model: Optional[str], optional + :param num_tokens_for_completion: The number of tokens for completion., defaults to None + :type num_tokens_for_completion: Optional[int], optional + """ + super().__init__(**kwargs) + self.model = model + self.num_tokens_for_completion = num_tokens_for_completion + self.llm_endpoint_params = llm_endpoint_params \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_agent_basic_text_tool_text_gen.py b/box_sdk_gen/schemas/ai_agent_basic_text_tool_text_gen.py new file mode 100644 index 000000000..fab89fc4b --- /dev/null +++ b/box_sdk_gen/schemas/ai_agent_basic_text_tool_text_gen.py @@ -0,0 +1,27 @@ +from typing import Optional + +from box_sdk_gen.schemas.ai_llm_endpoint_params import AiLlmEndpointParams + +from box_sdk_gen.schemas.ai_agent_basic_text_tool_base import AiAgentBasicTextToolBase + +from box_sdk_gen.box.errors import BoxSDKError + +class AiAgentBasicTextToolTextGen(AiAgentBasicTextToolBase): + def __init__(self, *, system_message: Optional[str] = None, prompt_template: Optional[str] = None, model: Optional[str] = None, num_tokens_for_completion: Optional[int] = None, llm_endpoint_params: Optional[AiLlmEndpointParams] = None, **kwargs): + """ + :param system_message: System messages aim at helping the LLM understand its role and what it is supposed to do. +The input for `{current_date}` is optional, depending on the use., defaults to None + :type system_message: Optional[str], optional + :param prompt_template: The prompt template contains contextual information of the request and the user prompt. + +When using the `prompt_template` parameter, you **must include** input for `{user_question}`. +Inputs for `{current_date}` and `{content}` are optional, depending on the use., defaults to None + :type prompt_template: Optional[str], optional + :param model: The model used for the AI agent for basic text. For specific model values, see the [available models list](g://box-ai/supported-models)., defaults to None + :type model: Optional[str], optional + :param num_tokens_for_completion: The number of tokens for completion., defaults to None + :type num_tokens_for_completion: Optional[int], optional + """ + super().__init__(model=model, num_tokens_for_completion=num_tokens_for_completion, llm_endpoint_params=llm_endpoint_params, **kwargs) + self.system_message = system_message + self.prompt_template = prompt_template \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_agent_extract.py b/box_sdk_gen/schemas/ai_agent_extract.py new file mode 100644 index 000000000..af79f029d --- /dev/null +++ b/box_sdk_gen/schemas/ai_agent_extract.py @@ -0,0 +1,27 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.ai_agent_long_text_tool import AiAgentLongTextTool + +from box_sdk_gen.schemas.ai_agent_basic_text_tool import AiAgentBasicTextTool + +from box_sdk_gen.box.errors import BoxSDKError + +class AiAgentExtractTypeField(str, Enum): + AI_AGENT_EXTRACT = 'ai_agent_extract' + +class AiAgentExtract(BaseObject): + _discriminator = 'type', {'ai_agent_extract'} + def __init__(self, *, type: AiAgentExtractTypeField = AiAgentExtractTypeField.AI_AGENT_EXTRACT, long_text: Optional[AiAgentLongTextTool] = None, basic_text: Optional[AiAgentBasicTextTool] = None, basic_image: Optional[AiAgentBasicTextTool] = None, **kwargs): + """ + :param type: The type of AI agent to be used for extraction., defaults to AiAgentExtractTypeField.AI_AGENT_EXTRACT + :type type: AiAgentExtractTypeField, optional + """ + super().__init__(**kwargs) + self.type = type + self.long_text = long_text + self.basic_text = basic_text + self.basic_image = basic_image \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_agent_extract_structured.py b/box_sdk_gen/schemas/ai_agent_extract_structured.py new file mode 100644 index 000000000..433f10e03 --- /dev/null +++ b/box_sdk_gen/schemas/ai_agent_extract_structured.py @@ -0,0 +1,27 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.ai_agent_long_text_tool import AiAgentLongTextTool + +from box_sdk_gen.schemas.ai_agent_basic_text_tool import AiAgentBasicTextTool + +from box_sdk_gen.box.errors import BoxSDKError + +class AiAgentExtractStructuredTypeField(str, Enum): + AI_AGENT_EXTRACT_STRUCTURED = 'ai_agent_extract_structured' + +class AiAgentExtractStructured(BaseObject): + _discriminator = 'type', {'ai_agent_extract_structured'} + def __init__(self, *, type: AiAgentExtractStructuredTypeField = AiAgentExtractStructuredTypeField.AI_AGENT_EXTRACT_STRUCTURED, long_text: Optional[AiAgentLongTextTool] = None, basic_text: Optional[AiAgentBasicTextTool] = None, basic_image: Optional[AiAgentBasicTextTool] = None, **kwargs): + """ + :param type: The type of AI agent to be used for extraction., defaults to AiAgentExtractStructuredTypeField.AI_AGENT_EXTRACT_STRUCTURED + :type type: AiAgentExtractStructuredTypeField, optional + """ + super().__init__(**kwargs) + self.type = type + self.long_text = long_text + self.basic_text = basic_text + self.basic_image = basic_image \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_agent_info.py b/box_sdk_gen/schemas/ai_agent_info.py new file mode 100644 index 000000000..571f7e452 --- /dev/null +++ b/box_sdk_gen/schemas/ai_agent_info.py @@ -0,0 +1,34 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from box_sdk_gen.box.errors import BoxSDKError + +class AiAgentInfoModelsField(BaseObject): + def __init__(self, *, name: Optional[str] = None, provider: Optional[str] = None, supported_purpose: Optional[str] = None, **kwargs): + """ + :param name: The name of the model used for the request, defaults to None + :type name: Optional[str], optional + :param provider: The provider that owns the model used for the request, defaults to None + :type provider: Optional[str], optional + :param supported_purpose: The supported purpose utilized by the model used for the request, defaults to None + :type supported_purpose: Optional[str], optional + """ + super().__init__(**kwargs) + self.name = name + self.provider = provider + self.supported_purpose = supported_purpose + +class AiAgentInfo(BaseObject): + def __init__(self, *, models: Optional[List[AiAgentInfoModelsField]] = None, processor: Optional[str] = None, **kwargs): + """ + :param models: The models used for the request, defaults to None + :type models: Optional[List[AiAgentInfoModelsField]], optional + :param processor: The processor used for the request, defaults to None + :type processor: Optional[str], optional + """ + super().__init__(**kwargs) + self.models = models + self.processor = processor \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_agent_long_text_tool.py b/box_sdk_gen/schemas/ai_agent_long_text_tool.py new file mode 100644 index 000000000..2ea9af109 --- /dev/null +++ b/box_sdk_gen/schemas/ai_agent_long_text_tool.py @@ -0,0 +1,50 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.ai_llm_endpoint_params import AiLlmEndpointParams + +from box_sdk_gen.schemas.ai_agent_basic_text_tool_base import AiAgentBasicTextToolBase + +from box_sdk_gen.schemas.ai_agent_basic_text_tool import AiAgentBasicTextTool + +from box_sdk_gen.box.errors import BoxSDKError + +class AiAgentLongTextToolEmbeddingsStrategyField(BaseObject): + def __init__(self, *, id: Optional[str] = None, num_tokens_per_chunk: Optional[int] = None, **kwargs): + """ + :param id: The strategy used for the AI agent for calculating embeddings., defaults to None + :type id: Optional[str], optional + :param num_tokens_per_chunk: The number of tokens per chunk., defaults to None + :type num_tokens_per_chunk: Optional[int], optional + """ + super().__init__(**kwargs) + self.id = id + self.num_tokens_per_chunk = num_tokens_per_chunk + +class AiAgentLongTextToolEmbeddingsField(BaseObject): + def __init__(self, *, model: Optional[str] = None, strategy: Optional[AiAgentLongTextToolEmbeddingsStrategyField] = None, **kwargs): + """ + :param model: The model used for the AI agent for calculating embeddings., defaults to None + :type model: Optional[str], optional + """ + super().__init__(**kwargs) + self.model = model + self.strategy = strategy + +class AiAgentLongTextTool(AiAgentBasicTextTool): + def __init__(self, *, embeddings: Optional[AiAgentLongTextToolEmbeddingsField] = None, system_message: Optional[str] = None, prompt_template: Optional[str] = None, model: Optional[str] = None, num_tokens_for_completion: Optional[int] = None, llm_endpoint_params: Optional[AiLlmEndpointParams] = None, **kwargs): + """ + :param system_message: System messages try to help the LLM "understand" its role and what it is supposed to do., defaults to None + :type system_message: Optional[str], optional + :param prompt_template: The prompt template contains contextual information of the request and the user prompt. +When passing `prompt_template` parameters, you **must include** inputs for `{user_question}` and `{content}`. +`{current_date}` is optional, depending on the use., defaults to None + :type prompt_template: Optional[str], optional + :param model: The model used for the AI agent for basic text. For specific model values, see the [available models list](g://box-ai/supported-models)., defaults to None + :type model: Optional[str], optional + :param num_tokens_for_completion: The number of tokens for completion., defaults to None + :type num_tokens_for_completion: Optional[int], optional + """ + super().__init__(system_message=system_message, prompt_template=prompt_template, model=model, num_tokens_for_completion=num_tokens_for_completion, llm_endpoint_params=llm_endpoint_params, **kwargs) + self.embeddings = embeddings \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_agent_long_text_tool_text_gen.py b/box_sdk_gen/schemas/ai_agent_long_text_tool_text_gen.py new file mode 100644 index 000000000..98dd2fd06 --- /dev/null +++ b/box_sdk_gen/schemas/ai_agent_long_text_tool_text_gen.py @@ -0,0 +1,52 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.ai_llm_endpoint_params import AiLlmEndpointParams + +from box_sdk_gen.schemas.ai_agent_basic_text_tool_base import AiAgentBasicTextToolBase + +from box_sdk_gen.schemas.ai_agent_basic_text_tool_text_gen import AiAgentBasicTextToolTextGen + +from box_sdk_gen.box.errors import BoxSDKError + +class AiAgentLongTextToolTextGenEmbeddingsStrategyField(BaseObject): + def __init__(self, *, id: Optional[str] = None, num_tokens_per_chunk: Optional[int] = None, **kwargs): + """ + :param id: The strategy used for the AI agent for calculating embeddings., defaults to None + :type id: Optional[str], optional + :param num_tokens_per_chunk: The number of tokens per chunk., defaults to None + :type num_tokens_per_chunk: Optional[int], optional + """ + super().__init__(**kwargs) + self.id = id + self.num_tokens_per_chunk = num_tokens_per_chunk + +class AiAgentLongTextToolTextGenEmbeddingsField(BaseObject): + def __init__(self, *, model: Optional[str] = None, strategy: Optional[AiAgentLongTextToolTextGenEmbeddingsStrategyField] = None, **kwargs): + """ + :param model: The model used for the AI agent for calculating embeddings., defaults to None + :type model: Optional[str], optional + """ + super().__init__(**kwargs) + self.model = model + self.strategy = strategy + +class AiAgentLongTextToolTextGen(AiAgentBasicTextToolTextGen): + def __init__(self, *, embeddings: Optional[AiAgentLongTextToolTextGenEmbeddingsField] = None, system_message: Optional[str] = None, prompt_template: Optional[str] = None, model: Optional[str] = None, num_tokens_for_completion: Optional[int] = None, llm_endpoint_params: Optional[AiLlmEndpointParams] = None, **kwargs): + """ + :param system_message: System messages aim at helping the LLM understand its role and what it is supposed to do. +The input for `{current_date}` is optional, depending on the use., defaults to None + :type system_message: Optional[str], optional + :param prompt_template: The prompt template contains contextual information of the request and the user prompt. + +When using the `prompt_template` parameter, you **must include** input for `{user_question}`. +Inputs for `{current_date}` and `{content}` are optional, depending on the use., defaults to None + :type prompt_template: Optional[str], optional + :param model: The model used for the AI agent for basic text. For specific model values, see the [available models list](g://box-ai/supported-models)., defaults to None + :type model: Optional[str], optional + :param num_tokens_for_completion: The number of tokens for completion., defaults to None + :type num_tokens_for_completion: Optional[int], optional + """ + super().__init__(system_message=system_message, prompt_template=prompt_template, model=model, num_tokens_for_completion=num_tokens_for_completion, llm_endpoint_params=llm_endpoint_params, **kwargs) + self.embeddings = embeddings \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_agent_reference.py b/box_sdk_gen/schemas/ai_agent_reference.py new file mode 100644 index 000000000..d0251ef61 --- /dev/null +++ b/box_sdk_gen/schemas/ai_agent_reference.py @@ -0,0 +1,23 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class AiAgentReferenceTypeField(str, Enum): + AI_AGENT_ID = 'ai_agent_id' + +class AiAgentReference(BaseObject): + _discriminator = 'type', {'ai_agent_id'} + def __init__(self, *, type: AiAgentReferenceTypeField = AiAgentReferenceTypeField.AI_AGENT_ID, id: Optional[str] = None, **kwargs): + """ + :param type: The type of AI agent used to handle queries., defaults to AiAgentReferenceTypeField.AI_AGENT_ID + :type type: AiAgentReferenceTypeField, optional + :param id: The ID of an Agent, defaults to None + :type id: Optional[str], optional + """ + super().__init__(**kwargs) + self.type = type + self.id = id \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_agent_text_gen.py b/box_sdk_gen/schemas/ai_agent_text_gen.py new file mode 100644 index 000000000..e6637eced --- /dev/null +++ b/box_sdk_gen/schemas/ai_agent_text_gen.py @@ -0,0 +1,23 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.ai_agent_basic_gen_tool import AiAgentBasicGenTool + +from box_sdk_gen.box.errors import BoxSDKError + +class AiAgentTextGenTypeField(str, Enum): + AI_AGENT_TEXT_GEN = 'ai_agent_text_gen' + +class AiAgentTextGen(BaseObject): + _discriminator = 'type', {'ai_agent_text_gen'} + def __init__(self, *, type: AiAgentTextGenTypeField = AiAgentTextGenTypeField.AI_AGENT_TEXT_GEN, basic_gen: Optional[AiAgentBasicGenTool] = None, **kwargs): + """ + :param type: The type of AI agent used for generating text., defaults to AiAgentTextGenTypeField.AI_AGENT_TEXT_GEN + :type type: AiAgentTextGenTypeField, optional + """ + super().__init__(**kwargs) + self.type = type + self.basic_gen = basic_gen \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_ask.py b/box_sdk_gen/schemas/ai_ask.py new file mode 100644 index 000000000..92479d9ad --- /dev/null +++ b/box_sdk_gen/schemas/ai_ask.py @@ -0,0 +1,45 @@ +from enum import Enum + +from typing import List + +from typing import Optional + +from typing import Union + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.ai_item_ask import AiItemAsk + +from box_sdk_gen.schemas.ai_dialogue_history import AiDialogueHistory + +from box_sdk_gen.schemas.ai_agent_ask import AiAgentAsk + +from box_sdk_gen.schemas.ai_agent_reference import AiAgentReference + +from box_sdk_gen.box.errors import BoxSDKError + +class AiAskModeField(str, Enum): + MULTIPLE_ITEM_QA = 'multiple_item_qa' + SINGLE_ITEM_QA = 'single_item_qa' + +class AiAsk(BaseObject): + def __init__(self, mode: AiAskModeField, prompt: str, items: List[AiItemAsk], *, dialogue_history: Optional[List[AiDialogueHistory]] = None, include_citations: Optional[bool] = None, ai_agent: Optional[Union[AiAgentAsk, AiAgentReference]] = None, **kwargs): + """ + :param mode: Box AI handles text documents with text representations up to 1MB in size, or a maximum of 25 files, whichever comes first. If the text file size exceeds 1MB, the first 1MB of text representation will be processed. Box AI handles image documents with a resolution of 1024 x 1024 pixels, with a maximum of 5 images or 5 pages for multi-page images. If the number of image or image pages exceeds 5, the first 5 images or pages will be processed. If you set mode parameter to `single_item_qa`, the items array can have one element only. Currently Box AI does not support multi-modal requests. If both images and text are sent Box AI will only process the text. + :type mode: AiAskModeField + :param prompt: The prompt provided by the client to be answered by the LLM. The prompt's length is limited to 10000 characters. + :type prompt: str + :param items: The items to be processed by the LLM, often files. + :type items: List[AiItemAsk] + :param dialogue_history: The history of prompts and answers previously passed to the LLM. This provides additional context to the LLM in generating the response., defaults to None + :type dialogue_history: Optional[List[AiDialogueHistory]], optional + :param include_citations: A flag to indicate whether citations should be returned., defaults to None + :type include_citations: Optional[bool], optional + """ + super().__init__(**kwargs) + self.mode = mode + self.prompt = prompt + self.items = items + self.dialogue_history = dialogue_history + self.include_citations = include_citations + self.ai_agent = ai_agent \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_citation.py b/box_sdk_gen/schemas/ai_citation.py new file mode 100644 index 000000000..500f24d2c --- /dev/null +++ b/box_sdk_gen/schemas/ai_citation.py @@ -0,0 +1,29 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class AiCitationTypeField(str, Enum): + FILE = 'file' + +class AiCitation(BaseObject): + _discriminator = 'type', {'file'} + def __init__(self, *, content: Optional[str] = None, id: Optional[str] = None, type: Optional[AiCitationTypeField] = None, name: Optional[str] = None, **kwargs): + """ + :param content: The specific content from where the answer was referenced., defaults to None + :type content: Optional[str], optional + :param id: The id of the item., defaults to None + :type id: Optional[str], optional + :param type: The type of the item., defaults to None + :type type: Optional[AiCitationTypeField], optional + :param name: The name of the item., defaults to None + :type name: Optional[str], optional + """ + super().__init__(**kwargs) + self.content = content + self.id = id + self.type = type + self.name = name \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_dialogue_history.py b/box_sdk_gen/schemas/ai_dialogue_history.py new file mode 100644 index 000000000..81b5ddfb3 --- /dev/null +++ b/box_sdk_gen/schemas/ai_dialogue_history.py @@ -0,0 +1,22 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class AiDialogueHistory(BaseObject): + def __init__(self, *, prompt: Optional[str] = None, answer: Optional[str] = None, created_at: Optional[DateTime] = None, **kwargs): + """ + :param prompt: The prompt previously provided by the client and answered by the LLM., defaults to None + :type prompt: Optional[str], optional + :param answer: The answer previously provided by the LLM., defaults to None + :type answer: Optional[str], optional + :param created_at: The ISO date formatted timestamp of when the previous answer to the prompt was created., defaults to None + :type created_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.prompt = prompt + self.answer = answer + self.created_at = created_at \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_extract.py b/box_sdk_gen/schemas/ai_extract.py new file mode 100644 index 000000000..3525c4945 --- /dev/null +++ b/box_sdk_gen/schemas/ai_extract.py @@ -0,0 +1,28 @@ +from typing import List + +from typing import Optional + +from typing import Union + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.ai_item_base import AiItemBase + +from box_sdk_gen.schemas.ai_agent_reference import AiAgentReference + +from box_sdk_gen.schemas.ai_agent_extract import AiAgentExtract + +from box_sdk_gen.box.errors import BoxSDKError + +class AiExtract(BaseObject): + def __init__(self, prompt: str, items: List[AiItemBase], *, ai_agent: Optional[Union[AiAgentReference, AiAgentExtract]] = None, **kwargs): + """ + :param prompt: The prompt provided to a Large Language Model (LLM) in the request. The prompt can be up to 10000 characters long and it can be an XML or a JSON schema. + :type prompt: str + :param items: The items that LLM will process. Currently, you can use files only. + :type items: List[AiItemBase] + """ + super().__init__(**kwargs) + self.prompt = prompt + self.items = items + self.ai_agent = ai_agent \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_extract_response.py b/box_sdk_gen/schemas/ai_extract_response.py new file mode 100644 index 000000000..ae26fb307 --- /dev/null +++ b/box_sdk_gen/schemas/ai_extract_response.py @@ -0,0 +1,7 @@ +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class AiExtractResponse(BaseObject): + def __init__(self, **kwargs): + super().__init__(**kwargs) \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_extract_structured.py b/box_sdk_gen/schemas/ai_extract_structured.py new file mode 100644 index 000000000..920d0aece --- /dev/null +++ b/box_sdk_gen/schemas/ai_extract_structured.py @@ -0,0 +1,96 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from typing import Dict + +from typing import Union + +from box_sdk_gen.schemas.ai_item_base import AiItemBase + +from box_sdk_gen.schemas.ai_agent_reference import AiAgentReference + +from box_sdk_gen.schemas.ai_agent_extract_structured import AiAgentExtractStructured + +from box_sdk_gen.box.errors import BoxSDKError + +class AiExtractStructuredMetadataTemplateTypeField(str, Enum): + METADATA_TEMPLATE = 'metadata_template' + +class AiExtractStructuredMetadataTemplateField(BaseObject): + _discriminator = 'type', {'metadata_template'} + def __init__(self, *, template_key: Optional[str] = None, type: Optional[AiExtractStructuredMetadataTemplateTypeField] = None, scope: Optional[str] = None, **kwargs): + """ + :param template_key: The name of the metadata template., defaults to None + :type template_key: Optional[str], optional + :param type: Value is always `metadata_template`., defaults to None + :type type: Optional[AiExtractStructuredMetadataTemplateTypeField], optional + :param scope: The scope of the metadata template that can either be global or +enterprise. +* The **global** scope is used for templates that are +available to any Box enterprise. +* The **enterprise** scope represents templates created within a specific enterprise, + containing the ID of that enterprise., defaults to None + :type scope: Optional[str], optional + """ + super().__init__(**kwargs) + self.template_key = template_key + self.type = type + self.scope = scope + +class AiExtractStructuredFieldsOptionsField(BaseObject): + def __init__(self, key: str, **kwargs): + """ + :param key: A unique identifier for the field. + :type key: str + """ + super().__init__(**kwargs) + self.key = key + +class AiExtractStructuredFieldsField(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'display_name': 'displayName', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'displayName': 'display_name', **BaseObject._json_to_fields_mapping} + def __init__(self, key: str, *, description: Optional[str] = None, display_name: Optional[str] = None, prompt: Optional[str] = None, type: Optional[str] = None, options: Optional[List[AiExtractStructuredFieldsOptionsField]] = None, **kwargs): + """ + :param key: A unique identifier for the field. + :type key: str + :param description: A description of the field., defaults to None + :type description: Optional[str], optional + :param display_name: The display name of the field., defaults to None + :type display_name: Optional[str], optional + :param prompt: The context about the key that may include how to find and format it., defaults to None + :type prompt: Optional[str], optional + :param type: The type of the field. It include but is not limited to string, float, date, enum, and multiSelect., defaults to None + :type type: Optional[str], optional + :param options: A list of options for this field. This is most often used in combination with the enum and multiSelect field types., defaults to None + :type options: Optional[List[AiExtractStructuredFieldsOptionsField]], optional + """ + super().__init__(**kwargs) + self.key = key + self.description = description + self.display_name = display_name + self.prompt = prompt + self.type = type + self.options = options + +class AiExtractStructured(BaseObject): + def __init__(self, items: List[AiItemBase], *, metadata_template: Optional[AiExtractStructuredMetadataTemplateField] = None, fields: Optional[List[AiExtractStructuredFieldsField]] = None, ai_agent: Optional[Union[AiAgentReference, AiAgentExtractStructured]] = None, **kwargs): + """ + :param items: The items to be processed by the LLM. Currently you can use files only. + :type items: List[AiItemBase] + :param metadata_template: The metadata template containing the fields to extract. +For your request to work, you must provide either `metadata_template` or `fields`, but not both., defaults to None + :type metadata_template: Optional[AiExtractStructuredMetadataTemplateField], optional + :param fields: The fields to be extracted from the provided items. +For your request to work, you must provide either `metadata_template` or `fields`, but not both., defaults to None + :type fields: Optional[List[AiExtractStructuredFieldsField]], optional + """ + super().__init__(**kwargs) + self.items = items + self.metadata_template = metadata_template + self.fields = fields + self.ai_agent = ai_agent \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_extract_structured_response.py b/box_sdk_gen/schemas/ai_extract_structured_response.py new file mode 100644 index 000000000..c237fcf50 --- /dev/null +++ b/box_sdk_gen/schemas/ai_extract_structured_response.py @@ -0,0 +1,25 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.ai_extract_response import AiExtractResponse + +from box_sdk_gen.schemas.ai_agent_info import AiAgentInfo + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class AiExtractStructuredResponse(BaseObject): + def __init__(self, answer: AiExtractResponse, created_at: DateTime, *, completion_reason: Optional[str] = None, ai_agent_info: Optional[AiAgentInfo] = None, **kwargs): + """ + :param created_at: The ISO date formatted timestamp of when the answer to the prompt was created. + :type created_at: DateTime + :param completion_reason: The reason the response finishes., defaults to None + :type completion_reason: Optional[str], optional + """ + super().__init__(**kwargs) + self.answer = answer + self.created_at = created_at + self.completion_reason = completion_reason + self.ai_agent_info = ai_agent_info \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_item_ask.py b/box_sdk_gen/schemas/ai_item_ask.py new file mode 100644 index 000000000..dd5fa9f94 --- /dev/null +++ b/box_sdk_gen/schemas/ai_item_ask.py @@ -0,0 +1,27 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class AiItemAskTypeField(str, Enum): + FILE = 'file' + HUBS = 'hubs' + +class AiItemAsk(BaseObject): + _discriminator = 'type', {'file', 'hubs'} + def __init__(self, id: str, type: AiItemAskTypeField, *, content: Optional[str] = None, **kwargs): + """ + :param id: The ID of the file. + :type id: str + :param type: The type of the item. A `hubs` item must be used as a single item. + :type type: AiItemAskTypeField + :param content: The content of the item, often the text representation., defaults to None + :type content: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.content = content \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_item_base.py b/box_sdk_gen/schemas/ai_item_base.py new file mode 100644 index 000000000..9eb9fcbda --- /dev/null +++ b/box_sdk_gen/schemas/ai_item_base.py @@ -0,0 +1,26 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class AiItemBaseTypeField(str, Enum): + FILE = 'file' + +class AiItemBase(BaseObject): + _discriminator = 'type', {'file'} + def __init__(self, id: str, *, type: AiItemBaseTypeField = AiItemBaseTypeField.FILE, content: Optional[str] = None, **kwargs): + """ + :param id: The ID of the file. + :type id: str + :param type: The type of the item. Currently the value can be `file` only., defaults to AiItemBaseTypeField.FILE + :type type: AiItemBaseTypeField, optional + :param content: The content of the item, often the text representation., defaults to None + :type content: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.content = content \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_llm_endpoint_params.py b/box_sdk_gen/schemas/ai_llm_endpoint_params.py new file mode 100644 index 000000000..9765b2134 --- /dev/null +++ b/box_sdk_gen/schemas/ai_llm_endpoint_params.py @@ -0,0 +1,13 @@ +from typing import Union + +from box_sdk_gen.schemas.ai_llm_endpoint_params_open_ai import AiLlmEndpointParamsOpenAi + +from box_sdk_gen.schemas.ai_llm_endpoint_params_google import AiLlmEndpointParamsGoogle + +from box_sdk_gen.schemas.ai_llm_endpoint_params_aws import AiLlmEndpointParamsAws + +from box_sdk_gen.schemas.ai_llm_endpoint_params_ibm import AiLlmEndpointParamsIbm + +from box_sdk_gen.box.errors import BoxSDKError + +AiLlmEndpointParams = Union[AiLlmEndpointParamsOpenAi, AiLlmEndpointParamsGoogle, AiLlmEndpointParamsAws, AiLlmEndpointParamsIbm] \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_llm_endpoint_params_aws.py b/box_sdk_gen/schemas/ai_llm_endpoint_params_aws.py new file mode 100644 index 000000000..2fffa7329 --- /dev/null +++ b/box_sdk_gen/schemas/ai_llm_endpoint_params_aws.py @@ -0,0 +1,31 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class AiLlmEndpointParamsAwsTypeField(str, Enum): + AWS_PARAMS = 'aws_params' + +class AiLlmEndpointParamsAws(BaseObject): + _discriminator = 'type', {'aws_params'} + def __init__(self, *, type: AiLlmEndpointParamsAwsTypeField = AiLlmEndpointParamsAwsTypeField.AWS_PARAMS, temperature: Optional[float] = None, top_p: Optional[float] = None, **kwargs): + """ + :param type: The type of the AI LLM endpoint params object for AWS. +This parameter is **required**., defaults to AiLlmEndpointParamsAwsTypeField.AWS_PARAMS + :type type: AiLlmEndpointParamsAwsTypeField, optional + :param temperature: What sampling temperature to use, between 0 and 1. Higher values like 0.8 will make the output more random, +while lower values like 0.2 will make it more focused and deterministic. +We generally recommend altering this or `top_p` but not both., defaults to None + :type temperature: Optional[float], optional + :param top_p: An alternative to sampling with temperature, called nucleus sampling, where the model considers the results +of the tokens with `top_p` probability mass. So 0.1 means only the tokens comprising the top 10% probability +mass are considered. We generally recommend altering this or temperature but not both., defaults to None + :type top_p: Optional[float], optional + """ + super().__init__(**kwargs) + self.type = type + self.temperature = temperature + self.top_p = top_p \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_llm_endpoint_params_google.py b/box_sdk_gen/schemas/ai_llm_endpoint_params_google.py new file mode 100644 index 000000000..c026b95a0 --- /dev/null +++ b/box_sdk_gen/schemas/ai_llm_endpoint_params_google.py @@ -0,0 +1,32 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class AiLlmEndpointParamsGoogleTypeField(str, Enum): + GOOGLE_PARAMS = 'google_params' + +class AiLlmEndpointParamsGoogle(BaseObject): + _discriminator = 'type', {'google_params'} + def __init__(self, *, type: AiLlmEndpointParamsGoogleTypeField = AiLlmEndpointParamsGoogleTypeField.GOOGLE_PARAMS, temperature: Optional[float] = None, top_p: Optional[float] = None, top_k: Optional[float] = None, **kwargs): + """ + :param type: The type of the AI LLM endpoint params object for Google. +This parameter is **required**., defaults to AiLlmEndpointParamsGoogleTypeField.GOOGLE_PARAMS + :type type: AiLlmEndpointParamsGoogleTypeField, optional + :param temperature: The temperature is used for sampling during response generation, which occurs when `top-P` and `top-K` are applied. Temperature controls the degree of randomness in the token selection., defaults to None + :type temperature: Optional[float], optional + :param top_p: `Top-P` changes how the model selects tokens for output. Tokens are selected from the most (see `top-K`) to least probable until the sum of their probabilities equals the `top-P` value., defaults to None + :type top_p: Optional[float], optional + :param top_k: `Top-K` changes how the model selects tokens for output. A `top-K` of 1 means the next selected token is +the most probable among all tokens in the model's vocabulary (also called greedy decoding), +while a `top-K` of 3 means that the next token is selected from among the three most probable tokens by using temperature., defaults to None + :type top_k: Optional[float], optional + """ + super().__init__(**kwargs) + self.type = type + self.temperature = temperature + self.top_p = top_p + self.top_k = top_k \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_llm_endpoint_params_ibm.py b/box_sdk_gen/schemas/ai_llm_endpoint_params_ibm.py new file mode 100644 index 000000000..f88de48bb --- /dev/null +++ b/box_sdk_gen/schemas/ai_llm_endpoint_params_ibm.py @@ -0,0 +1,36 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class AiLlmEndpointParamsIbmTypeField(str, Enum): + IBM_PARAMS = 'ibm_params' + +class AiLlmEndpointParamsIbm(BaseObject): + _discriminator = 'type', {'ibm_params'} + def __init__(self, *, type: AiLlmEndpointParamsIbmTypeField = AiLlmEndpointParamsIbmTypeField.IBM_PARAMS, temperature: Optional[float] = None, top_p: Optional[float] = None, top_k: Optional[float] = None, **kwargs): + """ + :param type: The type of the AI LLM endpoint params object for IBM. +This parameter is **required**., defaults to AiLlmEndpointParamsIbmTypeField.IBM_PARAMS + :type type: AiLlmEndpointParamsIbmTypeField, optional + :param temperature: What sampling temperature to use, between 0 and 1. Higher values like 0.8 will make the output more random, +while lower values like 0.2 will make it more focused and deterministic. +We generally recommend altering this or `top_p` but not both., defaults to None + :type temperature: Optional[float], optional + :param top_p: An alternative to sampling with temperature, called nucleus sampling, where the model considers the results +of the tokens with `top_p` probability mass. So 0.1 means only the tokens comprising the top 10% probability +mass are considered. We generally recommend altering this or temperature but not both., defaults to None + :type top_p: Optional[float], optional + :param top_k: `Top-K` changes how the model selects tokens for output. A `top-K` of 1 means the next selected token is +the most probable among all tokens in the model's vocabulary (also called greedy decoding), +while a `top-K` of 3 means that the next token is selected from among the three most probable tokens by using temperature., defaults to None + :type top_k: Optional[float], optional + """ + super().__init__(**kwargs) + self.type = type + self.temperature = temperature + self.top_p = top_p + self.top_k = top_k \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_llm_endpoint_params_open_ai.py b/box_sdk_gen/schemas/ai_llm_endpoint_params_open_ai.py new file mode 100644 index 000000000..7851cdb04 --- /dev/null +++ b/box_sdk_gen/schemas/ai_llm_endpoint_params_open_ai.py @@ -0,0 +1,41 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class AiLlmEndpointParamsOpenAiTypeField(str, Enum): + OPENAI_PARAMS = 'openai_params' + +class AiLlmEndpointParamsOpenAi(BaseObject): + _discriminator = 'type', {'openai_params'} + def __init__(self, *, type: AiLlmEndpointParamsOpenAiTypeField = AiLlmEndpointParamsOpenAiTypeField.OPENAI_PARAMS, temperature: Optional[float] = None, top_p: Optional[float] = None, frequency_penalty: Optional[float] = None, presence_penalty: Optional[float] = None, stop: Optional[str] = None, **kwargs): + """ + :param type: The type of the AI LLM endpoint params object for OpenAI. +This parameter is **required**., defaults to AiLlmEndpointParamsOpenAiTypeField.OPENAI_PARAMS + :type type: AiLlmEndpointParamsOpenAiTypeField, optional + :param temperature: What sampling temperature to use, between 0 and 2. Higher values like 0.8 will make the output more random, +while lower values like 0.2 will make it more focused and deterministic. +We generally recommend altering this or `top_p` but not both., defaults to None + :type temperature: Optional[float], optional + :param top_p: An alternative to sampling with temperature, called nucleus sampling, where the model considers the results +of the tokens with `top_p` probability mass. So 0.1 means only the tokens comprising the top 10% probability +mass are considered. We generally recommend altering this or temperature but not both., defaults to None + :type top_p: Optional[float], optional + :param frequency_penalty: A number between -2.0 and 2.0. Positive values penalize new tokens based on their existing frequency in the +text so far, decreasing the model's likelihood to repeat the same line verbatim., defaults to None + :type frequency_penalty: Optional[float], optional + :param presence_penalty: A number between -2.0 and 2.0. Positive values penalize new tokens based on whether they appear in the text so far, increasing the model's likelihood to talk about new topics., defaults to None + :type presence_penalty: Optional[float], optional + :param stop: Up to 4 sequences where the API will stop generating further tokens., defaults to None + :type stop: Optional[str], optional + """ + super().__init__(**kwargs) + self.type = type + self.temperature = temperature + self.top_p = top_p + self.frequency_penalty = frequency_penalty + self.presence_penalty = presence_penalty + self.stop = stop \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_multiple_agent_response.py b/box_sdk_gen/schemas/ai_multiple_agent_response.py new file mode 100644 index 000000000..a00df714c --- /dev/null +++ b/box_sdk_gen/schemas/ai_multiple_agent_response.py @@ -0,0 +1,29 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.ai_single_agent_response_full import AiSingleAgentResponseFull + +from box_sdk_gen.box.errors import BoxSDKError + +class AiMultipleAgentResponse(BaseObject): + def __init__(self, entries: List[AiSingleAgentResponseFull], *, limit: Optional[int] = None, next_marker: Optional[str] = None, prev_marker: Optional[str] = None, **kwargs): + """ + :param entries: The list of AI Agents. + :type entries: List[AiSingleAgentResponseFull] + :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.entries = entries + self.limit = limit + self.next_marker = next_marker + self.prev_marker = prev_marker \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_response.py b/box_sdk_gen/schemas/ai_response.py new file mode 100644 index 000000000..57b789b2d --- /dev/null +++ b/box_sdk_gen/schemas/ai_response.py @@ -0,0 +1,25 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.ai_agent_info import AiAgentInfo + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class AiResponse(BaseObject): + def __init__(self, answer: str, created_at: DateTime, *, completion_reason: Optional[str] = None, ai_agent_info: Optional[AiAgentInfo] = None, **kwargs): + """ + :param answer: The answer provided by the LLM. + :type answer: str + :param created_at: The ISO date formatted timestamp of when the answer to the prompt was created. + :type created_at: DateTime + :param completion_reason: The reason the response finishes., defaults to None + :type completion_reason: Optional[str], optional + """ + super().__init__(**kwargs) + self.answer = answer + self.created_at = created_at + self.completion_reason = completion_reason + self.ai_agent_info = ai_agent_info \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_response_full.py b/box_sdk_gen/schemas/ai_response_full.py new file mode 100644 index 000000000..3cc36226d --- /dev/null +++ b/box_sdk_gen/schemas/ai_response_full.py @@ -0,0 +1,28 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.utils import DateTime + +from box_sdk_gen.schemas.ai_agent_info import AiAgentInfo + +from box_sdk_gen.schemas.ai_response import AiResponse + +from box_sdk_gen.schemas.ai_citation import AiCitation + +from box_sdk_gen.box.errors import BoxSDKError + +class AiResponseFull(AiResponse): + def __init__(self, answer: str, created_at: DateTime, *, citations: Optional[List[AiCitation]] = None, completion_reason: Optional[str] = None, ai_agent_info: Optional[AiAgentInfo] = None, **kwargs): + """ + :param answer: The answer provided by the LLM. + :type answer: str + :param created_at: The ISO date formatted timestamp of when the answer to the prompt was created. + :type created_at: DateTime + :param citations: The citations of the LLM's answer reference., defaults to None + :type citations: Optional[List[AiCitation]], optional + :param completion_reason: The reason the response finishes., defaults to None + :type completion_reason: Optional[str], optional + """ + super().__init__(answer=answer, created_at=created_at, completion_reason=completion_reason, ai_agent_info=ai_agent_info, **kwargs) + self.citations = citations \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_single_agent_response.py b/box_sdk_gen/schemas/ai_single_agent_response.py new file mode 100644 index 000000000..795661de9 --- /dev/null +++ b/box_sdk_gen/schemas/ai_single_agent_response.py @@ -0,0 +1,58 @@ +from enum import Enum + +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.user_base import UserBase + +from box_sdk_gen.schemas.ai_agent_allowed_entity import AiAgentAllowedEntity + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class AiSingleAgentResponseTypeField(str, Enum): + AI_AGENT = 'ai_agent' + +class AiSingleAgentResponse(BaseObject): + _discriminator = 'type', {'ai_agent'} + def __init__(self, id: str, origin: str, name: str, access_state: str, *, type: Optional[AiSingleAgentResponseTypeField] = None, created_by: Optional[UserBase] = None, created_at: Optional[DateTime] = None, modified_by: Optional[UserBase] = None, modified_at: Optional[DateTime] = None, icon_reference: Optional[str] = None, allowed_entities: Optional[List[AiAgentAllowedEntity]] = None, **kwargs): + """ + :param id: The unique identifier of the AI Agent. + :type id: str + :param origin: The provider of the AI Agent. + :type origin: str + :param name: The name of the AI Agent. + :type name: str + :param access_state: The state of the AI Agent. Possible values are: `enabled`, `disabled`, and `enabled_for_selected_users`. + :type access_state: str + :param type: The type of agent used to handle queries., defaults to None + :type type: Optional[AiSingleAgentResponseTypeField], optional + :param created_by: The user who created this agent., defaults to None + :type created_by: Optional[UserBase], optional + :param created_at: The ISO date-time formatted timestamp of when this AI agent was created., defaults to None + :type created_at: Optional[DateTime], optional + :param modified_by: The user who most recently modified this agent., defaults to None + :type modified_by: Optional[UserBase], optional + :param modified_at: The ISO date-time formatted timestamp of when this AI agent was recently modified., defaults to None + :type modified_at: Optional[DateTime], optional + :param icon_reference: The icon reference of the AI Agent., defaults to None + :type icon_reference: Optional[str], optional + :param allowed_entities: List of allowed users or groups., defaults to None + :type allowed_entities: Optional[List[AiAgentAllowedEntity]], optional + """ + super().__init__(**kwargs) + self.id = id + self.origin = origin + self.name = name + self.access_state = access_state + self.type = type + self.created_by = created_by + self.created_at = created_at + self.modified_by = modified_by + self.modified_at = modified_at + self.icon_reference = icon_reference + self.allowed_entities = allowed_entities \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_single_agent_response_full.py b/box_sdk_gen/schemas/ai_single_agent_response_full.py new file mode 100644 index 000000000..22ebb8198 --- /dev/null +++ b/box_sdk_gen/schemas/ai_single_agent_response_full.py @@ -0,0 +1,52 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.schemas.ai_single_agent_response import AiSingleAgentResponseTypeField + +from box_sdk_gen.schemas.user_base import UserBase + +from box_sdk_gen.internal.utils import DateTime + +from box_sdk_gen.schemas.ai_agent_allowed_entity import AiAgentAllowedEntity + +from box_sdk_gen.schemas.ai_single_agent_response import AiSingleAgentResponse + +from box_sdk_gen.schemas.ai_studio_agent_ask_response import AiStudioAgentAskResponse + +from box_sdk_gen.schemas.ai_studio_agent_text_gen_response import AiStudioAgentTextGenResponse + +from box_sdk_gen.schemas.ai_studio_agent_extract_response import AiStudioAgentExtractResponse + +from box_sdk_gen.box.errors import BoxSDKError + +class AiSingleAgentResponseFull(AiSingleAgentResponse): + def __init__(self, id: str, origin: str, name: str, access_state: str, *, ask: Optional[AiStudioAgentAskResponse] = None, text_gen: Optional[AiStudioAgentTextGenResponse] = None, extract: Optional[AiStudioAgentExtractResponse] = None, type: Optional[AiSingleAgentResponseTypeField] = None, created_by: Optional[UserBase] = None, created_at: Optional[DateTime] = None, modified_by: Optional[UserBase] = None, modified_at: Optional[DateTime] = None, icon_reference: Optional[str] = None, allowed_entities: Optional[List[AiAgentAllowedEntity]] = None, **kwargs): + """ + :param id: The unique identifier of the AI Agent. + :type id: str + :param origin: The provider of the AI Agent. + :type origin: str + :param name: The name of the AI Agent. + :type name: str + :param access_state: The state of the AI Agent. Possible values are: `enabled`, `disabled`, and `enabled_for_selected_users`. + :type access_state: str + :param type: The type of agent used to handle queries., defaults to None + :type type: Optional[AiSingleAgentResponseTypeField], optional + :param created_by: The user who created this agent., defaults to None + :type created_by: Optional[UserBase], optional + :param created_at: The ISO date-time formatted timestamp of when this AI agent was created., defaults to None + :type created_at: Optional[DateTime], optional + :param modified_by: The user who most recently modified this agent., defaults to None + :type modified_by: Optional[UserBase], optional + :param modified_at: The ISO date-time formatted timestamp of when this AI agent was recently modified., defaults to None + :type modified_at: Optional[DateTime], optional + :param icon_reference: The icon reference of the AI Agent., defaults to None + :type icon_reference: Optional[str], optional + :param allowed_entities: List of allowed users or groups., defaults to None + :type allowed_entities: Optional[List[AiAgentAllowedEntity]], optional + """ + super().__init__(id=id, origin=origin, name=name, access_state=access_state, type=type, created_by=created_by, created_at=created_at, modified_by=modified_by, modified_at=modified_at, icon_reference=icon_reference, allowed_entities=allowed_entities, **kwargs) + self.ask = ask + self.text_gen = text_gen + self.extract = extract \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_studio_agent_ask.py b/box_sdk_gen/schemas/ai_studio_agent_ask.py new file mode 100644 index 000000000..3df428df4 --- /dev/null +++ b/box_sdk_gen/schemas/ai_studio_agent_ask.py @@ -0,0 +1,37 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.ai_studio_agent_long_text_tool import AiStudioAgentLongTextTool + +from box_sdk_gen.schemas.ai_studio_agent_basic_text_tool import AiStudioAgentBasicTextTool + +from box_sdk_gen.box.errors import BoxSDKError + +class AiStudioAgentAskTypeField(str, Enum): + AI_AGENT_ASK = 'ai_agent_ask' + +class AiStudioAgentAsk(BaseObject): + _discriminator = 'type', {'ai_agent_ask'} + def __init__(self, access_state: str, description: str, *, type: AiStudioAgentAskTypeField = AiStudioAgentAskTypeField.AI_AGENT_ASK, custom_instructions: Optional[str] = None, long_text: Optional[AiStudioAgentLongTextTool] = None, basic_text: Optional[AiStudioAgentBasicTextTool] = None, long_text_multi: Optional[AiStudioAgentLongTextTool] = None, basic_text_multi: Optional[AiStudioAgentBasicTextTool] = None, **kwargs): + """ + :param access_state: The state of the AI Agent capability. Possible values are: `enabled` and `disabled`. + :type access_state: str + :param description: The description of the AI Agent. + :type description: str + :param type: The type of AI agent used to handle queries., defaults to AiStudioAgentAskTypeField.AI_AGENT_ASK + :type type: AiStudioAgentAskTypeField, optional + :param custom_instructions: Custom instructions for the agent., defaults to None + :type custom_instructions: Optional[str], optional + """ + super().__init__(**kwargs) + self.access_state = access_state + self.description = description + self.type = type + self.custom_instructions = custom_instructions + self.long_text = long_text + self.basic_text = basic_text + self.long_text_multi = long_text_multi + self.basic_text_multi = basic_text_multi \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_studio_agent_ask_response.py b/box_sdk_gen/schemas/ai_studio_agent_ask_response.py new file mode 100644 index 000000000..563788370 --- /dev/null +++ b/box_sdk_gen/schemas/ai_studio_agent_ask_response.py @@ -0,0 +1,37 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.ai_studio_agent_long_text_tool_response import AiStudioAgentLongTextToolResponse + +from box_sdk_gen.schemas.ai_studio_agent_basic_text_tool_response import AiStudioAgentBasicTextToolResponse + +from box_sdk_gen.box.errors import BoxSDKError + +class AiStudioAgentAskResponseTypeField(str, Enum): + AI_AGENT_ASK = 'ai_agent_ask' + +class AiStudioAgentAskResponse(BaseObject): + _discriminator = 'type', {'ai_agent_ask'} + def __init__(self, access_state: str, description: str, *, type: AiStudioAgentAskResponseTypeField = AiStudioAgentAskResponseTypeField.AI_AGENT_ASK, custom_instructions: Optional[str] = None, long_text: Optional[AiStudioAgentLongTextToolResponse] = None, basic_text: Optional[AiStudioAgentBasicTextToolResponse] = None, long_text_multi: Optional[AiStudioAgentLongTextToolResponse] = None, basic_text_multi: Optional[AiStudioAgentBasicTextToolResponse] = None, **kwargs): + """ + :param access_state: The state of the AI Agent capability. Possible values are: `enabled` and `disabled`. + :type access_state: str + :param description: The description of the AI Agent. + :type description: str + :param type: The type of AI agent used to handle queries., defaults to AiStudioAgentAskResponseTypeField.AI_AGENT_ASK + :type type: AiStudioAgentAskResponseTypeField, optional + :param custom_instructions: Custom instructions for the agent., defaults to None + :type custom_instructions: Optional[str], optional + """ + super().__init__(**kwargs) + self.access_state = access_state + self.description = description + self.type = type + self.custom_instructions = custom_instructions + self.long_text = long_text + self.basic_text = basic_text + self.long_text_multi = long_text_multi + self.basic_text_multi = basic_text_multi \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_studio_agent_basic_gen_tool.py b/box_sdk_gen/schemas/ai_studio_agent_basic_gen_tool.py new file mode 100644 index 000000000..ccc14a62c --- /dev/null +++ b/box_sdk_gen/schemas/ai_studio_agent_basic_gen_tool.py @@ -0,0 +1,39 @@ +from typing import Optional + +from box_sdk_gen.schemas.ai_llm_endpoint_params import AiLlmEndpointParams + +from box_sdk_gen.schemas.ai_agent_basic_text_tool_base import AiAgentBasicTextToolBase + +from box_sdk_gen.schemas.ai_agent_basic_text_tool_text_gen import AiAgentBasicTextToolTextGen + +from box_sdk_gen.schemas.ai_agent_long_text_tool_text_gen import AiAgentLongTextToolTextGenEmbeddingsField + +from box_sdk_gen.schemas.ai_agent_long_text_tool_text_gen import AiAgentLongTextToolTextGen + +from box_sdk_gen.schemas.ai_agent_basic_gen_tool import AiAgentBasicGenTool + +from box_sdk_gen.box.errors import BoxSDKError + +class AiStudioAgentBasicGenTool(AiAgentBasicGenTool): + def __init__(self, *, is_custom_instructions_included: Optional[bool] = None, content_template: Optional[str] = None, embeddings: Optional[AiAgentLongTextToolTextGenEmbeddingsField] = None, system_message: Optional[str] = None, prompt_template: Optional[str] = None, model: Optional[str] = None, num_tokens_for_completion: Optional[int] = None, llm_endpoint_params: Optional[AiLlmEndpointParams] = None, **kwargs): + """ + :param is_custom_instructions_included: True if system message contains custom instructions placeholder, false otherwise, defaults to None + :type is_custom_instructions_included: Optional[bool], optional + :param content_template: How the content should be included in a request to the LLM. +Input for `{content}` is optional, depending on the use., defaults to None + :type content_template: Optional[str], optional + :param system_message: System messages aim at helping the LLM understand its role and what it is supposed to do. +The input for `{current_date}` is optional, depending on the use., defaults to None + :type system_message: Optional[str], optional + :param prompt_template: The prompt template contains contextual information of the request and the user prompt. + +When using the `prompt_template` parameter, you **must include** input for `{user_question}`. +Inputs for `{current_date}` and `{content}` are optional, depending on the use., defaults to None + :type prompt_template: Optional[str], optional + :param model: The model used for the AI agent for basic text. For specific model values, see the [available models list](g://box-ai/supported-models)., defaults to None + :type model: Optional[str], optional + :param num_tokens_for_completion: The number of tokens for completion., defaults to None + :type num_tokens_for_completion: Optional[int], optional + """ + super().__init__(content_template=content_template, embeddings=embeddings, system_message=system_message, prompt_template=prompt_template, model=model, num_tokens_for_completion=num_tokens_for_completion, llm_endpoint_params=llm_endpoint_params, **kwargs) + self.is_custom_instructions_included = is_custom_instructions_included \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_studio_agent_basic_gen_tool_response.py b/box_sdk_gen/schemas/ai_studio_agent_basic_gen_tool_response.py new file mode 100644 index 000000000..78ace9576 --- /dev/null +++ b/box_sdk_gen/schemas/ai_studio_agent_basic_gen_tool_response.py @@ -0,0 +1,45 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.schemas.ai_llm_endpoint_params import AiLlmEndpointParams + +from box_sdk_gen.schemas.ai_agent_basic_text_tool_base import AiAgentBasicTextToolBase + +from box_sdk_gen.schemas.ai_agent_basic_text_tool_text_gen import AiAgentBasicTextToolTextGen + +from box_sdk_gen.schemas.ai_agent_long_text_tool_text_gen import AiAgentLongTextToolTextGenEmbeddingsField + +from box_sdk_gen.schemas.ai_agent_long_text_tool_text_gen import AiAgentLongTextToolTextGen + +from box_sdk_gen.schemas.ai_agent_basic_gen_tool import AiAgentBasicGenTool + +from box_sdk_gen.schemas.ai_studio_agent_basic_gen_tool import AiStudioAgentBasicGenTool + +from box_sdk_gen.box.errors import BoxSDKError + +class AiStudioAgentBasicGenToolResponse(AiStudioAgentBasicGenTool): + def __init__(self, *, warnings: Optional[List[str]] = None, is_custom_instructions_included: Optional[bool] = None, content_template: Optional[str] = None, embeddings: Optional[AiAgentLongTextToolTextGenEmbeddingsField] = None, system_message: Optional[str] = None, prompt_template: Optional[str] = None, model: Optional[str] = None, num_tokens_for_completion: Optional[int] = None, llm_endpoint_params: Optional[AiLlmEndpointParams] = None, **kwargs): + """ + :param warnings: Warnings concerning tool, defaults to None + :type warnings: Optional[List[str]], optional + :param is_custom_instructions_included: True if system message contains custom instructions placeholder, false otherwise, defaults to None + :type is_custom_instructions_included: Optional[bool], optional + :param content_template: How the content should be included in a request to the LLM. +Input for `{content}` is optional, depending on the use., defaults to None + :type content_template: Optional[str], optional + :param system_message: System messages aim at helping the LLM understand its role and what it is supposed to do. +The input for `{current_date}` is optional, depending on the use., defaults to None + :type system_message: Optional[str], optional + :param prompt_template: The prompt template contains contextual information of the request and the user prompt. + +When using the `prompt_template` parameter, you **must include** input for `{user_question}`. +Inputs for `{current_date}` and `{content}` are optional, depending on the use., defaults to None + :type prompt_template: Optional[str], optional + :param model: The model used for the AI agent for basic text. For specific model values, see the [available models list](g://box-ai/supported-models)., defaults to None + :type model: Optional[str], optional + :param num_tokens_for_completion: The number of tokens for completion., defaults to None + :type num_tokens_for_completion: Optional[int], optional + """ + super().__init__(is_custom_instructions_included=is_custom_instructions_included, content_template=content_template, embeddings=embeddings, system_message=system_message, prompt_template=prompt_template, model=model, num_tokens_for_completion=num_tokens_for_completion, llm_endpoint_params=llm_endpoint_params, **kwargs) + self.warnings = warnings \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_studio_agent_basic_text_tool.py b/box_sdk_gen/schemas/ai_studio_agent_basic_text_tool.py new file mode 100644 index 000000000..9fbfc8596 --- /dev/null +++ b/box_sdk_gen/schemas/ai_studio_agent_basic_text_tool.py @@ -0,0 +1,28 @@ +from typing import Optional + +from box_sdk_gen.schemas.ai_llm_endpoint_params import AiLlmEndpointParams + +from box_sdk_gen.schemas.ai_agent_basic_text_tool_base import AiAgentBasicTextToolBase + +from box_sdk_gen.schemas.ai_agent_basic_text_tool import AiAgentBasicTextTool + +from box_sdk_gen.box.errors import BoxSDKError + +class AiStudioAgentBasicTextTool(AiAgentBasicTextTool): + def __init__(self, *, is_custom_instructions_included: Optional[bool] = None, system_message: Optional[str] = None, prompt_template: Optional[str] = None, model: Optional[str] = None, num_tokens_for_completion: Optional[int] = None, llm_endpoint_params: Optional[AiLlmEndpointParams] = None, **kwargs): + """ + :param is_custom_instructions_included: True if system message contains custom instructions placeholder, false otherwise, defaults to None + :type is_custom_instructions_included: Optional[bool], optional + :param system_message: System messages try to help the LLM "understand" its role and what it is supposed to do., defaults to None + :type system_message: Optional[str], optional + :param prompt_template: The prompt template contains contextual information of the request and the user prompt. +When passing `prompt_template` parameters, you **must include** inputs for `{user_question}` and `{content}`. +`{current_date}` is optional, depending on the use., defaults to None + :type prompt_template: Optional[str], optional + :param model: The model used for the AI agent for basic text. For specific model values, see the [available models list](g://box-ai/supported-models)., defaults to None + :type model: Optional[str], optional + :param num_tokens_for_completion: The number of tokens for completion., defaults to None + :type num_tokens_for_completion: Optional[int], optional + """ + super().__init__(system_message=system_message, prompt_template=prompt_template, model=model, num_tokens_for_completion=num_tokens_for_completion, llm_endpoint_params=llm_endpoint_params, **kwargs) + self.is_custom_instructions_included = is_custom_instructions_included \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_studio_agent_basic_text_tool_response.py b/box_sdk_gen/schemas/ai_studio_agent_basic_text_tool_response.py new file mode 100644 index 000000000..873db0664 --- /dev/null +++ b/box_sdk_gen/schemas/ai_studio_agent_basic_text_tool_response.py @@ -0,0 +1,34 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.schemas.ai_llm_endpoint_params import AiLlmEndpointParams + +from box_sdk_gen.schemas.ai_agent_basic_text_tool_base import AiAgentBasicTextToolBase + +from box_sdk_gen.schemas.ai_agent_basic_text_tool import AiAgentBasicTextTool + +from box_sdk_gen.schemas.ai_studio_agent_basic_text_tool import AiStudioAgentBasicTextTool + +from box_sdk_gen.box.errors import BoxSDKError + +class AiStudioAgentBasicTextToolResponse(AiStudioAgentBasicTextTool): + def __init__(self, *, warnings: Optional[List[str]] = None, is_custom_instructions_included: Optional[bool] = None, system_message: Optional[str] = None, prompt_template: Optional[str] = None, model: Optional[str] = None, num_tokens_for_completion: Optional[int] = None, llm_endpoint_params: Optional[AiLlmEndpointParams] = None, **kwargs): + """ + :param warnings: Warnings concerning tool, defaults to None + :type warnings: Optional[List[str]], optional + :param is_custom_instructions_included: True if system message contains custom instructions placeholder, false otherwise, defaults to None + :type is_custom_instructions_included: Optional[bool], optional + :param system_message: System messages try to help the LLM "understand" its role and what it is supposed to do., defaults to None + :type system_message: Optional[str], optional + :param prompt_template: The prompt template contains contextual information of the request and the user prompt. +When passing `prompt_template` parameters, you **must include** inputs for `{user_question}` and `{content}`. +`{current_date}` is optional, depending on the use., defaults to None + :type prompt_template: Optional[str], optional + :param model: The model used for the AI agent for basic text. For specific model values, see the [available models list](g://box-ai/supported-models)., defaults to None + :type model: Optional[str], optional + :param num_tokens_for_completion: The number of tokens for completion., defaults to None + :type num_tokens_for_completion: Optional[int], optional + """ + super().__init__(is_custom_instructions_included=is_custom_instructions_included, system_message=system_message, prompt_template=prompt_template, model=model, num_tokens_for_completion=num_tokens_for_completion, llm_endpoint_params=llm_endpoint_params, **kwargs) + self.warnings = warnings \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_studio_agent_extract.py b/box_sdk_gen/schemas/ai_studio_agent_extract.py new file mode 100644 index 000000000..960081750 --- /dev/null +++ b/box_sdk_gen/schemas/ai_studio_agent_extract.py @@ -0,0 +1,35 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.ai_studio_agent_long_text_tool import AiStudioAgentLongTextTool + +from box_sdk_gen.schemas.ai_studio_agent_basic_text_tool import AiStudioAgentBasicTextTool + +from box_sdk_gen.box.errors import BoxSDKError + +class AiStudioAgentExtractTypeField(str, Enum): + AI_AGENT_EXTRACT = 'ai_agent_extract' + +class AiStudioAgentExtract(BaseObject): + _discriminator = 'type', {'ai_agent_extract'} + def __init__(self, access_state: str, description: str, *, type: AiStudioAgentExtractTypeField = AiStudioAgentExtractTypeField.AI_AGENT_EXTRACT, custom_instructions: Optional[str] = None, long_text: Optional[AiStudioAgentLongTextTool] = None, basic_text: Optional[AiStudioAgentBasicTextTool] = None, **kwargs): + """ + :param access_state: The state of the AI Agent capability. Possible values are: `enabled` and `disabled`. + :type access_state: str + :param description: The description of the AI Agent. + :type description: str + :param type: The type of AI agent to be used for extraction., defaults to AiStudioAgentExtractTypeField.AI_AGENT_EXTRACT + :type type: AiStudioAgentExtractTypeField, optional + :param custom_instructions: Custom instructions for the agent., defaults to None + :type custom_instructions: Optional[str], optional + """ + super().__init__(**kwargs) + self.access_state = access_state + self.description = description + self.type = type + self.custom_instructions = custom_instructions + self.long_text = long_text + self.basic_text = basic_text \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_studio_agent_extract_response.py b/box_sdk_gen/schemas/ai_studio_agent_extract_response.py new file mode 100644 index 000000000..31dfb842a --- /dev/null +++ b/box_sdk_gen/schemas/ai_studio_agent_extract_response.py @@ -0,0 +1,35 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.ai_studio_agent_long_text_tool_response import AiStudioAgentLongTextToolResponse + +from box_sdk_gen.schemas.ai_studio_agent_basic_text_tool_response import AiStudioAgentBasicTextToolResponse + +from box_sdk_gen.box.errors import BoxSDKError + +class AiStudioAgentExtractResponseTypeField(str, Enum): + AI_AGENT_EXTRACT = 'ai_agent_extract' + +class AiStudioAgentExtractResponse(BaseObject): + _discriminator = 'type', {'ai_agent_extract'} + def __init__(self, access_state: str, description: str, *, type: AiStudioAgentExtractResponseTypeField = AiStudioAgentExtractResponseTypeField.AI_AGENT_EXTRACT, custom_instructions: Optional[str] = None, long_text: Optional[AiStudioAgentLongTextToolResponse] = None, basic_text: Optional[AiStudioAgentBasicTextToolResponse] = None, **kwargs): + """ + :param access_state: The state of the AI Agent capability. Possible values are: `enabled` and `disabled`. + :type access_state: str + :param description: The description of the AI Agent. + :type description: str + :param type: The type of AI agent to be used for extraction., defaults to AiStudioAgentExtractResponseTypeField.AI_AGENT_EXTRACT + :type type: AiStudioAgentExtractResponseTypeField, optional + :param custom_instructions: Custom instructions for the agent., defaults to None + :type custom_instructions: Optional[str], optional + """ + super().__init__(**kwargs) + self.access_state = access_state + self.description = description + self.type = type + self.custom_instructions = custom_instructions + self.long_text = long_text + self.basic_text = basic_text \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_studio_agent_long_text_tool.py b/box_sdk_gen/schemas/ai_studio_agent_long_text_tool.py new file mode 100644 index 000000000..098929914 --- /dev/null +++ b/box_sdk_gen/schemas/ai_studio_agent_long_text_tool.py @@ -0,0 +1,32 @@ +from typing import Optional + +from box_sdk_gen.schemas.ai_llm_endpoint_params import AiLlmEndpointParams + +from box_sdk_gen.schemas.ai_agent_basic_text_tool_base import AiAgentBasicTextToolBase + +from box_sdk_gen.schemas.ai_agent_basic_text_tool import AiAgentBasicTextTool + +from box_sdk_gen.schemas.ai_agent_long_text_tool import AiAgentLongTextToolEmbeddingsField + +from box_sdk_gen.schemas.ai_agent_long_text_tool import AiAgentLongTextTool + +from box_sdk_gen.box.errors import BoxSDKError + +class AiStudioAgentLongTextTool(AiAgentLongTextTool): + def __init__(self, *, is_custom_instructions_included: Optional[bool] = None, embeddings: Optional[AiAgentLongTextToolEmbeddingsField] = None, system_message: Optional[str] = None, prompt_template: Optional[str] = None, model: Optional[str] = None, num_tokens_for_completion: Optional[int] = None, llm_endpoint_params: Optional[AiLlmEndpointParams] = None, **kwargs): + """ + :param is_custom_instructions_included: True if system message contains custom instructions placeholder, false otherwise, defaults to None + :type is_custom_instructions_included: Optional[bool], optional + :param system_message: System messages try to help the LLM "understand" its role and what it is supposed to do., defaults to None + :type system_message: Optional[str], optional + :param prompt_template: The prompt template contains contextual information of the request and the user prompt. +When passing `prompt_template` parameters, you **must include** inputs for `{user_question}` and `{content}`. +`{current_date}` is optional, depending on the use., defaults to None + :type prompt_template: Optional[str], optional + :param model: The model used for the AI agent for basic text. For specific model values, see the [available models list](g://box-ai/supported-models)., defaults to None + :type model: Optional[str], optional + :param num_tokens_for_completion: The number of tokens for completion., defaults to None + :type num_tokens_for_completion: Optional[int], optional + """ + super().__init__(embeddings=embeddings, system_message=system_message, prompt_template=prompt_template, model=model, num_tokens_for_completion=num_tokens_for_completion, llm_endpoint_params=llm_endpoint_params, **kwargs) + self.is_custom_instructions_included = is_custom_instructions_included \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_studio_agent_long_text_tool_response.py b/box_sdk_gen/schemas/ai_studio_agent_long_text_tool_response.py new file mode 100644 index 000000000..2b4d18792 --- /dev/null +++ b/box_sdk_gen/schemas/ai_studio_agent_long_text_tool_response.py @@ -0,0 +1,38 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.schemas.ai_llm_endpoint_params import AiLlmEndpointParams + +from box_sdk_gen.schemas.ai_agent_basic_text_tool_base import AiAgentBasicTextToolBase + +from box_sdk_gen.schemas.ai_agent_basic_text_tool import AiAgentBasicTextTool + +from box_sdk_gen.schemas.ai_agent_long_text_tool import AiAgentLongTextToolEmbeddingsField + +from box_sdk_gen.schemas.ai_agent_long_text_tool import AiAgentLongTextTool + +from box_sdk_gen.schemas.ai_studio_agent_long_text_tool import AiStudioAgentLongTextTool + +from box_sdk_gen.box.errors import BoxSDKError + +class AiStudioAgentLongTextToolResponse(AiStudioAgentLongTextTool): + def __init__(self, *, warnings: Optional[List[str]] = None, is_custom_instructions_included: Optional[bool] = None, embeddings: Optional[AiAgentLongTextToolEmbeddingsField] = None, system_message: Optional[str] = None, prompt_template: Optional[str] = None, model: Optional[str] = None, num_tokens_for_completion: Optional[int] = None, llm_endpoint_params: Optional[AiLlmEndpointParams] = None, **kwargs): + """ + :param warnings: Warnings concerning tool, defaults to None + :type warnings: Optional[List[str]], optional + :param is_custom_instructions_included: True if system message contains custom instructions placeholder, false otherwise, defaults to None + :type is_custom_instructions_included: Optional[bool], optional + :param system_message: System messages try to help the LLM "understand" its role and what it is supposed to do., defaults to None + :type system_message: Optional[str], optional + :param prompt_template: The prompt template contains contextual information of the request and the user prompt. +When passing `prompt_template` parameters, you **must include** inputs for `{user_question}` and `{content}`. +`{current_date}` is optional, depending on the use., defaults to None + :type prompt_template: Optional[str], optional + :param model: The model used for the AI agent for basic text. For specific model values, see the [available models list](g://box-ai/supported-models)., defaults to None + :type model: Optional[str], optional + :param num_tokens_for_completion: The number of tokens for completion., defaults to None + :type num_tokens_for_completion: Optional[int], optional + """ + super().__init__(is_custom_instructions_included=is_custom_instructions_included, embeddings=embeddings, system_message=system_message, prompt_template=prompt_template, model=model, num_tokens_for_completion=num_tokens_for_completion, llm_endpoint_params=llm_endpoint_params, **kwargs) + self.warnings = warnings \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_studio_agent_text_gen.py b/box_sdk_gen/schemas/ai_studio_agent_text_gen.py new file mode 100644 index 000000000..d96e2e17c --- /dev/null +++ b/box_sdk_gen/schemas/ai_studio_agent_text_gen.py @@ -0,0 +1,32 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.ai_studio_agent_basic_gen_tool import AiStudioAgentBasicGenTool + +from box_sdk_gen.box.errors import BoxSDKError + +class AiStudioAgentTextGenTypeField(str, Enum): + AI_AGENT_TEXT_GEN = 'ai_agent_text_gen' + +class AiStudioAgentTextGen(BaseObject): + _discriminator = 'type', {'ai_agent_text_gen'} + def __init__(self, access_state: str, description: str, *, type: AiStudioAgentTextGenTypeField = AiStudioAgentTextGenTypeField.AI_AGENT_TEXT_GEN, custom_instructions: Optional[str] = None, basic_gen: Optional[AiStudioAgentBasicGenTool] = None, **kwargs): + """ + :param access_state: The state of the AI Agent capability. Possible values are: `enabled` and `disabled`. + :type access_state: str + :param description: The description of the AI Agent. + :type description: str + :param type: The type of AI agent used for generating text., defaults to AiStudioAgentTextGenTypeField.AI_AGENT_TEXT_GEN + :type type: AiStudioAgentTextGenTypeField, optional + :param custom_instructions: Custom instructions for the agent., defaults to None + :type custom_instructions: Optional[str], optional + """ + super().__init__(**kwargs) + self.access_state = access_state + self.description = description + self.type = type + self.custom_instructions = custom_instructions + self.basic_gen = basic_gen \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_studio_agent_text_gen_response.py b/box_sdk_gen/schemas/ai_studio_agent_text_gen_response.py new file mode 100644 index 000000000..d9d134800 --- /dev/null +++ b/box_sdk_gen/schemas/ai_studio_agent_text_gen_response.py @@ -0,0 +1,32 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.ai_studio_agent_basic_gen_tool_response import AiStudioAgentBasicGenToolResponse + +from box_sdk_gen.box.errors import BoxSDKError + +class AiStudioAgentTextGenResponseTypeField(str, Enum): + AI_AGENT_TEXT_GEN = 'ai_agent_text_gen' + +class AiStudioAgentTextGenResponse(BaseObject): + _discriminator = 'type', {'ai_agent_text_gen'} + def __init__(self, access_state: str, description: str, *, type: AiStudioAgentTextGenResponseTypeField = AiStudioAgentTextGenResponseTypeField.AI_AGENT_TEXT_GEN, custom_instructions: Optional[str] = None, basic_gen: Optional[AiStudioAgentBasicGenToolResponse] = None, **kwargs): + """ + :param access_state: The state of the AI Agent capability. Possible values are: `enabled` and `disabled`. + :type access_state: str + :param description: The description of the AI Agent. + :type description: str + :param type: The type of AI agent used for generating text., defaults to AiStudioAgentTextGenResponseTypeField.AI_AGENT_TEXT_GEN + :type type: AiStudioAgentTextGenResponseTypeField, optional + :param custom_instructions: Custom instructions for the agent., defaults to None + :type custom_instructions: Optional[str], optional + """ + super().__init__(**kwargs) + self.access_state = access_state + self.description = description + self.type = type + self.custom_instructions = custom_instructions + self.basic_gen = basic_gen \ No newline at end of file diff --git a/box_sdk_gen/schemas/ai_text_gen.py b/box_sdk_gen/schemas/ai_text_gen.py new file mode 100644 index 000000000..cf059505f --- /dev/null +++ b/box_sdk_gen/schemas/ai_text_gen.py @@ -0,0 +1,56 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from typing import Union + +from box_sdk_gen.schemas.ai_dialogue_history import AiDialogueHistory + +from box_sdk_gen.schemas.ai_agent_reference import AiAgentReference + +from box_sdk_gen.schemas.ai_agent_text_gen import AiAgentTextGen + +from box_sdk_gen.box.errors import BoxSDKError + +class AiTextGenItemsTypeField(str, Enum): + FILE = 'file' + +class AiTextGenItemsField(BaseObject): + _discriminator = 'type', {'file'} + def __init__(self, id: str, *, type: AiTextGenItemsTypeField = AiTextGenItemsTypeField.FILE, content: Optional[str] = None, **kwargs): + """ + :param id: The ID of the item. + :type id: str + :param type: The type of the item., defaults to AiTextGenItemsTypeField.FILE + :type type: AiTextGenItemsTypeField, optional + :param content: The content to use as context for generating new text or editing existing text., defaults to None + :type content: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.content = content + +class AiTextGen(BaseObject): + def __init__(self, prompt: str, items: List[AiTextGenItemsField], *, dialogue_history: Optional[List[AiDialogueHistory]] = None, ai_agent: Optional[Union[AiAgentReference, AiAgentTextGen]] = None, **kwargs): + """ + :param prompt: The prompt provided by the client to be answered by the LLM. The prompt's length is limited to 10000 characters. + :type prompt: str + :param items: The items to be processed by the LLM, often files. +The array can include **exactly one** element. + +**Note**: Box AI handles documents with text representations up to 1MB in size. +If the file size exceeds 1MB, the first 1MB of text representation will be processed. + :type items: List[AiTextGenItemsField] + :param dialogue_history: The history of prompts and answers previously passed to the LLM. This parameter provides the additional context to the LLM when generating the response., defaults to None + :type dialogue_history: Optional[List[AiDialogueHistory]], optional + """ + super().__init__(**kwargs) + self.prompt = prompt + self.items = items + self.dialogue_history = dialogue_history + self.ai_agent = ai_agent \ No newline at end of file diff --git a/box_sdk_gen/schemas/app_item.py b/box_sdk_gen/schemas/app_item.py new file mode 100644 index 000000000..1899debc0 --- /dev/null +++ b/box_sdk_gen/schemas/app_item.py @@ -0,0 +1,24 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +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, **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 + :type type: AppItemTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.application_type = application_type + self.type = type \ No newline at end of file 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 000000000..8b7ccced5 --- /dev/null +++ b/box_sdk_gen/schemas/app_item_association.py @@ -0,0 +1,33 @@ +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 + +from box_sdk_gen.box.errors import BoxSDKError + +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, **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 + :type type: AppItemAssociationTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.app_item = app_item + self.item = item + self.type = type \ No newline at end of file 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 000000000..cf48d7141 --- /dev/null +++ b/box_sdk_gen/schemas/app_item_associations.py @@ -0,0 +1,27 @@ +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 + +from box_sdk_gen.box.errors import BoxSDKError + +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 \ No newline at end of file diff --git a/box_sdk_gen/schemas/app_item_event_source.py b/box_sdk_gen/schemas/app_item_event_source.py new file mode 100644 index 000000000..7c5edf646 --- /dev/null +++ b/box_sdk_gen/schemas/app_item_event_source.py @@ -0,0 +1,33 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.schemas.group_mini import GroupMini + +from box_sdk_gen.box.errors import BoxSDKError + +class AppItemEventSourceTypeField(str, Enum): + APP_ITEM = 'app_item' + +class AppItemEventSource(BaseObject): + _discriminator = 'type', {'app_item'} + def __init__(self, id: str, app_item_type: str, *, type: AppItemEventSourceTypeField = AppItemEventSourceTypeField.APP_ITEM, user: Optional[UserMini] = None, group: Optional[GroupMini] = None, **kwargs): + """ + :param id: The id of the `AppItem` + :type id: str + :param app_item_type: The type of the `AppItem` + :type app_item_type: str + :param type: The type of the source that this event represents. Can only be `app_item`. +, defaults to AppItemEventSourceTypeField.APP_ITEM + :type type: AppItemEventSourceTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.app_item_type = app_item_type + self.type = type + self.user = user + self.group = group \ No newline at end of file diff --git a/box_sdk_gen/schemas/classification.py b/box_sdk_gen/schemas/classification.py new file mode 100644 index 000000000..d0b4b6a4b --- /dev/null +++ b/box_sdk_gen/schemas/classification.py @@ -0,0 +1,53 @@ +from enum import Enum + +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class ClassificationTemplateField(str, Enum): + SECURITYCLASSIFICATION_6VMVOCHWUWO = 'securityClassification-6VMVochwUWo' + +class Classification(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'box_security_classification_key': 'Box__Security__Classification__Key', 'parent': '$parent', 'template': '$template', 'scope': '$scope', 'version': '$version', 'type': '$type', 'type_version': '$typeVersion', 'can_edit': '$canEdit', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'Box__Security__Classification__Key': 'box_security_classification_key', '$parent': 'parent', '$template': 'template', '$scope': 'scope', '$version': 'version', '$type': 'type', '$typeVersion': 'type_version', '$canEdit': 'can_edit', **BaseObject._json_to_fields_mapping} + def __init__(self, *, box_security_classification_key: Optional[str] = None, parent: Optional[str] = None, template: Optional[ClassificationTemplateField] = None, scope: Optional[str] = None, version: Optional[int] = None, type: Optional[str] = None, type_version: Optional[float] = None, can_edit: Optional[bool] = None, **kwargs): + """ + :param box_security_classification_key: The name of the classification applied to the item., defaults to None + :type box_security_classification_key: Optional[str], optional + :param parent: The identifier of the item that this metadata instance +has been attached to. This combines the `type` and the `id` +of the parent in the form `{type}_{id}`., defaults to None + :type parent: Optional[str], optional + :param template: `securityClassification-6VMVochwUWo`, defaults to None + :type template: Optional[ClassificationTemplateField], optional + :param scope: The scope of the enterprise that this classification has been +applied for. + +This will be in the format `enterprise_{enterprise_id}`., defaults to None + :type scope: Optional[str], optional + :param version: The version of the metadata instance. This version starts at 0 and +increases every time a classification is updated., defaults to None + :type version: Optional[int], optional + :param type: The unique ID of this classification instance. This will be include +the name of the classification template and a unique ID., defaults to None + :type type: Optional[str], optional + :param type_version: The version of the metadata template. This version starts at 0 and +increases every time the template is updated. This is mostly for internal +use., defaults to None + :type type_version: Optional[float], optional + :param can_edit: Whether an end user can change the classification., defaults to None + :type can_edit: Optional[bool], optional + """ + super().__init__(**kwargs) + self.box_security_classification_key = box_security_classification_key + self.parent = parent + self.template = template + self.scope = scope + self.version = version + self.type = type + self.type_version = type_version + self.can_edit = can_edit \ No newline at end of file diff --git a/box_sdk_gen/schemas/classification_template.py b/box_sdk_gen/schemas/classification_template.py new file mode 100644 index 000000000..27a251e33 --- /dev/null +++ b/box_sdk_gen/schemas/classification_template.py @@ -0,0 +1,157 @@ +from enum import Enum + +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from box_sdk_gen.box.errors import BoxSDKError + +class ClassificationTemplateTypeField(str, Enum): + METADATA_TEMPLATE = 'metadata_template' + +class ClassificationTemplateTemplateKeyField(str, Enum): + SECURITYCLASSIFICATION_6VMVOCHWUWO = 'securityClassification-6VMVochwUWo' + +class ClassificationTemplateDisplayNameField(str, Enum): + CLASSIFICATION = 'Classification' + +class ClassificationTemplateFieldsTypeField(str, Enum): + ENUM = 'enum' + +class ClassificationTemplateFieldsKeyField(str, Enum): + BOX__SECURITY__CLASSIFICATION__KEY = 'Box__Security__Classification__Key' + +class ClassificationTemplateFieldsDisplayNameField(str, Enum): + CLASSIFICATION = 'Classification' + +class ClassificationTemplateFieldsOptionsStaticConfigClassificationField(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'classification_definition': 'classificationDefinition', 'color_id': 'colorID', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'classificationDefinition': 'classification_definition', 'colorID': 'color_id', **BaseObject._json_to_fields_mapping} + def __init__(self, *, classification_definition: Optional[str] = None, color_id: Optional[int] = None, **kwargs): + """ + :param classification_definition: A longer description of the classification., defaults to None + :type classification_definition: Optional[str], optional + :param color_id: An internal Box identifier used to assign a color to +a classification label. + +Mapping between a `colorID` and a color may change +without notice. Currently, the color mappings are as +follows. + +* `0`: Yellow +* `1`: Orange +* `2`: Watermelon red +* `3`: Purple rain +* `4`: Light blue +* `5`: Dark blue +* `6`: Light green +* `7`: Gray, defaults to None + :type color_id: Optional[int], optional + """ + super().__init__(**kwargs) + self.classification_definition = classification_definition + self.color_id = color_id + +class ClassificationTemplateFieldsOptionsStaticConfigField(BaseObject): + def __init__(self, *, classification: Optional[ClassificationTemplateFieldsOptionsStaticConfigClassificationField] = None, **kwargs): + """ + :param classification: Additional information about the classification. + +This is not an exclusive list of properties, and +more object fields might be returned. These fields +are used for internal Box Shield and Box Governance +purposes and no additional value must be derived from +these fields., defaults to None + :type classification: Optional[ClassificationTemplateFieldsOptionsStaticConfigClassificationField], optional + """ + super().__init__(**kwargs) + self.classification = classification + +class ClassificationTemplateFieldsOptionsField(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'static_config': 'staticConfig', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'staticConfig': 'static_config', **BaseObject._json_to_fields_mapping} + def __init__(self, id: str, key: str, *, static_config: Optional[ClassificationTemplateFieldsOptionsStaticConfigField] = None, **kwargs): + """ + :param id: The unique ID of this classification. + :type id: str + :param key: The display name and key for this classification. + :type key: str + :param static_config: Additional information about the classification., defaults to None + :type static_config: Optional[ClassificationTemplateFieldsOptionsStaticConfigField], optional + """ + super().__init__(**kwargs) + self.id = id + self.key = key + self.static_config = static_config + +class ClassificationTemplateFieldsField(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'display_name': 'displayName', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'displayName': 'display_name', **BaseObject._json_to_fields_mapping} + _discriminator = 'type', {'enum'} + def __init__(self, id: str, options: List[ClassificationTemplateFieldsOptionsField], *, type: ClassificationTemplateFieldsTypeField = ClassificationTemplateFieldsTypeField.ENUM, key: ClassificationTemplateFieldsKeyField = ClassificationTemplateFieldsKeyField.BOX__SECURITY__CLASSIFICATION__KEY, display_name: ClassificationTemplateFieldsDisplayNameField = ClassificationTemplateFieldsDisplayNameField.CLASSIFICATION, hidden: Optional[bool] = None, **kwargs): + """ + :param id: The unique ID of the field. + :type id: str + :param options: A list of classifications available in this enterprise. + :type options: List[ClassificationTemplateFieldsOptionsField] + :param type: The array item type., defaults to ClassificationTemplateFieldsTypeField.ENUM + :type type: ClassificationTemplateFieldsTypeField, optional + :param key: Defines classifications +available in the enterprise., defaults to ClassificationTemplateFieldsKeyField.BOX__SECURITY__CLASSIFICATION__KEY + :type key: ClassificationTemplateFieldsKeyField, optional + :param display_name: `Classification`, defaults to ClassificationTemplateFieldsDisplayNameField.CLASSIFICATION + :type display_name: ClassificationTemplateFieldsDisplayNameField, optional + :param hidden: Classifications are always visible to web and mobile users., defaults to None + :type hidden: Optional[bool], optional + """ + super().__init__(**kwargs) + self.id = id + self.options = options + self.type = type + self.key = key + self.display_name = display_name + self.hidden = hidden + +class ClassificationTemplate(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'template_key': 'templateKey', 'display_name': 'displayName', 'copy_instance_on_item_copy': 'copyInstanceOnItemCopy', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'templateKey': 'template_key', 'displayName': 'display_name', 'copyInstanceOnItemCopy': 'copy_instance_on_item_copy', **BaseObject._json_to_fields_mapping} + _discriminator = 'type', {'metadata_template'} + def __init__(self, id: str, scope: str, fields: List[ClassificationTemplateFieldsField], *, type: ClassificationTemplateTypeField = ClassificationTemplateTypeField.METADATA_TEMPLATE, template_key: ClassificationTemplateTemplateKeyField = ClassificationTemplateTemplateKeyField.SECURITYCLASSIFICATION_6VMVOCHWUWO, display_name: ClassificationTemplateDisplayNameField = ClassificationTemplateDisplayNameField.CLASSIFICATION, hidden: Optional[bool] = None, copy_instance_on_item_copy: Optional[bool] = None, **kwargs): + """ + :param id: The ID of the classification template. + :type id: str + :param scope: The scope of the classification template. This is in the format +`enterprise_{id}` where the `id` is the enterprise ID. + :type scope: str + :param fields: A list of fields for this classification template. This includes +only one field, the `Box__Security__Classification__Key`, which defines +the different classifications available in this enterprise. + :type fields: List[ClassificationTemplateFieldsField] + :param type: `metadata_template`, defaults to ClassificationTemplateTypeField.METADATA_TEMPLATE + :type type: ClassificationTemplateTypeField, optional + :param template_key: `securityClassification-6VMVochwUWo`, defaults to ClassificationTemplateTemplateKeyField.SECURITYCLASSIFICATION_6VMVOCHWUWO + :type template_key: ClassificationTemplateTemplateKeyField, optional + :param display_name: The name of this template as shown in web and mobile interfaces., defaults to ClassificationTemplateDisplayNameField.CLASSIFICATION + :type display_name: ClassificationTemplateDisplayNameField, optional + :param hidden: Determines if the +template is always available in web and mobile interfaces., defaults to None + :type hidden: Optional[bool], optional + :param copy_instance_on_item_copy: Determines if +classifications are +copied along when the file or folder is +copied., defaults to None + :type copy_instance_on_item_copy: Optional[bool], optional + """ + super().__init__(**kwargs) + self.id = id + self.scope = scope + self.fields = fields + self.type = type + self.template_key = template_key + self.display_name = display_name + self.hidden = hidden + self.copy_instance_on_item_copy = copy_instance_on_item_copy \ No newline at end of file diff --git a/box_sdk_gen/schemas/client_error.py b/box_sdk_gen/schemas/client_error.py new file mode 100644 index 000000000..9a6913c96 --- /dev/null +++ b/box_sdk_gen/schemas/client_error.py @@ -0,0 +1,62 @@ +from enum import Enum + +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class ClientErrorTypeField(str, Enum): + ERROR = 'error' + +class ClientErrorCodeField(str, Enum): + CREATED = 'created' + ACCEPTED = 'accepted' + NO_CONTENT = 'no_content' + REDIRECT = 'redirect' + NOT_MODIFIED = 'not_modified' + BAD_REQUEST = 'bad_request' + UNAUTHORIZED = 'unauthorized' + FORBIDDEN = 'forbidden' + NOT_FOUND = 'not_found' + METHOD_NOT_ALLOWED = 'method_not_allowed' + CONFLICT = 'conflict' + PRECONDITION_FAILED = 'precondition_failed' + TOO_MANY_REQUESTS = 'too_many_requests' + INTERNAL_SERVER_ERROR = 'internal_server_error' + UNAVAILABLE = 'unavailable' + ITEM_NAME_INVALID = 'item_name_invalid' + INSUFFICIENT_SCOPE = 'insufficient_scope' + +class ClientError(BaseObject): + _discriminator = 'type', {'error'} + def __init__(self, *, type: Optional[ClientErrorTypeField] = None, status: Optional[int] = None, code: Optional[ClientErrorCodeField] = None, message: Optional[str] = None, context_info: Optional[Dict] = None, help_url: Optional[str] = None, request_id: Optional[str] = None, **kwargs): + """ + :param type: error, defaults to None + :type type: Optional[ClientErrorTypeField], optional + :param status: The HTTP status of the response., defaults to None + :type status: Optional[int], optional + :param code: A Box-specific error code, defaults to None + :type code: Optional[ClientErrorCodeField], optional + :param message: A short message describing the error., defaults to None + :type message: Optional[str], optional + :param context_info: A free-form object that contains additional context +about the error. The possible fields are defined on +a per-endpoint basis. `message` is only one example., defaults to None + :type context_info: Optional[Dict], optional + :param help_url: A URL that links to more information about why this error occurred., defaults to None + :type help_url: Optional[str], optional + :param request_id: A unique identifier for this response, which can be used +when contacting Box support., defaults to None + :type request_id: Optional[str], optional + """ + super().__init__(**kwargs) + self.type = type + self.status = status + self.code = code + self.message = message + self.context_info = context_info + self.help_url = help_url + self.request_id = request_id \ No newline at end of file diff --git a/box_sdk_gen/schemas/collaboration.py b/box_sdk_gen/schemas/collaboration.py new file mode 100644 index 000000000..6935b47e8 --- /dev/null +++ b/box_sdk_gen/schemas/collaboration.py @@ -0,0 +1,143 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Union + +from box_sdk_gen.schemas.file import File + +from box_sdk_gen.schemas.folder import Folder + +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 + +from box_sdk_gen.schemas.terms_of_service_base import TermsOfServiceBase + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class CollaborationTypeField(str, Enum): + COLLABORATION = 'collaboration' + +class CollaborationRoleField(str, Enum): + EDITOR = 'editor' + VIEWER = 'viewer' + PREVIEWER = 'previewer' + UPLOADER = 'uploader' + PREVIEWER_UPLOADER = 'previewer uploader' + VIEWER_UPLOADER = 'viewer uploader' + CO_OWNER = 'co-owner' + OWNER = 'owner' + +class CollaborationStatusField(str, Enum): + ACCEPTED = 'accepted' + PENDING = 'pending' + REJECTED = 'rejected' + +class CollaborationAcceptanceRequirementsStatusTermsOfServiceRequirementField(BaseObject): + def __init__(self, *, is_accepted: Optional[bool] = None, terms_of_service: Optional[TermsOfServiceBase] = None, **kwargs): + """ + :param is_accepted: Whether or not the terms of service have been accepted. The +field is `null` when there is no terms of service required., defaults to None + :type is_accepted: Optional[bool], optional + """ + super().__init__(**kwargs) + self.is_accepted = is_accepted + self.terms_of_service = terms_of_service + +class CollaborationAcceptanceRequirementsStatusStrongPasswordRequirementField(BaseObject): + def __init__(self, *, enterprise_has_strong_password_required_for_external_users: Optional[bool] = None, user_has_strong_password: Optional[bool] = None, **kwargs): + """ + :param enterprise_has_strong_password_required_for_external_users: Whether or not the enterprise that owns the content requires +a strong password to collaborate on the content, or enforces +an exposed password detection for the external collaborators., defaults to None + :type enterprise_has_strong_password_required_for_external_users: Optional[bool], optional + :param user_has_strong_password: Whether or not the user has a strong and not exposed password set +for their account. The field is `null` when a strong password is +not required., defaults to None + :type user_has_strong_password: Optional[bool], optional + """ + super().__init__(**kwargs) + self.enterprise_has_strong_password_required_for_external_users = enterprise_has_strong_password_required_for_external_users + self.user_has_strong_password = user_has_strong_password + +class CollaborationAcceptanceRequirementsStatusTwoFactorAuthenticationRequirementField(BaseObject): + def __init__(self, *, enterprise_has_two_factor_auth_enabled: Optional[bool] = None, user_has_two_factor_authentication_enabled: Optional[bool] = None, **kwargs): + """ + :param enterprise_has_two_factor_auth_enabled: Whether or not the enterprise that owns the content requires +two-factor authentication to be enabled in order to +collaborate on the content., defaults to None + :type enterprise_has_two_factor_auth_enabled: Optional[bool], optional + :param user_has_two_factor_authentication_enabled: Whether or not the user has two-factor authentication +enabled. The field is `null` when two-factor +authentication is not required., defaults to None + :type user_has_two_factor_authentication_enabled: Optional[bool], optional + """ + super().__init__(**kwargs) + self.enterprise_has_two_factor_auth_enabled = enterprise_has_two_factor_auth_enabled + self.user_has_two_factor_authentication_enabled = user_has_two_factor_authentication_enabled + +class CollaborationAcceptanceRequirementsStatusField(BaseObject): + def __init__(self, *, terms_of_service_requirement: Optional[CollaborationAcceptanceRequirementsStatusTermsOfServiceRequirementField] = None, strong_password_requirement: Optional[CollaborationAcceptanceRequirementsStatusStrongPasswordRequirementField] = None, two_factor_authentication_requirement: Optional[CollaborationAcceptanceRequirementsStatusTwoFactorAuthenticationRequirementField] = None, **kwargs): + super().__init__(**kwargs) + self.terms_of_service_requirement = terms_of_service_requirement + self.strong_password_requirement = strong_password_requirement + self.two_factor_authentication_requirement = two_factor_authentication_requirement + +class Collaboration(BaseObject): + _discriminator = 'type', {'collaboration'} + def __init__(self, id: str, *, type: CollaborationTypeField = CollaborationTypeField.COLLABORATION, 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, expires_at: Optional[DateTime] = None, is_access_only: Optional[bool] = None, status: Optional[CollaborationStatusField] = None, acknowledged_at: Optional[DateTime] = None, created_by: Optional[UserCollaborations] = None, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, acceptance_requirements_status: Optional[CollaborationAcceptanceRequirementsStatusField] = None, **kwargs): + """ + :param id: The unique identifier for this collaboration. + :type id: str + :param type: `collaboration`, defaults to CollaborationTypeField.COLLABORATION + :type type: CollaborationTypeField, optional + :param invite_email: The email address used to invite an unregistered collaborator, if +they are not a registered user., defaults to None + :type invite_email: Optional[str], optional + :param role: The level of access granted., defaults to None + :type role: Optional[CollaborationRoleField], optional + :param expires_at: When the collaboration will expire, or `null` if no expiration +date is set., defaults to None + :type expires_at: Optional[DateTime], optional + :param is_access_only: If set to `true`, collaborators have access to +shared items, but such items won't be visible in the +All Files list. Additionally, collaborators won't +see the the path to the root folder for the +shared item., defaults to None + :type is_access_only: Optional[bool], optional + :param status: The status of the collaboration invitation. If the status +is `pending`, `login` and `name` return an empty string., defaults to None + :type status: Optional[CollaborationStatusField], optional + :param acknowledged_at: When the `status` of the collaboration object changed to +`accepted` or `rejected`., defaults to None + :type acknowledged_at: Optional[DateTime], optional + :param created_at: When the collaboration object was created., defaults to None + :type created_at: Optional[DateTime], optional + :param modified_at: When the collaboration object was last modified., defaults to None + :type modified_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + 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 + self.expires_at = expires_at + self.is_access_only = is_access_only + self.status = status + self.acknowledged_at = acknowledged_at + self.created_by = created_by + self.created_at = created_at + self.modified_at = modified_at + self.acceptance_requirements_status = acceptance_requirements_status \ No newline at end of file diff --git a/box_sdk_gen/schemas/collaboration_allowlist_entries.py b/box_sdk_gen/schemas/collaboration_allowlist_entries.py new file mode 100644 index 000000000..e63e37d31 --- /dev/null +++ b/box_sdk_gen/schemas/collaboration_allowlist_entries.py @@ -0,0 +1,29 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.collaboration_allowlist_entry import CollaborationAllowlistEntry + +from box_sdk_gen.box.errors import BoxSDKError + +class CollaborationAllowlistEntries(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, prev_marker: Optional[str] = None, entries: Optional[List[CollaborationAllowlistEntry]] = 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 + :param entries: A list of allowed collaboration domains, defaults to None + :type entries: Optional[List[CollaborationAllowlistEntry]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.prev_marker = prev_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/collaboration_allowlist_entry.py b/box_sdk_gen/schemas/collaboration_allowlist_entry.py new file mode 100644 index 000000000..f6ca3cf17 --- /dev/null +++ b/box_sdk_gen/schemas/collaboration_allowlist_entry.py @@ -0,0 +1,59 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class CollaborationAllowlistEntryTypeField(str, Enum): + COLLABORATION_WHITELIST_ENTRY = 'collaboration_whitelist_entry' + +class CollaborationAllowlistEntryDirectionField(str, Enum): + INBOUND = 'inbound' + OUTBOUND = 'outbound' + BOTH = 'both' + +class CollaborationAllowlistEntryEnterpriseTypeField(str, Enum): + ENTERPRISE = 'enterprise' + +class CollaborationAllowlistEntryEnterpriseField(BaseObject): + _discriminator = 'type', {'enterprise'} + def __init__(self, *, id: Optional[str] = None, type: Optional[CollaborationAllowlistEntryEnterpriseTypeField] = None, name: Optional[str] = None, **kwargs): + """ + :param id: The unique identifier for this enterprise., defaults to None + :type id: Optional[str], optional + :param type: `enterprise`, defaults to None + :type type: Optional[CollaborationAllowlistEntryEnterpriseTypeField], optional + :param name: The name of the enterprise, defaults to None + :type name: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.name = name + +class CollaborationAllowlistEntry(BaseObject): + _discriminator = 'type', {'collaboration_whitelist_entry'} + def __init__(self, *, id: Optional[str] = None, type: Optional[CollaborationAllowlistEntryTypeField] = None, domain: Optional[str] = None, direction: Optional[CollaborationAllowlistEntryDirectionField] = None, enterprise: Optional[CollaborationAllowlistEntryEnterpriseField] = None, created_at: Optional[DateTime] = None, **kwargs): + """ + :param id: The unique identifier for this entry, defaults to None + :type id: Optional[str], optional + :param type: `collaboration_whitelist_entry`, defaults to None + :type type: Optional[CollaborationAllowlistEntryTypeField], optional + :param domain: The whitelisted domain, defaults to None + :type domain: Optional[str], optional + :param direction: The direction of the collaborations to allow., defaults to None + :type direction: Optional[CollaborationAllowlistEntryDirectionField], optional + :param created_at: The time the entry was created at, defaults to None + :type created_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.domain = domain + self.direction = direction + self.enterprise = enterprise + self.created_at = created_at \ No newline at end of file diff --git a/box_sdk_gen/schemas/collaboration_allowlist_exempt_target.py b/box_sdk_gen/schemas/collaboration_allowlist_exempt_target.py new file mode 100644 index 000000000..2b40fd95c --- /dev/null +++ b/box_sdk_gen/schemas/collaboration_allowlist_exempt_target.py @@ -0,0 +1,54 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class CollaborationAllowlistExemptTargetTypeField(str, Enum): + COLLABORATION_WHITELIST_EXEMPT_TARGET = 'collaboration_whitelist_exempt_target' + +class CollaborationAllowlistExemptTargetEnterpriseTypeField(str, Enum): + ENTERPRISE = 'enterprise' + +class CollaborationAllowlistExemptTargetEnterpriseField(BaseObject): + _discriminator = 'type', {'enterprise'} + def __init__(self, *, id: Optional[str] = None, type: Optional[CollaborationAllowlistExemptTargetEnterpriseTypeField] = None, name: Optional[str] = None, **kwargs): + """ + :param id: The unique identifier for this enterprise., defaults to None + :type id: Optional[str], optional + :param type: `enterprise`, defaults to None + :type type: Optional[CollaborationAllowlistExemptTargetEnterpriseTypeField], optional + :param name: The name of the enterprise, defaults to None + :type name: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.name = name + +class CollaborationAllowlistExemptTarget(BaseObject): + _discriminator = 'type', {'collaboration_whitelist_exempt_target'} + def __init__(self, *, id: Optional[str] = None, type: Optional[CollaborationAllowlistExemptTargetTypeField] = None, enterprise: Optional[CollaborationAllowlistExemptTargetEnterpriseField] = None, user: Optional[UserMini] = None, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, **kwargs): + """ + :param id: The unique identifier for this exemption, defaults to None + :type id: Optional[str], optional + :param type: `collaboration_whitelist_exempt_target`, defaults to None + :type type: Optional[CollaborationAllowlistExemptTargetTypeField], optional + :param created_at: The time the entry was created, defaults to None + :type created_at: Optional[DateTime], optional + :param modified_at: The time the entry was modified, defaults to None + :type modified_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.enterprise = enterprise + self.user = user + self.created_at = created_at + self.modified_at = modified_at \ No newline at end of file diff --git a/box_sdk_gen/schemas/collaboration_allowlist_exempt_targets.py b/box_sdk_gen/schemas/collaboration_allowlist_exempt_targets.py new file mode 100644 index 000000000..4582819cc --- /dev/null +++ b/box_sdk_gen/schemas/collaboration_allowlist_exempt_targets.py @@ -0,0 +1,31 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.collaboration_allowlist_exempt_target import CollaborationAllowlistExemptTarget + +from box_sdk_gen.box.errors import BoxSDKError + +class CollaborationAllowlistExemptTargets(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, prev_marker: Optional[str] = None, entries: Optional[List[CollaborationAllowlistExemptTarget]] = 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 + :param entries: A list of users exempt from any of the restrictions +imposed by the list of allowed collaboration domains +for this enterprise., defaults to None + :type entries: Optional[List[CollaborationAllowlistExemptTarget]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.prev_marker = prev_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/collaborations.py b/box_sdk_gen/schemas/collaborations.py new file mode 100644 index 000000000..e359325ee --- /dev/null +++ b/box_sdk_gen/schemas/collaborations.py @@ -0,0 +1,29 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.collaboration import Collaboration + +from box_sdk_gen.box.errors import BoxSDKError + +class Collaborations(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, prev_marker: Optional[str] = None, entries: Optional[List[Collaboration]] = 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 + :param entries: A list of collaborations, defaults to None + :type entries: Optional[List[Collaboration]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.prev_marker = prev_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/collaborations_offset_paginated.py b/box_sdk_gen/schemas/collaborations_offset_paginated.py new file mode 100644 index 000000000..6193f4379 --- /dev/null +++ b/box_sdk_gen/schemas/collaborations_offset_paginated.py @@ -0,0 +1,38 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.collaboration import Collaboration + +from box_sdk_gen.box.errors import BoxSDKError + +class CollaborationsOffsetPaginated(BaseObject): + def __init__(self, *, total_count: Optional[int] = None, limit: Optional[int] = None, offset: Optional[int] = None, entries: Optional[List[Collaboration]] = None, **kwargs): + """ + :param total_count: One greater than the offset of the last entry in the entire collection. +The total number of entries in the collection may be less than +`total_count`. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type total_count: Optional[int], optional + :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 offset: The 0-based offset of the first entry in this set. This will be the same +as the `offset` query parameter. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type offset: Optional[int], optional + :param entries: A list of collaborations, defaults to None + :type entries: Optional[List[Collaboration]], optional + """ + super().__init__(**kwargs) + self.total_count = total_count + self.limit = limit + self.offset = offset + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/collaborator_variable.py b/box_sdk_gen/schemas/collaborator_variable.py new file mode 100644 index 000000000..494f1bbd5 --- /dev/null +++ b/box_sdk_gen/schemas/collaborator_variable.py @@ -0,0 +1,50 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from box_sdk_gen.box.errors import BoxSDKError + +class CollaboratorVariableTypeField(str, Enum): + VARIABLE = 'variable' + +class CollaboratorVariableVariableTypeField(str, Enum): + USER_LIST = 'user_list' + +class CollaboratorVariableVariableValueTypeField(str, Enum): + USER = 'user' + +class CollaboratorVariableVariableValueField(BaseObject): + _discriminator = 'type', {'user'} + def __init__(self, id: str, *, type: CollaboratorVariableVariableValueTypeField = CollaboratorVariableVariableValueTypeField.USER, **kwargs): + """ + :param id: User's ID. + :type id: str + :param type: The object type., defaults to CollaboratorVariableVariableValueTypeField.USER + :type type: CollaboratorVariableVariableValueTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class CollaboratorVariable(BaseObject): + _discriminator = 'type', {'variable'} + def __init__(self, variable_value: List[CollaboratorVariableVariableValueField], *, type: CollaboratorVariableTypeField = CollaboratorVariableTypeField.VARIABLE, variable_type: CollaboratorVariableVariableTypeField = CollaboratorVariableVariableTypeField.USER_LIST, **kwargs): + """ + :param variable_value: A list of user IDs. + :type variable_value: List[CollaboratorVariableVariableValueField] + :param type: Collaborator +object type. +, defaults to CollaboratorVariableTypeField.VARIABLE + :type type: CollaboratorVariableTypeField, optional + :param variable_type: Variable type +for the Collaborator +object. +, defaults to CollaboratorVariableVariableTypeField.USER_LIST + :type variable_type: CollaboratorVariableVariableTypeField, optional + """ + super().__init__(**kwargs) + self.variable_value = variable_value + self.type = type + self.variable_type = variable_type \ No newline at end of file diff --git a/box_sdk_gen/schemas/collection.py b/box_sdk_gen/schemas/collection.py new file mode 100644 index 000000000..625748ab4 --- /dev/null +++ b/box_sdk_gen/schemas/collection.py @@ -0,0 +1,37 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class CollectionTypeField(str, Enum): + COLLECTION = 'collection' + +class CollectionNameField(str, Enum): + FAVORITES = 'Favorites' + +class CollectionCollectionTypeField(str, Enum): + FAVORITES = 'favorites' + +class Collection(BaseObject): + _discriminator = 'type', {'collection'} + def __init__(self, *, id: Optional[str] = None, type: Optional[CollectionTypeField] = None, name: Optional[CollectionNameField] = None, collection_type: Optional[CollectionCollectionTypeField] = None, **kwargs): + """ + :param id: The unique identifier for this collection., defaults to None + :type id: Optional[str], optional + :param type: `collection`, defaults to None + :type type: Optional[CollectionTypeField], optional + :param name: The name of the collection., defaults to None + :type name: Optional[CollectionNameField], optional + :param collection_type: The type of the collection. This is used to +determine the proper visual treatment for +collections., defaults to None + :type collection_type: Optional[CollectionCollectionTypeField], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.name = name + self.collection_type = collection_type \ No newline at end of file diff --git a/box_sdk_gen/schemas/collections.py b/box_sdk_gen/schemas/collections.py new file mode 100644 index 000000000..21270cc86 --- /dev/null +++ b/box_sdk_gen/schemas/collections.py @@ -0,0 +1,62 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from box_sdk_gen.schemas.collection import Collection + +from box_sdk_gen.box.errors import BoxSDKError + +class CollectionsOrderDirectionField(str, Enum): + ASC = 'ASC' + DESC = 'DESC' + +class CollectionsOrderField(BaseObject): + def __init__(self, *, by: Optional[str] = None, direction: Optional[CollectionsOrderDirectionField] = None, **kwargs): + """ + :param by: The field to order by, defaults to None + :type by: Optional[str], optional + :param direction: The direction to order by, either ascending or descending, defaults to None + :type direction: Optional[CollectionsOrderDirectionField], optional + """ + super().__init__(**kwargs) + self.by = by + self.direction = direction + +class Collections(BaseObject): + def __init__(self, *, total_count: Optional[int] = None, limit: Optional[int] = None, offset: Optional[int] = None, order: Optional[List[CollectionsOrderField]] = None, entries: Optional[List[Collection]] = None, **kwargs): + """ + :param total_count: One greater than the offset of the last entry in the entire collection. +The total number of entries in the collection may be less than +`total_count`. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type total_count: Optional[int], optional + :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 offset: The 0-based offset of the first entry in this set. This will be the same +as the `offset` query parameter. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type offset: Optional[int], optional + :param order: The order by which items are returned. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type order: Optional[List[CollectionsOrderField]], optional + :param entries: A list of collections, defaults to None + :type entries: Optional[List[Collection]], optional + """ + super().__init__(**kwargs) + self.total_count = total_count + self.limit = limit + self.offset = offset + self.order = order + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/comment.py b/box_sdk_gen/schemas/comment.py new file mode 100644 index 000000000..b08886bb2 --- /dev/null +++ b/box_sdk_gen/schemas/comment.py @@ -0,0 +1,50 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.comment_base import CommentBaseTypeField + +from box_sdk_gen.schemas.comment_base import CommentBase + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class CommentItemField(BaseObject): + def __init__(self, *, id: Optional[str] = None, type: Optional[str] = None, **kwargs): + """ + :param id: The unique identifier for this object, defaults to None + :type id: Optional[str], optional + :param type: The type for this object, defaults to None + :type type: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class Comment(CommentBase): + def __init__(self, *, is_reply_comment: Optional[bool] = None, message: Optional[str] = None, created_by: Optional[UserMini] = None, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, item: Optional[CommentItemField] = None, id: Optional[str] = None, type: Optional[CommentBaseTypeField] = None, **kwargs): + """ + :param is_reply_comment: Whether or not this comment is a reply to another +comment, defaults to None + :type is_reply_comment: Optional[bool], optional + :param message: The text of the comment, as provided by the user, defaults to None + :type message: Optional[str], optional + :param created_at: The time this comment was created, defaults to None + :type created_at: Optional[DateTime], optional + :param modified_at: The time this comment was last modified, defaults to None + :type modified_at: Optional[DateTime], optional + :param id: The unique identifier for this comment., defaults to None + :type id: Optional[str], optional + :param type: `comment`, defaults to None + :type type: Optional[CommentBaseTypeField], optional + """ + super().__init__(id=id, type=type, **kwargs) + self.is_reply_comment = is_reply_comment + self.message = message + self.created_by = created_by + self.created_at = created_at + self.modified_at = modified_at + self.item = item \ No newline at end of file diff --git a/box_sdk_gen/schemas/comment_base.py b/box_sdk_gen/schemas/comment_base.py new file mode 100644 index 000000000..b03261bb4 --- /dev/null +++ b/box_sdk_gen/schemas/comment_base.py @@ -0,0 +1,23 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class CommentBaseTypeField(str, Enum): + COMMENT = 'comment' + +class CommentBase(BaseObject): + _discriminator = 'type', {'comment'} + def __init__(self, *, id: Optional[str] = None, type: Optional[CommentBaseTypeField] = None, **kwargs): + """ + :param id: The unique identifier for this comment., defaults to None + :type id: Optional[str], optional + :param type: `comment`, defaults to None + :type type: Optional[CommentBaseTypeField], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type \ No newline at end of file diff --git a/box_sdk_gen/schemas/comment_full.py b/box_sdk_gen/schemas/comment_full.py new file mode 100644 index 000000000..fde678b66 --- /dev/null +++ b/box_sdk_gen/schemas/comment_full.py @@ -0,0 +1,40 @@ +from typing import Optional + +from box_sdk_gen.schemas.comment_base import CommentBaseTypeField + +from box_sdk_gen.schemas.comment_base import CommentBase + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.internal.utils import DateTime + +from box_sdk_gen.schemas.comment import CommentItemField + +from box_sdk_gen.schemas.comment import Comment + +from box_sdk_gen.box.errors import BoxSDKError + +class CommentFull(Comment): + def __init__(self, *, tagged_message: Optional[str] = None, is_reply_comment: Optional[bool] = None, message: Optional[str] = None, created_by: Optional[UserMini] = None, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, item: Optional[CommentItemField] = None, id: Optional[str] = None, type: Optional[CommentBaseTypeField] = None, **kwargs): + """ + :param tagged_message: The string representing the comment text with +@mentions included. @mention format is @[id:username] +where `id` is user's Box ID and `username` is +their display name., defaults to None + :type tagged_message: Optional[str], optional + :param is_reply_comment: Whether or not this comment is a reply to another +comment, defaults to None + :type is_reply_comment: Optional[bool], optional + :param message: The text of the comment, as provided by the user, defaults to None + :type message: Optional[str], optional + :param created_at: The time this comment was created, defaults to None + :type created_at: Optional[DateTime], optional + :param modified_at: The time this comment was last modified, defaults to None + :type modified_at: Optional[DateTime], optional + :param id: The unique identifier for this comment., defaults to None + :type id: Optional[str], optional + :param type: `comment`, defaults to None + :type type: Optional[CommentBaseTypeField], optional + """ + super().__init__(is_reply_comment=is_reply_comment, message=message, created_by=created_by, created_at=created_at, modified_at=modified_at, item=item, id=id, type=type, **kwargs) + self.tagged_message = tagged_message \ No newline at end of file diff --git a/box_sdk_gen/schemas/comments.py b/box_sdk_gen/schemas/comments.py new file mode 100644 index 000000000..9ca88fc90 --- /dev/null +++ b/box_sdk_gen/schemas/comments.py @@ -0,0 +1,62 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from box_sdk_gen.schemas.comment_full import CommentFull + +from box_sdk_gen.box.errors import BoxSDKError + +class CommentsOrderDirectionField(str, Enum): + ASC = 'ASC' + DESC = 'DESC' + +class CommentsOrderField(BaseObject): + def __init__(self, *, by: Optional[str] = None, direction: Optional[CommentsOrderDirectionField] = None, **kwargs): + """ + :param by: The field to order by, defaults to None + :type by: Optional[str], optional + :param direction: The direction to order by, either ascending or descending, defaults to None + :type direction: Optional[CommentsOrderDirectionField], optional + """ + super().__init__(**kwargs) + self.by = by + self.direction = direction + +class Comments(BaseObject): + def __init__(self, *, total_count: Optional[int] = None, limit: Optional[int] = None, offset: Optional[int] = None, order: Optional[List[CommentsOrderField]] = None, entries: Optional[List[CommentFull]] = None, **kwargs): + """ + :param total_count: One greater than the offset of the last entry in the entire collection. +The total number of entries in the collection may be less than +`total_count`. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type total_count: Optional[int], optional + :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 offset: The 0-based offset of the first entry in this set. This will be the same +as the `offset` query parameter. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type offset: Optional[int], optional + :param order: The order by which items are returned. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type order: Optional[List[CommentsOrderField]], optional + :param entries: A list of comments, defaults to None + :type entries: Optional[List[CommentFull]], optional + """ + super().__init__(**kwargs) + self.total_count = total_count + self.limit = limit + self.offset = offset + self.order = order + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/completion_rule_variable.py b/box_sdk_gen/schemas/completion_rule_variable.py new file mode 100644 index 000000000..d7393fe0e --- /dev/null +++ b/box_sdk_gen/schemas/completion_rule_variable.py @@ -0,0 +1,39 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class CompletionRuleVariableTypeField(str, Enum): + VARIABLE = 'variable' + +class CompletionRuleVariableVariableTypeField(str, Enum): + TASK_COMPLETION_RULE = 'task_completion_rule' + +class CompletionRuleVariableVariableValueField(str, Enum): + ALL_ASSIGNEES = 'all_assignees' + ANY_ASSIGNEES = 'any_assignees' + +class CompletionRuleVariable(BaseObject): + _discriminator = 'type', {'variable'} + def __init__(self, variable_value: CompletionRuleVariableVariableValueField, *, type: CompletionRuleVariableTypeField = CompletionRuleVariableTypeField.VARIABLE, variable_type: CompletionRuleVariableVariableTypeField = CompletionRuleVariableVariableTypeField.TASK_COMPLETION_RULE, **kwargs): + """ + :param variable_value: Variable +values for a completion +rule. + + :type variable_value: CompletionRuleVariableVariableValueField + :param type: Completion +Rule object type. +, defaults to CompletionRuleVariableTypeField.VARIABLE + :type type: CompletionRuleVariableTypeField, optional + :param variable_type: Variable type +for the Completion +Rule object. +, defaults to CompletionRuleVariableVariableTypeField.TASK_COMPLETION_RULE + :type variable_type: CompletionRuleVariableVariableTypeField, optional + """ + super().__init__(**kwargs) + self.variable_value = variable_value + self.type = type + self.variable_type = variable_type \ No newline at end of file diff --git a/box_sdk_gen/schemas/conflict_error.py b/box_sdk_gen/schemas/conflict_error.py new file mode 100644 index 000000000..31864755b --- /dev/null +++ b/box_sdk_gen/schemas/conflict_error.py @@ -0,0 +1,49 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Dict + +from box_sdk_gen.schemas.client_error import ClientErrorTypeField + +from box_sdk_gen.schemas.client_error import ClientErrorCodeField + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.schemas.file_conflict import FileConflict + +from box_sdk_gen.box.errors import BoxSDKError + +class ConflictErrorContextInfoField(BaseObject): + def __init__(self, *, conflicts: Optional[List[FileConflict]] = None, **kwargs): + """ + :param conflicts: A list of the file conflicts that caused this error., defaults to None + :type conflicts: Optional[List[FileConflict]], optional + """ + super().__init__(**kwargs) + self.conflicts = conflicts + +class ConflictError(ClientError): + def __init__(self, *, type: Optional[ClientErrorTypeField] = None, status: Optional[int] = None, code: Optional[ClientErrorCodeField] = None, message: Optional[str] = None, context_info: Optional[Dict] = None, help_url: Optional[str] = None, request_id: Optional[str] = None, **kwargs): + """ + :param type: error, defaults to None + :type type: Optional[ClientErrorTypeField], optional + :param status: The HTTP status of the response., defaults to None + :type status: Optional[int], optional + :param code: A Box-specific error code, defaults to None + :type code: Optional[ClientErrorCodeField], optional + :param message: A short message describing the error., defaults to None + :type message: Optional[str], optional + :param context_info: A free-form object that contains additional context +about the error. The possible fields are defined on +a per-endpoint basis. `message` is only one example., defaults to None + :type context_info: Optional[Dict], optional + :param help_url: A URL that links to more information about why this error occurred., defaults to None + :type help_url: Optional[str], optional + :param request_id: A unique identifier for this response, which can be used +when contacting Box support., defaults to None + :type request_id: Optional[str], optional + """ + super().__init__(type=type, status=status, code=code, message=message, context_info=context_info, help_url=help_url, request_id=request_id, **kwargs) \ No newline at end of file diff --git a/box_sdk_gen/schemas/create_ai_agent.py b/box_sdk_gen/schemas/create_ai_agent.py new file mode 100644 index 000000000..4eec923b3 --- /dev/null +++ b/box_sdk_gen/schemas/create_ai_agent.py @@ -0,0 +1,46 @@ +from enum import Enum + +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.ai_agent_allowed_entity import AiAgentAllowedEntity + +from box_sdk_gen.schemas.ai_studio_agent_ask import AiStudioAgentAsk + +from box_sdk_gen.schemas.ai_studio_agent_text_gen import AiStudioAgentTextGen + +from box_sdk_gen.schemas.ai_studio_agent_extract import AiStudioAgentExtract + +from box_sdk_gen.box.errors import BoxSDKError + +class CreateAiAgentTypeField(str, Enum): + AI_AGENT = 'ai_agent' + +class CreateAiAgent(BaseObject): + _discriminator = 'type', {'ai_agent'} + def __init__(self, name: str, access_state: str, *, type: CreateAiAgentTypeField = CreateAiAgentTypeField.AI_AGENT, icon_reference: Optional[str] = None, allowed_entities: Optional[List[AiAgentAllowedEntity]] = None, ask: Optional[AiStudioAgentAsk] = None, text_gen: Optional[AiStudioAgentTextGen] = None, extract: Optional[AiStudioAgentExtract] = None, **kwargs): + """ + :param name: The name of the AI Agent. + :type name: str + :param access_state: The state of the AI Agent. Possible values are: `enabled`, `disabled`, and `enabled_for_selected_users`. + :type access_state: str + :param type: The type of agent used to handle queries., defaults to CreateAiAgentTypeField.AI_AGENT + :type type: CreateAiAgentTypeField, optional + :param icon_reference: The icon reference of the AI Agent. It should have format of the URL `https://cdn01.boxcdn.net/app-assets/aistudio/avatars/` +where possible values of `file_name` are: `logo_boxAi.png`,`logo_stamp.png`,`logo_legal.png`,`logo_finance.png`,`logo_config.png`,`logo_handshake.png`,`logo_analytics.png`,`logo_classification.png`, defaults to None + :type icon_reference: Optional[str], optional + :param allowed_entities: List of allowed users or groups., defaults to None + :type allowed_entities: Optional[List[AiAgentAllowedEntity]], optional + """ + super().__init__(**kwargs) + self.name = name + self.access_state = access_state + self.type = type + self.icon_reference = icon_reference + self.allowed_entities = allowed_entities + self.ask = ask + self.text_gen = text_gen + self.extract = extract \ No newline at end of file diff --git a/box_sdk_gen/schemas/device_pinner.py b/box_sdk_gen/schemas/device_pinner.py new file mode 100644 index 000000000..837a864a5 --- /dev/null +++ b/box_sdk_gen/schemas/device_pinner.py @@ -0,0 +1,29 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.box.errors import BoxSDKError + +class DevicePinnerTypeField(str, Enum): + DEVICE_PINNER = 'device_pinner' + +class DevicePinner(BaseObject): + _discriminator = 'type', {'device_pinner'} + def __init__(self, *, id: Optional[str] = None, type: Optional[DevicePinnerTypeField] = None, owned_by: Optional[UserMini] = None, product_name: Optional[str] = None, **kwargs): + """ + :param id: The unique identifier for this device pin., defaults to None + :type id: Optional[str], optional + :param type: `device_pinner`, defaults to None + :type type: Optional[DevicePinnerTypeField], optional + :param product_name: The type of device being pinned, defaults to None + :type product_name: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.owned_by = owned_by + self.product_name = product_name \ No newline at end of file diff --git a/box_sdk_gen/schemas/device_pinners.py b/box_sdk_gen/schemas/device_pinners.py new file mode 100644 index 000000000..f83fff2f3 --- /dev/null +++ b/box_sdk_gen/schemas/device_pinners.py @@ -0,0 +1,50 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from box_sdk_gen.schemas.device_pinner import DevicePinner + +from box_sdk_gen.box.errors import BoxSDKError + +class DevicePinnersOrderByField(str, Enum): + ID = 'id' + +class DevicePinnersOrderDirectionField(str, Enum): + ASC = 'asc' + DESC = 'desc' + +class DevicePinnersOrderField(BaseObject): + def __init__(self, *, by: Optional[DevicePinnersOrderByField] = None, direction: Optional[DevicePinnersOrderDirectionField] = None, **kwargs): + """ + :param by: The field that is ordered by, defaults to None + :type by: Optional[DevicePinnersOrderByField], optional + :param direction: The direction to order by, either ascending or descending, defaults to None + :type direction: Optional[DevicePinnersOrderDirectionField], optional + """ + super().__init__(**kwargs) + self.by = by + self.direction = direction + +class DevicePinners(BaseObject): + def __init__(self, *, entries: Optional[List[DevicePinner]] = None, limit: Optional[int] = None, next_marker: Optional[int] = None, order: Optional[List[DevicePinnersOrderField]] = None, **kwargs): + """ + :param entries: A list of device pins, defaults to None + :type entries: Optional[List[DevicePinner]], optional + :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., 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[int], optional + :param order: The order by which items are returned., defaults to None + :type order: Optional[List[DevicePinnersOrderField]], optional + """ + super().__init__(**kwargs) + self.entries = entries + self.limit = limit + self.next_marker = next_marker + self.order = order \ No newline at end of file diff --git a/box_sdk_gen/schemas/email_alias.py b/box_sdk_gen/schemas/email_alias.py new file mode 100644 index 000000000..02d964e76 --- /dev/null +++ b/box_sdk_gen/schemas/email_alias.py @@ -0,0 +1,29 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class EmailAliasTypeField(str, Enum): + EMAIL_ALIAS = 'email_alias' + +class EmailAlias(BaseObject): + _discriminator = 'type', {'email_alias'} + def __init__(self, *, id: Optional[str] = None, type: Optional[EmailAliasTypeField] = None, email: Optional[str] = None, is_confirmed: Optional[bool] = None, **kwargs): + """ + :param id: The unique identifier for this object, defaults to None + :type id: Optional[str], optional + :param type: `email_alias`, defaults to None + :type type: Optional[EmailAliasTypeField], optional + :param email: The email address, defaults to None + :type email: Optional[str], optional + :param is_confirmed: Whether the email address has been confirmed, defaults to None + :type is_confirmed: Optional[bool], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.email = email + self.is_confirmed = is_confirmed \ No newline at end of file diff --git a/box_sdk_gen/schemas/email_aliases.py b/box_sdk_gen/schemas/email_aliases.py new file mode 100644 index 000000000..afce96c2b --- /dev/null +++ b/box_sdk_gen/schemas/email_aliases.py @@ -0,0 +1,21 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.email_alias import EmailAlias + +from box_sdk_gen.box.errors import BoxSDKError + +class EmailAliases(BaseObject): + def __init__(self, *, total_count: Optional[int] = None, entries: Optional[List[EmailAlias]] = None, **kwargs): + """ + :param total_count: The number of email aliases., defaults to None + :type total_count: Optional[int], optional + :param entries: A list of email aliases, defaults to None + :type entries: Optional[List[EmailAlias]], optional + """ + super().__init__(**kwargs) + self.total_count = total_count + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/enterprise_base.py b/box_sdk_gen/schemas/enterprise_base.py new file mode 100644 index 000000000..5b3aaae71 --- /dev/null +++ b/box_sdk_gen/schemas/enterprise_base.py @@ -0,0 +1,23 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class EnterpriseBaseTypeField(str, Enum): + ENTERPRISE = 'enterprise' + +class EnterpriseBase(BaseObject): + _discriminator = 'type', {'enterprise'} + def __init__(self, *, id: Optional[str] = None, type: Optional[EnterpriseBaseTypeField] = None, **kwargs): + """ + :param id: The unique identifier for this enterprise, defaults to None + :type id: Optional[str], optional + :param type: `enterprise`, defaults to None + :type type: Optional[EnterpriseBaseTypeField], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type \ No newline at end of file diff --git a/box_sdk_gen/schemas/event.py b/box_sdk_gen/schemas/event.py new file mode 100644 index 000000000..6f74bd2bd --- /dev/null +++ b/box_sdk_gen/schemas/event.py @@ -0,0 +1,205 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Optional + +from typing import Union + +from typing import Dict + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.schemas.user import User + +from box_sdk_gen.schemas.event_source import EventSource + +from box_sdk_gen.schemas.file import File + +from box_sdk_gen.schemas.folder import Folder + +from box_sdk_gen.schemas.app_item_event_source import AppItemEventSource + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class EventEventTypeField(str, Enum): + ACCESS_GRANTED = 'ACCESS_GRANTED' + ACCESS_REVOKED = 'ACCESS_REVOKED' + ADD_DEVICE_ASSOCIATION = 'ADD_DEVICE_ASSOCIATION' + ADD_LOGIN_ACTIVITY_DEVICE = 'ADD_LOGIN_ACTIVITY_DEVICE' + ADMIN_LOGIN = 'ADMIN_LOGIN' + APPLICATION_CREATED = 'APPLICATION_CREATED' + APPLICATION_PUBLIC_KEY_ADDED = 'APPLICATION_PUBLIC_KEY_ADDED' + APPLICATION_PUBLIC_KEY_DELETED = 'APPLICATION_PUBLIC_KEY_DELETED' + CHANGE_ADMIN_ROLE = 'CHANGE_ADMIN_ROLE' + CHANGE_FOLDER_PERMISSION = 'CHANGE_FOLDER_PERMISSION' + COLLABORATION_ACCEPT = 'COLLABORATION_ACCEPT' + COLLABORATION_EXPIRATION = 'COLLABORATION_EXPIRATION' + COLLABORATION_INVITE = 'COLLABORATION_INVITE' + COLLABORATION_REMOVE = 'COLLABORATION_REMOVE' + COLLABORATION_ROLE_CHANGE = 'COLLABORATION_ROLE_CHANGE' + COLLAB_ADD_COLLABORATOR = 'COLLAB_ADD_COLLABORATOR' + COLLAB_INVITE_COLLABORATOR = 'COLLAB_INVITE_COLLABORATOR' + COLLAB_REMOVE_COLLABORATOR = 'COLLAB_REMOVE_COLLABORATOR' + COLLAB_ROLE_CHANGE = 'COLLAB_ROLE_CHANGE' + COMMENT_CREATE = 'COMMENT_CREATE' + COMMENT_DELETE = 'COMMENT_DELETE' + CONTENT_ACCESS = 'CONTENT_ACCESS' + CONTENT_WORKFLOW_ABNORMAL_DOWNLOAD_ACTIVITY = 'CONTENT_WORKFLOW_ABNORMAL_DOWNLOAD_ACTIVITY' + CONTENT_WORKFLOW_AUTOMATION_ADD = 'CONTENT_WORKFLOW_AUTOMATION_ADD' + CONTENT_WORKFLOW_AUTOMATION_DELETE = 'CONTENT_WORKFLOW_AUTOMATION_DELETE' + CONTENT_WORKFLOW_POLICY_ADD = 'CONTENT_WORKFLOW_POLICY_ADD' + CONTENT_WORKFLOW_SHARING_POLICY_VIOLATION = 'CONTENT_WORKFLOW_SHARING_POLICY_VIOLATION' + CONTENT_WORKFLOW_UPLOAD_POLICY_VIOLATION = 'CONTENT_WORKFLOW_UPLOAD_POLICY_VIOLATION' + COPY = 'COPY' + DATA_RETENTION_CREATE_RETENTION = 'DATA_RETENTION_CREATE_RETENTION' + DATA_RETENTION_REMOVE_RETENTION = 'DATA_RETENTION_REMOVE_RETENTION' + DELETE = 'DELETE' + DELETE_USER = 'DELETE_USER' + DEVICE_TRUST_CHECK_FAILED = 'DEVICE_TRUST_CHECK_FAILED' + DOWNLOAD = 'DOWNLOAD' + EDIT = 'EDIT' + EDIT_USER = 'EDIT_USER' + EDR_CROWDSTRIKE_DEVICE_DETECTED = 'EDR_CROWDSTRIKE_DEVICE_DETECTED' + EDR_CROWDSTRIKE_NO_BOX_TOOLS = 'EDR_CROWDSTRIKE_NO_BOX_TOOLS' + EDR_CROWDSTRIKE_BOX_TOOLS_OUTDATED = 'EDR_CROWDSTRIKE_BOX_TOOLS_OUTDATED' + EDR_CROWDSTRIKE_DRIVE_OUTDATED = 'EDR_CROWDSTRIKE_DRIVE_OUTDATED' + EDR_CROWDSTRIKE_ACCESS_ALLOWED_NO_CROWDSTRIKE_DEVICE = 'EDR_CROWDSTRIKE_ACCESS_ALLOWED_NO_CROWDSTRIKE_DEVICE' + EDR_CROWDSTRIKE_ACCESS_REVOKED = 'EDR_CROWDSTRIKE_ACCESS_REVOKED' + EMAIL_ALIAS_CONFIRM = 'EMAIL_ALIAS_CONFIRM' + EMAIL_ALIAS_REMOVE = 'EMAIL_ALIAS_REMOVE' + ENABLE_TWO_FACTOR_AUTH = 'ENABLE_TWO_FACTOR_AUTH' + ENTERPRISE_APP_AUTHORIZATION_UPDATE = 'ENTERPRISE_APP_AUTHORIZATION_UPDATE' + FAILED_LOGIN = 'FAILED_LOGIN' + FILE_MARKED_MALICIOUS = 'FILE_MARKED_MALICIOUS' + FILE_WATERMARKED_DOWNLOAD = 'FILE_WATERMARKED_DOWNLOAD' + GROUP_ADD_ITEM = 'GROUP_ADD_ITEM' + GROUP_ADD_USER = 'GROUP_ADD_USER' + GROUP_CREATION = 'GROUP_CREATION' + GROUP_DELETION = 'GROUP_DELETION' + GROUP_EDITED = 'GROUP_EDITED' + GROUP_REMOVE_ITEM = 'GROUP_REMOVE_ITEM' + GROUP_REMOVE_USER = 'GROUP_REMOVE_USER' + ITEM_COPY = 'ITEM_COPY' + ITEM_CREATE = 'ITEM_CREATE' + ITEM_DOWNLOAD = 'ITEM_DOWNLOAD' + ITEM_EMAIL_SEND = 'ITEM_EMAIL_SEND' + ITEM_MAKE_CURRENT_VERSION = 'ITEM_MAKE_CURRENT_VERSION' + ITEM_MODIFY = 'ITEM_MODIFY' + ITEM_MOVE = 'ITEM_MOVE' + ITEM_OPEN = 'ITEM_OPEN' + ITEM_PREVIEW = 'ITEM_PREVIEW' + ITEM_RENAME = 'ITEM_RENAME' + ITEM_SHARED = 'ITEM_SHARED' + ITEM_SHARED_CREATE = 'ITEM_SHARED_CREATE' + ITEM_SHARED_UNSHARE = 'ITEM_SHARED_UNSHARE' + ITEM_SHARED_UPDATE = 'ITEM_SHARED_UPDATE' + ITEM_SYNC = 'ITEM_SYNC' + ITEM_TRASH = 'ITEM_TRASH' + ITEM_UNDELETE_VIA_TRASH = 'ITEM_UNDELETE_VIA_TRASH' + ITEM_UNSYNC = 'ITEM_UNSYNC' + ITEM_UPLOAD = 'ITEM_UPLOAD' + LEGAL_HOLD_ASSIGNMENT_CREATE = 'LEGAL_HOLD_ASSIGNMENT_CREATE' + LEGAL_HOLD_ASSIGNMENT_DELETE = 'LEGAL_HOLD_ASSIGNMENT_DELETE' + LEGAL_HOLD_POLICY_CREATE = 'LEGAL_HOLD_POLICY_CREATE' + LEGAL_HOLD_POLICY_DELETE = 'LEGAL_HOLD_POLICY_DELETE' + LEGAL_HOLD_POLICY_UPDATE = 'LEGAL_HOLD_POLICY_UPDATE' + LOCK = 'LOCK' + LOCK_CREATE = 'LOCK_CREATE' + LOCK_DESTROY = 'LOCK_DESTROY' + LOGIN = 'LOGIN' + MASTER_INVITE_ACCEPT = 'MASTER_INVITE_ACCEPT' + MASTER_INVITE_REJECT = 'MASTER_INVITE_REJECT' + METADATA_INSTANCE_CREATE = 'METADATA_INSTANCE_CREATE' + METADATA_INSTANCE_DELETE = 'METADATA_INSTANCE_DELETE' + METADATA_INSTANCE_UPDATE = 'METADATA_INSTANCE_UPDATE' + METADATA_TEMPLATE_CREATE = 'METADATA_TEMPLATE_CREATE' + METADATA_TEMPLATE_DELETE = 'METADATA_TEMPLATE_DELETE' + METADATA_TEMPLATE_UPDATE = 'METADATA_TEMPLATE_UPDATE' + MOVE = 'MOVE' + NEW_USER = 'NEW_USER' + PREVIEW = 'PREVIEW' + REMOVE_DEVICE_ASSOCIATION = 'REMOVE_DEVICE_ASSOCIATION' + REMOVE_LOGIN_ACTIVITY_DEVICE = 'REMOVE_LOGIN_ACTIVITY_DEVICE' + RENAME = 'RENAME' + RETENTION_POLICY_ASSIGNMENT_ADD = 'RETENTION_POLICY_ASSIGNMENT_ADD' + SHARE = 'SHARE' + SHARED_LINK_SEND = 'SHARED_LINK_SEND' + SHARE_EXPIRATION = 'SHARE_EXPIRATION' + SHIELD_ALERT = 'SHIELD_ALERT' + SHIELD_EXTERNAL_COLLAB_ACCESS_BLOCKED = 'SHIELD_EXTERNAL_COLLAB_ACCESS_BLOCKED' + SHIELD_EXTERNAL_COLLAB_ACCESS_BLOCKED_MISSING_JUSTIFICATION = 'SHIELD_EXTERNAL_COLLAB_ACCESS_BLOCKED_MISSING_JUSTIFICATION' + SHIELD_EXTERNAL_COLLAB_INVITE_BLOCKED = 'SHIELD_EXTERNAL_COLLAB_INVITE_BLOCKED' + SHIELD_EXTERNAL_COLLAB_INVITE_BLOCKED_MISSING_JUSTIFICATION = 'SHIELD_EXTERNAL_COLLAB_INVITE_BLOCKED_MISSING_JUSTIFICATION' + SHIELD_JUSTIFICATION_APPROVAL = 'SHIELD_JUSTIFICATION_APPROVAL' + SHIELD_SHARED_LINK_ACCESS_BLOCKED = 'SHIELD_SHARED_LINK_ACCESS_BLOCKED' + SHIELD_SHARED_LINK_STATUS_RESTRICTED_ON_CREATE = 'SHIELD_SHARED_LINK_STATUS_RESTRICTED_ON_CREATE' + SHIELD_SHARED_LINK_STATUS_RESTRICTED_ON_UPDATE = 'SHIELD_SHARED_LINK_STATUS_RESTRICTED_ON_UPDATE' + SIGN_DOCUMENT_ASSIGNED = 'SIGN_DOCUMENT_ASSIGNED' + SIGN_DOCUMENT_CANCELLED = 'SIGN_DOCUMENT_CANCELLED' + SIGN_DOCUMENT_COMPLETED = 'SIGN_DOCUMENT_COMPLETED' + SIGN_DOCUMENT_CONVERTED = 'SIGN_DOCUMENT_CONVERTED' + SIGN_DOCUMENT_CREATED = 'SIGN_DOCUMENT_CREATED' + SIGN_DOCUMENT_DECLINED = 'SIGN_DOCUMENT_DECLINED' + SIGN_DOCUMENT_EXPIRED = 'SIGN_DOCUMENT_EXPIRED' + SIGN_DOCUMENT_SIGNED = 'SIGN_DOCUMENT_SIGNED' + SIGN_DOCUMENT_VIEWED_BY_SIGNED = 'SIGN_DOCUMENT_VIEWED_BY_SIGNED' + SIGNER_DOWNLOADED = 'SIGNER_DOWNLOADED' + SIGNER_FORWARDED = 'SIGNER_FORWARDED' + STORAGE_EXPIRATION = 'STORAGE_EXPIRATION' + TAG_ITEM_CREATE = 'TAG_ITEM_CREATE' + TASK_ASSIGNMENT_CREATE = 'TASK_ASSIGNMENT_CREATE' + TASK_ASSIGNMENT_DELETE = 'TASK_ASSIGNMENT_DELETE' + TASK_ASSIGNMENT_UPDATE = 'TASK_ASSIGNMENT_UPDATE' + TASK_CREATE = 'TASK_CREATE' + TASK_UPDATE = 'TASK_UPDATE' + TERMS_OF_SERVICE_ACCEPT = 'TERMS_OF_SERVICE_ACCEPT' + TERMS_OF_SERVICE_REJECT = 'TERMS_OF_SERVICE_REJECT' + UNDELETE = 'UNDELETE' + UNLOCK = 'UNLOCK' + UNSHARE = 'UNSHARE' + UPDATE_COLLABORATION_EXPIRATION = 'UPDATE_COLLABORATION_EXPIRATION' + UPDATE_SHARE_EXPIRATION = 'UPDATE_SHARE_EXPIRATION' + UPLOAD = 'UPLOAD' + USER_AUTHENTICATE_OAUTH2_ACCESS_TOKEN_CREATE = 'USER_AUTHENTICATE_OAUTH2_ACCESS_TOKEN_CREATE' + WATERMARK_LABEL_CREATE = 'WATERMARK_LABEL_CREATE' + WATERMARK_LABEL_DELETE = 'WATERMARK_LABEL_DELETE' + +class EventAdditionalDetailsField(BaseObject): + def __init__(self, **kwargs): + super().__init__(**kwargs) + +class Event(BaseObject): + def __init__(self, *, type: Optional[str] = None, created_at: Optional[DateTime] = None, recorded_at: Optional[DateTime] = None, event_id: Optional[str] = None, created_by: Optional[UserMini] = None, event_type: Optional[EventEventTypeField] = None, session_id: Optional[str] = None, source: Optional[Union[User, EventSource, File, Folder, Dict, AppItemEventSource]] = None, additional_details: Optional[EventAdditionalDetailsField] = None, **kwargs): + """ + :param type: `event`, defaults to None + :type type: Optional[str], optional + :param created_at: When the event object was created, defaults to None + :type created_at: Optional[DateTime], optional + :param recorded_at: When the event object was recorded in database, defaults to None + :type recorded_at: Optional[DateTime], optional + :param event_id: The ID of the event object. You can use this to detect duplicate events, defaults to None + :type event_id: Optional[str], optional + :param session_id: The session of the user that performed the action. Not all events will +populate this attribute., defaults to None + :type session_id: Optional[str], optional + :param additional_details: This object provides additional information about the event if available. + +This can include how a user performed an event as well as additional +information to correlate an event to external KeySafe logs. Not all events +have an `additional_details` object. This object is only available in the +Enterprise Events., defaults to None + :type additional_details: Optional[EventAdditionalDetailsField], optional + """ + super().__init__(**kwargs) + self.type = type + self.created_at = created_at + self.recorded_at = recorded_at + self.event_id = event_id + self.created_by = created_by + self.event_type = event_type + self.session_id = session_id + self.source = source + self.additional_details = additional_details \ No newline at end of file diff --git a/box_sdk_gen/schemas/event_source.py b/box_sdk_gen/schemas/event_source.py new file mode 100644 index 000000000..796940d34 --- /dev/null +++ b/box_sdk_gen/schemas/event_source.py @@ -0,0 +1,52 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.folder_mini import FolderMini + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.box.errors import BoxSDKError + +class EventSourceItemTypeField(str, Enum): + FILE = 'file' + FOLDER = 'folder' + +class EventSourceClassificationField(BaseObject): + def __init__(self, *, name: Optional[str] = None, **kwargs): + """ + :param name: The classification's name, defaults to None + :type name: Optional[str], optional + """ + super().__init__(**kwargs) + self.name = name + +class EventSource(BaseObject): + _discriminator = 'item_type', {'file', 'folder'} + def __init__(self, item_type: EventSourceItemTypeField, item_id: str, item_name: str, *, classification: Optional[EventSourceClassificationField] = None, parent: Optional[FolderMini] = None, owned_by: Optional[UserMini] = None, **kwargs): + """ + :param item_type: The type of the item that the event +represents. Can be `file` or `folder`. + + :type item_type: EventSourceItemTypeField + :param item_id: The unique identifier that represents the +item. + + :type item_id: str + :param item_name: The name of the item. + + :type item_name: str + :param classification: The object containing classification information for the item that +triggered the event. This field will not appear if the item does not +have a classification set., defaults to None + :type classification: Optional[EventSourceClassificationField], optional + """ + super().__init__(**kwargs) + self.item_type = item_type + self.item_id = item_id + self.item_name = item_name + self.classification = classification + self.parent = parent + self.owned_by = owned_by \ No newline at end of file diff --git a/box_sdk_gen/schemas/events.py b/box_sdk_gen/schemas/events.py new file mode 100644 index 000000000..786daf785 --- /dev/null +++ b/box_sdk_gen/schemas/events.py @@ -0,0 +1,27 @@ +from typing import Optional + +from typing import Union + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.event import Event + +from box_sdk_gen.box.errors import BoxSDKError + +class Events(BaseObject): + def __init__(self, *, chunk_size: Optional[int] = None, next_stream_position: Optional[Union[str, float]] = None, entries: Optional[List[Event]] = None, **kwargs): + """ + :param chunk_size: The number of events returned in this response., defaults to None + :type chunk_size: Optional[int], optional + :param next_stream_position: The stream position of the start of the next page (chunk) +of events., defaults to None + :type next_stream_position: Optional[Union[str, float]], optional + :param entries: A list of events, defaults to None + :type entries: Optional[List[Event]], optional + """ + super().__init__(**kwargs) + self.chunk_size = chunk_size + self.next_stream_position = next_stream_position + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/file.py b/box_sdk_gen/schemas/file.py new file mode 100644 index 000000000..f6871224d --- /dev/null +++ b/box_sdk_gen/schemas/file.py @@ -0,0 +1,219 @@ +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from enum import Enum + +from typing import Optional + +from box_sdk_gen.schemas.file_base import FileBaseTypeField + +from box_sdk_gen.schemas.file_base import FileBase + +from box_sdk_gen.schemas.file_version_mini import FileVersionMini + +from box_sdk_gen.schemas.file_mini import FileMini + +from box_sdk_gen.schemas.folder_mini import FolderMini + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class FilePathCollectionField(BaseObject): + def __init__(self, total_count: int, entries: List[FolderMini], **kwargs): + """ + :param total_count: The number of folders in this list. + :type total_count: int + :param entries: The parent folders for this item + :type entries: List[FolderMini] + """ + super().__init__(**kwargs) + self.total_count = total_count + self.entries = entries + +class FileSharedLinkAccessField(str, Enum): + OPEN = 'open' + COMPANY = 'company' + COLLABORATORS = 'collaborators' + +class FileSharedLinkEffectiveAccessField(str, Enum): + OPEN = 'open' + COMPANY = 'company' + COLLABORATORS = 'collaborators' + +class FileSharedLinkEffectivePermissionField(str, Enum): + CAN_EDIT = 'can_edit' + CAN_DOWNLOAD = 'can_download' + CAN_PREVIEW = 'can_preview' + NO_ACCESS = 'no_access' + +class FileSharedLinkPermissionsField(BaseObject): + def __init__(self, can_download: bool, can_preview: bool, can_edit: bool, **kwargs): + """ + :param can_download: Defines if the shared link allows for the item to be downloaded. For +shared links on folders, this also applies to any items in the folder. + +This value can be set to `true` when the effective access level is +set to `open` or `company`, not `collaborators`. + :type can_download: bool + :param can_preview: Defines if the shared link allows for the item to be previewed. + +This value is always `true`. For shared links on folders this also +applies to any items in the folder. + :type can_preview: bool + :param can_edit: Defines if the shared link allows for the item to be edited. + +This value can only be `true` if `can_download` is also `true` and if +the item has a type of `file`. + :type can_edit: bool + """ + super().__init__(**kwargs) + self.can_download = can_download + self.can_preview = can_preview + self.can_edit = can_edit + +class FileSharedLinkField(BaseObject): + def __init__(self, url: str, effective_access: FileSharedLinkEffectiveAccessField, effective_permission: FileSharedLinkEffectivePermissionField, is_password_enabled: bool, download_count: int, preview_count: int, *, download_url: Optional[str] = None, vanity_url: Optional[str] = None, vanity_name: Optional[str] = None, access: Optional[FileSharedLinkAccessField] = None, unshared_at: Optional[DateTime] = None, permissions: Optional[FileSharedLinkPermissionsField] = None, **kwargs): + """ + :param url: The URL that can be used to access the item on Box. + +This URL will display the item in Box's preview UI where the file +can be downloaded if allowed. + +This URL will continue to work even when a custom `vanity_url` +has been set for this shared link. + :type url: str + :param effective_access: The effective access level for the shared link. This can be a more +restrictive access level than the value in the `access` field when the +enterprise settings restrict the allowed access levels. + :type effective_access: FileSharedLinkEffectiveAccessField + :param effective_permission: The effective permissions for this shared link. +These result in the more restrictive combination of +the share link permissions and the item permissions set +by the administrator, the owner, and any ancestor item +such as a folder. + :type effective_permission: FileSharedLinkEffectivePermissionField + :param is_password_enabled: Defines if the shared link requires a password to access the item. + :type is_password_enabled: bool + :param download_count: The number of times this item has been downloaded. + :type download_count: int + :param preview_count: The number of times this item has been previewed. + :type preview_count: int + :param download_url: A URL that can be used to download the file. This URL can be used in +a browser to download the file. This URL includes the file +extension so that the file will be saved with the right file type. + +This property will be `null` for folders., defaults to None + :type download_url: Optional[str], optional + :param vanity_url: The "Custom URL" that can also be used to preview the item on Box. Custom +URLs can only be created or modified in the Box Web application., defaults to None + :type vanity_url: Optional[str], optional + :param vanity_name: The custom name of a shared link, as used in the `vanity_url` field., defaults to None + :type vanity_name: Optional[str], optional + :param access: The access level for this shared link. + +* `open` - provides access to this item to anyone with this link +* `company` - only provides access to this item to people the same company +* `collaborators` - only provides access to this item to people who are + collaborators on this item + +If this field is omitted when creating the shared link, the access level +will be set to the default access level specified by the enterprise admin., defaults to None + :type access: Optional[FileSharedLinkAccessField], optional + :param unshared_at: The date and time when this link will be unshared. This field can only be +set by users with paid accounts., defaults to None + :type unshared_at: Optional[DateTime], optional + :param permissions: Defines if this link allows a user to preview, edit, and download an item. +These permissions refer to the shared link only and +do not supersede permissions applied to the item itself., defaults to None + :type permissions: Optional[FileSharedLinkPermissionsField], optional + """ + super().__init__(**kwargs) + self.url = url + self.effective_access = effective_access + self.effective_permission = effective_permission + self.is_password_enabled = is_password_enabled + self.download_count = download_count + self.preview_count = preview_count + self.download_url = download_url + self.vanity_url = vanity_url + self.vanity_name = vanity_name + self.access = access + self.unshared_at = unshared_at + self.permissions = permissions + +class FileItemStatusField(str, Enum): + ACTIVE = 'active' + TRASHED = 'trashed' + DELETED = 'deleted' + +class File(FileMini): + def __init__(self, id: str, *, description: Optional[str] = None, size: Optional[int] = None, path_collection: Optional[FilePathCollectionField] = None, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, trashed_at: Optional[DateTime] = None, purged_at: Optional[DateTime] = None, content_created_at: Optional[DateTime] = None, content_modified_at: Optional[DateTime] = None, created_by: Optional[UserMini] = None, modified_by: Optional[UserMini] = None, owned_by: Optional[UserMini] = None, shared_link: Optional[FileSharedLinkField] = None, parent: Optional[FolderMini] = None, item_status: Optional[FileItemStatusField] = None, sequence_id: Optional[str] = None, name: Optional[str] = None, sha_1: Optional[str] = None, file_version: Optional[FileVersionMini] = None, etag: Optional[str] = None, type: FileBaseTypeField = FileBaseTypeField.FILE, **kwargs): + """ + :param id: The unique identifier that represent 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`. + :type id: str + :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 + :type description: Optional[str], optional + :param size: The file size in bytes. Be careful parsing this integer as it can +get very large and cause an integer overflow., defaults to None + :type size: Optional[int], optional + :param created_at: The date and time when the file was created on Box., defaults to None + :type created_at: Optional[DateTime], optional + :param modified_at: The date and time when the file was last updated on Box., defaults to None + :type modified_at: Optional[DateTime], optional + :param trashed_at: The time at which this file was put in the trash., defaults to None + :type trashed_at: Optional[DateTime], optional + :param purged_at: The time at which this file is expected to be purged +from the trash., defaults to None + :type purged_at: Optional[DateTime], optional + :param content_created_at: The date and time at which this file was originally +created, which might be before it was uploaded to Box., defaults to None + :type content_created_at: Optional[DateTime], optional + :param content_modified_at: The date and time at which this file was last updated, +which might be before it was uploaded to Box., defaults to None + :type content_modified_at: Optional[DateTime], optional + :param item_status: Defines if this item has been deleted or not. + +* `active` when the item has is not in the trash +* `trashed` when the item has been moved to the trash but not deleted +* `deleted` when the item has been permanently deleted., defaults to None + :type item_status: Optional[FileItemStatusField], optional + :param name: The name of the file, defaults to None + :type name: Optional[str], optional + :param sha_1: The SHA1 hash of the file. This can be used to compare the contents +of a file on Box with a local file., defaults to None + :type sha_1: Optional[str], optional + :param etag: The HTTP `etag` of this file. This can be used within some API +endpoints in the `If-Match` and `If-None-Match` headers to only +perform changes on the file if (no) changes have happened., defaults to None + :type etag: Optional[str], optional + :param type: `file`, defaults to FileBaseTypeField.FILE + :type type: FileBaseTypeField, optional + """ + super().__init__(id=id, sequence_id=sequence_id, name=name, sha_1=sha_1, file_version=file_version, etag=etag, type=type, **kwargs) + self.description = description + self.size = size + self.path_collection = path_collection + self.created_at = created_at + self.modified_at = modified_at + self.trashed_at = trashed_at + self.purged_at = purged_at + self.content_created_at = content_created_at + self.content_modified_at = content_modified_at + self.created_by = created_by + self.modified_by = modified_by + self.owned_by = owned_by + self.shared_link = shared_link + self.parent = parent + self.item_status = item_status \ No newline at end of file diff --git a/box_sdk_gen/schemas/file_base.py b/box_sdk_gen/schemas/file_base.py new file mode 100644 index 000000000..bf31a1cf3 --- /dev/null +++ b/box_sdk_gen/schemas/file_base.py @@ -0,0 +1,34 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class FileBaseTypeField(str, Enum): + FILE = 'file' + +class FileBase(BaseObject): + _discriminator = 'type', {'file'} + def __init__(self, id: str, *, etag: Optional[str] = None, type: FileBaseTypeField = FileBaseTypeField.FILE, **kwargs): + """ + :param id: The unique identifier that represent 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`. + :type id: str + :param etag: The HTTP `etag` of this file. This can be used within some API +endpoints in the `If-Match` and `If-None-Match` headers to only +perform changes on the file if (no) changes have happened., defaults to None + :type etag: Optional[str], optional + :param type: `file`, defaults to FileBaseTypeField.FILE + :type type: FileBaseTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.etag = etag + self.type = type \ No newline at end of file diff --git a/box_sdk_gen/schemas/file_conflict.py b/box_sdk_gen/schemas/file_conflict.py new file mode 100644 index 000000000..614fbbd33 --- /dev/null +++ b/box_sdk_gen/schemas/file_conflict.py @@ -0,0 +1,36 @@ +from typing import Optional + +from box_sdk_gen.schemas.file_base import FileBaseTypeField + +from box_sdk_gen.schemas.file_base import FileBase + +from box_sdk_gen.schemas.file_mini import FileMini + +from box_sdk_gen.schemas.file_version_mini import FileVersionMini + +from box_sdk_gen.box.errors import BoxSDKError + +class FileConflict(FileMini): + def __init__(self, id: str, *, sequence_id: Optional[str] = None, name: Optional[str] = None, sha_1: Optional[str] = None, file_version: Optional[FileVersionMini] = None, etag: Optional[str] = None, type: FileBaseTypeField = FileBaseTypeField.FILE, **kwargs): + """ + :param id: The unique identifier that represent 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`. + :type id: str + :param name: The name of the file, defaults to None + :type name: Optional[str], optional + :param sha_1: The SHA1 hash of the file. This can be used to compare the contents +of a file on Box with a local file., defaults to None + :type sha_1: Optional[str], optional + :param etag: The HTTP `etag` of this file. This can be used within some API +endpoints in the `If-Match` and `If-None-Match` headers to only +perform changes on the file if (no) changes have happened., defaults to None + :type etag: Optional[str], optional + :param type: `file`, defaults to FileBaseTypeField.FILE + :type type: FileBaseTypeField, optional + """ + super().__init__(id=id, sequence_id=sequence_id, name=name, sha_1=sha_1, file_version=file_version, etag=etag, type=type, **kwargs) \ No newline at end of file diff --git a/box_sdk_gen/schemas/file_full.py b/box_sdk_gen/schemas/file_full.py new file mode 100644 index 000000000..16df6512b --- /dev/null +++ b/box_sdk_gen/schemas/file_full.py @@ -0,0 +1,416 @@ +from box_sdk_gen.internal.base_object import BaseObject + +from enum import Enum + +from typing import Optional + +from typing import List + +from box_sdk_gen.schemas.file_base import FileBaseTypeField + +from box_sdk_gen.schemas.file_base import FileBase + +from box_sdk_gen.schemas.file_version_mini import FileVersionMini + +from box_sdk_gen.schemas.file_mini import FileMini + +from box_sdk_gen.schemas.file import FilePathCollectionField + +from box_sdk_gen.schemas.file import FileSharedLinkField + +from box_sdk_gen.schemas.folder_mini import FolderMini + +from box_sdk_gen.schemas.file import FileItemStatusField + +from box_sdk_gen.schemas.file import File + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.schemas.file_or_folder_scope import FileOrFolderScope + +from box_sdk_gen.schemas.metadata_full import MetadataFull + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class FileFullPermissionsField(BaseObject): + def __init__(self, can_delete: bool, can_download: bool, can_invite_collaborator: bool, can_rename: bool, can_set_share_access: bool, can_share: bool, can_annotate: bool, can_comment: bool, can_preview: bool, can_upload: bool, can_view_annotations_all: bool, can_view_annotations_self: bool, **kwargs): + """ + :param can_delete: Specifies if the current user can delete this item. + :type can_delete: bool + :param can_download: Specifies if the current user can download this item. + :type can_download: bool + :param can_invite_collaborator: Specifies if the current user can invite new +users to collaborate on this item, and if the user can +update the role of a user already collaborated on this +item. + :type can_invite_collaborator: bool + :param can_rename: Specifies if the user can rename this item. + :type can_rename: bool + :param can_set_share_access: Specifies if the user can change the access level of an +existing shared link on this item. + :type can_set_share_access: bool + :param can_share: Specifies if the user can create a shared link for this item. + :type can_share: bool + :param can_annotate: Specifies if the user can place annotations on this file. + :type can_annotate: bool + :param can_comment: Specifies if the user can place comments on this file. + :type can_comment: bool + :param can_preview: Specifies if the user can preview this file. + :type can_preview: bool + :param can_upload: Specifies if the user can upload a new version of this file. + :type can_upload: bool + :param can_view_annotations_all: Specifies if the user view all annotations placed on this file + :type can_view_annotations_all: bool + :param can_view_annotations_self: Specifies if the user view annotations placed by themselves +on this file + :type can_view_annotations_self: bool + """ + super().__init__(**kwargs) + self.can_delete = can_delete + self.can_download = can_download + self.can_invite_collaborator = can_invite_collaborator + self.can_rename = can_rename + self.can_set_share_access = can_set_share_access + self.can_share = can_share + self.can_annotate = can_annotate + self.can_comment = can_comment + self.can_preview = can_preview + self.can_upload = can_upload + self.can_view_annotations_all = can_view_annotations_all + self.can_view_annotations_self = can_view_annotations_self + +class FileFullLockTypeField(str, Enum): + LOCK = 'lock' + +class FileFullLockAppTypeField(str, Enum): + GSUITE = 'gsuite' + OFFICE_WOPI = 'office_wopi' + OFFICE_WOPIPLUS = 'office_wopiplus' + OTHER = 'other' + +class FileFullLockField(BaseObject): + _discriminator = 'type', {'lock'} + def __init__(self, *, id: Optional[str] = None, type: Optional[FileFullLockTypeField] = None, created_by: Optional[UserMini] = None, created_at: Optional[DateTime] = None, expired_at: Optional[DateTime] = None, is_download_prevented: Optional[bool] = None, app_type: Optional[FileFullLockAppTypeField] = None, **kwargs): + """ + :param id: The unique identifier for this lock, defaults to None + :type id: Optional[str], optional + :param type: `lock`, defaults to None + :type type: Optional[FileFullLockTypeField], optional + :param created_at: The time this lock was created at., defaults to None + :type created_at: Optional[DateTime], optional + :param expired_at: The time this lock is to expire at, which might be in the past., defaults to None + :type expired_at: Optional[DateTime], optional + :param is_download_prevented: Whether or not the file can be downloaded while locked., defaults to None + :type is_download_prevented: Optional[bool], optional + :param app_type: If the lock is managed by an application rather than a user, this +field identifies the type of the application that holds the lock. +This is an open enum and may be extended with additional values in +the future., defaults to None + :type app_type: Optional[FileFullLockAppTypeField], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.created_by = created_by + self.created_at = created_at + self.expired_at = expired_at + self.is_download_prevented = is_download_prevented + self.app_type = app_type + +class FileFullExpiringEmbedLinkTokenTypeField(str, Enum): + BEARER = 'bearer' + +class FileFullExpiringEmbedLinkField(BaseObject): + def __init__(self, *, access_token: Optional[str] = None, expires_in: Optional[int] = None, token_type: Optional[FileFullExpiringEmbedLinkTokenTypeField] = None, restricted_to: Optional[List[FileOrFolderScope]] = None, url: Optional[str] = None, **kwargs): + """ + :param access_token: The requested access token., defaults to None + :type access_token: Optional[str], optional + :param expires_in: The time in seconds by which this token will expire., defaults to None + :type expires_in: Optional[int], optional + :param token_type: The type of access token returned., defaults to None + :type token_type: Optional[FileFullExpiringEmbedLinkTokenTypeField], optional + :param restricted_to: The permissions that this access token permits, +providing a list of resources (files, folders, etc) +and the scopes permitted for each of those resources., defaults to None + :type restricted_to: Optional[List[FileOrFolderScope]], optional + :param url: The actual expiring embed URL for this file, constructed +from the file ID and access tokens specified in this object., defaults to None + :type url: Optional[str], optional + """ + super().__init__(**kwargs) + self.access_token = access_token + self.expires_in = expires_in + self.token_type = token_type + self.restricted_to = restricted_to + self.url = url + +class FileFullWatermarkInfoField(BaseObject): + def __init__(self, *, is_watermarked: Optional[bool] = None, **kwargs): + """ + :param is_watermarked: Specifies if this item has a watermark applied., defaults to None + :type is_watermarked: Optional[bool], optional + """ + super().__init__(**kwargs) + self.is_watermarked = is_watermarked + +class FileFullAllowedInviteeRolesField(str, Enum): + EDITOR = 'editor' + VIEWER = 'viewer' + PREVIEWER = 'previewer' + UPLOADER = 'uploader' + PREVIEWER_UPLOADER = 'previewer uploader' + VIEWER_UPLOADER = 'viewer uploader' + CO_OWNER = 'co-owner' + +class FileFullMetadataField(BaseObject): + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.extra_data = kwargs + +class FileFullRepresentationsEntriesContentField(BaseObject): + def __init__(self, *, url_template: Optional[str] = None, **kwargs): + """ + :param url_template: The download URL that can be used to fetch the representation. +Make sure to make an authenticated API call to this endpoint. + +This URL is a template and will require the `{+asset_path}` to +be replaced by a path. In general, for unpaged representations +it can be replaced by an empty string. + +For paged representations, replace the `{+asset_path}` with the +page to request plus the extension for the file, for example +`1.pdf`. + +When requesting the download URL the following additional +query params can be passed along. + +* `set_content_disposition_type` - Sets the +`Content-Disposition` header in the API response with the +specified disposition type of either `inline` or `attachment`. +If not supplied, the `Content-Disposition` header is not +included in the response. + +* `set_content_disposition_filename` - Allows the application to + define the representation's file name used in the + `Content-Disposition` header. If not defined, the filename + is derived from the source file name in Box combined with the + extension of the representation., defaults to None + :type url_template: Optional[str], optional + """ + super().__init__(**kwargs) + self.url_template = url_template + +class FileFullRepresentationsEntriesInfoField(BaseObject): + def __init__(self, *, url: Optional[str] = None, **kwargs): + """ + :param url: The API URL that can be used to get more info on this file +representation. Make sure to make an authenticated API call +to this endpoint., defaults to None + :type url: Optional[str], optional + """ + super().__init__(**kwargs) + self.url = url + +class FileFullRepresentationsEntriesPropertiesField(BaseObject): + def __init__(self, *, dimensions: Optional[str] = None, paged: Optional[str] = None, thumb: Optional[str] = None, **kwargs): + """ + :param dimensions: The width by height size of this representation in pixels., defaults to None + :type dimensions: Optional[str], optional + :param paged: Indicates if the representation is build up out of multiple +pages., defaults to None + :type paged: Optional[str], optional + :param thumb: Indicates if the representation can be used as a thumbnail of +the file., defaults to None + :type thumb: Optional[str], optional + """ + super().__init__(**kwargs) + self.dimensions = dimensions + self.paged = paged + self.thumb = thumb + +class FileFullRepresentationsEntriesStatusStateField(str, Enum): + SUCCESS = 'success' + VIEWABLE = 'viewable' + PENDING = 'pending' + NONE = 'none' + +class FileFullRepresentationsEntriesStatusField(BaseObject): + def __init__(self, *, state: Optional[FileFullRepresentationsEntriesStatusStateField] = None, **kwargs): + """ + :param state: The status of the representation. + +* `success` defines the representation as ready to be viewed. +* `viewable` defines a video to be ready for viewing. +* `pending` defines the representation as to be generated. Retry + this endpoint to re-check the status. +* `none` defines that the representation will be created when + requested. Request the URL defined in the `info` object to + trigger this generation., defaults to None + :type state: Optional[FileFullRepresentationsEntriesStatusStateField], optional + """ + super().__init__(**kwargs) + self.state = state + +class FileFullRepresentationsEntriesField(BaseObject): + def __init__(self, *, content: Optional[FileFullRepresentationsEntriesContentField] = None, info: Optional[FileFullRepresentationsEntriesInfoField] = None, properties: Optional[FileFullRepresentationsEntriesPropertiesField] = None, representation: Optional[str] = None, status: Optional[FileFullRepresentationsEntriesStatusField] = None, **kwargs): + """ + :param content: An object containing the URL that can be used to actually fetch +the representation., defaults to None + :type content: Optional[FileFullRepresentationsEntriesContentField], optional + :param info: An object containing the URL that can be used to fetch more info +on this representation., defaults to None + :type info: Optional[FileFullRepresentationsEntriesInfoField], optional + :param properties: An object containing the size and type of this presentation., defaults to None + :type properties: Optional[FileFullRepresentationsEntriesPropertiesField], optional + :param representation: Indicates the file type of the returned representation., defaults to None + :type representation: Optional[str], optional + :param status: An object containing the status of this representation., defaults to None + :type status: Optional[FileFullRepresentationsEntriesStatusField], optional + """ + super().__init__(**kwargs) + self.content = content + self.info = info + self.properties = properties + self.representation = representation + self.status = status + +class FileFullRepresentationsField(BaseObject): + def __init__(self, *, entries: Optional[List[FileFullRepresentationsEntriesField]] = None, **kwargs): + """ + :param entries: A list of files, defaults to None + :type entries: Optional[List[FileFullRepresentationsEntriesField]], optional + """ + super().__init__(**kwargs) + self.entries = entries + +class FileFullClassificationField(BaseObject): + def __init__(self, *, name: Optional[str] = None, definition: Optional[str] = None, color: Optional[str] = None, **kwargs): + """ + :param name: The name of the classification, defaults to None + :type name: Optional[str], optional + :param definition: An explanation of the meaning of this classification., defaults to None + :type definition: Optional[str], optional + :param color: The color that is used to display the +classification label in a user-interface. Colors are defined by the admin +or co-admin who created the classification in the Box web app., defaults to None + :type color: Optional[str], optional + """ + super().__init__(**kwargs) + self.name = name + self.definition = definition + self.color = color + +class FileFullSharedLinkPermissionOptionsField(str, Enum): + CAN_PREVIEW = 'can_preview' + CAN_DOWNLOAD = 'can_download' + CAN_EDIT = 'can_edit' + +class FileFull(File): + def __init__(self, id: str, *, version_number: Optional[str] = None, comment_count: Optional[int] = None, permissions: Optional[FileFullPermissionsField] = None, tags: Optional[List[str]] = None, lock: Optional[FileFullLockField] = None, extension: Optional[str] = None, is_package: Optional[bool] = None, expiring_embed_link: Optional[FileFullExpiringEmbedLinkField] = None, watermark_info: Optional[FileFullWatermarkInfoField] = None, is_accessible_via_shared_link: Optional[bool] = None, allowed_invitee_roles: Optional[List[FileFullAllowedInviteeRolesField]] = None, is_externally_owned: Optional[bool] = None, has_collaborations: Optional[bool] = None, metadata: Optional[FileFullMetadataField] = None, expires_at: Optional[DateTime] = None, representations: Optional[FileFullRepresentationsField] = None, classification: Optional[FileFullClassificationField] = None, uploader_display_name: Optional[str] = None, disposition_at: Optional[DateTime] = None, 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, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, trashed_at: Optional[DateTime] = None, purged_at: Optional[DateTime] = None, content_created_at: Optional[DateTime] = None, content_modified_at: Optional[DateTime] = None, created_by: Optional[UserMini] = None, modified_by: Optional[UserMini] = None, owned_by: Optional[UserMini] = None, shared_link: Optional[FileSharedLinkField] = None, parent: Optional[FolderMini] = None, item_status: Optional[FileItemStatusField] = None, sequence_id: Optional[str] = None, name: Optional[str] = None, sha_1: Optional[str] = None, file_version: Optional[FileVersionMini] = None, etag: Optional[str] = None, type: FileBaseTypeField = FileBaseTypeField.FILE, **kwargs): + """ + :param id: The unique identifier that represent 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`. + :type id: str + :param version_number: The version number of this file, defaults to None + :type version_number: Optional[str], optional + :param comment_count: The number of comments on this file, defaults to None + :type comment_count: Optional[int], optional + :param extension: Indicates the (optional) file extension for this file. By default, +this is set to an empty string., defaults to None + :type extension: Optional[str], optional + :param is_package: Indicates if the file is a package. Packages are commonly used +by Mac Applications and can include iWork files., defaults to None + :type is_package: Optional[bool], optional + :param is_accessible_via_shared_link: Specifies if the file can be accessed +via the direct shared link or a shared link +to a parent folder., defaults to None + :type is_accessible_via_shared_link: Optional[bool], optional + :param allowed_invitee_roles: A list of the types of roles that user can be invited at +when sharing this file., defaults to None + :type allowed_invitee_roles: Optional[List[FileFullAllowedInviteeRolesField]], optional + :param is_externally_owned: Specifies if this file is owned by a user outside of the +authenticated enterprise., defaults to None + :type is_externally_owned: Optional[bool], optional + :param has_collaborations: Specifies if this file has any other collaborators., defaults to None + :type has_collaborations: Optional[bool], optional + :param expires_at: When the file will automatically be deleted, defaults to None + :type expires_at: Optional[DateTime], optional + :param disposition_at: The retention expiration timestamp for the given file, defaults to None + :type disposition_at: Optional[DateTime], optional + :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 + :type description: Optional[str], optional + :param size: The file size in bytes. Be careful parsing this integer as it can +get very large and cause an integer overflow., defaults to None + :type size: Optional[int], optional + :param created_at: The date and time when the file was created on Box., defaults to None + :type created_at: Optional[DateTime], optional + :param modified_at: The date and time when the file was last updated on Box., defaults to None + :type modified_at: Optional[DateTime], optional + :param trashed_at: The time at which this file was put in the trash., defaults to None + :type trashed_at: Optional[DateTime], optional + :param purged_at: The time at which this file is expected to be purged +from the trash., defaults to None + :type purged_at: Optional[DateTime], optional + :param content_created_at: The date and time at which this file was originally +created, which might be before it was uploaded to Box., defaults to None + :type content_created_at: Optional[DateTime], optional + :param content_modified_at: The date and time at which this file was last updated, +which might be before it was uploaded to Box., defaults to None + :type content_modified_at: Optional[DateTime], optional + :param item_status: Defines if this item has been deleted or not. + +* `active` when the item has is not in the trash +* `trashed` when the item has been moved to the trash but not deleted +* `deleted` when the item has been permanently deleted., defaults to None + :type item_status: Optional[FileItemStatusField], optional + :param name: The name of the file, defaults to None + :type name: Optional[str], optional + :param sha_1: The SHA1 hash of the file. This can be used to compare the contents +of a file on Box with a local file., defaults to None + :type sha_1: Optional[str], optional + :param etag: The HTTP `etag` of this file. This can be used within some API +endpoints in the `If-Match` and `If-None-Match` headers to only +perform changes on the file if (no) changes have happened., defaults to None + :type etag: Optional[str], optional + :param type: `file`, defaults to FileBaseTypeField.FILE + :type type: FileBaseTypeField, optional + """ + super().__init__(id=id, description=description, size=size, path_collection=path_collection, created_at=created_at, modified_at=modified_at, trashed_at=trashed_at, purged_at=purged_at, content_created_at=content_created_at, content_modified_at=content_modified_at, created_by=created_by, modified_by=modified_by, owned_by=owned_by, shared_link=shared_link, parent=parent, item_status=item_status, sequence_id=sequence_id, name=name, sha_1=sha_1, file_version=file_version, etag=etag, type=type, **kwargs) + self.version_number = version_number + self.comment_count = comment_count + self.permissions = permissions + self.tags = tags + self.lock = lock + self.extension = extension + self.is_package = is_package + self.expiring_embed_link = expiring_embed_link + self.watermark_info = watermark_info + self.is_accessible_via_shared_link = is_accessible_via_shared_link + self.allowed_invitee_roles = allowed_invitee_roles + self.is_externally_owned = is_externally_owned + self.has_collaborations = has_collaborations + self.metadata = metadata + self.expires_at = expires_at + self.representations = representations + self.classification = classification + 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 \ No newline at end of file diff --git a/box_sdk_gen/schemas/file_mini.py b/box_sdk_gen/schemas/file_mini.py new file mode 100644 index 000000000..4ac55fabb --- /dev/null +++ b/box_sdk_gen/schemas/file_mini.py @@ -0,0 +1,42 @@ +from typing import Optional + +from typing import Dict + +from box_sdk_gen.schemas.file_base import FileBaseTypeField + +from box_sdk_gen.schemas.file_base import FileBase + +from box_sdk_gen.schemas.file_version_mini import FileVersionMini + +from box_sdk_gen.box.errors import BoxSDKError + +class FileMini(FileBase): + _fields_to_json_mapping: Dict[str, str] = {'sha_1': 'sha1', **FileBase._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'sha1': 'sha_1', **FileBase._json_to_fields_mapping} + def __init__(self, id: str, *, sequence_id: Optional[str] = None, name: Optional[str] = None, sha_1: Optional[str] = None, file_version: Optional[FileVersionMini] = None, etag: Optional[str] = None, type: FileBaseTypeField = FileBaseTypeField.FILE, **kwargs): + """ + :param id: The unique identifier that represent 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`. + :type id: str + :param name: The name of the file, defaults to None + :type name: Optional[str], optional + :param sha_1: The SHA1 hash of the file. This can be used to compare the contents +of a file on Box with a local file., defaults to None + :type sha_1: Optional[str], optional + :param etag: The HTTP `etag` of this file. This can be used within some API +endpoints in the `If-Match` and `If-None-Match` headers to only +perform changes on the file if (no) changes have happened., defaults to None + :type etag: Optional[str], optional + :param type: `file`, defaults to FileBaseTypeField.FILE + :type type: FileBaseTypeField, optional + """ + super().__init__(id=id, etag=etag, type=type, **kwargs) + self.sequence_id = sequence_id + self.name = name + self.sha_1 = sha_1 + self.file_version = file_version \ No newline at end of file diff --git a/box_sdk_gen/schemas/file_or_folder_scope.py b/box_sdk_gen/schemas/file_or_folder_scope.py new file mode 100644 index 000000000..c064af905 --- /dev/null +++ b/box_sdk_gen/schemas/file_or_folder_scope.py @@ -0,0 +1,39 @@ +from enum import Enum + +from typing import Optional + +from typing import Union + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.folder_mini import FolderMini + +from box_sdk_gen.schemas.file_mini import FileMini + +from box_sdk_gen.box.errors import BoxSDKError + +class FileOrFolderScopeScopeField(str, Enum): + ANNOTATION_EDIT = 'annotation_edit' + ANNOTATION_VIEW_ALL = 'annotation_view_all' + ANNOTATION_VIEW_SELF = 'annotation_view_self' + BASE_EXPLORER = 'base_explorer' + BASE_PICKER = 'base_picker' + BASE_PREVIEW = 'base_preview' + BASE_UPLOAD = 'base_upload' + ITEM_DELETE = 'item_delete' + ITEM_DOWNLOAD = 'item_download' + ITEM_PREVIEW = 'item_preview' + ITEM_RENAME = 'item_rename' + ITEM_SHARE = 'item_share' + ITEM_UPLOAD = 'item_upload' + ITEM_READ = 'item_read' + +class FileOrFolderScope(BaseObject): + def __init__(self, *, scope: Optional[FileOrFolderScopeScopeField] = None, object: Optional[Union[FolderMini, FileMini]] = None, **kwargs): + """ + :param scope: The scopes for the resource access, defaults to None + :type scope: Optional[FileOrFolderScopeScopeField], optional + """ + super().__init__(**kwargs) + self.scope = scope + self.object = object \ No newline at end of file diff --git a/box_sdk_gen/schemas/file_request.py b/box_sdk_gen/schemas/file_request.py new file mode 100644 index 000000000..4ca8c69ee --- /dev/null +++ b/box_sdk_gen/schemas/file_request.py @@ -0,0 +1,106 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.folder_mini import FolderMini + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class FileRequestTypeField(str, Enum): + FILE_REQUEST = 'file_request' + +class FileRequestStatusField(str, Enum): + ACTIVE = 'active' + INACTIVE = 'inactive' + +class FileRequest(BaseObject): + _discriminator = 'type', {'file_request'} + def __init__(self, id: str, folder: FolderMini, created_at: DateTime, updated_at: DateTime, *, type: FileRequestTypeField = FileRequestTypeField.FILE_REQUEST, title: Optional[str] = None, description: Optional[str] = None, status: Optional[FileRequestStatusField] = None, is_email_required: Optional[bool] = None, is_description_required: Optional[bool] = None, expires_at: Optional[DateTime] = None, url: Optional[str] = None, etag: Optional[str] = None, created_by: Optional[UserMini] = None, updated_by: Optional[UserMini] = None, **kwargs): + """ + :param id: The unique identifier for this file request. + :type id: str + :param created_at: The date and time when the file request was created. + :type created_at: DateTime + :param updated_at: The date and time when the file request was last updated. + :type updated_at: DateTime + :param type: `file_request`, defaults to FileRequestTypeField.FILE_REQUEST + :type type: FileRequestTypeField, optional + :param title: The title of file request. This is shown +in the Box UI to users uploading files. + +This defaults to title of the file request that was +copied to create this file request., defaults to None + :type title: Optional[str], optional + :param description: The optional description of this file request. This is +shown in the Box UI to users uploading files. + +This defaults to description of the file request that was +copied to create this file request., defaults to None + :type description: Optional[str], optional + :param status: The status of the file request. This defaults +to `active`. + +When the status is set to `inactive`, the file request +will no longer accept new submissions, and any visitor +to the file request URL will receive a `HTTP 404` status +code. + +This defaults to status of file request that was +copied to create this file request., defaults to None + :type status: Optional[FileRequestStatusField], optional + :param is_email_required: Whether a file request submitter is required to provide +their email address. + +When this setting is set to true, the Box UI will show +an email field on the file request form. + +This defaults to setting of file request that was +copied to create this file request., defaults to None + :type is_email_required: Optional[bool], optional + :param is_description_required: Whether a file request submitter is required to provide +a description of the files they are submitting. + +When this setting is set to true, the Box UI will show +a description field on the file request form. + +This defaults to setting of file request that was +copied to create this file request., defaults to None + :type is_description_required: Optional[bool], optional + :param expires_at: The date after which a file request will no longer accept new +submissions. + +After this date, the `status` will automatically be set to +`inactive`., defaults to None + :type expires_at: Optional[DateTime], optional + :param url: The generated URL for this file request. This URL can be shared +with users to let them upload files to the associated folder., defaults to None + :type url: Optional[str], optional + :param etag: The HTTP `etag` of this file. This can be used in combination with +the `If-Match` header when updating a file request. By providing that +header, a change will only be performed on the file request if the `etag` +on the file request still matches the `etag` provided in the `If-Match` +header., defaults to None + :type etag: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.folder = folder + self.created_at = created_at + self.updated_at = updated_at + self.type = type + self.title = title + self.description = description + self.status = status + self.is_email_required = is_email_required + self.is_description_required = is_description_required + self.expires_at = expires_at + self.url = url + self.etag = etag + self.created_by = created_by + self.updated_by = updated_by \ No newline at end of file diff --git a/box_sdk_gen/schemas/file_request_copy_request.py b/box_sdk_gen/schemas/file_request_copy_request.py new file mode 100644 index 000000000..aec010d00 --- /dev/null +++ b/box_sdk_gen/schemas/file_request_copy_request.py @@ -0,0 +1,82 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.file_request_update_request import FileRequestUpdateRequestStatusField + +from box_sdk_gen.internal.utils import DateTime + +from box_sdk_gen.schemas.file_request_update_request import FileRequestUpdateRequest + +from box_sdk_gen.box.errors import BoxSDKError + +class FileRequestCopyRequestFolderTypeField(str, Enum): + FOLDER = 'folder' + +class FileRequestCopyRequestFolderField(BaseObject): + _discriminator = 'type', {'folder'} + def __init__(self, id: str, *, type: Optional[FileRequestCopyRequestFolderTypeField] = None, **kwargs): + """ + :param id: The ID of the folder to associate the new +file request to. + :type id: str + :param type: `folder`, defaults to None + :type type: Optional[FileRequestCopyRequestFolderTypeField], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class FileRequestCopyRequest(FileRequestUpdateRequest): + def __init__(self, folder: FileRequestCopyRequestFolderField, *, title: Optional[str] = None, description: Optional[str] = None, status: Optional[FileRequestUpdateRequestStatusField] = None, is_email_required: Optional[bool] = None, is_description_required: Optional[bool] = None, expires_at: Optional[DateTime] = None, **kwargs): + """ + :param folder: The folder to associate the new file request to. + :type folder: FileRequestCopyRequestFolderField + :param title: An optional new title for the file request. This can be +used to change the title of the file request. + +This will default to the value on the existing file request., defaults to None + :type title: Optional[str], optional + :param description: An optional new description for the file request. This can be +used to change the description of the file request. + +This will default to the value on the existing file request., defaults to None + :type description: Optional[str], optional + :param status: An optional new status of the file request. + +When the status is set to `inactive`, the file request +will no longer accept new submissions, and any visitor +to the file request URL will receive a `HTTP 404` status +code. + +This will default to the value on the existing file request., defaults to None + :type status: Optional[FileRequestUpdateRequestStatusField], optional + :param is_email_required: Whether a file request submitter is required to provide +their email address. + +When this setting is set to true, the Box UI will show +an email field on the file request form. + +This will default to the value on the existing file request., defaults to None + :type is_email_required: Optional[bool], optional + :param is_description_required: Whether a file request submitter is required to provide +a description of the files they are submitting. + +When this setting is set to true, the Box UI will show +a description field on the file request form. + +This will default to the value on the existing file request., defaults to None + :type is_description_required: Optional[bool], optional + :param expires_at: The date after which a file request will no longer accept new +submissions. + +After this date, the `status` will automatically be set to +`inactive`. + +This will default to the value on the existing file request., defaults to None + :type expires_at: Optional[DateTime], optional + """ + super().__init__(title=title, description=description, status=status, is_email_required=is_email_required, is_description_required=is_description_required, expires_at=expires_at, **kwargs) + self.folder = folder \ No newline at end of file diff --git a/box_sdk_gen/schemas/file_request_update_request.py b/box_sdk_gen/schemas/file_request_update_request.py new file mode 100644 index 000000000..bf169cd46 --- /dev/null +++ b/box_sdk_gen/schemas/file_request_update_request.py @@ -0,0 +1,68 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class FileRequestUpdateRequestStatusField(str, Enum): + ACTIVE = 'active' + INACTIVE = 'inactive' + +class FileRequestUpdateRequest(BaseObject): + def __init__(self, *, title: Optional[str] = None, description: Optional[str] = None, status: Optional[FileRequestUpdateRequestStatusField] = None, is_email_required: Optional[bool] = None, is_description_required: Optional[bool] = None, expires_at: Optional[DateTime] = None, **kwargs): + """ + :param title: An optional new title for the file request. This can be +used to change the title of the file request. + +This will default to the value on the existing file request., defaults to None + :type title: Optional[str], optional + :param description: An optional new description for the file request. This can be +used to change the description of the file request. + +This will default to the value on the existing file request., defaults to None + :type description: Optional[str], optional + :param status: An optional new status of the file request. + +When the status is set to `inactive`, the file request +will no longer accept new submissions, and any visitor +to the file request URL will receive a `HTTP 404` status +code. + +This will default to the value on the existing file request., defaults to None + :type status: Optional[FileRequestUpdateRequestStatusField], optional + :param is_email_required: Whether a file request submitter is required to provide +their email address. + +When this setting is set to true, the Box UI will show +an email field on the file request form. + +This will default to the value on the existing file request., defaults to None + :type is_email_required: Optional[bool], optional + :param is_description_required: Whether a file request submitter is required to provide +a description of the files they are submitting. + +When this setting is set to true, the Box UI will show +a description field on the file request form. + +This will default to the value on the existing file request., defaults to None + :type is_description_required: Optional[bool], optional + :param expires_at: The date after which a file request will no longer accept new +submissions. + +After this date, the `status` will automatically be set to +`inactive`. + +This will default to the value on the existing file request., defaults to None + :type expires_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.title = title + self.description = description + self.status = status + self.is_email_required = is_email_required + self.is_description_required = is_description_required + self.expires_at = expires_at \ No newline at end of file diff --git a/box_sdk_gen/schemas/file_version.py b/box_sdk_gen/schemas/file_version.py new file mode 100644 index 000000000..b2ae081c2 --- /dev/null +++ b/box_sdk_gen/schemas/file_version.py @@ -0,0 +1,50 @@ +from typing import Optional + +from box_sdk_gen.schemas.file_version_base import FileVersionBaseTypeField + +from box_sdk_gen.schemas.file_version_base import FileVersionBase + +from box_sdk_gen.schemas.file_version_mini import FileVersionMini + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class FileVersion(FileVersionMini): + def __init__(self, id: str, *, name: Optional[str] = None, size: Optional[int] = None, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, modified_by: Optional[UserMini] = None, trashed_at: Optional[DateTime] = None, trashed_by: Optional[UserMini] = None, restored_at: Optional[DateTime] = None, restored_by: Optional[UserMini] = None, purged_at: Optional[DateTime] = None, uploader_display_name: Optional[str] = None, sha_1: Optional[str] = None, type: FileVersionBaseTypeField = FileVersionBaseTypeField.FILE_VERSION, **kwargs): + """ + :param id: The unique identifier that represent a file version. + :type id: str + :param name: The name of the file version, defaults to None + :type name: Optional[str], optional + :param size: Size of the file version in bytes, defaults to None + :type size: Optional[int], optional + :param created_at: When the file version object was created, defaults to None + :type created_at: Optional[DateTime], optional + :param modified_at: When the file version object was last updated, defaults to None + :type modified_at: Optional[DateTime], optional + :param trashed_at: When the file version object was trashed., defaults to None + :type trashed_at: Optional[DateTime], optional + :param restored_at: When the file version was restored from the trash., defaults to None + :type restored_at: Optional[DateTime], optional + :param purged_at: When the file version object will be permanently deleted., defaults to None + :type purged_at: Optional[DateTime], optional + :param sha_1: The SHA1 hash of this version of the file., defaults to None + :type sha_1: Optional[str], optional + :param type: `file_version`, defaults to FileVersionBaseTypeField.FILE_VERSION + :type type: FileVersionBaseTypeField, optional + """ + super().__init__(id=id, sha_1=sha_1, type=type, **kwargs) + self.name = name + self.size = size + self.created_at = created_at + self.modified_at = modified_at + self.modified_by = modified_by + self.trashed_at = trashed_at + self.trashed_by = trashed_by + self.restored_at = restored_at + self.restored_by = restored_by + self.purged_at = purged_at + self.uploader_display_name = uploader_display_name \ No newline at end of file diff --git a/box_sdk_gen/schemas/file_version_base.py b/box_sdk_gen/schemas/file_version_base.py new file mode 100644 index 000000000..74d2bba52 --- /dev/null +++ b/box_sdk_gen/schemas/file_version_base.py @@ -0,0 +1,21 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class FileVersionBaseTypeField(str, Enum): + FILE_VERSION = 'file_version' + +class FileVersionBase(BaseObject): + _discriminator = 'type', {'file_version'} + def __init__(self, id: str, *, type: FileVersionBaseTypeField = FileVersionBaseTypeField.FILE_VERSION, **kwargs): + """ + :param id: The unique identifier that represent a file version. + :type id: str + :param type: `file_version`, defaults to FileVersionBaseTypeField.FILE_VERSION + :type type: FileVersionBaseTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type \ No newline at end of file diff --git a/box_sdk_gen/schemas/file_version_full.py b/box_sdk_gen/schemas/file_version_full.py new file mode 100644 index 000000000..22f294dfc --- /dev/null +++ b/box_sdk_gen/schemas/file_version_full.py @@ -0,0 +1,44 @@ +from typing import Optional + +from box_sdk_gen.schemas.file_version_base import FileVersionBaseTypeField + +from box_sdk_gen.schemas.file_version_base import FileVersionBase + +from box_sdk_gen.schemas.file_version_mini import FileVersionMini + +from box_sdk_gen.internal.utils import DateTime + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.schemas.file_version import FileVersion + +from box_sdk_gen.box.errors import BoxSDKError + +class FileVersionFull(FileVersion): + def __init__(self, id: str, *, version_number: Optional[str] = None, name: Optional[str] = None, size: Optional[int] = None, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, modified_by: Optional[UserMini] = None, trashed_at: Optional[DateTime] = None, trashed_by: Optional[UserMini] = None, restored_at: Optional[DateTime] = None, restored_by: Optional[UserMini] = None, purged_at: Optional[DateTime] = None, uploader_display_name: Optional[str] = None, sha_1: Optional[str] = None, type: FileVersionBaseTypeField = FileVersionBaseTypeField.FILE_VERSION, **kwargs): + """ + :param id: The unique identifier that represent a file version. + :type id: str + :param version_number: The version number of this file version, defaults to None + :type version_number: Optional[str], optional + :param name: The name of the file version, defaults to None + :type name: Optional[str], optional + :param size: Size of the file version in bytes, defaults to None + :type size: Optional[int], optional + :param created_at: When the file version object was created, defaults to None + :type created_at: Optional[DateTime], optional + :param modified_at: When the file version object was last updated, defaults to None + :type modified_at: Optional[DateTime], optional + :param trashed_at: When the file version object was trashed., defaults to None + :type trashed_at: Optional[DateTime], optional + :param restored_at: When the file version was restored from the trash., defaults to None + :type restored_at: Optional[DateTime], optional + :param purged_at: When the file version object will be permanently deleted., defaults to None + :type purged_at: Optional[DateTime], optional + :param sha_1: The SHA1 hash of this version of the file., defaults to None + :type sha_1: Optional[str], optional + :param type: `file_version`, defaults to FileVersionBaseTypeField.FILE_VERSION + :type type: FileVersionBaseTypeField, optional + """ + super().__init__(id=id, name=name, size=size, created_at=created_at, modified_at=modified_at, modified_by=modified_by, trashed_at=trashed_at, trashed_by=trashed_by, restored_at=restored_at, restored_by=restored_by, purged_at=purged_at, uploader_display_name=uploader_display_name, sha_1=sha_1, type=type, **kwargs) + self.version_number = version_number \ No newline at end of file diff --git a/box_sdk_gen/schemas/file_version_legal_hold.py b/box_sdk_gen/schemas/file_version_legal_hold.py new file mode 100644 index 000000000..67a003e0e --- /dev/null +++ b/box_sdk_gen/schemas/file_version_legal_hold.py @@ -0,0 +1,42 @@ +from enum import Enum + +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.file_version_mini import FileVersionMini + +from box_sdk_gen.schemas.file_mini import FileMini + +from box_sdk_gen.schemas.legal_hold_policy_assignment import LegalHoldPolicyAssignment + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class FileVersionLegalHoldTypeField(str, Enum): + FILE_VERSION_LEGAL_HOLD = 'file_version_legal_hold' + +class FileVersionLegalHold(BaseObject): + _discriminator = 'type', {'file_version_legal_hold'} + def __init__(self, *, id: Optional[str] = None, type: Optional[FileVersionLegalHoldTypeField] = None, file_version: Optional[FileVersionMini] = None, file: Optional[FileMini] = None, legal_hold_policy_assignments: Optional[List[LegalHoldPolicyAssignment]] = None, deleted_at: Optional[DateTime] = None, **kwargs): + """ + :param id: The unique identifier for this file version legal hold, defaults to None + :type id: Optional[str], optional + :param type: `file_version_legal_hold`, defaults to None + :type type: Optional[FileVersionLegalHoldTypeField], optional + :param legal_hold_policy_assignments: List of assignments contributing to this Hold., defaults to None + :type legal_hold_policy_assignments: Optional[List[LegalHoldPolicyAssignment]], optional + :param deleted_at: Time that this File-Version-Legal-Hold was +deleted., defaults to None + :type deleted_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.file_version = file_version + self.file = file + self.legal_hold_policy_assignments = legal_hold_policy_assignments + self.deleted_at = deleted_at \ No newline at end of file diff --git a/box_sdk_gen/schemas/file_version_legal_holds.py b/box_sdk_gen/schemas/file_version_legal_holds.py new file mode 100644 index 000000000..4b7cbc214 --- /dev/null +++ b/box_sdk_gen/schemas/file_version_legal_holds.py @@ -0,0 +1,29 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.file_version_legal_hold import FileVersionLegalHold + +from box_sdk_gen.box.errors import BoxSDKError + +class FileVersionLegalHolds(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, prev_marker: Optional[str] = None, entries: Optional[List[FileVersionLegalHold]] = 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 + :param entries: A list of file version legal holds, defaults to None + :type entries: Optional[List[FileVersionLegalHold]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.prev_marker = prev_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/file_version_mini.py b/box_sdk_gen/schemas/file_version_mini.py new file mode 100644 index 000000000..de03afdab --- /dev/null +++ b/box_sdk_gen/schemas/file_version_mini.py @@ -0,0 +1,24 @@ +from typing import Optional + +from typing import Dict + +from box_sdk_gen.schemas.file_version_base import FileVersionBaseTypeField + +from box_sdk_gen.schemas.file_version_base import FileVersionBase + +from box_sdk_gen.box.errors import BoxSDKError + +class FileVersionMini(FileVersionBase): + _fields_to_json_mapping: Dict[str, str] = {'sha_1': 'sha1', **FileVersionBase._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'sha1': 'sha_1', **FileVersionBase._json_to_fields_mapping} + def __init__(self, id: str, *, sha_1: Optional[str] = None, type: FileVersionBaseTypeField = FileVersionBaseTypeField.FILE_VERSION, **kwargs): + """ + :param id: The unique identifier that represent a file version. + :type id: str + :param sha_1: The SHA1 hash of this version of the file., defaults to None + :type sha_1: Optional[str], optional + :param type: `file_version`, defaults to FileVersionBaseTypeField.FILE_VERSION + :type type: FileVersionBaseTypeField, optional + """ + super().__init__(id=id, type=type, **kwargs) + self.sha_1 = sha_1 \ No newline at end of file diff --git a/box_sdk_gen/schemas/file_version_retention.py b/box_sdk_gen/schemas/file_version_retention.py new file mode 100644 index 000000000..d48372b20 --- /dev/null +++ b/box_sdk_gen/schemas/file_version_retention.py @@ -0,0 +1,42 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.file_version_mini import FileVersionMini + +from box_sdk_gen.schemas.file_mini import FileMini + +from box_sdk_gen.schemas.retention_policy_mini import RetentionPolicyMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class FileVersionRetentionTypeField(str, Enum): + FILE_VERSION_RETENTION = 'file_version_retention' + +class FileVersionRetention(BaseObject): + _discriminator = 'type', {'file_version_retention'} + def __init__(self, *, id: Optional[str] = None, type: Optional[FileVersionRetentionTypeField] = None, file_version: Optional[FileVersionMini] = None, file: Optional[FileMini] = None, applied_at: Optional[DateTime] = None, disposition_at: Optional[DateTime] = None, winning_retention_policy: Optional[RetentionPolicyMini] = None, **kwargs): + """ + :param id: The unique identifier for this file version retention., defaults to None + :type id: Optional[str], optional + :param type: `file_version_retention`, defaults to None + :type type: Optional[FileVersionRetentionTypeField], optional + :param applied_at: When this file version retention object was +created, defaults to None + :type applied_at: Optional[DateTime], optional + :param disposition_at: When the retention expires on this file +version retention, defaults to None + :type disposition_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.file_version = file_version + self.file = file + self.applied_at = applied_at + self.disposition_at = disposition_at + self.winning_retention_policy = winning_retention_policy \ No newline at end of file diff --git a/box_sdk_gen/schemas/file_version_retentions.py b/box_sdk_gen/schemas/file_version_retentions.py new file mode 100644 index 000000000..08c207f05 --- /dev/null +++ b/box_sdk_gen/schemas/file_version_retentions.py @@ -0,0 +1,29 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.file_version_retention import FileVersionRetention + +from box_sdk_gen.box.errors import BoxSDKError + +class FileVersionRetentions(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, prev_marker: Optional[str] = None, entries: Optional[List[FileVersionRetention]] = 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 + :param entries: A list of file version retentions, defaults to None + :type entries: Optional[List[FileVersionRetention]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.prev_marker = prev_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/file_versions.py b/box_sdk_gen/schemas/file_versions.py new file mode 100644 index 000000000..ab922428c --- /dev/null +++ b/box_sdk_gen/schemas/file_versions.py @@ -0,0 +1,62 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from box_sdk_gen.schemas.file_version_full import FileVersionFull + +from box_sdk_gen.box.errors import BoxSDKError + +class FileVersionsOrderDirectionField(str, Enum): + ASC = 'ASC' + DESC = 'DESC' + +class FileVersionsOrderField(BaseObject): + def __init__(self, *, by: Optional[str] = None, direction: Optional[FileVersionsOrderDirectionField] = None, **kwargs): + """ + :param by: The field to order by, defaults to None + :type by: Optional[str], optional + :param direction: The direction to order by, either ascending or descending, defaults to None + :type direction: Optional[FileVersionsOrderDirectionField], optional + """ + super().__init__(**kwargs) + self.by = by + self.direction = direction + +class FileVersions(BaseObject): + def __init__(self, *, total_count: Optional[int] = None, limit: Optional[int] = None, offset: Optional[int] = None, order: Optional[List[FileVersionsOrderField]] = None, entries: Optional[List[FileVersionFull]] = None, **kwargs): + """ + :param total_count: One greater than the offset of the last entry in the entire collection. +The total number of entries in the collection may be less than +`total_count`. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type total_count: Optional[int], optional + :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 offset: The 0-based offset of the first entry in this set. This will be the same +as the `offset` query parameter. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type offset: Optional[int], optional + :param order: The order by which items are returned. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type order: Optional[List[FileVersionsOrderField]], optional + :param entries: A list of file versions, defaults to None + :type entries: Optional[List[FileVersionFull]], optional + """ + super().__init__(**kwargs) + self.total_count = total_count + self.limit = limit + self.offset = offset + self.order = order + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/files.py b/box_sdk_gen/schemas/files.py new file mode 100644 index 000000000..65671111f --- /dev/null +++ b/box_sdk_gen/schemas/files.py @@ -0,0 +1,21 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.box.errors import BoxSDKError + +class Files(BaseObject): + def __init__(self, *, total_count: Optional[int] = None, entries: Optional[List[FileFull]] = None, **kwargs): + """ + :param total_count: The number of files., defaults to None + :type total_count: Optional[int], optional + :param entries: A list of files, defaults to None + :type entries: Optional[List[FileFull]], optional + """ + super().__init__(**kwargs) + self.total_count = total_count + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/files_on_hold.py b/box_sdk_gen/schemas/files_on_hold.py new file mode 100644 index 000000000..2b7177c78 --- /dev/null +++ b/box_sdk_gen/schemas/files_on_hold.py @@ -0,0 +1,29 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.file_mini import FileMini + +from box_sdk_gen.box.errors import BoxSDKError + +class FilesOnHold(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, prev_marker: Optional[str] = None, entries: Optional[List[FileMini]] = 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 + :param entries: A list of files, defaults to None + :type entries: Optional[List[FileMini]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.prev_marker = prev_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/files_under_retention.py b/box_sdk_gen/schemas/files_under_retention.py new file mode 100644 index 000000000..310088553 --- /dev/null +++ b/box_sdk_gen/schemas/files_under_retention.py @@ -0,0 +1,29 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.file_mini import FileMini + +from box_sdk_gen.box.errors import BoxSDKError + +class FilesUnderRetention(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, prev_marker: Optional[str] = None, entries: Optional[List[FileMini]] = 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 + :param entries: A list of files, defaults to None + :type entries: Optional[List[FileMini]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.prev_marker = prev_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/folder.py b/box_sdk_gen/schemas/folder.py new file mode 100644 index 000000000..19bf680f9 --- /dev/null +++ b/box_sdk_gen/schemas/folder.py @@ -0,0 +1,253 @@ +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from enum import Enum + +from typing import Optional + +from box_sdk_gen.schemas.folder_base import FolderBaseTypeField + +from box_sdk_gen.schemas.folder_base import FolderBase + +from box_sdk_gen.schemas.folder_mini import FolderMini + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.schemas.items import Items + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class FolderPathCollectionField(BaseObject): + def __init__(self, total_count: int, entries: List[FolderMini], **kwargs): + """ + :param total_count: The number of folders in this list. + :type total_count: int + :param entries: The parent folders for this item + :type entries: List[FolderMini] + """ + super().__init__(**kwargs) + self.total_count = total_count + self.entries = entries + +class FolderSharedLinkAccessField(str, Enum): + OPEN = 'open' + COMPANY = 'company' + COLLABORATORS = 'collaborators' + +class FolderSharedLinkEffectiveAccessField(str, Enum): + OPEN = 'open' + COMPANY = 'company' + COLLABORATORS = 'collaborators' + +class FolderSharedLinkEffectivePermissionField(str, Enum): + CAN_EDIT = 'can_edit' + CAN_DOWNLOAD = 'can_download' + CAN_PREVIEW = 'can_preview' + NO_ACCESS = 'no_access' + +class FolderSharedLinkPermissionsField(BaseObject): + def __init__(self, can_download: bool, can_preview: bool, can_edit: bool, **kwargs): + """ + :param can_download: Defines if the shared link allows for the item to be downloaded. For +shared links on folders, this also applies to any items in the folder. + +This value can be set to `true` when the effective access level is +set to `open` or `company`, not `collaborators`. + :type can_download: bool + :param can_preview: Defines if the shared link allows for the item to be previewed. + +This value is always `true`. For shared links on folders this also +applies to any items in the folder. + :type can_preview: bool + :param can_edit: Defines if the shared link allows for the item to be edited. + +This value can only be `true` if `can_download` is also `true` and if +the item has a type of `file`. + :type can_edit: bool + """ + super().__init__(**kwargs) + self.can_download = can_download + self.can_preview = can_preview + self.can_edit = can_edit + +class FolderSharedLinkField(BaseObject): + def __init__(self, url: str, effective_access: FolderSharedLinkEffectiveAccessField, effective_permission: FolderSharedLinkEffectivePermissionField, is_password_enabled: bool, download_count: int, preview_count: int, *, download_url: Optional[str] = None, vanity_url: Optional[str] = None, vanity_name: Optional[str] = None, access: Optional[FolderSharedLinkAccessField] = None, unshared_at: Optional[DateTime] = None, permissions: Optional[FolderSharedLinkPermissionsField] = None, **kwargs): + """ + :param url: The URL that can be used to access the item on Box. + +This URL will display the item in Box's preview UI where the file +can be downloaded if allowed. + +This URL will continue to work even when a custom `vanity_url` +has been set for this shared link. + :type url: str + :param effective_access: The effective access level for the shared link. This can be a more +restrictive access level than the value in the `access` field when the +enterprise settings restrict the allowed access levels. + :type effective_access: FolderSharedLinkEffectiveAccessField + :param effective_permission: The effective permissions for this shared link. +These result in the more restrictive combination of +the share link permissions and the item permissions set +by the administrator, the owner, and any ancestor item +such as a folder. + :type effective_permission: FolderSharedLinkEffectivePermissionField + :param is_password_enabled: Defines if the shared link requires a password to access the item. + :type is_password_enabled: bool + :param download_count: The number of times this item has been downloaded. + :type download_count: int + :param preview_count: The number of times this item has been previewed. + :type preview_count: int + :param download_url: A URL that can be used to download the file. This URL can be used in +a browser to download the file. This URL includes the file +extension so that the file will be saved with the right file type. + +This property will be `null` for folders., defaults to None + :type download_url: Optional[str], optional + :param vanity_url: The "Custom URL" that can also be used to preview the item on Box. Custom +URLs can only be created or modified in the Box Web application., defaults to None + :type vanity_url: Optional[str], optional + :param vanity_name: The custom name of a shared link, as used in the `vanity_url` field., defaults to None + :type vanity_name: Optional[str], optional + :param access: The access level for this shared link. + +* `open` - provides access to this item to anyone with this link +* `company` - only provides access to this item to people the same company +* `collaborators` - only provides access to this item to people who are + collaborators on this item + +If this field is omitted when creating the shared link, the access level +will be set to the default access level specified by the enterprise admin., defaults to None + :type access: Optional[FolderSharedLinkAccessField], optional + :param unshared_at: The date and time when this link will be unshared. This field can only be +set by users with paid accounts., defaults to None + :type unshared_at: Optional[DateTime], optional + :param permissions: Defines if this link allows a user to preview, edit, and download an item. +These permissions refer to the shared link only and +do not supersede permissions applied to the item itself., defaults to None + :type permissions: Optional[FolderSharedLinkPermissionsField], optional + """ + super().__init__(**kwargs) + self.url = url + self.effective_access = effective_access + self.effective_permission = effective_permission + self.is_password_enabled = is_password_enabled + self.download_count = download_count + self.preview_count = preview_count + self.download_url = download_url + self.vanity_url = vanity_url + self.vanity_name = vanity_name + self.access = access + self.unshared_at = unshared_at + self.permissions = permissions + +class FolderFolderUploadEmailAccessField(str, Enum): + OPEN = 'open' + COLLABORATORS = 'collaborators' + +class FolderFolderUploadEmailField(BaseObject): + def __init__(self, *, access: Optional[FolderFolderUploadEmailAccessField] = None, email: Optional[str] = None, **kwargs): + """ + :param access: When this parameter has been set, users can email files +to the email address that has been automatically +created for this folder. + +To create an email address, set this property either when +creating or updating the folder. + +When set to `collaborators`, only emails from registered email +addresses for collaborators will be accepted. This includes +any email aliases a user might have registered. + +When set to `open` it will accept emails from any email +address., defaults to None + :type access: Optional[FolderFolderUploadEmailAccessField], optional + :param email: The optional upload email address for this folder., defaults to None + :type email: Optional[str], optional + """ + super().__init__(**kwargs) + self.access = access + self.email = email + +class FolderItemStatusField(str, Enum): + ACTIVE = 'active' + TRASHED = 'trashed' + DELETED = 'deleted' + +class Folder(FolderMini): + def __init__(self, id: str, *, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, description: Optional[str] = None, size: Optional[int] = None, path_collection: Optional[FolderPathCollectionField] = None, created_by: Optional[UserMini] = None, modified_by: Optional[UserMini] = None, trashed_at: Optional[DateTime] = None, purged_at: Optional[DateTime] = None, content_created_at: Optional[DateTime] = None, content_modified_at: Optional[DateTime] = None, owned_by: Optional[UserMini] = None, shared_link: Optional[FolderSharedLinkField] = None, folder_upload_email: Optional[FolderFolderUploadEmailField] = None, parent: Optional[FolderMini] = None, item_status: Optional[FolderItemStatusField] = None, item_collection: Optional[Items] = None, sequence_id: Optional[str] = None, name: Optional[str] = None, etag: Optional[str] = None, type: FolderBaseTypeField = FolderBaseTypeField.FOLDER, **kwargs): + """ + :param id: The unique identifier that represent a folder. + +The ID for any folder can be determined +by visiting a folder in the web application +and copying the ID from the URL. For example, +for the URL `https://*.app.box.com/folders/123` +the `folder_id` is `123`. + :type id: str + :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 + :type created_at: Optional[DateTime], optional + :param modified_at: The date and time when the folder was last updated. This value may +be `null` for some folders such as the root folder or the trash +folder., defaults to None + :type modified_at: Optional[DateTime], optional + :param size: The folder size in bytes. + +Be careful parsing this integer as its +value can get very large., defaults to None + :type size: Optional[int], optional + :param trashed_at: The time at which this folder was put in the trash., defaults to None + :type trashed_at: Optional[DateTime], optional + :param purged_at: The time at which this folder is expected to be purged +from the trash., defaults to None + :type purged_at: Optional[DateTime], optional + :param content_created_at: The date and time at which this folder was originally +created., defaults to None + :type content_created_at: Optional[DateTime], optional + :param content_modified_at: The date and time at which this folder was last updated., defaults to None + :type content_modified_at: Optional[DateTime], optional + :param folder_upload_email: The `folder_upload_email` parameter is not `null` if one of the following options is **true**: + + * The **Allow uploads to this folder via email** and the **Only allow email uploads from collaborators in this folder** are [enabled for a folder in the Admin Console](https://support.box.com/hc/en-us/articles/360043697534-Upload-to-Box-Through-Email), and the user has at least **Upload** permissions granted. + + * The **Allow uploads to this folder via email** setting is enabled for a folder in the Admin Console, and the **Only allow email uploads from collaborators in this folder** setting is deactivated (unchecked). + +If the conditions are not met, the parameter will have the following value: `folder_upload_email: null`, defaults to None + :type folder_upload_email: Optional[FolderFolderUploadEmailField], optional + :param item_status: Defines if this item has been deleted or not. + +* `active` when the item has is not in the trash +* `trashed` when the item has been moved to the trash but not deleted +* `deleted` when the item has been permanently deleted., defaults to None + :type item_status: Optional[FolderItemStatusField], optional + :param name: The name of the folder., defaults to None + :type name: Optional[str], optional + :param etag: The HTTP `etag` of this folder. This can be used within some API +endpoints in the `If-Match` and `If-None-Match` headers to only +perform changes on the folder if (no) changes have happened., defaults to None + :type etag: Optional[str], optional + :param type: `folder`, defaults to FolderBaseTypeField.FOLDER + :type type: FolderBaseTypeField, optional + """ + super().__init__(id=id, sequence_id=sequence_id, name=name, etag=etag, type=type, **kwargs) + self.created_at = created_at + self.modified_at = modified_at + self.description = description + self.size = size + self.path_collection = path_collection + self.created_by = created_by + self.modified_by = modified_by + self.trashed_at = trashed_at + self.purged_at = purged_at + self.content_created_at = content_created_at + self.content_modified_at = content_modified_at + self.owned_by = owned_by + self.shared_link = shared_link + self.folder_upload_email = folder_upload_email + self.parent = parent + self.item_status = item_status + self.item_collection = item_collection \ No newline at end of file diff --git a/box_sdk_gen/schemas/folder_base.py b/box_sdk_gen/schemas/folder_base.py new file mode 100644 index 000000000..8a621a230 --- /dev/null +++ b/box_sdk_gen/schemas/folder_base.py @@ -0,0 +1,34 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class FolderBaseTypeField(str, Enum): + FOLDER = 'folder' + +class FolderBase(BaseObject): + _discriminator = 'type', {'folder'} + def __init__(self, id: str, *, etag: Optional[str] = None, type: FolderBaseTypeField = FolderBaseTypeField.FOLDER, **kwargs): + """ + :param id: The unique identifier that represent a folder. + +The ID for any folder can be determined +by visiting a folder in the web application +and copying the ID from the URL. For example, +for the URL `https://*.app.box.com/folders/123` +the `folder_id` is `123`. + :type id: str + :param etag: The HTTP `etag` of this folder. This can be used within some API +endpoints in the `If-Match` and `If-None-Match` headers to only +perform changes on the folder if (no) changes have happened., defaults to None + :type etag: Optional[str], optional + :param type: `folder`, defaults to FolderBaseTypeField.FOLDER + :type type: FolderBaseTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.etag = etag + self.type = type \ No newline at end of file diff --git a/box_sdk_gen/schemas/folder_full.py b/box_sdk_gen/schemas/folder_full.py new file mode 100644 index 000000000..854cc8b2c --- /dev/null +++ b/box_sdk_gen/schemas/folder_full.py @@ -0,0 +1,218 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Optional + +from typing import List + +from box_sdk_gen.schemas.folder_base import FolderBaseTypeField + +from box_sdk_gen.schemas.folder_base import FolderBase + +from box_sdk_gen.schemas.folder_mini import FolderMini + +from box_sdk_gen.internal.utils import DateTime + +from box_sdk_gen.schemas.folder import FolderPathCollectionField + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.schemas.folder import FolderSharedLinkField + +from box_sdk_gen.schemas.folder import FolderFolderUploadEmailField + +from box_sdk_gen.schemas.folder import FolderItemStatusField + +from box_sdk_gen.schemas.items import Items + +from box_sdk_gen.schemas.folder import Folder + +from box_sdk_gen.schemas.metadata_full import MetadataFull + +from box_sdk_gen.box.errors import BoxSDKError + +class FolderFullSyncStateField(str, Enum): + SYNCED = 'synced' + NOT_SYNCED = 'not_synced' + PARTIALLY_SYNCED = 'partially_synced' + +class FolderFullPermissionsField(BaseObject): + def __init__(self, can_delete: bool, can_download: bool, can_invite_collaborator: bool, can_rename: bool, can_set_share_access: bool, can_share: bool, can_upload: bool, **kwargs): + """ + :param can_delete: Specifies if the current user can delete this item. + :type can_delete: bool + :param can_download: Specifies if the current user can download this item. + :type can_download: bool + :param can_invite_collaborator: Specifies if the current user can invite new +users to collaborate on this item, and if the user can +update the role of a user already collaborated on this +item. + :type can_invite_collaborator: bool + :param can_rename: Specifies if the user can rename this item. + :type can_rename: bool + :param can_set_share_access: Specifies if the user can change the access level of an +existing shared link on this item. + :type can_set_share_access: bool + :param can_share: Specifies if the user can create a shared link for this item. + :type can_share: bool + :param can_upload: Specifies if the user can upload into this folder. + :type can_upload: bool + """ + super().__init__(**kwargs) + self.can_delete = can_delete + self.can_download = can_download + self.can_invite_collaborator = can_invite_collaborator + self.can_rename = can_rename + self.can_set_share_access = can_set_share_access + self.can_share = can_share + self.can_upload = can_upload + +class FolderFullMetadataField(BaseObject): + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.extra_data = kwargs + +class FolderFullAllowedSharedLinkAccessLevelsField(str, Enum): + OPEN = 'open' + COMPANY = 'company' + COLLABORATORS = 'collaborators' + +class FolderFullAllowedInviteeRolesField(str, Enum): + EDITOR = 'editor' + VIEWER = 'viewer' + PREVIEWER = 'previewer' + UPLOADER = 'uploader' + PREVIEWER_UPLOADER = 'previewer uploader' + VIEWER_UPLOADER = 'viewer uploader' + CO_OWNER = 'co-owner' + +class FolderFullWatermarkInfoField(BaseObject): + def __init__(self, *, is_watermarked: Optional[bool] = None, **kwargs): + """ + :param is_watermarked: Specifies if this item has a watermark applied., defaults to None + :type is_watermarked: Optional[bool], optional + """ + super().__init__(**kwargs) + self.is_watermarked = is_watermarked + +class FolderFullClassificationField(BaseObject): + def __init__(self, *, name: Optional[str] = None, definition: Optional[str] = None, color: Optional[str] = None, **kwargs): + """ + :param name: The name of the classification, defaults to None + :type name: Optional[str], optional + :param definition: An explanation of the meaning of this classification., defaults to None + :type definition: Optional[str], optional + :param color: The color that is used to display the +classification label in a user-interface. Colors are defined by the admin +or co-admin who created the classification in the Box web app., defaults to None + :type color: Optional[str], optional + """ + super().__init__(**kwargs) + self.name = name + self.definition = definition + self.color = color + +class FolderFull(Folder): + def __init__(self, id: str, *, sync_state: Optional[FolderFullSyncStateField] = None, has_collaborations: Optional[bool] = None, permissions: Optional[FolderFullPermissionsField] = None, tags: Optional[List[str]] = None, can_non_owners_invite: Optional[bool] = None, is_externally_owned: Optional[bool] = None, metadata: Optional[FolderFullMetadataField] = None, is_collaboration_restricted_to_enterprise: Optional[bool] = None, allowed_shared_link_access_levels: Optional[List[FolderFullAllowedSharedLinkAccessLevelsField]] = None, allowed_invitee_roles: Optional[List[FolderFullAllowedInviteeRolesField]] = None, watermark_info: Optional[FolderFullWatermarkInfoField] = None, 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, size: Optional[int] = None, path_collection: Optional[FolderPathCollectionField] = None, created_by: Optional[UserMini] = None, modified_by: Optional[UserMini] = None, trashed_at: Optional[DateTime] = None, purged_at: Optional[DateTime] = None, content_created_at: Optional[DateTime] = None, content_modified_at: Optional[DateTime] = None, owned_by: Optional[UserMini] = None, shared_link: Optional[FolderSharedLinkField] = None, folder_upload_email: Optional[FolderFolderUploadEmailField] = None, parent: Optional[FolderMini] = None, item_status: Optional[FolderItemStatusField] = None, item_collection: Optional[Items] = None, sequence_id: Optional[str] = None, name: Optional[str] = None, etag: Optional[str] = None, type: FolderBaseTypeField = FolderBaseTypeField.FOLDER, **kwargs): + """ + :param id: The unique identifier that represent a folder. + +The ID for any folder can be determined +by visiting a folder in the web application +and copying the ID from the URL. For example, +for the URL `https://*.app.box.com/folders/123` +the `folder_id` is `123`. + :type id: str + :param has_collaborations: Specifies if this folder has any other collaborators., defaults to None + :type has_collaborations: Optional[bool], optional + :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. + +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 + :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 + :type allowed_invitee_roles: Optional[List[FolderFullAllowedInviteeRolesField]], optional + :param is_accessible_via_shared_link: Specifies if the folder can be accessed +with the direct shared link or a shared link +to a parent folder., defaults to None + :type is_accessible_via_shared_link: Optional[bool], optional + :param can_non_owners_view_collaborators: Specifies if collaborators who are not owners +of this folder are restricted from viewing other +collaborations on this folder. + +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 + :type created_at: Optional[DateTime], optional + :param modified_at: The date and time when the folder was last updated. This value may +be `null` for some folders such as the root folder or the trash +folder., defaults to None + :type modified_at: Optional[DateTime], optional + :param size: The folder size in bytes. + +Be careful parsing this integer as its +value can get very large., defaults to None + :type size: Optional[int], optional + :param trashed_at: The time at which this folder was put in the trash., defaults to None + :type trashed_at: Optional[DateTime], optional + :param purged_at: The time at which this folder is expected to be purged +from the trash., defaults to None + :type purged_at: Optional[DateTime], optional + :param content_created_at: The date and time at which this folder was originally +created., defaults to None + :type content_created_at: Optional[DateTime], optional + :param content_modified_at: The date and time at which this folder was last updated., defaults to None + :type content_modified_at: Optional[DateTime], optional + :param folder_upload_email: The `folder_upload_email` parameter is not `null` if one of the following options is **true**: + + * The **Allow uploads to this folder via email** and the **Only allow email uploads from collaborators in this folder** are [enabled for a folder in the Admin Console](https://support.box.com/hc/en-us/articles/360043697534-Upload-to-Box-Through-Email), and the user has at least **Upload** permissions granted. + + * The **Allow uploads to this folder via email** setting is enabled for a folder in the Admin Console, and the **Only allow email uploads from collaborators in this folder** setting is deactivated (unchecked). + +If the conditions are not met, the parameter will have the following value: `folder_upload_email: null`, defaults to None + :type folder_upload_email: Optional[FolderFolderUploadEmailField], optional + :param item_status: Defines if this item has been deleted or not. + +* `active` when the item has is not in the trash +* `trashed` when the item has been moved to the trash but not deleted +* `deleted` when the item has been permanently deleted., defaults to None + :type item_status: Optional[FolderItemStatusField], optional + :param name: The name of the folder., defaults to None + :type name: Optional[str], optional + :param etag: The HTTP `etag` of this folder. This can be used within some API +endpoints in the `If-Match` and `If-None-Match` headers to only +perform changes on the folder if (no) changes have happened., defaults to None + :type etag: Optional[str], optional + :param type: `folder`, defaults to FolderBaseTypeField.FOLDER + :type type: FolderBaseTypeField, optional + """ + super().__init__(id=id, created_at=created_at, modified_at=modified_at, description=description, size=size, path_collection=path_collection, created_by=created_by, modified_by=modified_by, trashed_at=trashed_at, purged_at=purged_at, content_created_at=content_created_at, content_modified_at=content_modified_at, owned_by=owned_by, shared_link=shared_link, folder_upload_email=folder_upload_email, parent=parent, item_status=item_status, item_collection=item_collection, sequence_id=sequence_id, name=name, etag=etag, type=type, **kwargs) + self.sync_state = sync_state + self.has_collaborations = has_collaborations + self.permissions = permissions + self.tags = tags + self.can_non_owners_invite = can_non_owners_invite + self.is_externally_owned = is_externally_owned + self.metadata = metadata + self.is_collaboration_restricted_to_enterprise = is_collaboration_restricted_to_enterprise + self.allowed_shared_link_access_levels = allowed_shared_link_access_levels + self.allowed_invitee_roles = allowed_invitee_roles + self.watermark_info = watermark_info + 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 \ No newline at end of file diff --git a/box_sdk_gen/schemas/folder_lock.py b/box_sdk_gen/schemas/folder_lock.py new file mode 100644 index 000000000..502a2b23c --- /dev/null +++ b/box_sdk_gen/schemas/folder_lock.py @@ -0,0 +1,49 @@ +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Optional + +from box_sdk_gen.schemas.folder_mini import FolderMini + +from box_sdk_gen.schemas.user_base import UserBase + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class FolderLockLockedOperationsField(BaseObject): + def __init__(self, move: bool, delete: bool, **kwargs): + """ + :param move: Whether moving the folder is restricted. + :type move: bool + :param delete: Whether deleting the folder is restricted. + :type delete: bool + """ + super().__init__(**kwargs) + self.move = move + self.delete = delete + +class FolderLock(BaseObject): + def __init__(self, *, folder: Optional[FolderMini] = None, id: Optional[str] = None, type: Optional[str] = None, created_by: Optional[UserBase] = None, created_at: Optional[DateTime] = None, locked_operations: Optional[FolderLockLockedOperationsField] = None, lock_type: Optional[str] = None, **kwargs): + """ + :param id: The unique identifier for this folder lock., defaults to None + :type id: Optional[str], optional + :param type: The object type, always `folder_lock`., defaults to None + :type type: Optional[str], optional + :param created_at: When the folder lock object was created., defaults to None + :type created_at: Optional[DateTime], optional + :param locked_operations: The operations that have been locked. Currently the `move` +and `delete` operations cannot be locked separately, and both need to be +set to `true`. +, defaults to None + :type locked_operations: Optional[FolderLockLockedOperationsField], optional + :param lock_type: The lock type, always `freeze`., defaults to None + :type lock_type: Optional[str], optional + """ + super().__init__(**kwargs) + self.folder = folder + self.id = id + self.type = type + self.created_by = created_by + self.created_at = created_at + self.locked_operations = locked_operations + self.lock_type = lock_type \ No newline at end of file diff --git a/box_sdk_gen/schemas/folder_locks.py b/box_sdk_gen/schemas/folder_locks.py new file mode 100644 index 000000000..e0f4ca3fd --- /dev/null +++ b/box_sdk_gen/schemas/folder_locks.py @@ -0,0 +1,26 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.folder_lock import FolderLock + +from box_sdk_gen.box.errors import BoxSDKError + +class FolderLocks(BaseObject): + def __init__(self, *, entries: Optional[List[FolderLock]] = None, limit: Optional[str] = None, next_marker: Optional[str] = None, **kwargs): + """ + :param entries: A list of folder locks, defaults to None + :type entries: Optional[List[FolderLock]], optional + :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[str], optional + :param next_marker: The marker for the start of the next page of results., defaults to None + :type next_marker: Optional[str], optional + """ + super().__init__(**kwargs) + self.entries = entries + self.limit = limit + self.next_marker = next_marker \ No newline at end of file diff --git a/box_sdk_gen/schemas/folder_mini.py b/box_sdk_gen/schemas/folder_mini.py new file mode 100644 index 000000000..aba7acbac --- /dev/null +++ b/box_sdk_gen/schemas/folder_mini.py @@ -0,0 +1,31 @@ +from typing import Optional + +from box_sdk_gen.schemas.folder_base import FolderBaseTypeField + +from box_sdk_gen.schemas.folder_base import FolderBase + +from box_sdk_gen.box.errors import BoxSDKError + +class FolderMini(FolderBase): + def __init__(self, id: str, *, sequence_id: Optional[str] = None, name: Optional[str] = None, etag: Optional[str] = None, type: FolderBaseTypeField = FolderBaseTypeField.FOLDER, **kwargs): + """ + :param id: The unique identifier that represent a folder. + +The ID for any folder can be determined +by visiting a folder in the web application +and copying the ID from the URL. For example, +for the URL `https://*.app.box.com/folders/123` +the `folder_id` is `123`. + :type id: str + :param name: The name of the folder., defaults to None + :type name: Optional[str], optional + :param etag: The HTTP `etag` of this folder. This can be used within some API +endpoints in the `If-Match` and `If-None-Match` headers to only +perform changes on the folder if (no) changes have happened., defaults to None + :type etag: Optional[str], optional + :param type: `folder`, defaults to FolderBaseTypeField.FOLDER + :type type: FolderBaseTypeField, optional + """ + super().__init__(id=id, etag=etag, type=type, **kwargs) + self.sequence_id = sequence_id + self.name = name \ No newline at end of file diff --git a/box_sdk_gen/schemas/folder_reference.py b/box_sdk_gen/schemas/folder_reference.py new file mode 100644 index 000000000..4c8e39f5f --- /dev/null +++ b/box_sdk_gen/schemas/folder_reference.py @@ -0,0 +1,21 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class FolderReferenceTypeField(str, Enum): + FOLDER = 'folder' + +class FolderReference(BaseObject): + _discriminator = 'type', {'folder'} + def __init__(self, id: str, *, type: FolderReferenceTypeField = FolderReferenceTypeField.FOLDER, **kwargs): + """ + :param id: ID of the folder + :type id: str + :param type: `folder`, defaults to FolderReferenceTypeField.FOLDER + :type type: FolderReferenceTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type \ No newline at end of file diff --git a/box_sdk_gen/schemas/generic_source.py b/box_sdk_gen/schemas/generic_source.py new file mode 100644 index 000000000..78372fcaa --- /dev/null +++ b/box_sdk_gen/schemas/generic_source.py @@ -0,0 +1 @@ +from box_sdk_gen.box.errors import BoxSDKError \ No newline at end of file diff --git a/box_sdk_gen/schemas/group.py b/box_sdk_gen/schemas/group.py new file mode 100644 index 000000000..40d384663 --- /dev/null +++ b/box_sdk_gen/schemas/group.py @@ -0,0 +1,33 @@ +from typing import Optional + +from box_sdk_gen.schemas.group_base import GroupBaseTypeField + +from box_sdk_gen.schemas.group_base import GroupBase + +from box_sdk_gen.schemas.group_mini import GroupMiniGroupTypeField + +from box_sdk_gen.schemas.group_mini import GroupMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class Group(GroupMini): + def __init__(self, id: str, *, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, name: Optional[str] = None, group_type: Optional[GroupMiniGroupTypeField] = None, type: GroupBaseTypeField = GroupBaseTypeField.GROUP, **kwargs): + """ + :param id: The unique identifier for this object + :type id: str + :param created_at: When the group object was created, defaults to None + :type created_at: Optional[DateTime], optional + :param modified_at: When the group object was last modified, defaults to None + :type modified_at: Optional[DateTime], optional + :param name: The name of the group, defaults to None + :type name: Optional[str], optional + :param group_type: The type of the group., defaults to None + :type group_type: Optional[GroupMiniGroupTypeField], optional + :param type: `group`, defaults to GroupBaseTypeField.GROUP + :type type: GroupBaseTypeField, optional + """ + super().__init__(id=id, name=name, group_type=group_type, type=type, **kwargs) + self.created_at = created_at + self.modified_at = modified_at \ No newline at end of file diff --git a/box_sdk_gen/schemas/group_base.py b/box_sdk_gen/schemas/group_base.py new file mode 100644 index 000000000..d58c9ddd6 --- /dev/null +++ b/box_sdk_gen/schemas/group_base.py @@ -0,0 +1,21 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class GroupBaseTypeField(str, Enum): + GROUP = 'group' + +class GroupBase(BaseObject): + _discriminator = 'type', {'group'} + def __init__(self, id: str, *, type: GroupBaseTypeField = GroupBaseTypeField.GROUP, **kwargs): + """ + :param id: The unique identifier for this object + :type id: str + :param type: `group`, defaults to GroupBaseTypeField.GROUP + :type type: GroupBaseTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type \ No newline at end of file diff --git a/box_sdk_gen/schemas/group_full.py b/box_sdk_gen/schemas/group_full.py new file mode 100644 index 000000000..fdb963663 --- /dev/null +++ b/box_sdk_gen/schemas/group_full.py @@ -0,0 +1,100 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.group_base import GroupBaseTypeField + +from box_sdk_gen.schemas.group_base import GroupBase + +from box_sdk_gen.schemas.group_mini import GroupMiniGroupTypeField + +from box_sdk_gen.schemas.group_mini import GroupMini + +from box_sdk_gen.internal.utils import DateTime + +from box_sdk_gen.schemas.group import Group + +from box_sdk_gen.box.errors import BoxSDKError + +class GroupFullInvitabilityLevelField(str, Enum): + ADMINS_ONLY = 'admins_only' + ADMINS_AND_MEMBERS = 'admins_and_members' + ALL_MANAGED_USERS = 'all_managed_users' + +class GroupFullMemberViewabilityLevelField(str, Enum): + ADMINS_ONLY = 'admins_only' + ADMINS_AND_MEMBERS = 'admins_and_members' + ALL_MANAGED_USERS = 'all_managed_users' + +class GroupFullPermissionsField(BaseObject): + def __init__(self, *, can_invite_as_collaborator: Optional[bool] = None, **kwargs): + """ + :param can_invite_as_collaborator: Specifies if the user can invite the group to collaborate on any items., defaults to None + :type can_invite_as_collaborator: Optional[bool], optional + """ + super().__init__(**kwargs) + self.can_invite_as_collaborator = can_invite_as_collaborator + +class GroupFull(Group): + def __init__(self, id: str, *, provenance: Optional[str] = None, external_sync_identifier: Optional[str] = None, description: Optional[str] = None, invitability_level: Optional[GroupFullInvitabilityLevelField] = None, member_viewability_level: Optional[GroupFullMemberViewabilityLevelField] = None, permissions: Optional[GroupFullPermissionsField] = None, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, name: Optional[str] = None, group_type: Optional[GroupMiniGroupTypeField] = None, type: GroupBaseTypeField = GroupBaseTypeField.GROUP, **kwargs): + """ + :param id: The unique identifier for this object + :type id: str + :param provenance: Keeps track of which external source this group is +coming from (e.g. "Active Directory", "Google Groups", +"Facebook Groups"). Setting this will +also prevent Box users from editing the group name +and its members directly via the Box web application. +This is desirable for one-way syncing of groups., defaults to None + :type provenance: Optional[str], optional + :param external_sync_identifier: An arbitrary identifier that can be used by +external group sync tools to link this Box Group to +an external group. Example values of this field +could be an Active Directory Object ID or a Google +Group ID. We recommend you use of this field in +order to avoid issues when group names are updated in +either Box or external systems., defaults to None + :type external_sync_identifier: Optional[str], optional + :param description: Human readable description of the group., defaults to None + :type description: Optional[str], optional + :param invitability_level: Specifies who can invite the group to collaborate +on items. + +When set to `admins_only` the enterprise admin, co-admins, +and the group's admin can invite the group. + +When set to `admins_and_members` all the admins listed +above and group members can invite the group. + +When set to `all_managed_users` all managed users in the +enterprise can invite the group., defaults to None + :type invitability_level: Optional[GroupFullInvitabilityLevelField], optional + :param member_viewability_level: Specifies who can view the members of the group +(Get Memberships for Group). + +* `admins_only` - the enterprise admin, co-admins, group's + group admin +* `admins_and_members` - all admins and group members +* `all_managed_users` - all managed users in the + enterprise, defaults to None + :type member_viewability_level: Optional[GroupFullMemberViewabilityLevelField], optional + :param created_at: When the group object was created, defaults to None + :type created_at: Optional[DateTime], optional + :param modified_at: When the group object was last modified, defaults to None + :type modified_at: Optional[DateTime], optional + :param name: The name of the group, defaults to None + :type name: Optional[str], optional + :param group_type: The type of the group., defaults to None + :type group_type: Optional[GroupMiniGroupTypeField], optional + :param type: `group`, defaults to GroupBaseTypeField.GROUP + :type type: GroupBaseTypeField, optional + """ + super().__init__(id=id, created_at=created_at, modified_at=modified_at, name=name, group_type=group_type, type=type, **kwargs) + self.provenance = provenance + self.external_sync_identifier = external_sync_identifier + self.description = description + self.invitability_level = invitability_level + self.member_viewability_level = member_viewability_level + self.permissions = permissions \ No newline at end of file diff --git a/box_sdk_gen/schemas/group_membership.py b/box_sdk_gen/schemas/group_membership.py new file mode 100644 index 000000000..45bbfb7f3 --- /dev/null +++ b/box_sdk_gen/schemas/group_membership.py @@ -0,0 +1,44 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.schemas.group_mini import GroupMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class GroupMembershipTypeField(str, Enum): + GROUP_MEMBERSHIP = 'group_membership' + +class GroupMembershipRoleField(str, Enum): + MEMBER = 'member' + ADMIN = 'admin' + +class GroupMembership(BaseObject): + _discriminator = 'type', {'group_membership'} + def __init__(self, *, id: Optional[str] = None, type: Optional[GroupMembershipTypeField] = None, user: Optional[UserMini] = None, group: Optional[GroupMini] = None, role: Optional[GroupMembershipRoleField] = None, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, **kwargs): + """ + :param id: The unique identifier for this group membership, defaults to None + :type id: Optional[str], optional + :param type: `group_membership`, defaults to None + :type type: Optional[GroupMembershipTypeField], optional + :param role: The role of the user in the group., defaults to None + :type role: Optional[GroupMembershipRoleField], optional + :param created_at: The time this membership was created., defaults to None + :type created_at: Optional[DateTime], optional + :param modified_at: The time this membership was last modified., defaults to None + :type modified_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.user = user + self.group = group + self.role = role + self.created_at = created_at + self.modified_at = modified_at \ No newline at end of file diff --git a/box_sdk_gen/schemas/group_memberships.py b/box_sdk_gen/schemas/group_memberships.py new file mode 100644 index 000000000..5ac9a73b9 --- /dev/null +++ b/box_sdk_gen/schemas/group_memberships.py @@ -0,0 +1,62 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from box_sdk_gen.schemas.group_membership import GroupMembership + +from box_sdk_gen.box.errors import BoxSDKError + +class GroupMembershipsOrderDirectionField(str, Enum): + ASC = 'ASC' + DESC = 'DESC' + +class GroupMembershipsOrderField(BaseObject): + def __init__(self, *, by: Optional[str] = None, direction: Optional[GroupMembershipsOrderDirectionField] = None, **kwargs): + """ + :param by: The field to order by, defaults to None + :type by: Optional[str], optional + :param direction: The direction to order by, either ascending or descending, defaults to None + :type direction: Optional[GroupMembershipsOrderDirectionField], optional + """ + super().__init__(**kwargs) + self.by = by + self.direction = direction + +class GroupMemberships(BaseObject): + def __init__(self, *, total_count: Optional[int] = None, limit: Optional[int] = None, offset: Optional[int] = None, order: Optional[List[GroupMembershipsOrderField]] = None, entries: Optional[List[GroupMembership]] = None, **kwargs): + """ + :param total_count: One greater than the offset of the last entry in the entire collection. +The total number of entries in the collection may be less than +`total_count`. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type total_count: Optional[int], optional + :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 offset: The 0-based offset of the first entry in this set. This will be the same +as the `offset` query parameter. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type offset: Optional[int], optional + :param order: The order by which items are returned. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type order: Optional[List[GroupMembershipsOrderField]], optional + :param entries: A list of group memberships, defaults to None + :type entries: Optional[List[GroupMembership]], optional + """ + super().__init__(**kwargs) + self.total_count = total_count + self.limit = limit + self.offset = offset + self.order = order + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/group_mini.py b/box_sdk_gen/schemas/group_mini.py new file mode 100644 index 000000000..d80a0c869 --- /dev/null +++ b/box_sdk_gen/schemas/group_mini.py @@ -0,0 +1,29 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.schemas.group_base import GroupBaseTypeField + +from box_sdk_gen.schemas.group_base import GroupBase + +from box_sdk_gen.box.errors import BoxSDKError + +class GroupMiniGroupTypeField(str, Enum): + MANAGED_GROUP = 'managed_group' + ALL_USERS_GROUP = 'all_users_group' + +class GroupMini(GroupBase): + def __init__(self, id: str, *, name: Optional[str] = None, group_type: Optional[GroupMiniGroupTypeField] = None, type: GroupBaseTypeField = GroupBaseTypeField.GROUP, **kwargs): + """ + :param id: The unique identifier for this object + :type id: str + :param name: The name of the group, defaults to None + :type name: Optional[str], optional + :param group_type: The type of the group., defaults to None + :type group_type: Optional[GroupMiniGroupTypeField], optional + :param type: `group`, defaults to GroupBaseTypeField.GROUP + :type type: GroupBaseTypeField, optional + """ + super().__init__(id=id, type=type, **kwargs) + self.name = name + self.group_type = group_type \ No newline at end of file diff --git a/box_sdk_gen/schemas/groups.py b/box_sdk_gen/schemas/groups.py new file mode 100644 index 000000000..c2322ae17 --- /dev/null +++ b/box_sdk_gen/schemas/groups.py @@ -0,0 +1,62 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from box_sdk_gen.schemas.group_full import GroupFull + +from box_sdk_gen.box.errors import BoxSDKError + +class GroupsOrderDirectionField(str, Enum): + ASC = 'ASC' + DESC = 'DESC' + +class GroupsOrderField(BaseObject): + def __init__(self, *, by: Optional[str] = None, direction: Optional[GroupsOrderDirectionField] = None, **kwargs): + """ + :param by: The field to order by, defaults to None + :type by: Optional[str], optional + :param direction: The direction to order by, either ascending or descending, defaults to None + :type direction: Optional[GroupsOrderDirectionField], optional + """ + super().__init__(**kwargs) + self.by = by + self.direction = direction + +class Groups(BaseObject): + def __init__(self, *, total_count: Optional[int] = None, limit: Optional[int] = None, offset: Optional[int] = None, order: Optional[List[GroupsOrderField]] = None, entries: Optional[List[GroupFull]] = None, **kwargs): + """ + :param total_count: One greater than the offset of the last entry in the entire collection. +The total number of entries in the collection may be less than +`total_count`. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type total_count: Optional[int], optional + :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 offset: The 0-based offset of the first entry in this set. This will be the same +as the `offset` query parameter. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type offset: Optional[int], optional + :param order: The order by which items are returned. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type order: Optional[List[GroupsOrderField]], optional + :param entries: A list of groups, defaults to None + :type entries: Optional[List[GroupFull]], optional + """ + super().__init__(**kwargs) + self.total_count = total_count + self.limit = limit + self.offset = offset + self.order = order + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/integration_mapping.py b/box_sdk_gen/schemas/integration_mapping.py new file mode 100644 index 000000000..9d9c2f99b --- /dev/null +++ b/box_sdk_gen/schemas/integration_mapping.py @@ -0,0 +1,69 @@ +from enum import Enum + +from typing import Optional + +from typing import Union + +from box_sdk_gen.schemas.integration_mapping_base import IntegrationMappingBaseTypeField + +from box_sdk_gen.schemas.integration_mapping_base import IntegrationMappingBase + +from box_sdk_gen.schemas.integration_mapping_slack_options import IntegrationMappingSlackOptions + +from box_sdk_gen.schemas.user_integration_mappings import UserIntegrationMappings + +from box_sdk_gen.schemas.integration_mapping_partner_item_slack import IntegrationMappingPartnerItemSlack + +from box_sdk_gen.schemas.folder_mini import FolderMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class IntegrationMappingIntegrationTypeField(str, Enum): + SLACK = 'slack' + +class IntegrationMapping(IntegrationMappingBase): + def __init__(self, partner_item: Union[IntegrationMappingPartnerItemSlack], box_item: FolderMini, id: str, *, integration_type: Optional[IntegrationMappingIntegrationTypeField] = None, is_manually_created: Optional[bool] = None, options: Optional[IntegrationMappingSlackOptions] = None, created_by: Optional[UserIntegrationMappings] = None, modified_by: Optional[UserIntegrationMappings] = None, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, type: IntegrationMappingBaseTypeField = IntegrationMappingBaseTypeField.INTEGRATION_MAPPING, **kwargs): + """ + :param partner_item: Mapped item object for Slack + :type partner_item: Union[IntegrationMappingPartnerItemSlack] + :param box_item: The Box folder, to which the object from the +partner app domain (referenced in `partner_item_id`) is mapped + :type box_item: FolderMini + :param id: A unique identifier of a folder mapping +(part of a composite key together +with `integration_type`) + :type id: str + :param integration_type: Identifies the Box partner app, +with which the mapping is associated. +Currently only supports Slack. +(part of the composite key together with `id`), defaults to None + :type integration_type: Optional[IntegrationMappingIntegrationTypeField], optional + :param is_manually_created: Identifies whether the mapping has +been manually set +(as opposed to being automatically created), defaults to None + :type is_manually_created: Optional[bool], optional + :param created_by: An object representing the user who +created the integration mapping, defaults to None + :type created_by: Optional[UserIntegrationMappings], optional + :param modified_by: The user who +last modified the integration mapping, defaults to None + :type modified_by: Optional[UserIntegrationMappings], optional + :param created_at: When the integration mapping object was created, defaults to None + :type created_at: Optional[DateTime], optional + :param modified_at: When the integration mapping object was last modified, defaults to None + :type modified_at: Optional[DateTime], optional + :param type: Mapping type, defaults to IntegrationMappingBaseTypeField.INTEGRATION_MAPPING + :type type: IntegrationMappingBaseTypeField, optional + """ + super().__init__(id=id, type=type, **kwargs) + self.partner_item = partner_item + self.box_item = box_item + self.integration_type = integration_type + self.is_manually_created = is_manually_created + self.options = options + self.created_by = created_by + self.modified_by = modified_by + self.created_at = created_at + self.modified_at = modified_at \ No newline at end of file diff --git a/box_sdk_gen/schemas/integration_mapping_base.py b/box_sdk_gen/schemas/integration_mapping_base.py new file mode 100644 index 000000000..eee91caab --- /dev/null +++ b/box_sdk_gen/schemas/integration_mapping_base.py @@ -0,0 +1,23 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class IntegrationMappingBaseTypeField(str, Enum): + INTEGRATION_MAPPING = 'integration_mapping' + +class IntegrationMappingBase(BaseObject): + _discriminator = 'type', {'integration_mapping'} + def __init__(self, id: str, *, type: IntegrationMappingBaseTypeField = IntegrationMappingBaseTypeField.INTEGRATION_MAPPING, **kwargs): + """ + :param id: A unique identifier of a folder mapping +(part of a composite key together +with `integration_type`) + :type id: str + :param type: Mapping type, defaults to IntegrationMappingBaseTypeField.INTEGRATION_MAPPING + :type type: IntegrationMappingBaseTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type \ No newline at end of file diff --git a/box_sdk_gen/schemas/integration_mapping_box_item_slack.py b/box_sdk_gen/schemas/integration_mapping_box_item_slack.py new file mode 100644 index 000000000..f33c0df21 --- /dev/null +++ b/box_sdk_gen/schemas/integration_mapping_box_item_slack.py @@ -0,0 +1,21 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class IntegrationMappingBoxItemSlackTypeField(str, Enum): + FOLDER = 'folder' + +class IntegrationMappingBoxItemSlack(BaseObject): + _discriminator = 'type', {'folder'} + def __init__(self, id: str, *, type: IntegrationMappingBoxItemSlackTypeField = IntegrationMappingBoxItemSlackTypeField.FOLDER, **kwargs): + """ + :param id: ID of the mapped item (of type referenced in `type`) + :type id: str + :param type: Type of the mapped item referenced in `id`, defaults to IntegrationMappingBoxItemSlackTypeField.FOLDER + :type type: IntegrationMappingBoxItemSlackTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type \ No newline at end of file diff --git a/box_sdk_gen/schemas/integration_mapping_partner_item_slack.py b/box_sdk_gen/schemas/integration_mapping_partner_item_slack.py new file mode 100644 index 000000000..d76dde251 --- /dev/null +++ b/box_sdk_gen/schemas/integration_mapping_partner_item_slack.py @@ -0,0 +1,29 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class IntegrationMappingPartnerItemSlackTypeField(str, Enum): + CHANNEL = 'channel' + +class IntegrationMappingPartnerItemSlack(BaseObject): + _discriminator = 'type', {'channel'} + def __init__(self, id: str, *, type: IntegrationMappingPartnerItemSlackTypeField = IntegrationMappingPartnerItemSlackTypeField.CHANNEL, slack_workspace_id: Optional[str] = None, slack_org_id: Optional[str] = None, **kwargs): + """ + :param id: ID of the mapped item (of type referenced in `type`) + :type id: str + :param type: Type of the mapped item referenced in `id`, defaults to IntegrationMappingPartnerItemSlackTypeField.CHANNEL + :type type: IntegrationMappingPartnerItemSlackTypeField, optional + :param slack_workspace_id: ID of the Slack workspace with which the item is associated. Use this parameter if Box for Slack is installed at a workspace level. Do not use `slack_org_id` at the same time., defaults to None + :type slack_workspace_id: Optional[str], optional + :param slack_org_id: ID of the Slack org with which the item is associated. Use this parameter if Box for Slack is installed at the org level. Do not use `slack_workspace_id` at the same time., defaults to None + :type slack_org_id: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.slack_workspace_id = slack_workspace_id + self.slack_org_id = slack_org_id \ No newline at end of file diff --git a/box_sdk_gen/schemas/integration_mapping_partner_item_teams.py b/box_sdk_gen/schemas/integration_mapping_partner_item_teams.py new file mode 100644 index 000000000..b9c5fe955 --- /dev/null +++ b/box_sdk_gen/schemas/integration_mapping_partner_item_teams.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 IntegrationMappingPartnerItemTeamsTypeField(str, Enum): + CHANNEL = 'channel' + TEAM = 'team' + +class IntegrationMappingPartnerItemTeams(BaseObject): + _discriminator = 'type', {'channel', 'team'} + def __init__(self, type: IntegrationMappingPartnerItemTeamsTypeField, id: str, tenant_id: str, **kwargs): + """ + :param type: Type of the mapped item referenced in `id` + :type type: IntegrationMappingPartnerItemTeamsTypeField + :param id: ID of the mapped item (of type referenced in `type`) + :type id: str + :param tenant_id: ID of the tenant that is registered with Microsoft Teams. + :type tenant_id: str + """ + super().__init__(**kwargs) + self.type = type + self.id = id + self.tenant_id = tenant_id \ No newline at end of file diff --git a/box_sdk_gen/schemas/integration_mapping_partner_item_teams_create_request.py b/box_sdk_gen/schemas/integration_mapping_partner_item_teams_create_request.py new file mode 100644 index 000000000..962b8b174 --- /dev/null +++ b/box_sdk_gen/schemas/integration_mapping_partner_item_teams_create_request.py @@ -0,0 +1,28 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class IntegrationMappingPartnerItemTeamsCreateRequestTypeField(str, Enum): + CHANNEL = 'channel' + TEAM = 'team' + +class IntegrationMappingPartnerItemTeamsCreateRequest(BaseObject): + _discriminator = 'type', {'channel', 'team'} + def __init__(self, type: IntegrationMappingPartnerItemTeamsCreateRequestTypeField, id: str, tenant_id: str, team_id: str, **kwargs): + """ + :param type: Type of the mapped item referenced in `id` + :type type: IntegrationMappingPartnerItemTeamsCreateRequestTypeField + :param id: ID of the mapped item (of type referenced in `type`) + :type id: str + :param tenant_id: ID of the tenant that is registered with Microsoft Teams. + :type tenant_id: str + :param team_id: ID of the team that is registered with Microsoft Teams. + :type team_id: str + """ + super().__init__(**kwargs) + self.type = type + self.id = id + self.tenant_id = tenant_id + self.team_id = team_id \ No newline at end of file diff --git a/box_sdk_gen/schemas/integration_mapping_slack_create_request.py b/box_sdk_gen/schemas/integration_mapping_slack_create_request.py new file mode 100644 index 000000000..1b5a58b09 --- /dev/null +++ b/box_sdk_gen/schemas/integration_mapping_slack_create_request.py @@ -0,0 +1,18 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.integration_mapping_partner_item_slack import IntegrationMappingPartnerItemSlack + +from box_sdk_gen.schemas.integration_mapping_box_item_slack import IntegrationMappingBoxItemSlack + +from box_sdk_gen.schemas.integration_mapping_slack_options import IntegrationMappingSlackOptions + +from box_sdk_gen.box.errors import BoxSDKError + +class IntegrationMappingSlackCreateRequest(BaseObject): + def __init__(self, partner_item: IntegrationMappingPartnerItemSlack, box_item: IntegrationMappingBoxItemSlack, *, options: Optional[IntegrationMappingSlackOptions] = None, **kwargs): + super().__init__(**kwargs) + self.partner_item = partner_item + self.box_item = box_item + self.options = options \ No newline at end of file diff --git a/box_sdk_gen/schemas/integration_mapping_slack_options.py b/box_sdk_gen/schemas/integration_mapping_slack_options.py new file mode 100644 index 000000000..65763c369 --- /dev/null +++ b/box_sdk_gen/schemas/integration_mapping_slack_options.py @@ -0,0 +1,18 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class IntegrationMappingSlackOptions(BaseObject): + def __init__(self, *, is_access_management_disabled: Optional[bool] = None, **kwargs): + """ + :param is_access_management_disabled: Indicates whether or not channel member +access to the underlying box item +should be automatically managed. +Depending on type of channel, access is managed +through creating collaborations or shared links., defaults to None + :type is_access_management_disabled: Optional[bool], optional + """ + super().__init__(**kwargs) + self.is_access_management_disabled = is_access_management_disabled \ No newline at end of file diff --git a/box_sdk_gen/schemas/integration_mapping_teams.py b/box_sdk_gen/schemas/integration_mapping_teams.py new file mode 100644 index 000000000..f46e4a345 --- /dev/null +++ b/box_sdk_gen/schemas/integration_mapping_teams.py @@ -0,0 +1,53 @@ +from enum import Enum + +from typing import Optional + +from typing import Union + +from box_sdk_gen.schemas.integration_mapping_base import IntegrationMappingBaseTypeField + +from box_sdk_gen.schemas.integration_mapping_base import IntegrationMappingBase + +from box_sdk_gen.schemas.integration_mapping_partner_item_teams import IntegrationMappingPartnerItemTeams + +from box_sdk_gen.schemas.folder_reference import FolderReference + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class IntegrationMappingTeamsIntegrationTypeField(str, Enum): + TEAMS = 'teams' + +class IntegrationMappingTeams(IntegrationMappingBase): + def __init__(self, partner_item: Union[IntegrationMappingPartnerItemTeams], box_item: FolderReference, id: str, *, integration_type: Optional[IntegrationMappingTeamsIntegrationTypeField] = None, is_overridden_by_manual_mapping: Optional[bool] = None, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, type: IntegrationMappingBaseTypeField = IntegrationMappingBaseTypeField.INTEGRATION_MAPPING, **kwargs): + """ + :param partner_item: Mapped item object for Teams + :type partner_item: Union[IntegrationMappingPartnerItemTeams] + :param id: A unique identifier of a folder mapping +(part of a composite key together +with `integration_type`) + :type id: str + :param integration_type: Identifies the Box partner app, +with which the mapping is associated. +Supports Slack and Teams. +(part of the composite key together with `id`), defaults to None + :type integration_type: Optional[IntegrationMappingTeamsIntegrationTypeField], optional + :param is_overridden_by_manual_mapping: Identifies whether the mapping has +been manually set by the team owner from UI for channels +(as opposed to being automatically created), defaults to None + :type is_overridden_by_manual_mapping: Optional[bool], optional + :param created_at: When the integration mapping object was created, defaults to None + :type created_at: Optional[DateTime], optional + :param modified_at: When the integration mapping object was last modified, defaults to None + :type modified_at: Optional[DateTime], optional + :param type: Mapping type, defaults to IntegrationMappingBaseTypeField.INTEGRATION_MAPPING + :type type: IntegrationMappingBaseTypeField, optional + """ + super().__init__(id=id, type=type, **kwargs) + self.partner_item = partner_item + self.box_item = box_item + self.integration_type = integration_type + self.is_overridden_by_manual_mapping = is_overridden_by_manual_mapping + self.created_at = created_at + self.modified_at = modified_at \ No newline at end of file diff --git a/box_sdk_gen/schemas/integration_mapping_teams_create_request.py b/box_sdk_gen/schemas/integration_mapping_teams_create_request.py new file mode 100644 index 000000000..fe814e444 --- /dev/null +++ b/box_sdk_gen/schemas/integration_mapping_teams_create_request.py @@ -0,0 +1,13 @@ +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.integration_mapping_partner_item_teams_create_request import IntegrationMappingPartnerItemTeamsCreateRequest + +from box_sdk_gen.schemas.folder_reference import FolderReference + +from box_sdk_gen.box.errors import BoxSDKError + +class IntegrationMappingTeamsCreateRequest(BaseObject): + def __init__(self, partner_item: IntegrationMappingPartnerItemTeamsCreateRequest, box_item: FolderReference, **kwargs): + super().__init__(**kwargs) + self.partner_item = partner_item + self.box_item = box_item \ No newline at end of file diff --git a/box_sdk_gen/schemas/integration_mappings.py b/box_sdk_gen/schemas/integration_mappings.py new file mode 100644 index 000000000..7e71c5e6a --- /dev/null +++ b/box_sdk_gen/schemas/integration_mappings.py @@ -0,0 +1,26 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.integration_mapping import IntegrationMapping + +from box_sdk_gen.box.errors import BoxSDKError + +class IntegrationMappings(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, entries: Optional[List[IntegrationMapping]] = 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 entries: A list of integration mappings, defaults to None + :type entries: Optional[List[IntegrationMapping]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/integration_mappings_teams.py b/box_sdk_gen/schemas/integration_mappings_teams.py new file mode 100644 index 000000000..75dc6dd88 --- /dev/null +++ b/box_sdk_gen/schemas/integration_mappings_teams.py @@ -0,0 +1,18 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.integration_mapping_teams import IntegrationMappingTeams + +from box_sdk_gen.box.errors import BoxSDKError + +class IntegrationMappingsTeams(BaseObject): + def __init__(self, *, entries: Optional[List[IntegrationMappingTeams]] = None, **kwargs): + """ + :param entries: A list of integration mappings, defaults to None + :type entries: Optional[List[IntegrationMappingTeams]], optional + """ + super().__init__(**kwargs) + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/invite.py b/box_sdk_gen/schemas/invite.py new file mode 100644 index 000000000..e7e22708e --- /dev/null +++ b/box_sdk_gen/schemas/invite.py @@ -0,0 +1,60 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class InviteTypeField(str, Enum): + INVITE = 'invite' + +class InviteInvitedToTypeField(str, Enum): + ENTERPRISE = 'enterprise' + +class InviteInvitedToField(BaseObject): + _discriminator = 'type', {'enterprise'} + def __init__(self, *, id: Optional[str] = None, type: Optional[InviteInvitedToTypeField] = None, name: Optional[str] = None, **kwargs): + """ + :param id: The unique identifier for this enterprise., defaults to None + :type id: Optional[str], optional + :param type: `enterprise`, defaults to None + :type type: Optional[InviteInvitedToTypeField], optional + :param name: The name of the enterprise, defaults to None + :type name: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.name = name + +class Invite(BaseObject): + _discriminator = 'type', {'invite'} + def __init__(self, id: str, *, type: InviteTypeField = InviteTypeField.INVITE, invited_to: Optional[InviteInvitedToField] = None, actionable_by: Optional[UserMini] = None, invited_by: Optional[UserMini] = None, status: Optional[str] = None, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, **kwargs): + """ + :param id: The unique identifier for this invite + :type id: str + :param type: `invite`, defaults to InviteTypeField.INVITE + :type type: InviteTypeField, optional + :param invited_to: A representation of a Box enterprise, defaults to None + :type invited_to: Optional[InviteInvitedToField], optional + :param status: The status of the invite, defaults to None + :type status: Optional[str], optional + :param created_at: When the invite was created, defaults to None + :type created_at: Optional[DateTime], optional + :param modified_at: When the invite was modified., defaults to None + :type modified_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.invited_to = invited_to + self.actionable_by = actionable_by + self.invited_by = invited_by + self.status = status + self.created_at = created_at + self.modified_at = modified_at \ No newline at end of file diff --git a/box_sdk_gen/schemas/items.py b/box_sdk_gen/schemas/items.py new file mode 100644 index 000000000..365673aab --- /dev/null +++ b/box_sdk_gen/schemas/items.py @@ -0,0 +1,74 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from typing import Union + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.folder_mini import FolderMini + +from box_sdk_gen.schemas.web_link import WebLink + +from box_sdk_gen.box.errors import BoxSDKError + +class ItemsOrderDirectionField(str, Enum): + ASC = 'ASC' + DESC = 'DESC' + +class ItemsOrderField(BaseObject): + def __init__(self, *, by: Optional[str] = None, direction: Optional[ItemsOrderDirectionField] = None, **kwargs): + """ + :param by: The field to order by, defaults to None + :type by: Optional[str], optional + :param direction: The direction to order by, either ascending or descending, defaults to None + :type direction: Optional[ItemsOrderDirectionField], optional + """ + super().__init__(**kwargs) + self.by = by + self.direction = direction + +class Items(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, prev_marker: Optional[str] = None, total_count: Optional[int] = None, offset: Optional[int] = None, order: Optional[List[ItemsOrderField]] = None, entries: Optional[List[Union[FileFull, FolderMini, WebLink]]] = 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 + :param total_count: One greater than the offset of the last entry in the entire collection. +The total number of entries in the collection may be less than +`total_count`. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type total_count: Optional[int], optional + :param offset: The 0-based offset of the first entry in this set. This will be the same +as the `offset` query parameter. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type offset: Optional[int], optional + :param order: The order by which items are returned. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type order: Optional[List[ItemsOrderField]], optional + :param entries: The items in this collection., defaults to None + :type entries: Optional[List[Union[FileFull, FolderMini, WebLink]]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.prev_marker = prev_marker + self.total_count = total_count + self.offset = offset + self.order = order + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/items_offset_paginated.py b/box_sdk_gen/schemas/items_offset_paginated.py new file mode 100644 index 000000000..d8b7dd2c5 --- /dev/null +++ b/box_sdk_gen/schemas/items_offset_paginated.py @@ -0,0 +1,68 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from typing import Union + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.folder_mini import FolderMini + +from box_sdk_gen.schemas.web_link import WebLink + +from box_sdk_gen.box.errors import BoxSDKError + +class ItemsOffsetPaginatedOrderDirectionField(str, Enum): + ASC = 'ASC' + DESC = 'DESC' + +class ItemsOffsetPaginatedOrderField(BaseObject): + def __init__(self, *, by: Optional[str] = None, direction: Optional[ItemsOffsetPaginatedOrderDirectionField] = None, **kwargs): + """ + :param by: The field to order by, defaults to None + :type by: Optional[str], optional + :param direction: The direction to order by, either ascending or descending, defaults to None + :type direction: Optional[ItemsOffsetPaginatedOrderDirectionField], optional + """ + super().__init__(**kwargs) + self.by = by + self.direction = direction + +class ItemsOffsetPaginated(BaseObject): + def __init__(self, *, total_count: Optional[int] = None, limit: Optional[int] = None, offset: Optional[int] = None, order: Optional[List[ItemsOffsetPaginatedOrderField]] = None, entries: Optional[List[Union[FileFull, FolderMini, WebLink]]] = None, **kwargs): + """ + :param total_count: One greater than the offset of the last entry in the entire collection. +The total number of entries in the collection may be less than +`total_count`. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type total_count: Optional[int], optional + :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 offset: The 0-based offset of the first entry in this set. This will be the same +as the `offset` query parameter. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type offset: Optional[int], optional + :param order: The order by which items are returned. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type order: Optional[List[ItemsOffsetPaginatedOrderField]], optional + :param entries: The items in this collection., defaults to None + :type entries: Optional[List[Union[FileFull, FolderMini, WebLink]]], optional + """ + super().__init__(**kwargs) + self.total_count = total_count + self.limit = limit + self.offset = offset + self.order = order + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/keyword_skill_card.py b/box_sdk_gen/schemas/keyword_skill_card.py new file mode 100644 index 000000000..d1015ebce --- /dev/null +++ b/box_sdk_gen/schemas/keyword_skill_card.py @@ -0,0 +1,104 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class KeywordSkillCardTypeField(str, Enum): + SKILL_CARD = 'skill_card' + +class KeywordSkillCardSkillCardTypeField(str, Enum): + KEYWORD = 'keyword' + +class KeywordSkillCardSkillCardTitleField(BaseObject): + def __init__(self, message: str, *, code: Optional[str] = None, **kwargs): + """ + :param message: The actual title to show in the UI. + :type message: str + :param code: An optional identifier for the title., defaults to None + :type code: Optional[str], optional + """ + super().__init__(**kwargs) + self.message = message + self.code = code + +class KeywordSkillCardSkillTypeField(str, Enum): + SERVICE = 'service' + +class KeywordSkillCardSkillField(BaseObject): + _discriminator = 'type', {'service'} + def __init__(self, id: str, *, type: KeywordSkillCardSkillTypeField = KeywordSkillCardSkillTypeField.SERVICE, **kwargs): + """ + :param id: A custom identifier that represent the service that +applied this metadata. + :type id: str + :param type: `service`, defaults to KeywordSkillCardSkillTypeField.SERVICE + :type type: KeywordSkillCardSkillTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class KeywordSkillCardInvocationTypeField(str, Enum): + SKILL_INVOCATION = 'skill_invocation' + +class KeywordSkillCardInvocationField(BaseObject): + _discriminator = 'type', {'skill_invocation'} + def __init__(self, id: str, *, type: KeywordSkillCardInvocationTypeField = KeywordSkillCardInvocationTypeField.SKILL_INVOCATION, **kwargs): + """ + :param id: A custom identifier that represent the instance of +the service that applied this metadata. For example, +if your `image-recognition-service` runs on multiple +nodes, this field can be used to identify the ID of +the node that was used to apply the metadata. + :type id: str + :param type: `skill_invocation`, defaults to KeywordSkillCardInvocationTypeField.SKILL_INVOCATION + :type type: KeywordSkillCardInvocationTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class KeywordSkillCardEntriesField(BaseObject): + def __init__(self, *, text: Optional[str] = None, **kwargs): + """ + :param text: The text of the keyword., defaults to None + :type text: Optional[str], optional + """ + super().__init__(**kwargs) + self.text = text + +class KeywordSkillCard(BaseObject): + _discriminator = 'skill_card_type', {'keyword'} + def __init__(self, skill: KeywordSkillCardSkillField, invocation: KeywordSkillCardInvocationField, entries: List[KeywordSkillCardEntriesField], *, created_at: Optional[DateTime] = None, type: KeywordSkillCardTypeField = KeywordSkillCardTypeField.SKILL_CARD, skill_card_type: KeywordSkillCardSkillCardTypeField = KeywordSkillCardSkillCardTypeField.KEYWORD, skill_card_title: Optional[KeywordSkillCardSkillCardTitleField] = None, **kwargs): + """ + :param skill: The service that applied this metadata. + :type skill: KeywordSkillCardSkillField + :param invocation: The invocation of this service, used to track +which instance of a service applied the metadata. + :type invocation: KeywordSkillCardInvocationField + :param entries: An list of entries in the metadata card. + :type entries: List[KeywordSkillCardEntriesField] + :param created_at: The optional date and time this card was created at., defaults to None + :type created_at: Optional[DateTime], optional + :param type: `skill_card`, defaults to KeywordSkillCardTypeField.SKILL_CARD + :type type: KeywordSkillCardTypeField, optional + :param skill_card_type: `keyword`, defaults to KeywordSkillCardSkillCardTypeField.KEYWORD + :type skill_card_type: KeywordSkillCardSkillCardTypeField, optional + :param skill_card_title: The title of the card., defaults to None + :type skill_card_title: Optional[KeywordSkillCardSkillCardTitleField], optional + """ + super().__init__(**kwargs) + self.skill = skill + self.invocation = invocation + self.entries = entries + self.created_at = created_at + self.type = type + self.skill_card_type = skill_card_type + self.skill_card_title = skill_card_title \ No newline at end of file diff --git a/box_sdk_gen/schemas/legal_hold_policies.py b/box_sdk_gen/schemas/legal_hold_policies.py new file mode 100644 index 000000000..e7b1c8088 --- /dev/null +++ b/box_sdk_gen/schemas/legal_hold_policies.py @@ -0,0 +1,29 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.legal_hold_policy import LegalHoldPolicy + +from box_sdk_gen.box.errors import BoxSDKError + +class LegalHoldPolicies(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, prev_marker: Optional[str] = None, entries: Optional[List[LegalHoldPolicy]] = 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 + :param entries: A list of legal hold policies, defaults to None + :type entries: Optional[List[LegalHoldPolicy]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.prev_marker = prev_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/legal_hold_policy.py b/box_sdk_gen/schemas/legal_hold_policy.py new file mode 100644 index 000000000..dc34790ed --- /dev/null +++ b/box_sdk_gen/schemas/legal_hold_policy.py @@ -0,0 +1,93 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.legal_hold_policy_mini import LegalHoldPolicyMiniTypeField + +from box_sdk_gen.schemas.legal_hold_policy_mini import LegalHoldPolicyMini + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class LegalHoldPolicyStatusField(str, Enum): + ACTIVE = 'active' + APPLYING = 'applying' + RELEASING = 'releasing' + RELEASED = 'released' + +class LegalHoldPolicyAssignmentCountsField(BaseObject): + def __init__(self, *, user: Optional[int] = None, folder: Optional[int] = None, file: Optional[int] = None, file_version: Optional[int] = None, **kwargs): + """ + :param user: The number of users this policy is applied to, defaults to None + :type user: Optional[int], optional + :param folder: The number of folders this policy is applied to, defaults to None + :type folder: Optional[int], optional + :param file: The number of files this policy is applied to, defaults to None + :type file: Optional[int], optional + :param file_version: The number of file versions this policy is applied to, defaults to None + :type file_version: Optional[int], optional + """ + super().__init__(**kwargs) + self.user = user + self.folder = folder + self.file = file + self.file_version = file_version + +class LegalHoldPolicy(LegalHoldPolicyMini): + def __init__(self, id: str, *, policy_name: Optional[str] = None, description: Optional[str] = None, status: Optional[LegalHoldPolicyStatusField] = None, assignment_counts: Optional[LegalHoldPolicyAssignmentCountsField] = None, created_by: Optional[UserMini] = None, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, deleted_at: Optional[DateTime] = None, filter_started_at: Optional[DateTime] = None, filter_ended_at: Optional[DateTime] = None, release_notes: Optional[str] = None, type: LegalHoldPolicyMiniTypeField = LegalHoldPolicyMiniTypeField.LEGAL_HOLD_POLICY, **kwargs): + """ + :param id: The unique identifier for this legal hold policy + :type id: str + :param policy_name: Name of the legal hold policy., defaults to None + :type policy_name: Optional[str], optional + :param description: Description of the legal hold policy. Optional +property with a 500 character limit., defaults to None + :type description: Optional[str], optional + :param status: * 'active' - the policy is not in a transition state +* 'applying' - that the policy is in the process of + being applied +* 'releasing' - that the process is in the process + of being released +* 'released' - the policy is no longer active, defaults to None + :type status: Optional[LegalHoldPolicyStatusField], optional + :param assignment_counts: Counts of assignments within this a legal hold policy by item type, defaults to None + :type assignment_counts: Optional[LegalHoldPolicyAssignmentCountsField], optional + :param created_at: When the legal hold policy object was created, defaults to None + :type created_at: Optional[DateTime], optional + :param modified_at: When the legal hold policy object was modified. +Does not update when assignments are added or removed., defaults to None + :type modified_at: Optional[DateTime], optional + :param deleted_at: When the policy release request was sent. (Because +it can take time for a policy to fully delete, this +isn't quite the same time that the policy is fully deleted). + +If `null`, the policy was not deleted., defaults to None + :type deleted_at: Optional[DateTime], optional + :param filter_started_at: User-specified, optional date filter applies to +Custodian assignments only, defaults to None + :type filter_started_at: Optional[DateTime], optional + :param filter_ended_at: User-specified, optional date filter applies to +Custodian assignments only, defaults to None + :type filter_ended_at: Optional[DateTime], optional + :param release_notes: Optional notes about why the policy was created., defaults to None + :type release_notes: Optional[str], optional + :param type: `legal_hold_policy`, defaults to LegalHoldPolicyMiniTypeField.LEGAL_HOLD_POLICY + :type type: LegalHoldPolicyMiniTypeField, optional + """ + super().__init__(id=id, type=type, **kwargs) + self.policy_name = policy_name + self.description = description + self.status = status + self.assignment_counts = assignment_counts + self.created_by = created_by + self.created_at = created_at + self.modified_at = modified_at + self.deleted_at = deleted_at + self.filter_started_at = filter_started_at + self.filter_ended_at = filter_ended_at + self.release_notes = release_notes \ No newline at end of file diff --git a/box_sdk_gen/schemas/legal_hold_policy_assignment.py b/box_sdk_gen/schemas/legal_hold_policy_assignment.py new file mode 100644 index 000000000..b024ee306 --- /dev/null +++ b/box_sdk_gen/schemas/legal_hold_policy_assignment.py @@ -0,0 +1,45 @@ +from typing import Optional + +from typing import Union + +from box_sdk_gen.schemas.legal_hold_policy_assignment_base import LegalHoldPolicyAssignmentBaseTypeField + +from box_sdk_gen.schemas.legal_hold_policy_assignment_base import LegalHoldPolicyAssignmentBase + +from box_sdk_gen.schemas.legal_hold_policy_mini import LegalHoldPolicyMini + +from box_sdk_gen.schemas.file import File + +from box_sdk_gen.schemas.folder import Folder + +from box_sdk_gen.schemas.web_link import WebLink + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class LegalHoldPolicyAssignment(LegalHoldPolicyAssignmentBase): + def __init__(self, *, legal_hold_policy: Optional[LegalHoldPolicyMini] = None, assigned_to: Optional[Union[File, Folder, WebLink]] = None, assigned_by: Optional[UserMini] = None, assigned_at: Optional[DateTime] = None, deleted_at: Optional[DateTime] = None, id: Optional[str] = None, type: Optional[LegalHoldPolicyAssignmentBaseTypeField] = None, **kwargs): + """ + :param assigned_at: When the legal hold policy assignment object was +created, defaults to None + :type assigned_at: Optional[DateTime], optional + :param deleted_at: When the assignment release request was sent. +(Because it can take time for an assignment to fully +delete, this isn't quite the same time that the +assignment is fully deleted). If null, Assignment +was not deleted., defaults to None + :type deleted_at: Optional[DateTime], optional + :param id: The unique identifier for this legal hold assignment, defaults to None + :type id: Optional[str], optional + :param type: `legal_hold_policy_assignment`, defaults to None + :type type: Optional[LegalHoldPolicyAssignmentBaseTypeField], optional + """ + super().__init__(id=id, type=type, **kwargs) + self.legal_hold_policy = legal_hold_policy + self.assigned_to = assigned_to + self.assigned_by = assigned_by + self.assigned_at = assigned_at + self.deleted_at = deleted_at \ No newline at end of file diff --git a/box_sdk_gen/schemas/legal_hold_policy_assignment_base.py b/box_sdk_gen/schemas/legal_hold_policy_assignment_base.py new file mode 100644 index 000000000..d169ed613 --- /dev/null +++ b/box_sdk_gen/schemas/legal_hold_policy_assignment_base.py @@ -0,0 +1,23 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class LegalHoldPolicyAssignmentBaseTypeField(str, Enum): + LEGAL_HOLD_POLICY_ASSIGNMENT = 'legal_hold_policy_assignment' + +class LegalHoldPolicyAssignmentBase(BaseObject): + _discriminator = 'type', {'legal_hold_policy_assignment'} + def __init__(self, *, id: Optional[str] = None, type: Optional[LegalHoldPolicyAssignmentBaseTypeField] = None, **kwargs): + """ + :param id: The unique identifier for this legal hold assignment, defaults to None + :type id: Optional[str], optional + :param type: `legal_hold_policy_assignment`, defaults to None + :type type: Optional[LegalHoldPolicyAssignmentBaseTypeField], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type \ No newline at end of file diff --git a/box_sdk_gen/schemas/legal_hold_policy_assignments.py b/box_sdk_gen/schemas/legal_hold_policy_assignments.py new file mode 100644 index 000000000..8b038034e --- /dev/null +++ b/box_sdk_gen/schemas/legal_hold_policy_assignments.py @@ -0,0 +1,30 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.legal_hold_policy_assignment import LegalHoldPolicyAssignment + +from box_sdk_gen.box.errors import BoxSDKError + +class LegalHoldPolicyAssignments(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, prev_marker: Optional[str] = None, entries: Optional[List[LegalHoldPolicyAssignment]] = 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 + :param entries: A list of legal hold +policy assignments, defaults to None + :type entries: Optional[List[LegalHoldPolicyAssignment]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.prev_marker = prev_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/legal_hold_policy_mini.py b/box_sdk_gen/schemas/legal_hold_policy_mini.py new file mode 100644 index 000000000..075ec3518 --- /dev/null +++ b/box_sdk_gen/schemas/legal_hold_policy_mini.py @@ -0,0 +1,21 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class LegalHoldPolicyMiniTypeField(str, Enum): + LEGAL_HOLD_POLICY = 'legal_hold_policy' + +class LegalHoldPolicyMini(BaseObject): + _discriminator = 'type', {'legal_hold_policy'} + def __init__(self, id: str, *, type: LegalHoldPolicyMiniTypeField = LegalHoldPolicyMiniTypeField.LEGAL_HOLD_POLICY, **kwargs): + """ + :param id: The unique identifier for this legal hold policy + :type id: str + :param type: `legal_hold_policy`, defaults to LegalHoldPolicyMiniTypeField.LEGAL_HOLD_POLICY + :type type: LegalHoldPolicyMiniTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type \ No newline at end of file diff --git a/box_sdk_gen/schemas/metadata.py b/box_sdk_gen/schemas/metadata.py new file mode 100644 index 000000000..06fc76039 --- /dev/null +++ b/box_sdk_gen/schemas/metadata.py @@ -0,0 +1,25 @@ +from typing import Optional + +from box_sdk_gen.schemas.metadata_base import MetadataBase + +from box_sdk_gen.box.errors import BoxSDKError + +class Metadata(MetadataBase): + def __init__(self, *, parent: Optional[str] = None, template: Optional[str] = None, scope: Optional[str] = None, version: Optional[int] = None, **kwargs): + """ + :param parent: The identifier of the item that this metadata instance +has been attached to. This combines the `type` and the `id` +of the parent in the form `{type}_{id}`., defaults to None + :type parent: Optional[str], optional + :param template: The name of the template, defaults to None + :type template: Optional[str], optional + :param scope: An ID for the scope in which this template +has been applied. This will be `enterprise_{enterprise_id}` for templates +defined for use in this enterprise, and `global` for general templates +that are available to all enterprises using Box., defaults to None + :type scope: Optional[str], optional + :param version: The version of the metadata instance. This version starts at 0 and +increases every time a user-defined property is modified., defaults to None + :type version: Optional[int], optional + """ + super().__init__(parent=parent, template=template, scope=scope, version=version, **kwargs) \ No newline at end of file diff --git a/box_sdk_gen/schemas/metadata_base.py b/box_sdk_gen/schemas/metadata_base.py new file mode 100644 index 000000000..4032dab5c --- /dev/null +++ b/box_sdk_gen/schemas/metadata_base.py @@ -0,0 +1,33 @@ +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class MetadataBase(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'parent': '$parent', 'template': '$template', 'scope': '$scope', 'version': '$version', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'$parent': 'parent', '$template': 'template', '$scope': 'scope', '$version': 'version', **BaseObject._json_to_fields_mapping} + def __init__(self, *, parent: Optional[str] = None, template: Optional[str] = None, scope: Optional[str] = None, version: Optional[int] = None, **kwargs): + """ + :param parent: The identifier of the item that this metadata instance +has been attached to. This combines the `type` and the `id` +of the parent in the form `{type}_{id}`., defaults to None + :type parent: Optional[str], optional + :param template: The name of the template, defaults to None + :type template: Optional[str], optional + :param scope: An ID for the scope in which this template +has been applied. This will be `enterprise_{enterprise_id}` for templates +defined for use in this enterprise, and `global` for general templates +that are available to all enterprises using Box., defaults to None + :type scope: Optional[str], optional + :param version: The version of the metadata instance. This version starts at 0 and +increases every time a user-defined property is modified., defaults to None + :type version: Optional[int], optional + """ + super().__init__(**kwargs) + self.parent = parent + self.template = template + self.scope = scope + self.version = version \ No newline at end of file diff --git a/box_sdk_gen/schemas/metadata_cascade_policies.py b/box_sdk_gen/schemas/metadata_cascade_policies.py new file mode 100644 index 000000000..adb7d3b43 --- /dev/null +++ b/box_sdk_gen/schemas/metadata_cascade_policies.py @@ -0,0 +1,29 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.metadata_cascade_policy import MetadataCascadePolicy + +from box_sdk_gen.box.errors import BoxSDKError + +class MetadataCascadePolicies(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, prev_marker: Optional[str] = None, entries: Optional[List[MetadataCascadePolicy]] = 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 + :param entries: A list of metadata cascade policies, defaults to None + :type entries: Optional[List[MetadataCascadePolicy]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.prev_marker = prev_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/metadata_cascade_policy.py b/box_sdk_gen/schemas/metadata_cascade_policy.py new file mode 100644 index 000000000..d173e1cbb --- /dev/null +++ b/box_sdk_gen/schemas/metadata_cascade_policy.py @@ -0,0 +1,89 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Dict + +from box_sdk_gen.box.errors import BoxSDKError + +class MetadataCascadePolicyTypeField(str, Enum): + METADATA_CASCADE_POLICY = 'metadata_cascade_policy' + +class MetadataCascadePolicyOwnerEnterpriseTypeField(str, Enum): + ENTERPRISE = 'enterprise' + +class MetadataCascadePolicyOwnerEnterpriseField(BaseObject): + _discriminator = 'type', {'enterprise'} + def __init__(self, *, type: Optional[MetadataCascadePolicyOwnerEnterpriseTypeField] = None, id: Optional[str] = None, **kwargs): + """ + :param type: `enterprise`, defaults to None + :type type: Optional[MetadataCascadePolicyOwnerEnterpriseTypeField], optional + :param id: The ID of the enterprise that owns the policy., defaults to None + :type id: Optional[str], optional + """ + super().__init__(**kwargs) + self.type = type + self.id = id + +class MetadataCascadePolicyParentTypeField(str, Enum): + FOLDER = 'folder' + +class MetadataCascadePolicyParentField(BaseObject): + _discriminator = 'type', {'folder'} + def __init__(self, *, type: Optional[MetadataCascadePolicyParentTypeField] = None, id: Optional[str] = None, **kwargs): + """ + :param type: `folder`, defaults to None + :type type: Optional[MetadataCascadePolicyParentTypeField], optional + :param id: The ID of the folder the policy is applied to., defaults to None + :type id: Optional[str], optional + """ + super().__init__(**kwargs) + self.type = type + self.id = id + +class MetadataCascadePolicy(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'template_key': 'templateKey', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'templateKey': 'template_key', **BaseObject._json_to_fields_mapping} + _discriminator = 'type', {'metadata_cascade_policy'} + def __init__(self, id: str, *, type: MetadataCascadePolicyTypeField = MetadataCascadePolicyTypeField.METADATA_CASCADE_POLICY, owner_enterprise: Optional[MetadataCascadePolicyOwnerEnterpriseField] = None, parent: Optional[MetadataCascadePolicyParentField] = None, scope: Optional[str] = None, template_key: Optional[str] = None, **kwargs): + """ + :param id: The ID of the metadata cascade policy object + :type id: str + :param type: `metadata_cascade_policy`, defaults to MetadataCascadePolicyTypeField.METADATA_CASCADE_POLICY + :type type: MetadataCascadePolicyTypeField, optional + :param owner_enterprise: The enterprise that owns this policy., defaults to None + :type owner_enterprise: Optional[MetadataCascadePolicyOwnerEnterpriseField], optional + :param parent: Represent the folder the policy is applied to., defaults to None + :type parent: Optional[MetadataCascadePolicyParentField], optional + :param scope: The scope of the metadata cascade policy can either be `global` or +`enterprise_*`. The `global` scope is used for policies that are +available to any Box enterprise. The `enterprise_*` scope represents +policies that have been created within a specific enterprise, where `*` +will be the ID of that enterprise., defaults to None + :type scope: Optional[str], optional + :param template_key: The key of the template that is cascaded down to the folder's +children. + +In many cases the template key is automatically derived +of its display name, for example `Contract Template` would +become `contractTemplate`. In some cases the creator of the +template will have provided its own template key. + +Please [list the templates for an enterprise][list], or +get all instances on a [file][file] or [folder][folder] +to inspect a template's key. + +[list]: e://get-metadata-templates-enterprise +[file]: e://get-files-id-metadata +[folder]: e://get-folders-id-metadata, defaults to None + :type template_key: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.owner_enterprise = owner_enterprise + self.parent = parent + self.scope = scope + self.template_key = template_key \ No newline at end of file diff --git a/box_sdk_gen/schemas/metadata_field_filter_date_range.py b/box_sdk_gen/schemas/metadata_field_filter_date_range.py new file mode 100644 index 000000000..1c44281ca --- /dev/null +++ b/box_sdk_gen/schemas/metadata_field_filter_date_range.py @@ -0,0 +1,25 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class MetadataFieldFilterDateRange(BaseObject): + def __init__(self, *, lt: Optional[DateTime] = None, gt: Optional[DateTime] = None, **kwargs): + """ + :param lt: Specifies the (inclusive) upper bound for the metadata field +value. The value of a field must be lower than (`lt`) or +equal to this value for the search query to match this +template., defaults to None + :type lt: Optional[DateTime], optional + :param gt: Specifies the (inclusive) lower bound for the metadata field +value. The value of a field must be greater than (`gt`) or +equal to this value for the search query to match this +template., defaults to None + :type gt: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.lt = lt + self.gt = gt \ No newline at end of file diff --git a/box_sdk_gen/schemas/metadata_field_filter_float_range.py b/box_sdk_gen/schemas/metadata_field_filter_float_range.py new file mode 100644 index 000000000..65f0a0785 --- /dev/null +++ b/box_sdk_gen/schemas/metadata_field_filter_float_range.py @@ -0,0 +1,23 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class MetadataFieldFilterFloatRange(BaseObject): + def __init__(self, *, lt: Optional[float] = None, gt: Optional[float] = None, **kwargs): + """ + :param lt: Specifies the (inclusive) upper bound for the metadata field +value. The value of a field must be lower than (`lt`) or +equal to this value for the search query to match this +template., defaults to None + :type lt: Optional[float], optional + :param gt: Specifies the (inclusive) lower bound for the metadata field +value. The value of a field must be greater than (`gt`) or +equal to this value for the search query to match this +template., defaults to None + :type gt: Optional[float], optional + """ + super().__init__(**kwargs) + self.lt = lt + self.gt = gt \ No newline at end of file diff --git a/box_sdk_gen/schemas/metadata_filter.py b/box_sdk_gen/schemas/metadata_filter.py new file mode 100644 index 000000000..872a031a9 --- /dev/null +++ b/box_sdk_gen/schemas/metadata_filter.py @@ -0,0 +1,59 @@ +from enum import Enum + +from typing import Optional + +from typing import Dict + +from typing import Union + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.metadata_field_filter_float_range import MetadataFieldFilterFloatRange + +from box_sdk_gen.schemas.metadata_field_filter_date_range import MetadataFieldFilterDateRange + +from box_sdk_gen.box.errors import BoxSDKError + +class MetadataFilterScopeField(str, Enum): + GLOBAL = 'global' + ENTERPRISE = 'enterprise' + ENTERPRISE__ENTERPRISE_ID_ = 'enterprise_{enterprise_id}' + +class MetadataFilter(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'template_key': 'templateKey', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'templateKey': 'template_key', **BaseObject._json_to_fields_mapping} + def __init__(self, *, scope: Optional[MetadataFilterScopeField] = None, template_key: Optional[str] = None, filters: Optional[Dict[str, Union[str, float, List[str], MetadataFieldFilterFloatRange, MetadataFieldFilterDateRange]]] = None, **kwargs): + """ + :param scope: Specifies the scope of the template to filter search results by. + +This will be `enterprise_{enterprise_id}` for templates defined +for use in this enterprise, and `global` for general templates +that are available to all enterprises using Box., defaults to None + :type scope: Optional[MetadataFilterScopeField], optional + :param template_key: The key of the template used to filter search results. + +In many cases the template key is automatically derived +of its display name, for example `Contract Template` would +become `contractTemplate`. In some cases the creator of the +template will have provided its own template key. + +Please [list the templates for an enterprise][list], or +get all instances on a [file][file] or [folder][folder] +to inspect a template's key. + +[list]: e://get-metadata-templates-enterprise +[file]: e://get-files-id-metadata +[folder]: e://get-folders-id-metadata, defaults to None + :type template_key: Optional[str], optional + :param filters: Specifies which fields on the template to filter the search +results by. When more than one field is specified, the query +performs a logical `AND` to ensure that the instance of the +template matches each of the fields specified., defaults to None + :type filters: Optional[Dict[str, Union[str, float, List[str], MetadataFieldFilterFloatRange, MetadataFieldFilterDateRange]]], optional + """ + super().__init__(**kwargs) + self.scope = scope + self.template_key = template_key + self.filters = filters \ No newline at end of file diff --git a/box_sdk_gen/schemas/metadata_full.py b/box_sdk_gen/schemas/metadata_full.py new file mode 100644 index 000000000..0d3f64149 --- /dev/null +++ b/box_sdk_gen/schemas/metadata_full.py @@ -0,0 +1,48 @@ +from typing import Optional + +from typing import Dict + +from box_sdk_gen.schemas.metadata_base import MetadataBase + +from box_sdk_gen.schemas.metadata import Metadata + +from box_sdk_gen.box.errors import BoxSDKError + +class MetadataFull(Metadata): + _fields_to_json_mapping: Dict[str, str] = {'can_edit': '$canEdit', 'id': '$id', 'type': '$type', 'type_version': '$typeVersion', **Metadata._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'$canEdit': 'can_edit', '$id': 'id', '$type': 'type', '$typeVersion': 'type_version', **Metadata._json_to_fields_mapping} + def __init__(self, *, can_edit: Optional[bool] = None, id: Optional[str] = None, type: Optional[str] = None, type_version: Optional[int] = None, parent: Optional[str] = None, template: Optional[str] = None, scope: Optional[str] = None, version: Optional[int] = None, **kwargs): + """ + :param can_edit: Whether the user can edit this metadata instance., defaults to None + :type can_edit: Optional[bool], optional + :param id: A UUID to identify the metadata instance., defaults to None + :type id: Optional[str], optional + :param type: A unique identifier for the "type" of this instance. This is an +internal system property and should not be used by a client +application., defaults to None + :type type: Optional[str], optional + :param type_version: The last-known version of the template of the object. This is an +internal system property and should not be used by a client +application., defaults to None + :type type_version: Optional[int], optional + :param parent: The identifier of the item that this metadata instance +has been attached to. This combines the `type` and the `id` +of the parent in the form `{type}_{id}`., defaults to None + :type parent: Optional[str], optional + :param template: The name of the template, defaults to None + :type template: Optional[str], optional + :param scope: An ID for the scope in which this template +has been applied. This will be `enterprise_{enterprise_id}` for templates +defined for use in this enterprise, and `global` for general templates +that are available to all enterprises using Box., defaults to None + :type scope: Optional[str], optional + :param version: The version of the metadata instance. This version starts at 0 and +increases every time a user-defined property is modified., defaults to None + :type version: Optional[int], optional + """ + super().__init__(parent=parent, template=template, scope=scope, version=version, **kwargs) + self.can_edit = can_edit + self.id = id + self.type = type + self.type_version = type_version + self.extra_data = kwargs \ No newline at end of file diff --git a/box_sdk_gen/schemas/metadata_instance_value.py b/box_sdk_gen/schemas/metadata_instance_value.py new file mode 100644 index 000000000..33a5942a1 --- /dev/null +++ b/box_sdk_gen/schemas/metadata_instance_value.py @@ -0,0 +1,7 @@ +from typing import Union + +from typing import List + +from box_sdk_gen.box.errors import BoxSDKError + +MetadataInstanceValue = Union[str, int, float, List[str]] \ No newline at end of file diff --git a/box_sdk_gen/schemas/metadata_query.py b/box_sdk_gen/schemas/metadata_query.py new file mode 100644 index 000000000..247bea67b --- /dev/null +++ b/box_sdk_gen/schemas/metadata_query.py @@ -0,0 +1,101 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Dict + +from typing import List + +from box_sdk_gen.box.errors import BoxSDKError + +class MetadataQueryOrderByDirectionField(str, Enum): + ASC = 'ASC' + DESC = 'DESC' + +class MetadataQueryOrderByField(BaseObject): + def __init__(self, *, field_key: Optional[str] = None, direction: Optional[MetadataQueryOrderByDirectionField] = None, **kwargs): + """ + :param field_key: The metadata template field to order by. + +The `field_key` represents the `key` value of a field from the +metadata template being searched for., defaults to None + :type field_key: Optional[str], optional + :param direction: The direction to order by, either ascending or descending. + +The `ordering` direction must be the same for each item in the +array., defaults to None + :type direction: Optional[MetadataQueryOrderByDirectionField], optional + """ + super().__init__(**kwargs) + self.field_key = field_key + self.direction = direction + +class MetadataQuery(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'from_': 'from', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'from': 'from_', **BaseObject._json_to_fields_mapping} + def __init__(self, from_: str, ancestor_folder_id: str, *, query: Optional[str] = None, query_params: Optional[Dict] = None, order_by: Optional[List[MetadataQueryOrderByField]] = None, limit: Optional[int] = None, marker: Optional[str] = None, fields: Optional[List[str]] = None, **kwargs): + """ + :param from_: Specifies the template used in the query. Must be in the form +`scope.templateKey`. Not all templates can be used in this field, +most notably the built-in, Box-provided classification templates +can not be used in a query. + :type from_: str + :param ancestor_folder_id: The ID of the folder that you are restricting the query to. A +value of zero will return results from all folders you have access +to. A non-zero value will only return results found in the folder +corresponding to the ID or in any of its subfolders. + :type ancestor_folder_id: str + :param query: The query to perform. A query is a logical expression that is very similar +to a SQL `SELECT` statement. Values in the search query can be turned into +parameters specified in the `query_param` arguments list to prevent having +to manually insert search values into the query string. + +For example, a value of `:amount` would represent the `amount` value in +`query_params` object., defaults to None + :type query: Optional[str], optional + :param query_params: Set of arguments corresponding to the parameters specified in the +`query`. The type of each parameter used in the `query_params` must match +the type of the corresponding metadata template field., defaults to None + :type query_params: Optional[Dict], optional + :param order_by: A list of template fields and directions to sort the metadata query +results by. + +The ordering `direction` must be the same for each item in the array., defaults to None + :type order_by: Optional[List[MetadataQueryOrderByField]], optional + :param limit: A value between 0 and 100 that indicates the maximum number of results +to return for a single request. This only specifies a maximum +boundary and will not guarantee the minimum number of results +returned., defaults to None + :type limit: Optional[int], optional + :param marker: Marker to use for requesting the next page., defaults to None + :type marker: Optional[str], optional + :param fields: By default, this endpoint returns only the most basic info about the items for +which the query matches. This attribute can be used to specify a list of +additional attributes to return for any item, including its metadata. + +This attribute takes a list of item fields, metadata template identifiers, +or metadata template field identifiers. + +For example: + +* `created_by` will add the details of the user who created the item to +the response. +* `metadata..` will return the mini-representation +of the metadata instance identified by the `scope` and `templateKey`. +* `metadata...` will return all the mini-representation +of the metadata instance identified by the `scope` and `templateKey` plus +the field specified by the `field` name. Multiple fields for the same +`scope` and `templateKey` can be defined., defaults to None + :type fields: Optional[List[str]], optional + """ + super().__init__(**kwargs) + self.from_ = from_ + self.ancestor_folder_id = ancestor_folder_id + self.query = query + self.query_params = query_params + self.order_by = order_by + self.limit = limit + self.marker = marker + self.fields = fields \ No newline at end of file diff --git a/box_sdk_gen/schemas/metadata_query_index.py b/box_sdk_gen/schemas/metadata_query_index.py new file mode 100644 index 000000000..f51ed78d0 --- /dev/null +++ b/box_sdk_gen/schemas/metadata_query_index.py @@ -0,0 +1,48 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from box_sdk_gen.box.errors import BoxSDKError + +class MetadataQueryIndexStatusField(str, Enum): + BUILDING = 'building' + ACTIVE = 'active' + DISABLED = 'disabled' + +class MetadataQueryIndexFieldsSortDirectionField(str, Enum): + ASC = 'asc' + DESC = 'desc' + +class MetadataQueryIndexFieldsField(BaseObject): + def __init__(self, *, key: Optional[str] = None, sort_direction: Optional[MetadataQueryIndexFieldsSortDirectionField] = None, **kwargs): + """ + :param key: The metadata template field key., defaults to None + :type key: Optional[str], optional + :param sort_direction: The sort direction of the field., defaults to None + :type sort_direction: Optional[MetadataQueryIndexFieldsSortDirectionField], optional + """ + super().__init__(**kwargs) + self.key = key + self.sort_direction = sort_direction + +class MetadataQueryIndex(BaseObject): + def __init__(self, type: str, status: MetadataQueryIndexStatusField, *, id: Optional[str] = None, fields: Optional[List[MetadataQueryIndexFieldsField]] = None, **kwargs): + """ + :param type: Value is always `metadata_query_index` + :type type: str + :param status: The status of the metadata query index + :type status: MetadataQueryIndexStatusField + :param id: The ID of the metadata query index., defaults to None + :type id: Optional[str], optional + :param fields: A list of template fields which make up the index., defaults to None + :type fields: Optional[List[MetadataQueryIndexFieldsField]], optional + """ + super().__init__(**kwargs) + self.type = type + self.status = status + self.id = id + self.fields = fields \ No newline at end of file diff --git a/box_sdk_gen/schemas/metadata_query_results.py b/box_sdk_gen/schemas/metadata_query_results.py new file mode 100644 index 000000000..afac717ee --- /dev/null +++ b/box_sdk_gen/schemas/metadata_query_results.py @@ -0,0 +1,35 @@ +from typing import Optional + +from typing import List + +from typing import Union + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.box.errors import BoxSDKError + +class MetadataQueryResults(BaseObject): + def __init__(self, *, entries: Optional[List[Union[FileFull, FolderFull]]] = None, limit: Optional[int] = None, next_marker: Optional[str] = None, **kwargs): + """ + :param entries: The mini representation of the files and folders that match the search +terms. + +By default, this endpoint returns only the most basic info about the +items. To get additional fields for each item, including any of the +metadata, use the `fields` attribute in the query., defaults to None + :type entries: Optional[List[Union[FileFull, FolderFull]]], optional + :param limit: The limit that was used for this search. This will be the same as the +`limit` query parameter unless that value exceeded the maximum value +allowed., 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 + """ + super().__init__(**kwargs) + self.entries = entries + self.limit = limit + self.next_marker = next_marker \ No newline at end of file diff --git a/box_sdk_gen/schemas/metadata_template.py b/box_sdk_gen/schemas/metadata_template.py new file mode 100644 index 000000000..a4c219a67 --- /dev/null +++ b/box_sdk_gen/schemas/metadata_template.py @@ -0,0 +1,122 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from typing import Dict + +from box_sdk_gen.box.errors import BoxSDKError + +class MetadataTemplateTypeField(str, Enum): + METADATA_TEMPLATE = 'metadata_template' + +class MetadataTemplateFieldsTypeField(str, Enum): + STRING = 'string' + FLOAT = 'float' + DATE = 'date' + ENUM = 'enum' + MULTISELECT = 'multiSelect' + INTEGER = 'integer' + +class MetadataTemplateFieldsOptionsField(BaseObject): + def __init__(self, key: str, *, id: Optional[str] = None, **kwargs): + """ + :param key: The text value of the option. This represents both the display name of the +option and the internal key used when updating templates. + :type key: str + :param id: The internal unique identifier of the the option., defaults to None + :type id: Optional[str], optional + """ + super().__init__(**kwargs) + self.key = key + self.id = id + +class MetadataTemplateFieldsField(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'display_name': 'displayName', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'displayName': 'display_name', **BaseObject._json_to_fields_mapping} + _discriminator = 'type', {'string', 'float', 'date', 'enum', 'multiSelect', 'integer'} + def __init__(self, type: MetadataTemplateFieldsTypeField, key: str, display_name: str, *, description: Optional[str] = None, hidden: Optional[bool] = None, options: Optional[List[MetadataTemplateFieldsOptionsField]] = None, id: Optional[str] = None, **kwargs): + """ + :param type: The type of field. The basic fields are a `string` field for text, a +`float` field for numbers, and a `date` fields to present the user with a +date-time picker. + +Additionally, metadata templates support an `enum` field for a basic list +of items, and ` multiSelect` field for a similar list of items where the +user can select more than one value. + +**Note**: The `integer` value is deprecated. +It is still present in the response, +but cannot be used in the POST request. + :type type: MetadataTemplateFieldsTypeField + :param key: A unique identifier for the field. The identifier must +be unique within the template to which it belongs. + :type key: str + :param display_name: The display name of the field as it is shown to the user in the web and +mobile apps. + :type display_name: str + :param description: A description of the field. This is not shown to the user., defaults to None + :type description: Optional[str], optional + :param hidden: Whether this field is hidden in the UI for the user and can only be set +through the API instead., defaults to None + :type hidden: Optional[bool], optional + :param options: A list of options for this field. This is used in combination +with the `enum` and `multiSelect` field types., defaults to None + :type options: Optional[List[MetadataTemplateFieldsOptionsField]], optional + :param id: The unique ID of the metadata template field., defaults to None + :type id: Optional[str], optional + """ + super().__init__(**kwargs) + self.type = type + self.key = key + self.display_name = display_name + self.description = description + self.hidden = hidden + self.options = options + self.id = id + +class MetadataTemplate(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'template_key': 'templateKey', 'display_name': 'displayName', 'copy_instance_on_item_copy': 'copyInstanceOnItemCopy', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'templateKey': 'template_key', 'displayName': 'display_name', 'copyInstanceOnItemCopy': 'copy_instance_on_item_copy', **BaseObject._json_to_fields_mapping} + _discriminator = 'type', {'metadata_template'} + def __init__(self, id: str, *, type: MetadataTemplateTypeField = MetadataTemplateTypeField.METADATA_TEMPLATE, scope: Optional[str] = None, template_key: Optional[str] = None, display_name: Optional[str] = None, hidden: Optional[bool] = None, fields: Optional[List[MetadataTemplateFieldsField]] = None, copy_instance_on_item_copy: Optional[bool] = None, **kwargs): + """ + :param id: The ID of the metadata template. + :type id: str + :param type: `metadata_template`, defaults to MetadataTemplateTypeField.METADATA_TEMPLATE + :type type: MetadataTemplateTypeField, optional + :param scope: The scope of the metadata template can either be `global` or +`enterprise_*`. The `global` scope is used for templates that are +available to any Box enterprise. The `enterprise_*` scope represents +templates that have been created within a specific enterprise, where `*` +will be the ID of that enterprise., defaults to None + :type scope: Optional[str], optional + :param template_key: A unique identifier for the template. This identifier is unique across +the `scope` of the enterprise to which the metadata template is being +applied, yet is not necessarily unique across different enterprises., defaults to None + :type template_key: Optional[str], optional + :param display_name: The display name of the template. This can be seen in the Box web app +and mobile apps., defaults to None + :type display_name: Optional[str], optional + :param hidden: Defines if this template is visible in the Box web app UI, or if +it is purely intended for usage through the API., defaults to None + :type hidden: Optional[bool], optional + :param fields: An ordered list of template fields which are part of the template. Each +field can be a regular text field, date field, number field, as well as a +single or multi-select list., defaults to None + :type fields: Optional[List[MetadataTemplateFieldsField]], optional + :param copy_instance_on_item_copy: Whether or not to include the metadata when a file or folder is copied., defaults to None + :type copy_instance_on_item_copy: Optional[bool], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.scope = scope + self.template_key = template_key + self.display_name = display_name + self.hidden = hidden + self.fields = fields + self.copy_instance_on_item_copy = copy_instance_on_item_copy \ No newline at end of file diff --git a/box_sdk_gen/schemas/metadata_templates.py b/box_sdk_gen/schemas/metadata_templates.py new file mode 100644 index 000000000..909d36c8b --- /dev/null +++ b/box_sdk_gen/schemas/metadata_templates.py @@ -0,0 +1,29 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.metadata_template import MetadataTemplate + +from box_sdk_gen.box.errors import BoxSDKError + +class MetadataTemplates(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, prev_marker: Optional[str] = None, entries: Optional[List[MetadataTemplate]] = 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 + :param entries: A list of metadata templates, defaults to None + :type entries: Optional[List[MetadataTemplate]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.prev_marker = prev_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/metadatas.py b/box_sdk_gen/schemas/metadatas.py new file mode 100644 index 000000000..4c61fbabf --- /dev/null +++ b/box_sdk_gen/schemas/metadatas.py @@ -0,0 +1,21 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.metadata import Metadata + +from box_sdk_gen.box.errors import BoxSDKError + +class Metadatas(BaseObject): + def __init__(self, *, entries: Optional[List[Metadata]] = None, limit: Optional[int] = None, **kwargs): + """ + :param entries: A list of metadata instances, as applied to this file or folder., defaults to None + :type entries: Optional[List[Metadata]], optional + :param limit: The limit that was used for this page of results., defaults to None + :type limit: Optional[int], optional + """ + super().__init__(**kwargs) + self.entries = entries + self.limit = limit \ No newline at end of file diff --git a/box_sdk_gen/schemas/o_auth_2_error.py b/box_sdk_gen/schemas/o_auth_2_error.py new file mode 100644 index 000000000..68bd61ad1 --- /dev/null +++ b/box_sdk_gen/schemas/o_auth_2_error.py @@ -0,0 +1,17 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class OAuth2Error(BaseObject): + def __init__(self, *, error: Optional[str] = None, error_description: Optional[str] = None, **kwargs): + """ + :param error: The type of the error returned., defaults to None + :type error: Optional[str], optional + :param error_description: The type of the error returned., defaults to None + :type error_description: Optional[str], optional + """ + super().__init__(**kwargs) + self.error = error + self.error_description = error_description \ No newline at end of file diff --git a/box_sdk_gen/schemas/outcome.py b/box_sdk_gen/schemas/outcome.py new file mode 100644 index 000000000..78a7b65cd --- /dev/null +++ b/box_sdk_gen/schemas/outcome.py @@ -0,0 +1,25 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.collaborator_variable import CollaboratorVariable + +from box_sdk_gen.schemas.completion_rule_variable import CompletionRuleVariable + +from box_sdk_gen.schemas.role_variable import RoleVariable + +from box_sdk_gen.box.errors import BoxSDKError + +class Outcome(BaseObject): + def __init__(self, id: str, *, collaborators: Optional[CollaboratorVariable] = None, completion_rule: Optional[CompletionRuleVariable] = None, file_collaborator_role: Optional[RoleVariable] = None, task_collaborators: Optional[CollaboratorVariable] = None, role: Optional[RoleVariable] = None, **kwargs): + """ + :param id: ID of a specific outcome + :type id: str + """ + super().__init__(**kwargs) + self.id = id + self.collaborators = collaborators + self.completion_rule = completion_rule + self.file_collaborator_role = file_collaborator_role + self.task_collaborators = task_collaborators + self.role = role \ No newline at end of file diff --git a/box_sdk_gen/schemas/post_o_auth_2_revoke.py b/box_sdk_gen/schemas/post_o_auth_2_revoke.py new file mode 100644 index 000000000..4fb21fce0 --- /dev/null +++ b/box_sdk_gen/schemas/post_o_auth_2_revoke.py @@ -0,0 +1,22 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class PostOAuth2Revoke(BaseObject): + def __init__(self, *, client_id: Optional[str] = None, client_secret: Optional[str] = None, token: Optional[str] = None, **kwargs): + """ + :param client_id: The Client ID of the application requesting to revoke the +access token., defaults to None + :type client_id: Optional[str], optional + :param client_secret: The client secret of the application requesting to revoke +an access token., defaults to None + :type client_secret: Optional[str], optional + :param token: The access token to revoke., defaults to None + :type token: Optional[str], optional + """ + super().__init__(**kwargs) + self.client_id = client_id + self.client_secret = client_secret + self.token = token \ No newline at end of file diff --git a/box_sdk_gen/schemas/post_o_auth_2_token.py b/box_sdk_gen/schemas/post_o_auth_2_token.py new file mode 100644 index 000000000..a2b9e7a6f --- /dev/null +++ b/box_sdk_gen/schemas/post_o_auth_2_token.py @@ -0,0 +1,114 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class PostOAuth2TokenGrantTypeField(str, Enum): + AUTHORIZATION_CODE = 'authorization_code' + REFRESH_TOKEN = 'refresh_token' + CLIENT_CREDENTIALS = 'client_credentials' + URN_IETF_PARAMS_OAUTH_GRANT_TYPE_JWT_BEARER = 'urn:ietf:params:oauth:grant-type:jwt-bearer' + URN_IETF_PARAMS_OAUTH_GRANT_TYPE_TOKEN_EXCHANGE = 'urn:ietf:params:oauth:grant-type:token-exchange' + +class PostOAuth2TokenSubjectTokenTypeField(str, Enum): + URN_IETF_PARAMS_OAUTH_TOKEN_TYPE_ACCESS_TOKEN = 'urn:ietf:params:oauth:token-type:access_token' + +class PostOAuth2TokenActorTokenTypeField(str, Enum): + URN_IETF_PARAMS_OAUTH_TOKEN_TYPE_ID_TOKEN = 'urn:ietf:params:oauth:token-type:id_token' + +class PostOAuth2TokenBoxSubjectTypeField(str, Enum): + ENTERPRISE = 'enterprise' + USER = 'user' + +class PostOAuth2Token(BaseObject): + def __init__(self, grant_type: PostOAuth2TokenGrantTypeField, *, client_id: Optional[str] = None, client_secret: Optional[str] = None, code: Optional[str] = None, refresh_token: Optional[str] = None, assertion: Optional[str] = None, subject_token: Optional[str] = None, subject_token_type: Optional[PostOAuth2TokenSubjectTokenTypeField] = None, actor_token: Optional[str] = None, actor_token_type: Optional[PostOAuth2TokenActorTokenTypeField] = None, scope: Optional[str] = None, resource: Optional[str] = None, box_subject_type: Optional[PostOAuth2TokenBoxSubjectTypeField] = None, box_subject_id: Optional[str] = None, box_shared_link: Optional[str] = None, **kwargs): + """ + :param grant_type: The type of request being made, either using a client-side obtained +authorization code, a refresh token, a JWT assertion, client credentials +grant or another access token for the purpose of downscoping a token. + :type grant_type: PostOAuth2TokenGrantTypeField + :param client_id: The Client ID of the application requesting an access token. + +Used in combination with `authorization_code`, `client_credentials`, or +`urn:ietf:params:oauth:grant-type:jwt-bearer` as the `grant_type`., defaults to None + :type client_id: Optional[str], optional + :param client_secret: The client secret of the application requesting an access token. + +Used in combination with `authorization_code`, `client_credentials`, or +`urn:ietf:params:oauth:grant-type:jwt-bearer` as the `grant_type`., defaults to None + :type client_secret: Optional[str], optional + :param code: The client-side authorization code passed to your application by +Box in the browser redirect after the user has successfully +granted your application permission to make API calls on their +behalf. + +Used in combination with `authorization_code` as the `grant_type`., defaults to None + :type code: Optional[str], optional + :param refresh_token: A refresh token used to get a new access token with. + +Used in combination with `refresh_token` as the `grant_type`., defaults to None + :type refresh_token: Optional[str], optional + :param assertion: A JWT assertion for which to request a new access token. + +Used in combination with `urn:ietf:params:oauth:grant-type:jwt-bearer` +as the `grant_type`., defaults to None + :type assertion: Optional[str], optional + :param subject_token: The token to exchange for a downscoped token. This can be a regular +access token, a JWT assertion, or an app token. + +Used in combination with `urn:ietf:params:oauth:grant-type:token-exchange` +as the `grant_type`., defaults to None + :type subject_token: Optional[str], optional + :param subject_token_type: The type of `subject_token` passed in. + +Used in combination with `urn:ietf:params:oauth:grant-type:token-exchange` +as the `grant_type`., defaults to None + :type subject_token_type: Optional[PostOAuth2TokenSubjectTokenTypeField], optional + :param actor_token: The token used to create an annotator token. +This is a JWT assertion. + +Used in combination with `urn:ietf:params:oauth:grant-type:token-exchange` +as the `grant_type`., defaults to None + :type actor_token: Optional[str], optional + :param actor_token_type: The type of `actor_token` passed in. + +Used in combination with `urn:ietf:params:oauth:grant-type:token-exchange` +as the `grant_type`., defaults to None + :type actor_token_type: Optional[PostOAuth2TokenActorTokenTypeField], optional + :param scope: The space-delimited list of scopes that you want apply to the +new access token. + +The `subject_token` will need to have all of these scopes or +the call will error with **401 Unauthorized**., defaults to None + :type scope: Optional[str], optional + :param resource: Full URL for the file that the token should be generated for., defaults to None + :type resource: Optional[str], optional + :param box_subject_type: Used in combination with `client_credentials` as the `grant_type`., defaults to None + :type box_subject_type: Optional[PostOAuth2TokenBoxSubjectTypeField], optional + :param box_subject_id: Used in combination with `client_credentials` as the `grant_type`. +Value is determined by `box_subject_type`. If `user` use user ID and if +`enterprise` use enterprise ID., defaults to None + :type box_subject_id: Optional[str], optional + :param box_shared_link: Full URL of the shared link on the file or folder +that the token should be generated for., defaults to None + :type box_shared_link: Optional[str], optional + """ + super().__init__(**kwargs) + self.grant_type = grant_type + self.client_id = client_id + self.client_secret = client_secret + self.code = code + self.refresh_token = refresh_token + self.assertion = assertion + self.subject_token = subject_token + self.subject_token_type = subject_token_type + self.actor_token = actor_token + self.actor_token_type = actor_token_type + self.scope = scope + self.resource = resource + self.box_subject_type = box_subject_type + self.box_subject_id = box_subject_id + self.box_shared_link = box_shared_link \ No newline at end of file diff --git a/box_sdk_gen/schemas/post_o_auth_2_token_refresh_access_token.py b/box_sdk_gen/schemas/post_o_auth_2_token_refresh_access_token.py new file mode 100644 index 000000000..8526a43e6 --- /dev/null +++ b/box_sdk_gen/schemas/post_o_auth_2_token_refresh_access_token.py @@ -0,0 +1,26 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class PostOAuth2TokenRefreshAccessTokenGrantTypeField(str, Enum): + REFRESH_TOKEN = 'refresh_token' + +class PostOAuth2TokenRefreshAccessToken(BaseObject): + def __init__(self, client_id: str, client_secret: str, refresh_token: str, *, grant_type: PostOAuth2TokenRefreshAccessTokenGrantTypeField = PostOAuth2TokenRefreshAccessTokenGrantTypeField.REFRESH_TOKEN, **kwargs): + """ + :param client_id: The client ID of the application requesting to refresh the token. + :type client_id: str + :param client_secret: The client secret of the application requesting to refresh the token. + :type client_secret: str + :param refresh_token: The refresh token to refresh. + :type refresh_token: str + :param grant_type: The type of request being made, in this case a refresh request., defaults to PostOAuth2TokenRefreshAccessTokenGrantTypeField.REFRESH_TOKEN + :type grant_type: PostOAuth2TokenRefreshAccessTokenGrantTypeField, optional + """ + super().__init__(**kwargs) + self.client_id = client_id + self.client_secret = client_secret + self.refresh_token = refresh_token + self.grant_type = grant_type \ No newline at end of file diff --git a/box_sdk_gen/schemas/realtime_server.py b/box_sdk_gen/schemas/realtime_server.py new file mode 100644 index 000000000..7b8eccc78 --- /dev/null +++ b/box_sdk_gen/schemas/realtime_server.py @@ -0,0 +1,33 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class RealtimeServer(BaseObject): + def __init__(self, *, type: Optional[str] = None, url: Optional[str] = None, ttl: Optional[str] = None, max_retries: Optional[str] = None, retry_timeout: Optional[int] = None, **kwargs): + """ + :param type: `realtime_server`, defaults to None + :type type: Optional[str], optional + :param url: The URL for the server., defaults to None + :type url: Optional[str], optional + :param ttl: The time in minutes for which this server is available, defaults to None + :type ttl: Optional[str], optional + :param max_retries: The maximum number of retries this server will +allow before a new long poll should be started by +getting a [new list of server](#options-events)., defaults to None + :type max_retries: Optional[str], optional + :param retry_timeout: The maximum number of seconds without a response +after which you should retry the long poll connection. + +This helps to overcome network issues where the long +poll looks to be working but no packages are coming +through., defaults to None + :type retry_timeout: Optional[int], optional + """ + super().__init__(**kwargs) + self.type = type + self.url = url + self.ttl = ttl + self.max_retries = max_retries + self.retry_timeout = retry_timeout \ No newline at end of file diff --git a/box_sdk_gen/schemas/realtime_servers.py b/box_sdk_gen/schemas/realtime_servers.py new file mode 100644 index 000000000..525877ed5 --- /dev/null +++ b/box_sdk_gen/schemas/realtime_servers.py @@ -0,0 +1,21 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.realtime_server import RealtimeServer + +from box_sdk_gen.box.errors import BoxSDKError + +class RealtimeServers(BaseObject): + def __init__(self, *, chunk_size: Optional[int] = None, entries: Optional[List[RealtimeServer]] = None, **kwargs): + """ + :param chunk_size: The number of items in this response., defaults to None + :type chunk_size: Optional[int], optional + :param entries: A list of real-time servers, defaults to None + :type entries: Optional[List[RealtimeServer]], optional + """ + super().__init__(**kwargs) + self.chunk_size = chunk_size + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/recent_item.py b/box_sdk_gen/schemas/recent_item.py new file mode 100644 index 000000000..ce580ba5b --- /dev/null +++ b/box_sdk_gen/schemas/recent_item.py @@ -0,0 +1,45 @@ +from enum import Enum + +from typing import Optional + +from typing import Union + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.schemas.web_link import WebLink + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class RecentItemInteractionTypeField(str, Enum): + ITEM_PREVIEW = 'item_preview' + ITEM_UPLOAD = 'item_upload' + ITEM_COMMENT = 'item_comment' + ITEM_OPEN = 'item_open' + ITEM_MODIFY = 'item_modify' + +class RecentItem(BaseObject): + def __init__(self, *, type: Optional[str] = None, item: Optional[Union[FileFull, FolderFull, WebLink]] = None, interaction_type: Optional[RecentItemInteractionTypeField] = None, interacted_at: Optional[DateTime] = None, interaction_shared_link: Optional[str] = None, **kwargs): + """ + :param type: `recent_item`, defaults to None + :type type: Optional[str], optional + :param interaction_type: The most recent type of access the user performed on +the item., defaults to None + :type interaction_type: Optional[RecentItemInteractionTypeField], optional + :param interacted_at: The time of the most recent interaction., defaults to None + :type interacted_at: Optional[DateTime], optional + :param interaction_shared_link: If the item was accessed through a shared link it will appear here, +otherwise this will be null., defaults to None + :type interaction_shared_link: Optional[str], optional + """ + super().__init__(**kwargs) + self.type = type + self.item = item + self.interaction_type = interaction_type + self.interacted_at = interacted_at + self.interaction_shared_link = interaction_shared_link \ No newline at end of file diff --git a/box_sdk_gen/schemas/recent_items.py b/box_sdk_gen/schemas/recent_items.py new file mode 100644 index 000000000..0ab6f0630 --- /dev/null +++ b/box_sdk_gen/schemas/recent_items.py @@ -0,0 +1,29 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.recent_item import RecentItem + +from box_sdk_gen.box.errors import BoxSDKError + +class RecentItems(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, prev_marker: Optional[str] = None, entries: Optional[List[RecentItem]] = 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 + :param entries: A list of recent items, defaults to None + :type entries: Optional[List[RecentItem]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.prev_marker = prev_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/retention_policies.py b/box_sdk_gen/schemas/retention_policies.py new file mode 100644 index 000000000..3c31c295d --- /dev/null +++ b/box_sdk_gen/schemas/retention_policies.py @@ -0,0 +1,26 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.retention_policy import RetentionPolicy + +from box_sdk_gen.box.errors import BoxSDKError + +class RetentionPolicies(BaseObject): + def __init__(self, *, entries: Optional[List[RetentionPolicy]] = None, limit: Optional[int] = None, next_marker: Optional[str] = None, **kwargs): + """ + :param entries: A list in which each entry represents a retention policy object., defaults to None + :type entries: Optional[List[RetentionPolicy]], optional + :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 + """ + super().__init__(**kwargs) + self.entries = entries + self.limit = limit + self.next_marker = next_marker \ No newline at end of file diff --git a/box_sdk_gen/schemas/retention_policy.py b/box_sdk_gen/schemas/retention_policy.py new file mode 100644 index 000000000..26857cc67 --- /dev/null +++ b/box_sdk_gen/schemas/retention_policy.py @@ -0,0 +1,132 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from box_sdk_gen.schemas.retention_policy_base import RetentionPolicyBaseTypeField + +from box_sdk_gen.schemas.retention_policy_base import RetentionPolicyBase + +from box_sdk_gen.schemas.retention_policy_mini import RetentionPolicyMiniDispositionActionField + +from box_sdk_gen.schemas.retention_policy_mini import RetentionPolicyMini + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class RetentionPolicyPolicyTypeField(str, Enum): + FINITE = 'finite' + INDEFINITE = 'indefinite' + +class RetentionPolicyRetentionTypeField(str, Enum): + MODIFIABLE = 'modifiable' + NON_MODIFIABLE = 'non_modifiable' + +class RetentionPolicyStatusField(str, Enum): + ACTIVE = 'active' + RETIRED = 'retired' + +class RetentionPolicyAssignmentCountsField(BaseObject): + def __init__(self, *, enterprise: Optional[int] = None, folder: Optional[int] = None, metadata_template: Optional[int] = None, **kwargs): + """ + :param enterprise: The number of enterprise assignments this policy has. The maximum value is 1., defaults to None + :type enterprise: Optional[int], optional + :param folder: The number of folder assignments this policy has., defaults to None + :type folder: Optional[int], optional + :param metadata_template: The number of metadata template assignments this policy has., defaults to None + :type metadata_template: Optional[int], optional + """ + super().__init__(**kwargs) + self.enterprise = enterprise + self.folder = folder + self.metadata_template = metadata_template + +class RetentionPolicy(RetentionPolicyMini): + def __init__(self, id: str, *, description: Optional[str] = None, policy_type: Optional[RetentionPolicyPolicyTypeField] = None, retention_type: Optional[RetentionPolicyRetentionTypeField] = None, status: Optional[RetentionPolicyStatusField] = None, created_by: Optional[UserMini] = None, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, can_owner_extend_retention: Optional[bool] = None, are_owners_notified: Optional[bool] = None, custom_notification_recipients: Optional[List[UserMini]] = None, assignment_counts: Optional[RetentionPolicyAssignmentCountsField] = None, policy_name: Optional[str] = None, retention_length: Optional[str] = None, disposition_action: Optional[RetentionPolicyMiniDispositionActionField] = None, type: RetentionPolicyBaseTypeField = RetentionPolicyBaseTypeField.RETENTION_POLICY, **kwargs): + """ + :param id: The unique identifier that represents a retention policy. + :type id: str + :param description: The additional text description of the retention policy., defaults to None + :type description: Optional[str], optional + :param policy_type: The type of the retention policy. A retention +policy type can either be `finite`, where a +specific amount of time to retain the content is known +upfront, or `indefinite`, where the amount of time +to retain the content is still unknown., defaults to None + :type policy_type: Optional[RetentionPolicyPolicyTypeField], optional + :param retention_type: Specifies the retention type: + +* `modifiable`: You can modify the retention policy. For example, + you can add or remove folders, shorten or lengthen + the policy duration, or delete the assignment. + Use this type if your retention policy + is not related to any regulatory purposes. + +* `non-modifiable`: You can modify the retention policy + only in a limited way: add a folder, lengthen the duration, + retire the policy, change the disposition action + or notification settings. You cannot perform other actions, + such as deleting the assignment or shortening the + policy duration. Use this type to ensure + compliance with regulatory retention policies., defaults to None + :type retention_type: Optional[RetentionPolicyRetentionTypeField], optional + :param status: The status of the retention policy. The status of +a policy will be `active`, unless explicitly retired by an +administrator, in which case the status will be `retired`. +Once a policy has been retired, it cannot become +active again., defaults to None + :type status: Optional[RetentionPolicyStatusField], optional + :param created_at: When the retention policy object was created., defaults to None + :type created_at: Optional[DateTime], optional + :param modified_at: When the retention policy object was last modified., defaults to None + :type modified_at: Optional[DateTime], optional + :param can_owner_extend_retention: Determines if the owner of items under the policy +can extend the retention when the original +retention duration is about to end., defaults to None + :type can_owner_extend_retention: Optional[bool], optional + :param are_owners_notified: Determines if owners and co-owners of items +under the policy are notified when +the retention duration is about to end., defaults to None + :type are_owners_notified: Optional[bool], optional + :param custom_notification_recipients: A list of users notified when the retention policy duration is about to end., defaults to None + :type custom_notification_recipients: Optional[List[UserMini]], optional + :param assignment_counts: Counts the retention policy assignments for each item type., defaults to None + :type assignment_counts: Optional[RetentionPolicyAssignmentCountsField], optional + :param policy_name: The name given to the retention policy., defaults to None + :type policy_name: Optional[str], optional + :param retention_length: The length of the retention policy. This value +specifies the duration in days that the retention +policy will be active for after being assigned to +content. If the policy has a `policy_type` of +`indefinite`, the `retention_length` will also be +`indefinite`., defaults to None + :type retention_length: Optional[str], optional + :param disposition_action: The disposition action of the retention policy. +This action can be `permanently_delete`, which +will cause the content retained by the policy +to be permanently deleted, or `remove_retention`, +which will lift the retention policy from the content, +allowing it to be deleted by users, +once the retention policy has expired., defaults to None + :type disposition_action: Optional[RetentionPolicyMiniDispositionActionField], optional + :param type: `retention_policy`, defaults to RetentionPolicyBaseTypeField.RETENTION_POLICY + :type type: RetentionPolicyBaseTypeField, optional + """ + super().__init__(id=id, policy_name=policy_name, retention_length=retention_length, disposition_action=disposition_action, type=type, **kwargs) + self.description = description + self.policy_type = policy_type + self.retention_type = retention_type + self.status = status + self.created_by = created_by + self.created_at = created_at + self.modified_at = modified_at + self.can_owner_extend_retention = can_owner_extend_retention + self.are_owners_notified = are_owners_notified + self.custom_notification_recipients = custom_notification_recipients + self.assignment_counts = assignment_counts \ No newline at end of file diff --git a/box_sdk_gen/schemas/retention_policy_assignment.py b/box_sdk_gen/schemas/retention_policy_assignment.py new file mode 100644 index 000000000..54e9c9664 --- /dev/null +++ b/box_sdk_gen/schemas/retention_policy_assignment.py @@ -0,0 +1,84 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from box_sdk_gen.schemas.retention_policy_mini import RetentionPolicyMini + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class RetentionPolicyAssignmentTypeField(str, Enum): + RETENTION_POLICY_ASSIGNMENT = 'retention_policy_assignment' + +class RetentionPolicyAssignmentAssignedToTypeField(str, Enum): + FOLDER = 'folder' + ENTERPRISE = 'enterprise' + METADATA_TEMPLATE = 'metadata_template' + +class RetentionPolicyAssignmentAssignedToField(BaseObject): + _discriminator = 'type', {'folder', 'enterprise', 'metadata_template'} + def __init__(self, *, id: Optional[str] = None, type: Optional[RetentionPolicyAssignmentAssignedToTypeField] = None, **kwargs): + """ + :param id: The ID of the folder, enterprise, or metadata template +the policy is assigned to. +Set to null or omit when type is set to enterprise., defaults to None + :type id: Optional[str], optional + :param type: The type of resource the policy is assigned to., defaults to None + :type type: Optional[RetentionPolicyAssignmentAssignedToTypeField], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class RetentionPolicyAssignmentFilterFieldsField(BaseObject): + def __init__(self, *, field: Optional[str] = None, value: Optional[str] = None, **kwargs): + """ + :param field: The metadata attribute key id., defaults to None + :type field: Optional[str], optional + :param value: The metadata attribute field id. For value, only +enum and multiselect types are supported., defaults to None + :type value: Optional[str], optional + """ + super().__init__(**kwargs) + self.field = field + self.value = value + +class RetentionPolicyAssignment(BaseObject): + _discriminator = 'type', {'retention_policy_assignment'} + def __init__(self, id: str, *, type: RetentionPolicyAssignmentTypeField = RetentionPolicyAssignmentTypeField.RETENTION_POLICY_ASSIGNMENT, retention_policy: Optional[RetentionPolicyMini] = None, assigned_to: Optional[RetentionPolicyAssignmentAssignedToField] = None, filter_fields: Optional[List[RetentionPolicyAssignmentFilterFieldsField]] = None, assigned_by: Optional[UserMini] = None, assigned_at: Optional[DateTime] = None, start_date_field: Optional[str] = None, **kwargs): + """ + :param id: The unique identifier for a retention policy assignment. + :type id: str + :param type: `retention_policy_assignment`, defaults to RetentionPolicyAssignmentTypeField.RETENTION_POLICY_ASSIGNMENT + :type type: RetentionPolicyAssignmentTypeField, optional + :param assigned_to: The `type` and `id` of the content that is under +retention. The `type` can either be `folder` +`enterprise`, or `metadata_template`., defaults to None + :type assigned_to: Optional[RetentionPolicyAssignmentAssignedToField], optional + :param filter_fields: An array of field objects. Values are only returned if the `assigned_to` +type is `metadata_template`. Otherwise, the array is blank., defaults to None + :type filter_fields: Optional[List[RetentionPolicyAssignmentFilterFieldsField]], optional + :param assigned_at: When the retention policy assignment object was +created., defaults to None + :type assigned_at: Optional[DateTime], optional + :param start_date_field: The date the retention policy assignment begins. +If the `assigned_to` type is `metadata_template`, +this field can be a date field's metadata attribute key id., defaults to None + :type start_date_field: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.retention_policy = retention_policy + self.assigned_to = assigned_to + self.filter_fields = filter_fields + self.assigned_by = assigned_by + self.assigned_at = assigned_at + self.start_date_field = start_date_field \ No newline at end of file diff --git a/box_sdk_gen/schemas/retention_policy_assignment_base.py b/box_sdk_gen/schemas/retention_policy_assignment_base.py new file mode 100644 index 000000000..c10c7fec7 --- /dev/null +++ b/box_sdk_gen/schemas/retention_policy_assignment_base.py @@ -0,0 +1,21 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class RetentionPolicyAssignmentBaseTypeField(str, Enum): + RETENTION_POLICY_ASSIGNMENT = 'retention_policy_assignment' + +class RetentionPolicyAssignmentBase(BaseObject): + _discriminator = 'type', {'retention_policy_assignment'} + def __init__(self, id: str, *, type: RetentionPolicyAssignmentBaseTypeField = RetentionPolicyAssignmentBaseTypeField.RETENTION_POLICY_ASSIGNMENT, **kwargs): + """ + :param id: The unique identifier that represents a file version. + :type id: str + :param type: `retention_policy_assignment`, defaults to RetentionPolicyAssignmentBaseTypeField.RETENTION_POLICY_ASSIGNMENT + :type type: RetentionPolicyAssignmentBaseTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type \ No newline at end of file diff --git a/box_sdk_gen/schemas/retention_policy_assignments.py b/box_sdk_gen/schemas/retention_policy_assignments.py new file mode 100644 index 000000000..45706dd9e --- /dev/null +++ b/box_sdk_gen/schemas/retention_policy_assignments.py @@ -0,0 +1,26 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.retention_policy_assignment import RetentionPolicyAssignment + +from box_sdk_gen.box.errors import BoxSDKError + +class RetentionPolicyAssignments(BaseObject): + def __init__(self, *, entries: Optional[List[RetentionPolicyAssignment]] = None, limit: Optional[int] = None, next_marker: Optional[str] = None, **kwargs): + """ + :param entries: A list of retention policy assignments, defaults to None + :type entries: Optional[List[RetentionPolicyAssignment]], optional + :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 + """ + super().__init__(**kwargs) + self.entries = entries + self.limit = limit + self.next_marker = next_marker \ No newline at end of file diff --git a/box_sdk_gen/schemas/retention_policy_base.py b/box_sdk_gen/schemas/retention_policy_base.py new file mode 100644 index 000000000..6135ee3f9 --- /dev/null +++ b/box_sdk_gen/schemas/retention_policy_base.py @@ -0,0 +1,21 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class RetentionPolicyBaseTypeField(str, Enum): + RETENTION_POLICY = 'retention_policy' + +class RetentionPolicyBase(BaseObject): + _discriminator = 'type', {'retention_policy'} + def __init__(self, id: str, *, type: RetentionPolicyBaseTypeField = RetentionPolicyBaseTypeField.RETENTION_POLICY, **kwargs): + """ + :param id: The unique identifier that represents a retention policy. + :type id: str + :param type: `retention_policy`, defaults to RetentionPolicyBaseTypeField.RETENTION_POLICY + :type type: RetentionPolicyBaseTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type \ No newline at end of file diff --git a/box_sdk_gen/schemas/retention_policy_mini.py b/box_sdk_gen/schemas/retention_policy_mini.py new file mode 100644 index 000000000..0c05a4829 --- /dev/null +++ b/box_sdk_gen/schemas/retention_policy_mini.py @@ -0,0 +1,43 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.schemas.retention_policy_base import RetentionPolicyBaseTypeField + +from box_sdk_gen.schemas.retention_policy_base import RetentionPolicyBase + +from box_sdk_gen.box.errors import BoxSDKError + +class RetentionPolicyMiniDispositionActionField(str, Enum): + PERMANENTLY_DELETE = 'permanently_delete' + REMOVE_RETENTION = 'remove_retention' + +class RetentionPolicyMini(RetentionPolicyBase): + def __init__(self, id: str, *, policy_name: Optional[str] = None, retention_length: Optional[str] = None, disposition_action: Optional[RetentionPolicyMiniDispositionActionField] = None, type: RetentionPolicyBaseTypeField = RetentionPolicyBaseTypeField.RETENTION_POLICY, **kwargs): + """ + :param id: The unique identifier that represents a retention policy. + :type id: str + :param policy_name: The name given to the retention policy., defaults to None + :type policy_name: Optional[str], optional + :param retention_length: The length of the retention policy. This value +specifies the duration in days that the retention +policy will be active for after being assigned to +content. If the policy has a `policy_type` of +`indefinite`, the `retention_length` will also be +`indefinite`., defaults to None + :type retention_length: Optional[str], optional + :param disposition_action: The disposition action of the retention policy. +This action can be `permanently_delete`, which +will cause the content retained by the policy +to be permanently deleted, or `remove_retention`, +which will lift the retention policy from the content, +allowing it to be deleted by users, +once the retention policy has expired., defaults to None + :type disposition_action: Optional[RetentionPolicyMiniDispositionActionField], optional + :param type: `retention_policy`, defaults to RetentionPolicyBaseTypeField.RETENTION_POLICY + :type type: RetentionPolicyBaseTypeField, optional + """ + super().__init__(id=id, type=type, **kwargs) + self.policy_name = policy_name + self.retention_length = retention_length + self.disposition_action = disposition_action \ No newline at end of file diff --git a/box_sdk_gen/schemas/role_variable.py b/box_sdk_gen/schemas/role_variable.py new file mode 100644 index 000000000..638dd38af --- /dev/null +++ b/box_sdk_gen/schemas/role_variable.py @@ -0,0 +1,37 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class RoleVariableTypeField(str, Enum): + VARIABLE = 'variable' + +class RoleVariableVariableTypeField(str, Enum): + COLLABORATOR_ROLE = 'collaborator_role' + +class RoleVariableVariableValueField(str, Enum): + EDITOR = 'editor' + VIEWER = 'viewer' + PREVIEWER = 'previewer' + UPLOADER = 'uploader' + PREVIEWER_UPLOADER = 'previewer uploader' + VIEWER_UPLOADER = 'viewer uploader' + CO_OWNER = 'co-owner' + +class RoleVariable(BaseObject): + _discriminator = 'type', {'variable'} + def __init__(self, variable_value: RoleVariableVariableValueField, *, type: RoleVariableTypeField = RoleVariableTypeField.VARIABLE, variable_type: RoleVariableVariableTypeField = RoleVariableVariableTypeField.COLLABORATOR_ROLE, **kwargs): + """ + :param type: Role object type. +, defaults to RoleVariableTypeField.VARIABLE + :type type: RoleVariableTypeField, optional + :param variable_type: The variable type used +by the object. +, defaults to RoleVariableVariableTypeField.COLLABORATOR_ROLE + :type variable_type: RoleVariableVariableTypeField, optional + """ + super().__init__(**kwargs) + self.variable_value = variable_value + self.type = type + self.variable_type = variable_type \ No newline at end of file diff --git a/box_sdk_gen/schemas/search_result_with_shared_link.py b/box_sdk_gen/schemas/search_result_with_shared_link.py new file mode 100644 index 000000000..42c7e6d56 --- /dev/null +++ b/box_sdk_gen/schemas/search_result_with_shared_link.py @@ -0,0 +1,29 @@ +from typing import Optional + +from typing import Union + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.schemas.web_link import WebLink + +from box_sdk_gen.box.errors import BoxSDKError + +class SearchResultWithSharedLink(BaseObject): + def __init__(self, *, accessible_via_shared_link: Optional[str] = None, item: Optional[Union[FileFull, FolderFull, WebLink]] = None, type: Optional[str] = None, **kwargs): + """ + :param accessible_via_shared_link: The optional shared link through which the user has access to this +item. This value is only returned for items for which the user has +recently accessed the file through a shared link. For all other +items this value will return `null`., defaults to None + :type accessible_via_shared_link: Optional[str], optional + :param type: The result type. The value is always `search_result`., defaults to None + :type type: Optional[str], optional + """ + super().__init__(**kwargs) + self.accessible_via_shared_link = accessible_via_shared_link + self.item = item + self.type = type \ No newline at end of file diff --git a/box_sdk_gen/schemas/search_results.py b/box_sdk_gen/schemas/search_results.py new file mode 100644 index 000000000..c0449ebc3 --- /dev/null +++ b/box_sdk_gen/schemas/search_results.py @@ -0,0 +1,47 @@ +from enum import Enum + +from typing import Optional + +from typing import List + +from typing import Union + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.schemas.web_link import WebLink + +from box_sdk_gen.box.errors import BoxSDKError + +class SearchResultsTypeField(str, Enum): + SEARCH_RESULTS_ITEMS = 'search_results_items' + +class SearchResults(BaseObject): + _discriminator = 'type', {'search_results_items'} + def __init__(self, *, total_count: Optional[int] = None, limit: Optional[int] = None, offset: Optional[int] = None, type: SearchResultsTypeField = SearchResultsTypeField.SEARCH_RESULTS_ITEMS, entries: Optional[List[Union[FileFull, FolderFull, WebLink]]] = None, **kwargs): + """ + :param total_count: One greater than the offset of the last entry in the search results. +The total number of entries in the collection may be less than +`total_count`., defaults to None + :type total_count: Optional[int], optional + :param limit: The limit that was used for this search. This will be the same as the +`limit` query parameter unless that value exceeded the maximum value +allowed., defaults to None + :type limit: Optional[int], optional + :param offset: The 0-based offset of the first entry in this set. This will be the same +as the `offset` query parameter used., defaults to None + :type offset: Optional[int], optional + :param type: Specifies the response as search result items without shared links, defaults to SearchResultsTypeField.SEARCH_RESULTS_ITEMS + :type type: SearchResultsTypeField, optional + :param entries: The search results for the query provided., defaults to None + :type entries: Optional[List[Union[FileFull, FolderFull, WebLink]]], optional + """ + super().__init__(**kwargs) + self.total_count = total_count + self.limit = limit + self.offset = offset + self.type = type + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/search_results_with_shared_links.py b/box_sdk_gen/schemas/search_results_with_shared_links.py new file mode 100644 index 000000000..a95e6ce3f --- /dev/null +++ b/box_sdk_gen/schemas/search_results_with_shared_links.py @@ -0,0 +1,43 @@ +from enum import Enum + +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.search_result_with_shared_link import SearchResultWithSharedLink + +from box_sdk_gen.box.errors import BoxSDKError + +class SearchResultsWithSharedLinksTypeField(str, Enum): + SEARCH_RESULTS_WITH_SHARED_LINKS = 'search_results_with_shared_links' + +class SearchResultsWithSharedLinks(BaseObject): + _discriminator = 'type', {'search_results_with_shared_links'} + def __init__(self, *, total_count: Optional[int] = None, limit: Optional[int] = None, offset: Optional[int] = None, type: SearchResultsWithSharedLinksTypeField = SearchResultsWithSharedLinksTypeField.SEARCH_RESULTS_WITH_SHARED_LINKS, entries: Optional[List[SearchResultWithSharedLink]] = None, **kwargs): + """ + :param total_count: One greater than the offset of the last entry in the search results. +The total number of entries in the collection may be less than +`total_count`., defaults to None + :type total_count: Optional[int], optional + :param limit: The limit that was used for this search. This will be the same as the +`limit` query parameter unless that value exceeded the maximum value +allowed., defaults to None + :type limit: Optional[int], optional + :param offset: The 0-based offset of the first entry in this set. This will be the same +as the `offset` query parameter used., defaults to None + :type offset: Optional[int], optional + :param type: Specifies the response as search result items with shared links, defaults to SearchResultsWithSharedLinksTypeField.SEARCH_RESULTS_WITH_SHARED_LINKS + :type type: SearchResultsWithSharedLinksTypeField, optional + :param entries: The search results for the query provided, including the +additional information about any shared links through +which the item has been shared with the user., defaults to None + :type entries: Optional[List[SearchResultWithSharedLink]], optional + """ + super().__init__(**kwargs) + self.total_count = total_count + self.limit = limit + self.offset = offset + self.type = type + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/session_termination_message.py b/box_sdk_gen/schemas/session_termination_message.py new file mode 100644 index 000000000..f5533ea66 --- /dev/null +++ b/box_sdk_gen/schemas/session_termination_message.py @@ -0,0 +1,14 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class SessionTerminationMessage(BaseObject): + def __init__(self, *, message: Optional[str] = None, **kwargs): + """ + :param message: The unique identifier for the termination job status, defaults to None + :type message: Optional[str], optional + """ + super().__init__(**kwargs) + self.message = message \ No newline at end of file diff --git a/box_sdk_gen/schemas/shield_information_barrier.py b/box_sdk_gen/schemas/shield_information_barrier.py new file mode 100644 index 000000000..0a6d4d5db --- /dev/null +++ b/box_sdk_gen/schemas/shield_information_barrier.py @@ -0,0 +1,59 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.enterprise_base import EnterpriseBase + +from box_sdk_gen.schemas.user_base import UserBase + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class ShieldInformationBarrierTypeField(str, Enum): + SHIELD_INFORMATION_BARRIER = 'shield_information_barrier' + +class ShieldInformationBarrierStatusField(str, Enum): + DRAFT = 'draft' + PENDING = 'pending' + DISABLED = 'disabled' + ENABLED = 'enabled' + INVALID = 'invalid' + +class ShieldInformationBarrier(BaseObject): + _discriminator = 'type', {'shield_information_barrier'} + def __init__(self, *, id: Optional[str] = None, type: Optional[ShieldInformationBarrierTypeField] = None, enterprise: Optional[EnterpriseBase] = None, status: Optional[ShieldInformationBarrierStatusField] = None, created_at: Optional[DateTime] = None, created_by: Optional[UserBase] = None, updated_at: Optional[DateTime] = None, updated_by: Optional[UserBase] = None, enabled_at: Optional[DateTime] = None, enabled_by: Optional[UserBase] = None, **kwargs): + """ + :param id: The unique identifier for the shield information barrier, defaults to None + :type id: Optional[str], optional + :param type: The type of the shield information barrier, defaults to None + :type type: Optional[ShieldInformationBarrierTypeField], optional + :param enterprise: The `type` and `id` of enterprise this barrier is under., defaults to None + :type enterprise: Optional[EnterpriseBase], optional + :param status: Status of the shield information barrier, defaults to None + :type status: Optional[ShieldInformationBarrierStatusField], optional + :param created_at: ISO date time string when this +shield information barrier object was created., defaults to None + :type created_at: Optional[DateTime], optional + :param created_by: The user who created this shield information barrier., defaults to None + :type created_by: Optional[UserBase], optional + :param updated_at: ISO date time string when this shield information barrier was updated., defaults to None + :type updated_at: Optional[DateTime], optional + :param updated_by: The user that updated this shield information barrier., defaults to None + :type updated_by: Optional[UserBase], optional + :param enabled_at: ISO date time string when this shield information barrier was enabled., defaults to None + :type enabled_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.enterprise = enterprise + self.status = status + self.created_at = created_at + self.created_by = created_by + self.updated_at = updated_at + self.updated_by = updated_by + self.enabled_at = enabled_at + self.enabled_by = enabled_by \ No newline at end of file diff --git a/box_sdk_gen/schemas/shield_information_barrier_base.py b/box_sdk_gen/schemas/shield_information_barrier_base.py new file mode 100644 index 000000000..64bdc7d2a --- /dev/null +++ b/box_sdk_gen/schemas/shield_information_barrier_base.py @@ -0,0 +1,23 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class ShieldInformationBarrierBaseTypeField(str, Enum): + SHIELD_INFORMATION_BARRIER = 'shield_information_barrier' + +class ShieldInformationBarrierBase(BaseObject): + _discriminator = 'type', {'shield_information_barrier'} + def __init__(self, *, id: Optional[str] = None, type: Optional[ShieldInformationBarrierBaseTypeField] = None, **kwargs): + """ + :param id: The unique identifier for the shield information barrier, defaults to None + :type id: Optional[str], optional + :param type: The type of the shield information barrier, defaults to None + :type type: Optional[ShieldInformationBarrierBaseTypeField], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type \ No newline at end of file diff --git a/box_sdk_gen/schemas/shield_information_barrier_reference.py b/box_sdk_gen/schemas/shield_information_barrier_reference.py new file mode 100644 index 000000000..305caadd2 --- /dev/null +++ b/box_sdk_gen/schemas/shield_information_barrier_reference.py @@ -0,0 +1,12 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.shield_information_barrier_base import ShieldInformationBarrierBase + +from box_sdk_gen.box.errors import BoxSDKError + +class ShieldInformationBarrierReference(BaseObject): + def __init__(self, *, shield_information_barrier: Optional[ShieldInformationBarrierBase] = None, **kwargs): + super().__init__(**kwargs) + self.shield_information_barrier = shield_information_barrier \ No newline at end of file diff --git a/box_sdk_gen/schemas/shield_information_barrier_report.py b/box_sdk_gen/schemas/shield_information_barrier_report.py new file mode 100644 index 000000000..7be9b82cf --- /dev/null +++ b/box_sdk_gen/schemas/shield_information_barrier_report.py @@ -0,0 +1,47 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.schemas.shield_information_barrier_report_base import ShieldInformationBarrierReportBaseTypeField + +from box_sdk_gen.schemas.shield_information_barrier_report_base import ShieldInformationBarrierReportBase + +from box_sdk_gen.schemas.shield_information_barrier_reference import ShieldInformationBarrierReference + +from box_sdk_gen.schemas.shield_information_barrier_report_details import ShieldInformationBarrierReportDetails + +from box_sdk_gen.schemas.user_base import UserBase + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class ShieldInformationBarrierReportStatusField(str, Enum): + PENDING = 'pending' + ERROR = 'error' + DONE = 'done' + CANCELLED = 'cancelled' + +class ShieldInformationBarrierReport(ShieldInformationBarrierReportBase): + def __init__(self, *, shield_information_barrier: Optional[ShieldInformationBarrierReference] = None, status: Optional[ShieldInformationBarrierReportStatusField] = None, details: Optional[ShieldInformationBarrierReportDetails] = None, created_at: Optional[DateTime] = None, created_by: Optional[UserBase] = None, updated_at: Optional[DateTime] = None, id: Optional[str] = None, type: Optional[ShieldInformationBarrierReportBaseTypeField] = None, **kwargs): + """ + :param status: Status of the shield information report, defaults to None + :type status: Optional[ShieldInformationBarrierReportStatusField], optional + :param created_at: ISO date time string when this +shield information barrier report object was created., defaults to None + :type created_at: Optional[DateTime], optional + :param updated_at: ISO date time string when this +shield information barrier report was updated., defaults to None + :type updated_at: Optional[DateTime], optional + :param id: The unique identifier for the shield information barrier report, defaults to None + :type id: Optional[str], optional + :param type: The type of the shield information barrier report, defaults to None + :type type: Optional[ShieldInformationBarrierReportBaseTypeField], optional + """ + super().__init__(id=id, type=type, **kwargs) + self.shield_information_barrier = shield_information_barrier + self.status = status + self.details = details + self.created_at = created_at + self.created_by = created_by + self.updated_at = updated_at \ No newline at end of file diff --git a/box_sdk_gen/schemas/shield_information_barrier_report_base.py b/box_sdk_gen/schemas/shield_information_barrier_report_base.py new file mode 100644 index 000000000..70c4c4ff0 --- /dev/null +++ b/box_sdk_gen/schemas/shield_information_barrier_report_base.py @@ -0,0 +1,23 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class ShieldInformationBarrierReportBaseTypeField(str, Enum): + SHIELD_INFORMATION_BARRIER_REPORT = 'shield_information_barrier_report' + +class ShieldInformationBarrierReportBase(BaseObject): + _discriminator = 'type', {'shield_information_barrier_report'} + def __init__(self, *, id: Optional[str] = None, type: Optional[ShieldInformationBarrierReportBaseTypeField] = None, **kwargs): + """ + :param id: The unique identifier for the shield information barrier report, defaults to None + :type id: Optional[str], optional + :param type: The type of the shield information barrier report, defaults to None + :type type: Optional[ShieldInformationBarrierReportBaseTypeField], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type \ No newline at end of file diff --git a/box_sdk_gen/schemas/shield_information_barrier_report_details.py b/box_sdk_gen/schemas/shield_information_barrier_report_details.py new file mode 100644 index 000000000..e88313a76 --- /dev/null +++ b/box_sdk_gen/schemas/shield_information_barrier_report_details.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 ShieldInformationBarrierReportDetailsDetailsField(BaseObject): + def __init__(self, *, folder_id: Optional[str] = None, **kwargs): + """ + :param folder_id: Folder ID for locating this report, defaults to None + :type folder_id: Optional[str], optional + """ + super().__init__(**kwargs) + self.folder_id = folder_id + +class ShieldInformationBarrierReportDetails(BaseObject): + def __init__(self, *, details: Optional[ShieldInformationBarrierReportDetailsDetailsField] = None, **kwargs): + super().__init__(**kwargs) + self.details = details \ No newline at end of file diff --git a/box_sdk_gen/schemas/shield_information_barrier_reports.py b/box_sdk_gen/schemas/shield_information_barrier_reports.py new file mode 100644 index 000000000..a9540cb1a --- /dev/null +++ b/box_sdk_gen/schemas/shield_information_barrier_reports.py @@ -0,0 +1,27 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.shield_information_barrier_report import ShieldInformationBarrierReport + +from box_sdk_gen.box.errors import BoxSDKError + +class ShieldInformationBarrierReports(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, entries: Optional[List[ShieldInformationBarrierReport]] = 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 entries: A list of shield information +barrier reports., defaults to None + :type entries: Optional[List[ShieldInformationBarrierReport]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/shield_information_barrier_segment.py b/box_sdk_gen/schemas/shield_information_barrier_segment.py new file mode 100644 index 000000000..4e9d46ed1 --- /dev/null +++ b/box_sdk_gen/schemas/shield_information_barrier_segment.py @@ -0,0 +1,46 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.shield_information_barrier_base import ShieldInformationBarrierBase + +from box_sdk_gen.schemas.user_base import UserBase + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class ShieldInformationBarrierSegmentTypeField(str, Enum): + SHIELD_INFORMATION_BARRIER_SEGMENT = 'shield_information_barrier_segment' + +class ShieldInformationBarrierSegment(BaseObject): + _discriminator = 'type', {'shield_information_barrier_segment'} + def __init__(self, *, id: Optional[str] = None, type: Optional[ShieldInformationBarrierSegmentTypeField] = None, shield_information_barrier: Optional[ShieldInformationBarrierBase] = None, name: Optional[str] = None, description: Optional[str] = None, created_at: Optional[DateTime] = None, created_by: Optional[UserBase] = None, updated_at: Optional[DateTime] = None, updated_by: Optional[UserBase] = None, **kwargs): + """ + :param id: The unique identifier for the shield information barrier segment, defaults to None + :type id: Optional[str], optional + :param type: The type of the shield information barrier segment, defaults to None + :type type: Optional[ShieldInformationBarrierSegmentTypeField], optional + :param name: Name of the shield information barrier segment, defaults to None + :type name: Optional[str], optional + :param description: Description of the shield information barrier segment, defaults to None + :type description: Optional[str], optional + :param created_at: ISO date time string when this shield information +barrier object was created., defaults to None + :type created_at: Optional[DateTime], optional + :param updated_at: ISO date time string when this +shield information barrier segment was updated., defaults to None + :type updated_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.shield_information_barrier = shield_information_barrier + self.name = name + self.description = description + self.created_at = created_at + self.created_by = created_by + self.updated_at = updated_at + self.updated_by = updated_by \ No newline at end of file diff --git a/box_sdk_gen/schemas/shield_information_barrier_segment_member.py b/box_sdk_gen/schemas/shield_information_barrier_segment_member.py new file mode 100644 index 000000000..07250ad3e --- /dev/null +++ b/box_sdk_gen/schemas/shield_information_barrier_segment_member.py @@ -0,0 +1,62 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.shield_information_barrier_segment_member_base import ShieldInformationBarrierSegmentMemberBaseTypeField + +from box_sdk_gen.schemas.shield_information_barrier_segment_member_base import ShieldInformationBarrierSegmentMemberBase + +from box_sdk_gen.schemas.shield_information_barrier_segment_member_mini import ShieldInformationBarrierSegmentMemberMini + +from box_sdk_gen.schemas.shield_information_barrier_base import ShieldInformationBarrierBase + +from box_sdk_gen.schemas.user_base import UserBase + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class ShieldInformationBarrierSegmentMemberShieldInformationBarrierSegmentTypeField(str, Enum): + SHIELD_INFORMATION_BARRIER_SEGMENT = 'shield_information_barrier_segment' + +class ShieldInformationBarrierSegmentMemberShieldInformationBarrierSegmentField(BaseObject): + _discriminator = 'type', {'shield_information_barrier_segment'} + def __init__(self, *, id: Optional[str] = None, type: Optional[ShieldInformationBarrierSegmentMemberShieldInformationBarrierSegmentTypeField] = None, **kwargs): + """ + :param id: The ID reference of the requesting +shield information barrier segment., defaults to None + :type id: Optional[str], optional + :param type: The type of the shield information barrier segment, defaults to None + :type type: Optional[ShieldInformationBarrierSegmentMemberShieldInformationBarrierSegmentTypeField], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class ShieldInformationBarrierSegmentMember(ShieldInformationBarrierSegmentMemberMini): + def __init__(self, *, shield_information_barrier: Optional[ShieldInformationBarrierBase] = None, shield_information_barrier_segment: Optional[ShieldInformationBarrierSegmentMemberShieldInformationBarrierSegmentField] = None, created_at: Optional[DateTime] = None, created_by: Optional[UserBase] = None, updated_at: Optional[DateTime] = None, updated_by: Optional[UserBase] = None, user: Optional[UserBase] = None, id: Optional[str] = None, type: Optional[ShieldInformationBarrierSegmentMemberBaseTypeField] = None, **kwargs): + """ + :param shield_information_barrier_segment: The `type` and `id` of the requested +shield information barrier segment., defaults to None + :type shield_information_barrier_segment: Optional[ShieldInformationBarrierSegmentMemberShieldInformationBarrierSegmentField], optional + :param created_at: ISO date time string when this shield +information barrier object was created., defaults to None + :type created_at: Optional[DateTime], optional + :param updated_at: ISO date time string when this +shield information barrier segment Member was updated., defaults to None + :type updated_at: Optional[DateTime], optional + :param id: The unique identifier for the +shield information barrier segment member, defaults to None + :type id: Optional[str], optional + :param type: The type of the shield information barrier segment member, defaults to None + :type type: Optional[ShieldInformationBarrierSegmentMemberBaseTypeField], optional + """ + super().__init__(user=user, id=id, type=type, **kwargs) + self.shield_information_barrier = shield_information_barrier + self.shield_information_barrier_segment = shield_information_barrier_segment + self.created_at = created_at + self.created_by = created_by + self.updated_at = updated_at + self.updated_by = updated_by \ No newline at end of file diff --git a/box_sdk_gen/schemas/shield_information_barrier_segment_member_base.py b/box_sdk_gen/schemas/shield_information_barrier_segment_member_base.py new file mode 100644 index 000000000..8048bf2d5 --- /dev/null +++ b/box_sdk_gen/schemas/shield_information_barrier_segment_member_base.py @@ -0,0 +1,24 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class ShieldInformationBarrierSegmentMemberBaseTypeField(str, Enum): + SHIELD_INFORMATION_BARRIER_SEGMENT_MEMBER = 'shield_information_barrier_segment_member' + +class ShieldInformationBarrierSegmentMemberBase(BaseObject): + _discriminator = 'type', {'shield_information_barrier_segment_member'} + def __init__(self, *, id: Optional[str] = None, type: Optional[ShieldInformationBarrierSegmentMemberBaseTypeField] = None, **kwargs): + """ + :param id: The unique identifier for the +shield information barrier segment member, defaults to None + :type id: Optional[str], optional + :param type: The type of the shield information barrier segment member, defaults to None + :type type: Optional[ShieldInformationBarrierSegmentMemberBaseTypeField], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type \ No newline at end of file diff --git a/box_sdk_gen/schemas/shield_information_barrier_segment_member_mini.py b/box_sdk_gen/schemas/shield_information_barrier_segment_member_mini.py new file mode 100644 index 000000000..16bda45c4 --- /dev/null +++ b/box_sdk_gen/schemas/shield_information_barrier_segment_member_mini.py @@ -0,0 +1,21 @@ +from typing import Optional + +from box_sdk_gen.schemas.shield_information_barrier_segment_member_base import ShieldInformationBarrierSegmentMemberBaseTypeField + +from box_sdk_gen.schemas.shield_information_barrier_segment_member_base import ShieldInformationBarrierSegmentMemberBase + +from box_sdk_gen.schemas.user_base import UserBase + +from box_sdk_gen.box.errors import BoxSDKError + +class ShieldInformationBarrierSegmentMemberMini(ShieldInformationBarrierSegmentMemberBase): + def __init__(self, *, user: Optional[UserBase] = None, id: Optional[str] = None, type: Optional[ShieldInformationBarrierSegmentMemberBaseTypeField] = None, **kwargs): + """ + :param id: The unique identifier for the +shield information barrier segment member, defaults to None + :type id: Optional[str], optional + :param type: The type of the shield information barrier segment member, defaults to None + :type type: Optional[ShieldInformationBarrierSegmentMemberBaseTypeField], optional + """ + super().__init__(id=id, type=type, **kwargs) + self.user = user \ No newline at end of file diff --git a/box_sdk_gen/schemas/shield_information_barrier_segment_members.py b/box_sdk_gen/schemas/shield_information_barrier_segment_members.py new file mode 100644 index 000000000..56ad4bef0 --- /dev/null +++ b/box_sdk_gen/schemas/shield_information_barrier_segment_members.py @@ -0,0 +1,27 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.shield_information_barrier_segment_member import ShieldInformationBarrierSegmentMember + +from box_sdk_gen.box.errors import BoxSDKError + +class ShieldInformationBarrierSegmentMembers(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, entries: Optional[List[ShieldInformationBarrierSegmentMember]] = 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 entries: A list of shield information +barrier segment members, defaults to None + :type entries: Optional[List[ShieldInformationBarrierSegmentMember]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/shield_information_barrier_segment_restriction.py b/box_sdk_gen/schemas/shield_information_barrier_segment_restriction.py new file mode 100644 index 000000000..29e6744be --- /dev/null +++ b/box_sdk_gen/schemas/shield_information_barrier_segment_restriction.py @@ -0,0 +1,49 @@ +from typing import Optional + +from box_sdk_gen.schemas.shield_information_barrier_segment_restriction_base import ShieldInformationBarrierSegmentRestrictionBaseTypeField + +from box_sdk_gen.schemas.shield_information_barrier_segment_restriction_base import ShieldInformationBarrierSegmentRestrictionBase + +from box_sdk_gen.schemas.shield_information_barrier_segment_restriction_mini import ShieldInformationBarrierSegmentRestrictionMiniShieldInformationBarrierSegmentField + +from box_sdk_gen.schemas.shield_information_barrier_segment_restriction_mini import ShieldInformationBarrierSegmentRestrictionMiniRestrictedSegmentField + +from box_sdk_gen.schemas.shield_information_barrier_segment_restriction_mini import ShieldInformationBarrierSegmentRestrictionMini + +from box_sdk_gen.schemas.shield_information_barrier_base import ShieldInformationBarrierBase + +from box_sdk_gen.schemas.user_base import UserBase + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class ShieldInformationBarrierSegmentRestriction(ShieldInformationBarrierSegmentRestrictionMini): + def __init__(self, shield_information_barrier_segment: ShieldInformationBarrierSegmentRestrictionMiniShieldInformationBarrierSegmentField, restricted_segment: ShieldInformationBarrierSegmentRestrictionMiniRestrictedSegmentField, *, shield_information_barrier: Optional[ShieldInformationBarrierBase] = None, created_at: Optional[DateTime] = None, created_by: Optional[UserBase] = None, updated_at: Optional[DateTime] = None, updated_by: Optional[UserBase] = None, type: Optional[ShieldInformationBarrierSegmentRestrictionBaseTypeField] = None, id: Optional[str] = None, **kwargs): + """ + :param shield_information_barrier_segment: The `type` and `id` of the +requested shield information barrier segment. + :type shield_information_barrier_segment: ShieldInformationBarrierSegmentRestrictionMiniShieldInformationBarrierSegmentField + :param restricted_segment: The `type` and `id` of the +restricted shield information barrier segment. + :type restricted_segment: ShieldInformationBarrierSegmentRestrictionMiniRestrictedSegmentField + :param created_at: ISO date time string when this +shield information barrier +Segment Restriction object was created., defaults to None + :type created_at: Optional[DateTime], optional + :param updated_at: ISO date time string when this +shield information barrier segment +Restriction was updated., defaults to None + :type updated_at: Optional[DateTime], optional + :param type: Shield information barrier segment restriction, defaults to None + :type type: Optional[ShieldInformationBarrierSegmentRestrictionBaseTypeField], optional + :param id: The unique identifier for the +shield information barrier segment restriction., defaults to None + :type id: Optional[str], optional + """ + super().__init__(shield_information_barrier_segment=shield_information_barrier_segment, restricted_segment=restricted_segment, type=type, id=id, **kwargs) + self.shield_information_barrier = shield_information_barrier + self.created_at = created_at + self.created_by = created_by + self.updated_at = updated_at + self.updated_by = updated_by \ No newline at end of file diff --git a/box_sdk_gen/schemas/shield_information_barrier_segment_restriction_base.py b/box_sdk_gen/schemas/shield_information_barrier_segment_restriction_base.py new file mode 100644 index 000000000..9412d9c11 --- /dev/null +++ b/box_sdk_gen/schemas/shield_information_barrier_segment_restriction_base.py @@ -0,0 +1,24 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class ShieldInformationBarrierSegmentRestrictionBaseTypeField(str, Enum): + SHIELD_INFORMATION_BARRIER_SEGMENT_RESTRICTION = 'shield_information_barrier_segment_restriction' + +class ShieldInformationBarrierSegmentRestrictionBase(BaseObject): + _discriminator = 'type', {'shield_information_barrier_segment_restriction'} + def __init__(self, *, type: Optional[ShieldInformationBarrierSegmentRestrictionBaseTypeField] = None, id: Optional[str] = None, **kwargs): + """ + :param type: Shield information barrier segment restriction, defaults to None + :type type: Optional[ShieldInformationBarrierSegmentRestrictionBaseTypeField], optional + :param id: The unique identifier for the +shield information barrier segment restriction., defaults to None + :type id: Optional[str], optional + """ + super().__init__(**kwargs) + self.type = type + self.id = id \ No newline at end of file diff --git a/box_sdk_gen/schemas/shield_information_barrier_segment_restriction_mini.py b/box_sdk_gen/schemas/shield_information_barrier_segment_restriction_mini.py new file mode 100644 index 000000000..008175420 --- /dev/null +++ b/box_sdk_gen/schemas/shield_information_barrier_segment_restriction_mini.py @@ -0,0 +1,64 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.shield_information_barrier_segment_restriction_base import ShieldInformationBarrierSegmentRestrictionBaseTypeField + +from box_sdk_gen.schemas.shield_information_barrier_segment_restriction_base import ShieldInformationBarrierSegmentRestrictionBase + +from box_sdk_gen.box.errors import BoxSDKError + +class ShieldInformationBarrierSegmentRestrictionMiniShieldInformationBarrierSegmentTypeField(str, Enum): + SHIELD_INFORMATION_BARRIER_SEGMENT = 'shield_information_barrier_segment' + +class ShieldInformationBarrierSegmentRestrictionMiniShieldInformationBarrierSegmentField(BaseObject): + _discriminator = 'type', {'shield_information_barrier_segment'} + def __init__(self, *, id: Optional[str] = None, type: Optional[ShieldInformationBarrierSegmentRestrictionMiniShieldInformationBarrierSegmentTypeField] = None, **kwargs): + """ + :param id: The ID reference of the +requesting shield information barrier segment., defaults to None + :type id: Optional[str], optional + :param type: The type of the shield information barrier segment, defaults to None + :type type: Optional[ShieldInformationBarrierSegmentRestrictionMiniShieldInformationBarrierSegmentTypeField], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class ShieldInformationBarrierSegmentRestrictionMiniRestrictedSegmentTypeField(str, Enum): + SHIELD_INFORMATION_BARRIER_SEGMENT = 'shield_information_barrier_segment' + +class ShieldInformationBarrierSegmentRestrictionMiniRestrictedSegmentField(BaseObject): + _discriminator = 'type', {'shield_information_barrier_segment'} + def __init__(self, *, id: Optional[str] = None, type: Optional[ShieldInformationBarrierSegmentRestrictionMiniRestrictedSegmentTypeField] = None, **kwargs): + """ + :param id: The ID reference of the +restricted shield information barrier segment., defaults to None + :type id: Optional[str], optional + :param type: The type of the shield information segment, defaults to None + :type type: Optional[ShieldInformationBarrierSegmentRestrictionMiniRestrictedSegmentTypeField], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class ShieldInformationBarrierSegmentRestrictionMini(ShieldInformationBarrierSegmentRestrictionBase): + def __init__(self, shield_information_barrier_segment: ShieldInformationBarrierSegmentRestrictionMiniShieldInformationBarrierSegmentField, restricted_segment: ShieldInformationBarrierSegmentRestrictionMiniRestrictedSegmentField, *, type: Optional[ShieldInformationBarrierSegmentRestrictionBaseTypeField] = None, id: Optional[str] = None, **kwargs): + """ + :param shield_information_barrier_segment: The `type` and `id` of the +requested shield information barrier segment. + :type shield_information_barrier_segment: ShieldInformationBarrierSegmentRestrictionMiniShieldInformationBarrierSegmentField + :param restricted_segment: The `type` and `id` of the +restricted shield information barrier segment. + :type restricted_segment: ShieldInformationBarrierSegmentRestrictionMiniRestrictedSegmentField + :param type: Shield information barrier segment restriction, defaults to None + :type type: Optional[ShieldInformationBarrierSegmentRestrictionBaseTypeField], optional + :param id: The unique identifier for the +shield information barrier segment restriction., defaults to None + :type id: Optional[str], optional + """ + super().__init__(type=type, id=id, **kwargs) + self.shield_information_barrier_segment = shield_information_barrier_segment + self.restricted_segment = restricted_segment \ No newline at end of file diff --git a/box_sdk_gen/schemas/shield_information_barrier_segment_restrictions.py b/box_sdk_gen/schemas/shield_information_barrier_segment_restrictions.py new file mode 100644 index 000000000..e9f67603a --- /dev/null +++ b/box_sdk_gen/schemas/shield_information_barrier_segment_restrictions.py @@ -0,0 +1,27 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.shield_information_barrier_segment_restriction import ShieldInformationBarrierSegmentRestriction + +from box_sdk_gen.box.errors import BoxSDKError + +class ShieldInformationBarrierSegmentRestrictions(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, entries: Optional[List[ShieldInformationBarrierSegmentRestriction]] = 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 entries: A list of shield information barrier +segment restriction objects, defaults to None + :type entries: Optional[List[ShieldInformationBarrierSegmentRestriction]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/shield_information_barrier_segments.py b/box_sdk_gen/schemas/shield_information_barrier_segments.py new file mode 100644 index 000000000..26f1754dc --- /dev/null +++ b/box_sdk_gen/schemas/shield_information_barrier_segments.py @@ -0,0 +1,27 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.shield_information_barrier_segment import ShieldInformationBarrierSegment + +from box_sdk_gen.box.errors import BoxSDKError + +class ShieldInformationBarrierSegments(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, entries: Optional[List[ShieldInformationBarrierSegment]] = 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 entries: A list of shield information barrier +segments, defaults to None + :type entries: Optional[List[ShieldInformationBarrierSegment]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/shield_information_barriers.py b/box_sdk_gen/schemas/shield_information_barriers.py new file mode 100644 index 000000000..e2e3674d5 --- /dev/null +++ b/box_sdk_gen/schemas/shield_information_barriers.py @@ -0,0 +1,26 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.shield_information_barrier import ShieldInformationBarrier + +from box_sdk_gen.box.errors import BoxSDKError + +class ShieldInformationBarriers(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, entries: Optional[List[ShieldInformationBarrier]] = 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 entries: A list of shield information barrier objects, defaults to None + :type entries: Optional[List[ShieldInformationBarrier]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/sign_request.py b/box_sdk_gen/schemas/sign_request.py new file mode 100644 index 000000000..898d77503 --- /dev/null +++ b/box_sdk_gen/schemas/sign_request.py @@ -0,0 +1,131 @@ +from enum import Enum + +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.sign_request_prefill_tag import SignRequestPrefillTag + +from box_sdk_gen.schemas.sign_request_base import SignRequestBase + +from box_sdk_gen.schemas.file_base import FileBase + +from box_sdk_gen.schemas.sign_request_signer import SignRequestSigner + +from box_sdk_gen.schemas.file_mini import FileMini + +from box_sdk_gen.schemas.folder_mini import FolderMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class SignRequestTypeField(str, Enum): + SIGN_REQUEST = 'sign-request' + +class SignRequestStatusField(str, Enum): + CONVERTING = 'converting' + CREATED = 'created' + SENT = 'sent' + VIEWED = 'viewed' + SIGNED = 'signed' + CANCELLED = 'cancelled' + DECLINED = 'declined' + ERROR_CONVERTING = 'error_converting' + ERROR_SENDING = 'error_sending' + EXPIRED = 'expired' + FINALIZING = 'finalizing' + ERROR_FINALIZING = 'error_finalizing' + +class SignRequestSignFilesField(BaseObject): + def __init__(self, *, files: Optional[List[FileMini]] = None, is_ready_for_download: Optional[bool] = None, **kwargs): + """ + :param is_ready_for_download: Indicates whether the `sign_files` documents are processing +and the PDFs may be out of date. A change to any document +requires processing on all `sign_files`. We +recommended waiting until processing is finished +(and this value is true) before downloading the PDFs., defaults to None + :type is_ready_for_download: Optional[bool], optional + """ + super().__init__(**kwargs) + self.files = files + self.is_ready_for_download = is_ready_for_download + +class SignRequest(SignRequestBase): + def __init__(self, *, type: Optional[SignRequestTypeField] = None, source_files: Optional[List[FileBase]] = None, signers: Optional[List[SignRequestSigner]] = None, signature_color: Optional[str] = None, id: Optional[str] = None, prepare_url: Optional[str] = None, signing_log: Optional[FileMini] = None, status: Optional[SignRequestStatusField] = None, sign_files: Optional[SignRequestSignFilesField] = None, auto_expire_at: Optional[DateTime] = None, parent_folder: Optional[FolderMini] = None, collaborator_level: Optional[str] = None, sender_email: Optional[str] = None, sender_id: Optional[int] = None, is_document_preparation_needed: Optional[bool] = None, redirect_url: Optional[str] = None, declined_redirect_url: Optional[str] = None, are_text_signatures_enabled: Optional[bool] = None, email_subject: Optional[str] = None, email_message: Optional[str] = None, are_reminders_enabled: Optional[bool] = None, name: Optional[str] = None, prefill_tags: Optional[List[SignRequestPrefillTag]] = None, days_valid: Optional[int] = None, external_id: Optional[str] = None, template_id: Optional[str] = None, external_system_name: Optional[str] = None, **kwargs): + """ + :param type: object type, defaults to None + :type type: Optional[SignRequestTypeField], optional + :param source_files: List of files to create a signing document from. This is currently limited to ten files. Only the ID and type fields are required for each file., defaults to None + :type source_files: Optional[List[FileBase]], optional + :param signers: Array of signers for the signature request., defaults to None + :type signers: Optional[List[SignRequestSigner]], optional + :param signature_color: Force a specific color for the signature (blue, black, or red)., defaults to None + :type signature_color: Optional[str], optional + :param id: Box Sign request ID., defaults to None + :type id: Optional[str], optional + :param prepare_url: This URL is returned if `is_document_preparation_needed` is +set to `true` in the request. The parameter is used to prepare +the signature request +using the UI. The signature request is not +sent until the preparation +phase is complete., defaults to None + :type prepare_url: Optional[str], optional + :param status: Describes the status of the signature request., defaults to None + :type status: Optional[SignRequestStatusField], optional + :param sign_files: List of files that will be signed, which are copies of the original +source files. A new version of these files are created as signers sign +and can be downloaded at any point in the signing process., defaults to None + :type sign_files: Optional[SignRequestSignFilesField], optional + :param auto_expire_at: Uses `days_valid` to calculate the date and time, in GMT, the sign request will expire if unsigned., defaults to None + :type auto_expire_at: Optional[DateTime], optional + :param collaborator_level: The collaborator level of the user to the sign request. Values can include "owner", "editor", and "viewer", defaults to None + :type collaborator_level: Optional[str], optional + :param sender_email: The email address of the sender of the sign request., defaults to None + :type sender_email: Optional[str], optional + :param sender_id: The user ID of the sender of the sign request., defaults to None + :type sender_id: Optional[int], optional + :param is_document_preparation_needed: Indicates if the sender should receive a `prepare_url` in the response to complete document preparation using the UI., defaults to None + :type is_document_preparation_needed: Optional[bool], optional + :param redirect_url: When specified, the signature request will be redirected to this url when a document is signed., defaults to None + :type redirect_url: Optional[str], optional + :param declined_redirect_url: The uri that a signer will be redirected to after declining to sign a document., defaults to None + :type declined_redirect_url: Optional[str], optional + :param are_text_signatures_enabled: Disables the usage of signatures generated by typing (text)., defaults to None + :type are_text_signatures_enabled: Optional[bool], optional + :param email_subject: Subject of sign request email. This is cleaned by sign request. If this field is not passed, a default subject will be used., defaults to None + :type email_subject: Optional[str], optional + :param email_message: Message to include in sign request email. The field is cleaned through sanitization of specific characters. However, some html tags are allowed. Links included in the message are also converted to hyperlinks in the email. The message may contain the following html tags including `a`, `abbr`, `acronym`, `b`, `blockquote`, `code`, `em`, `i`, `ul`, `li`, `ol`, and `strong`. Be aware that when the text to html ratio is too high, the email may end up in spam filters. Custom styles on these tags are not allowed. If this field is not passed, a default message will be used., defaults to None + :type email_message: Optional[str], optional + :param are_reminders_enabled: Reminds signers to sign a document on day 3, 8, 13 and 18. Reminders are only sent to outstanding signers., defaults to None + :type are_reminders_enabled: Optional[bool], optional + :param name: Name of the signature request., defaults to None + :type name: Optional[str], optional + :param prefill_tags: When a document contains sign-related tags in the content, you can prefill them using this `prefill_tags` by referencing the 'id' of the tag as the `external_id` field of the prefill tag., defaults to None + :type prefill_tags: Optional[List[SignRequestPrefillTag]], optional + :param days_valid: Set the number of days after which the created signature request will automatically expire if not completed. By default, we do not apply any expiration date on signature requests, and the signature request does not expire., defaults to None + :type days_valid: Optional[int], optional + :param external_id: This can be used to reference an ID in an external system that the sign request is related to., defaults to None + :type external_id: Optional[str], optional + :param template_id: When a signature request is created from a template this field will indicate the id of that template., defaults to None + :type template_id: Optional[str], optional + :param external_system_name: Used as an optional system name to appear in the signature log next to the signers who have been assigned the `embed_url_external_id`., defaults to None + :type external_system_name: Optional[str], optional + """ + super().__init__(is_document_preparation_needed=is_document_preparation_needed, redirect_url=redirect_url, declined_redirect_url=declined_redirect_url, are_text_signatures_enabled=are_text_signatures_enabled, email_subject=email_subject, email_message=email_message, are_reminders_enabled=are_reminders_enabled, name=name, prefill_tags=prefill_tags, days_valid=days_valid, external_id=external_id, template_id=template_id, external_system_name=external_system_name, **kwargs) + self.type = type + self.source_files = source_files + self.signers = signers + self.signature_color = signature_color + self.id = id + self.prepare_url = prepare_url + self.signing_log = signing_log + self.status = status + self.sign_files = sign_files + self.auto_expire_at = auto_expire_at + self.parent_folder = parent_folder + self.collaborator_level = collaborator_level + self.sender_email = sender_email + self.sender_id = sender_id \ No newline at end of file diff --git a/box_sdk_gen/schemas/sign_request_base.py b/box_sdk_gen/schemas/sign_request_base.py new file mode 100644 index 000000000..a5a0c8da2 --- /dev/null +++ b/box_sdk_gen/schemas/sign_request_base.py @@ -0,0 +1,54 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.sign_request_prefill_tag import SignRequestPrefillTag + +from box_sdk_gen.box.errors import BoxSDKError + +class SignRequestBase(BaseObject): + def __init__(self, *, is_document_preparation_needed: Optional[bool] = None, redirect_url: Optional[str] = None, declined_redirect_url: Optional[str] = None, are_text_signatures_enabled: Optional[bool] = None, email_subject: Optional[str] = None, email_message: Optional[str] = None, are_reminders_enabled: Optional[bool] = None, name: Optional[str] = None, prefill_tags: Optional[List[SignRequestPrefillTag]] = None, days_valid: Optional[int] = None, external_id: Optional[str] = None, template_id: Optional[str] = None, external_system_name: Optional[str] = None, **kwargs): + """ + :param is_document_preparation_needed: Indicates if the sender should receive a `prepare_url` in the response to complete document preparation using the UI., defaults to None + :type is_document_preparation_needed: Optional[bool], optional + :param redirect_url: When specified, the signature request will be redirected to this url when a document is signed., defaults to None + :type redirect_url: Optional[str], optional + :param declined_redirect_url: The uri that a signer will be redirected to after declining to sign a document., defaults to None + :type declined_redirect_url: Optional[str], optional + :param are_text_signatures_enabled: Disables the usage of signatures generated by typing (text)., defaults to None + :type are_text_signatures_enabled: Optional[bool], optional + :param email_subject: Subject of sign request email. This is cleaned by sign request. If this field is not passed, a default subject will be used., defaults to None + :type email_subject: Optional[str], optional + :param email_message: Message to include in sign request email. The field is cleaned through sanitization of specific characters. However, some html tags are allowed. Links included in the message are also converted to hyperlinks in the email. The message may contain the following html tags including `a`, `abbr`, `acronym`, `b`, `blockquote`, `code`, `em`, `i`, `ul`, `li`, `ol`, and `strong`. Be aware that when the text to html ratio is too high, the email may end up in spam filters. Custom styles on these tags are not allowed. If this field is not passed, a default message will be used., defaults to None + :type email_message: Optional[str], optional + :param are_reminders_enabled: Reminds signers to sign a document on day 3, 8, 13 and 18. Reminders are only sent to outstanding signers., defaults to None + :type are_reminders_enabled: Optional[bool], optional + :param name: Name of the signature request., defaults to None + :type name: Optional[str], optional + :param prefill_tags: When a document contains sign-related tags in the content, you can prefill them using this `prefill_tags` by referencing the 'id' of the tag as the `external_id` field of the prefill tag., defaults to None + :type prefill_tags: Optional[List[SignRequestPrefillTag]], optional + :param days_valid: Set the number of days after which the created signature request will automatically expire if not completed. By default, we do not apply any expiration date on signature requests, and the signature request does not expire., defaults to None + :type days_valid: Optional[int], optional + :param external_id: This can be used to reference an ID in an external system that the sign request is related to., defaults to None + :type external_id: Optional[str], optional + :param template_id: When a signature request is created from a template this field will indicate the id of that template., defaults to None + :type template_id: Optional[str], optional + :param external_system_name: Used as an optional system name to appear in the signature log next to the signers who have been assigned the `embed_url_external_id`., defaults to None + :type external_system_name: Optional[str], optional + """ + super().__init__(**kwargs) + self.is_document_preparation_needed = is_document_preparation_needed + self.redirect_url = redirect_url + self.declined_redirect_url = declined_redirect_url + self.are_text_signatures_enabled = are_text_signatures_enabled + self.email_subject = email_subject + self.email_message = email_message + self.are_reminders_enabled = are_reminders_enabled + self.name = name + self.prefill_tags = prefill_tags + self.days_valid = days_valid + self.external_id = external_id + self.template_id = template_id + self.external_system_name = external_system_name \ No newline at end of file diff --git a/box_sdk_gen/schemas/sign_request_create_request.py b/box_sdk_gen/schemas/sign_request_create_request.py new file mode 100644 index 000000000..20f796d35 --- /dev/null +++ b/box_sdk_gen/schemas/sign_request_create_request.py @@ -0,0 +1,71 @@ +from enum import Enum + +from typing import Optional + +from typing import List + +from box_sdk_gen.schemas.sign_request_prefill_tag import SignRequestPrefillTag + +from box_sdk_gen.schemas.sign_request_base import SignRequestBase + +from box_sdk_gen.schemas.file_base import FileBase + +from box_sdk_gen.schemas.sign_request_create_signer import SignRequestCreateSigner + +from box_sdk_gen.schemas.folder_mini import FolderMini + +from box_sdk_gen.box.errors import BoxSDKError + +class SignRequestCreateRequestSignatureColorField(str, Enum): + BLUE = 'blue' + BLACK = 'black' + RED = 'red' + +class SignRequestCreateRequest(SignRequestBase): + def __init__(self, signers: List[SignRequestCreateSigner], *, source_files: Optional[List[FileBase]] = None, signature_color: Optional[SignRequestCreateRequestSignatureColorField] = None, parent_folder: Optional[FolderMini] = None, is_document_preparation_needed: Optional[bool] = None, redirect_url: Optional[str] = None, declined_redirect_url: Optional[str] = None, are_text_signatures_enabled: Optional[bool] = None, email_subject: Optional[str] = None, email_message: Optional[str] = None, are_reminders_enabled: Optional[bool] = None, name: Optional[str] = None, prefill_tags: Optional[List[SignRequestPrefillTag]] = None, days_valid: Optional[int] = None, external_id: Optional[str] = None, template_id: Optional[str] = None, external_system_name: Optional[str] = None, **kwargs): + """ + :param signers: Array of signers for the signature request. 35 is the +max number of signers permitted. + +**Note**: It may happen that some signers belong to conflicting [segments](r://shield-information-barrier-segment-member) (user groups). +This means that due to the security policies, users are assigned to segments to prevent exchanges or communication that could lead to ethical conflicts. +In such a case, an attempt to send the sign request will result in an error. + +Read more about [segments and ethical walls](https://support.box.com/hc/en-us/articles/9920431507603-Understanding-Information-Barriers#h_01GFVJEHQA06N7XEZ4GCZ9GFAQ). + :type signers: List[SignRequestCreateSigner] + :param source_files: List of files to create a signing document from. This is currently limited to ten files. Only the ID and type fields are required for each file., defaults to None + :type source_files: Optional[List[FileBase]], optional + :param signature_color: Force a specific color for the signature (blue, black, or red), defaults to None + :type signature_color: Optional[SignRequestCreateRequestSignatureColorField], optional + :param is_document_preparation_needed: Indicates if the sender should receive a `prepare_url` in the response to complete document preparation using the UI., defaults to None + :type is_document_preparation_needed: Optional[bool], optional + :param redirect_url: When specified, the signature request will be redirected to this url when a document is signed., defaults to None + :type redirect_url: Optional[str], optional + :param declined_redirect_url: The uri that a signer will be redirected to after declining to sign a document., defaults to None + :type declined_redirect_url: Optional[str], optional + :param are_text_signatures_enabled: Disables the usage of signatures generated by typing (text)., defaults to None + :type are_text_signatures_enabled: Optional[bool], optional + :param email_subject: Subject of sign request email. This is cleaned by sign request. If this field is not passed, a default subject will be used., defaults to None + :type email_subject: Optional[str], optional + :param email_message: Message to include in sign request email. The field is cleaned through sanitization of specific characters. However, some html tags are allowed. Links included in the message are also converted to hyperlinks in the email. The message may contain the following html tags including `a`, `abbr`, `acronym`, `b`, `blockquote`, `code`, `em`, `i`, `ul`, `li`, `ol`, and `strong`. Be aware that when the text to html ratio is too high, the email may end up in spam filters. Custom styles on these tags are not allowed. If this field is not passed, a default message will be used., defaults to None + :type email_message: Optional[str], optional + :param are_reminders_enabled: Reminds signers to sign a document on day 3, 8, 13 and 18. Reminders are only sent to outstanding signers., defaults to None + :type are_reminders_enabled: Optional[bool], optional + :param name: Name of the signature request., defaults to None + :type name: Optional[str], optional + :param prefill_tags: When a document contains sign-related tags in the content, you can prefill them using this `prefill_tags` by referencing the 'id' of the tag as the `external_id` field of the prefill tag., defaults to None + :type prefill_tags: Optional[List[SignRequestPrefillTag]], optional + :param days_valid: Set the number of days after which the created signature request will automatically expire if not completed. By default, we do not apply any expiration date on signature requests, and the signature request does not expire., defaults to None + :type days_valid: Optional[int], optional + :param external_id: This can be used to reference an ID in an external system that the sign request is related to., defaults to None + :type external_id: Optional[str], optional + :param template_id: When a signature request is created from a template this field will indicate the id of that template., defaults to None + :type template_id: Optional[str], optional + :param external_system_name: Used as an optional system name to appear in the signature log next to the signers who have been assigned the `embed_url_external_id`., defaults to None + :type external_system_name: Optional[str], optional + """ + super().__init__(is_document_preparation_needed=is_document_preparation_needed, redirect_url=redirect_url, declined_redirect_url=declined_redirect_url, are_text_signatures_enabled=are_text_signatures_enabled, email_subject=email_subject, email_message=email_message, are_reminders_enabled=are_reminders_enabled, name=name, prefill_tags=prefill_tags, days_valid=days_valid, external_id=external_id, template_id=template_id, external_system_name=external_system_name, **kwargs) + self.signers = signers + self.source_files = source_files + self.signature_color = signature_color + self.parent_folder = parent_folder \ No newline at end of file diff --git a/box_sdk_gen/schemas/sign_request_create_signer.py b/box_sdk_gen/schemas/sign_request_create_signer.py new file mode 100644 index 000000000..b7aaeff42 --- /dev/null +++ b/box_sdk_gen/schemas/sign_request_create_signer.py @@ -0,0 +1,80 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class SignRequestCreateSignerRoleField(str, Enum): + SIGNER = 'signer' + APPROVER = 'approver' + FINAL_COPY_READER = 'final_copy_reader' + +class SignRequestCreateSigner(BaseObject): + def __init__(self, *, email: Optional[str] = None, role: Optional[SignRequestCreateSignerRoleField] = None, is_in_person: Optional[bool] = None, order: Optional[int] = None, embed_url_external_user_id: Optional[str] = None, redirect_url: Optional[str] = None, declined_redirect_url: Optional[str] = None, login_required: Optional[bool] = None, verification_phone_number: Optional[str] = None, password: Optional[str] = None, signer_group_id: Optional[str] = None, suppress_notifications: Optional[bool] = None, **kwargs): + """ + :param email: Email address of the signer. +The email address of the signer is required when making signature requests, except when using templates that are configured to include emails., defaults to None + :type email: Optional[str], optional + :param role: Defines the role of the signer in the signature request. A `signer` +must sign the document and an `approver` must approve the document. A +`final_copy_reader` only receives the final signed document and signing +log., defaults to None + :type role: Optional[SignRequestCreateSignerRoleField], optional + :param is_in_person: Used in combination with an embed URL for a sender. After the +sender signs, they are redirected to the next `in_person` signer., defaults to None + :type is_in_person: Optional[bool], optional + :param order: Order of the signer, defaults to None + :type order: Optional[int], optional + :param embed_url_external_user_id: User ID for the signer in an external application responsible +for authentication when accessing the embed URL., defaults to None + :type embed_url_external_user_id: Optional[str], optional + :param redirect_url: The URL that a signer will be redirected +to after signing a document. Defining this URL +overrides default or global redirect URL +settings for a specific signer. +If no declined redirect URL is specified, +this URL will be used for decline actions as well., defaults to None + :type redirect_url: Optional[str], optional + :param declined_redirect_url: The URL that a signer will be redirect +to after declining to sign a document. +Defining this URL overrides default or global +declined redirect URL settings for a specific signer., defaults to None + :type declined_redirect_url: Optional[str], optional + :param login_required: If set to true, the signer will need to log in to a Box account +before signing the request. If the signer does not have +an existing account, they will have the option to create +a free Box account., defaults to None + :type login_required: Optional[bool], optional + :param verification_phone_number: If set, this phone number will be used to verify the signer +via two-factor authentication before they are able to sign the document. +Cannot be selected in combination with `login_required`., defaults to None + :type verification_phone_number: Optional[str], optional + :param password: If set, the signer is required to enter the password before they are able +to sign a document. This field is write only., defaults to None + :type password: Optional[str], optional + :param signer_group_id: If set, signers who have the same value will be assigned to the same input and to the same signer group. +A signer group is not a Box Group. It is an entity that belongs to a Sign Request and can only be +used/accessed within this Sign Request. A signer group is expected to have more than one signer. +If the provided value is only used for one signer, this value will be ignored and request will be handled +as it was intended for an individual signer. The value provided can be any string and only used to +determine which signers belongs to same group. A successful response will provide a generated UUID value +instead for signers in the same signer group., defaults to None + :type signer_group_id: Optional[str], optional + :param suppress_notifications: If true, no emails about the sign request will be sent, defaults to None + :type suppress_notifications: Optional[bool], optional + """ + super().__init__(**kwargs) + self.email = email + self.role = role + self.is_in_person = is_in_person + self.order = order + self.embed_url_external_user_id = embed_url_external_user_id + self.redirect_url = redirect_url + self.declined_redirect_url = declined_redirect_url + self.login_required = login_required + self.verification_phone_number = verification_phone_number + self.password = password + self.signer_group_id = signer_group_id + self.suppress_notifications = suppress_notifications \ No newline at end of file diff --git a/box_sdk_gen/schemas/sign_request_prefill_tag.py b/box_sdk_gen/schemas/sign_request_prefill_tag.py new file mode 100644 index 000000000..3601dfb90 --- /dev/null +++ b/box_sdk_gen/schemas/sign_request_prefill_tag.py @@ -0,0 +1,25 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import Date + +class SignRequestPrefillTag(BaseObject): + def __init__(self, *, document_tag_id: Optional[str] = None, text_value: Optional[str] = None, checkbox_value: Optional[bool] = None, date_value: Optional[Date] = None, **kwargs): + """ + :param document_tag_id: This references the ID of a specific tag contained in a file of the signature request., defaults to None + :type document_tag_id: Optional[str], optional + :param text_value: Text prefill value, defaults to None + :type text_value: Optional[str], optional + :param checkbox_value: Checkbox prefill value, defaults to None + :type checkbox_value: Optional[bool], optional + :param date_value: Date prefill value, defaults to None + :type date_value: Optional[Date], optional + """ + super().__init__(**kwargs) + self.document_tag_id = document_tag_id + self.text_value = text_value + self.checkbox_value = checkbox_value + self.date_value = date_value \ No newline at end of file diff --git a/box_sdk_gen/schemas/sign_request_signer.py b/box_sdk_gen/schemas/sign_request_signer.py new file mode 100644 index 000000000..1dca064a8 --- /dev/null +++ b/box_sdk_gen/schemas/sign_request_signer.py @@ -0,0 +1,111 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from box_sdk_gen.schemas.sign_request_create_signer import SignRequestCreateSignerRoleField + +from box_sdk_gen.schemas.sign_request_create_signer import SignRequestCreateSigner + +from box_sdk_gen.schemas.sign_request_signer_input import SignRequestSignerInput + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class SignRequestSignerSignerDecisionTypeField(str, Enum): + SIGNED = 'signed' + DECLINED = 'declined' + +class SignRequestSignerSignerDecisionField(BaseObject): + _discriminator = 'type', {'signed', 'declined'} + def __init__(self, *, type: Optional[SignRequestSignerSignerDecisionTypeField] = None, finalized_at: Optional[DateTime] = None, additional_info: Optional[str] = None, **kwargs): + """ + :param type: Type of decision made by the signer., defaults to None + :type type: Optional[SignRequestSignerSignerDecisionTypeField], optional + :param finalized_at: Date and Time that the decision was made., defaults to None + :type finalized_at: Optional[DateTime], optional + :param additional_info: Additional info about the decision, such as the decline reason from the signer., defaults to None + :type additional_info: Optional[str], optional + """ + super().__init__(**kwargs) + self.type = type + self.finalized_at = finalized_at + self.additional_info = additional_info + +class SignRequestSigner(SignRequestCreateSigner): + def __init__(self, *, has_viewed_document: Optional[bool] = None, signer_decision: Optional[SignRequestSignerSignerDecisionField] = None, inputs: Optional[List[SignRequestSignerInput]] = None, embed_url: Optional[str] = None, iframeable_embed_url: Optional[str] = None, email: Optional[str] = None, role: Optional[SignRequestCreateSignerRoleField] = None, is_in_person: Optional[bool] = None, order: Optional[int] = None, embed_url_external_user_id: Optional[str] = None, redirect_url: Optional[str] = None, declined_redirect_url: Optional[str] = None, login_required: Optional[bool] = None, verification_phone_number: Optional[str] = None, password: Optional[str] = None, signer_group_id: Optional[str] = None, suppress_notifications: Optional[bool] = None, **kwargs): + """ + :param has_viewed_document: Set to `true` if the signer views the document, defaults to None + :type has_viewed_document: Optional[bool], optional + :param signer_decision: Final decision made by the signer., defaults to None + :type signer_decision: Optional[SignRequestSignerSignerDecisionField], optional + :param embed_url: URL to direct a signer to for signing, defaults to None + :type embed_url: Optional[str], optional + :param iframeable_embed_url: This URL is specifically designed for +signing documents within an HTML `iframe` tag. +It will be returned in the response +only if the `embed_url_external_user_id` +parameter was passed in the +`create Box Sign request` call., defaults to None + :type iframeable_embed_url: Optional[str], optional + :param email: Email address of the signer. +The email address of the signer is required when making signature requests, except when using templates that are configured to include emails., defaults to None + :type email: Optional[str], optional + :param role: Defines the role of the signer in the signature request. A `signer` +must sign the document and an `approver` must approve the document. A +`final_copy_reader` only receives the final signed document and signing +log., defaults to None + :type role: Optional[SignRequestCreateSignerRoleField], optional + :param is_in_person: Used in combination with an embed URL for a sender. After the +sender signs, they are redirected to the next `in_person` signer., defaults to None + :type is_in_person: Optional[bool], optional + :param order: Order of the signer, defaults to None + :type order: Optional[int], optional + :param embed_url_external_user_id: User ID for the signer in an external application responsible +for authentication when accessing the embed URL., defaults to None + :type embed_url_external_user_id: Optional[str], optional + :param redirect_url: The URL that a signer will be redirected +to after signing a document. Defining this URL +overrides default or global redirect URL +settings for a specific signer. +If no declined redirect URL is specified, +this URL will be used for decline actions as well., defaults to None + :type redirect_url: Optional[str], optional + :param declined_redirect_url: The URL that a signer will be redirect +to after declining to sign a document. +Defining this URL overrides default or global +declined redirect URL settings for a specific signer., defaults to None + :type declined_redirect_url: Optional[str], optional + :param login_required: If set to true, the signer will need to log in to a Box account +before signing the request. If the signer does not have +an existing account, they will have the option to create +a free Box account., defaults to None + :type login_required: Optional[bool], optional + :param verification_phone_number: If set, this phone number will be used to verify the signer +via two-factor authentication before they are able to sign the document. +Cannot be selected in combination with `login_required`., defaults to None + :type verification_phone_number: Optional[str], optional + :param password: If set, the signer is required to enter the password before they are able +to sign a document. This field is write only., defaults to None + :type password: Optional[str], optional + :param signer_group_id: If set, signers who have the same value will be assigned to the same input and to the same signer group. +A signer group is not a Box Group. It is an entity that belongs to a Sign Request and can only be +used/accessed within this Sign Request. A signer group is expected to have more than one signer. +If the provided value is only used for one signer, this value will be ignored and request will be handled +as it was intended for an individual signer. The value provided can be any string and only used to +determine which signers belongs to same group. A successful response will provide a generated UUID value +instead for signers in the same signer group., defaults to None + :type signer_group_id: Optional[str], optional + :param suppress_notifications: If true, no emails about the sign request will be sent, defaults to None + :type suppress_notifications: Optional[bool], optional + """ + super().__init__(email=email, role=role, is_in_person=is_in_person, order=order, embed_url_external_user_id=embed_url_external_user_id, redirect_url=redirect_url, declined_redirect_url=declined_redirect_url, login_required=login_required, verification_phone_number=verification_phone_number, password=password, signer_group_id=signer_group_id, suppress_notifications=suppress_notifications, **kwargs) + self.has_viewed_document = has_viewed_document + self.signer_decision = signer_decision + self.inputs = inputs + self.embed_url = embed_url + self.iframeable_embed_url = iframeable_embed_url \ No newline at end of file diff --git a/box_sdk_gen/schemas/sign_request_signer_input.py b/box_sdk_gen/schemas/sign_request_signer_input.py new file mode 100644 index 000000000..76d664829 --- /dev/null +++ b/box_sdk_gen/schemas/sign_request_signer_input.py @@ -0,0 +1,60 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.utils import Date + +from box_sdk_gen.schemas.sign_request_prefill_tag import SignRequestPrefillTag + +from box_sdk_gen.box.errors import BoxSDKError + +class SignRequestSignerInputTypeField(str, Enum): + SIGNATURE = 'signature' + DATE = 'date' + TEXT = 'text' + CHECKBOX = 'checkbox' + RADIO = 'radio' + DROPDOWN = 'dropdown' + +class SignRequestSignerInputContentTypeField(str, Enum): + SIGNATURE = 'signature' + INITIAL = 'initial' + STAMP = 'stamp' + DATE = 'date' + CHECKBOX = 'checkbox' + TEXT = 'text' + FULL_NAME = 'full_name' + FIRST_NAME = 'first_name' + LAST_NAME = 'last_name' + COMPANY = 'company' + TITLE = 'title' + EMAIL = 'email' + ATTACHMENT = 'attachment' + RADIO = 'radio' + DROPDOWN = 'dropdown' + +class SignRequestSignerInput(SignRequestPrefillTag): + def __init__(self, page_index: int, *, type: Optional[SignRequestSignerInputTypeField] = None, content_type: Optional[SignRequestSignerInputContentTypeField] = None, read_only: Optional[bool] = None, document_tag_id: Optional[str] = None, text_value: Optional[str] = None, checkbox_value: Optional[bool] = None, date_value: Optional[Date] = None, **kwargs): + """ + :param page_index: Index of page that the input is on + :type page_index: int + :param type: Type of input, defaults to None + :type type: Optional[SignRequestSignerInputTypeField], optional + :param content_type: Content type of input, defaults to None + :type content_type: Optional[SignRequestSignerInputContentTypeField], optional + :param read_only: Whether this input was defined as read-only(immutable by signers) or not, defaults to None + :type read_only: Optional[bool], optional + :param document_tag_id: This references the ID of a specific tag contained in a file of the signature request., defaults to None + :type document_tag_id: Optional[str], optional + :param text_value: Text prefill value, defaults to None + :type text_value: Optional[str], optional + :param checkbox_value: Checkbox prefill value, defaults to None + :type checkbox_value: Optional[bool], optional + :param date_value: Date prefill value, defaults to None + :type date_value: Optional[Date], optional + """ + super().__init__(document_tag_id=document_tag_id, text_value=text_value, checkbox_value=checkbox_value, date_value=date_value, **kwargs) + self.page_index = page_index + self.type = type + self.content_type = content_type + self.read_only = read_only \ No newline at end of file diff --git a/box_sdk_gen/schemas/sign_requests.py b/box_sdk_gen/schemas/sign_requests.py new file mode 100644 index 000000000..2901e0e76 --- /dev/null +++ b/box_sdk_gen/schemas/sign_requests.py @@ -0,0 +1,26 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.sign_request import SignRequest + +from box_sdk_gen.box.errors import BoxSDKError + +class SignRequests(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, entries: Optional[List[SignRequest]] = 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 entries: A list of Box Sign requests., defaults to None + :type entries: Optional[List[SignRequest]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/sign_template.py b/box_sdk_gen/schemas/sign_template.py new file mode 100644 index 000000000..bc7a8ccc1 --- /dev/null +++ b/box_sdk_gen/schemas/sign_template.py @@ -0,0 +1,160 @@ +from enum import Enum + +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.folder_mini import FolderMini + +from box_sdk_gen.schemas.file_mini import FileMini + +from box_sdk_gen.schemas.template_signer import TemplateSigner + +from box_sdk_gen.box.errors import BoxSDKError + +class SignTemplateTypeField(str, Enum): + SIGN_TEMPLATE = 'sign-template' + +class SignTemplateAdditionalInfoNonEditableField(str, Enum): + EMAIL_SUBJECT = 'email_subject' + EMAIL_MESSAGE = 'email_message' + NAME = 'name' + DAYS_VALID = 'days_valid' + SIGNERS = 'signers' + SOURCE_FILES = 'source_files' + +class SignTemplateAdditionalInfoRequiredSignersField(str, Enum): + EMAIL = 'email' + +class SignTemplateAdditionalInfoRequiredField(BaseObject): + def __init__(self, *, signers: Optional[List[List[SignTemplateAdditionalInfoRequiredSignersField]]] = None, **kwargs): + """ + :param signers: Required signer fields., defaults to None + :type signers: Optional[List[List[SignTemplateAdditionalInfoRequiredSignersField]]], optional + """ + super().__init__(**kwargs) + self.signers = signers + +class SignTemplateAdditionalInfoField(BaseObject): + def __init__(self, *, non_editable: Optional[List[SignTemplateAdditionalInfoNonEditableField]] = None, required: Optional[SignTemplateAdditionalInfoRequiredField] = None, **kwargs): + """ + :param non_editable: Non editable fields., defaults to None + :type non_editable: Optional[List[SignTemplateAdditionalInfoNonEditableField]], optional + :param required: Required fields., defaults to None + :type required: Optional[SignTemplateAdditionalInfoRequiredField], optional + """ + super().__init__(**kwargs) + self.non_editable = non_editable + self.required = required + +class SignTemplateReadySignLinkField(BaseObject): + def __init__(self, *, url: Optional[str] = None, name: Optional[str] = None, instructions: Optional[str] = None, folder_id: Optional[str] = None, is_notification_disabled: Optional[bool] = None, is_active: Optional[bool] = None, **kwargs): + """ + :param url: The URL that can be sent to signers., defaults to None + :type url: Optional[str], optional + :param name: Request name., defaults to None + :type name: Optional[str], optional + :param instructions: Extra instructions for all signers., defaults to None + :type instructions: Optional[str], optional + :param folder_id: The destination folder to place final, +signed document and signing +log. Only `ID` and `type` fields are required. +The root folder, +folder ID `0`, cannot be used., defaults to None + :type folder_id: Optional[str], optional + :param is_notification_disabled: Whether to disable notifications when +a signer has signed., defaults to None + :type is_notification_disabled: Optional[bool], optional + :param is_active: Whether the ready sign link is enabled or not., defaults to None + :type is_active: Optional[bool], optional + """ + super().__init__(**kwargs) + self.url = url + self.name = name + self.instructions = instructions + self.folder_id = folder_id + self.is_notification_disabled = is_notification_disabled + self.is_active = is_active + +class SignTemplateCustomBrandingField(BaseObject): + def __init__(self, *, company_name: Optional[str] = None, logo_uri: Optional[str] = None, branding_color: Optional[str] = None, email_footer_text: Optional[str] = None, **kwargs): + """ + :param company_name: Name of the company, defaults to None + :type company_name: Optional[str], optional + :param logo_uri: Custom branding logo URI in the form of a base64 image., defaults to None + :type logo_uri: Optional[str], optional + :param branding_color: Custom branding color in hex., defaults to None + :type branding_color: Optional[str], optional + :param email_footer_text: Content of the email footer., defaults to None + :type email_footer_text: Optional[str], optional + """ + super().__init__(**kwargs) + self.company_name = company_name + self.logo_uri = logo_uri + self.branding_color = branding_color + self.email_footer_text = email_footer_text + +class SignTemplate(BaseObject): + _discriminator = 'type', {'sign-template'} + def __init__(self, *, type: Optional[SignTemplateTypeField] = None, id: Optional[str] = None, name: Optional[str] = None, email_subject: Optional[str] = None, email_message: Optional[str] = None, days_valid: Optional[int] = None, parent_folder: Optional[FolderMini] = None, source_files: Optional[List[FileMini]] = None, are_fields_locked: Optional[bool] = None, are_options_locked: Optional[bool] = None, are_recipients_locked: Optional[bool] = None, are_email_settings_locked: Optional[bool] = None, are_files_locked: Optional[bool] = None, signers: Optional[List[TemplateSigner]] = None, additional_info: Optional[SignTemplateAdditionalInfoField] = None, ready_sign_link: Optional[SignTemplateReadySignLinkField] = None, custom_branding: Optional[SignTemplateCustomBrandingField] = None, **kwargs): + """ + :param type: object type, defaults to None + :type type: Optional[SignTemplateTypeField], optional + :param id: Template identifier., defaults to None + :type id: Optional[str], optional + :param name: The name of the template., defaults to None + :type name: Optional[str], optional + :param email_subject: Subject of signature request email. This is cleaned by sign request. If this field is not passed, a default subject will be used., defaults to None + :type email_subject: Optional[str], optional + :param email_message: Message to include in signature request email. The field is cleaned through sanitization of specific characters. However, some html tags are allowed. Links included in the message are also converted to hyperlinks in the email. The message may contain the following html tags including `a`, `abbr`, `acronym`, `b`, `blockquote`, `code`, `em`, `i`, `ul`, `li`, `ol`, and `strong`. Be aware that when the text to html ratio is too high, the email may end up in spam filters. Custom styles on these tags are not allowed. If this field is not passed, a default message will be used., defaults to None + :type email_message: Optional[str], optional + :param days_valid: Set the number of days after which the created signature request will automatically expire if not completed. By default, we do not apply any expiration date on signature requests, and the signature request does not expire., defaults to None + :type days_valid: Optional[int], optional + :param source_files: List of files to create a signing document from. Only the ID and type fields are required for each file., defaults to None + :type source_files: Optional[List[FileMini]], optional + :param are_fields_locked: Indicates if the template input fields are editable or not., defaults to None + :type are_fields_locked: Optional[bool], optional + :param are_options_locked: Indicates if the template document options are editable or not, for example renaming the document., defaults to None + :type are_options_locked: Optional[bool], optional + :param are_recipients_locked: Indicates if the template signers are editable or not., defaults to None + :type are_recipients_locked: Optional[bool], optional + :param are_email_settings_locked: Indicates if the template email settings are editable or not., defaults to None + :type are_email_settings_locked: Optional[bool], optional + :param are_files_locked: Indicates if the template files are editable or not. This includes deleting or renaming template files., defaults to None + :type are_files_locked: Optional[bool], optional + :param signers: Array of signers for the template. + +**Note**: It may happen that some signers specified in the template belong to conflicting [segments](r://shield-information-barrier-segment-member) (user groups). +This means that due to the security policies, users are assigned to segments to prevent exchanges or communication that could lead to ethical conflicts. +In such a case, an attempt to send a sign request based on a template that lists signers in conflicting segments will result in an error. + +Read more about [segments and ethical walls](https://support.box.com/hc/en-us/articles/9920431507603-Understanding-Information-Barriers#h_01GFVJEHQA06N7XEZ4GCZ9GFAQ)., defaults to None + :type signers: Optional[List[TemplateSigner]], optional + :param additional_info: Additional information on which fields are required and which fields are not editable., defaults to None + :type additional_info: Optional[SignTemplateAdditionalInfoField], optional + :param ready_sign_link: Box's ready-sign link feature enables you to create a link to a signature request that you've created from a template. Use this link when you want to post a signature request on a public form — such as an email, social media post, or web page — without knowing who the signers will be. Note: The ready-sign link feature is limited to Enterprise Plus customers and not available to Box Verified Enterprises., defaults to None + :type ready_sign_link: Optional[SignTemplateReadySignLinkField], optional + :param custom_branding: Custom branding applied to notifications +and signature requests., defaults to None + :type custom_branding: Optional[SignTemplateCustomBrandingField], optional + """ + super().__init__(**kwargs) + self.type = type + self.id = id + self.name = name + self.email_subject = email_subject + self.email_message = email_message + self.days_valid = days_valid + self.parent_folder = parent_folder + self.source_files = source_files + self.are_fields_locked = are_fields_locked + self.are_options_locked = are_options_locked + self.are_recipients_locked = are_recipients_locked + self.are_email_settings_locked = are_email_settings_locked + self.are_files_locked = are_files_locked + self.signers = signers + self.additional_info = additional_info + self.ready_sign_link = ready_sign_link + self.custom_branding = custom_branding \ No newline at end of file diff --git a/box_sdk_gen/schemas/sign_templates.py b/box_sdk_gen/schemas/sign_templates.py new file mode 100644 index 000000000..847d30d72 --- /dev/null +++ b/box_sdk_gen/schemas/sign_templates.py @@ -0,0 +1,29 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.sign_template import SignTemplate + +from box_sdk_gen.box.errors import BoxSDKError + +class SignTemplates(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, prev_marker: Optional[str] = None, entries: Optional[List[SignTemplate]] = 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 + :param entries: A list of templates., defaults to None + :type entries: Optional[List[SignTemplate]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.prev_marker = prev_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/skill_cards_metadata.py b/box_sdk_gen/schemas/skill_cards_metadata.py new file mode 100644 index 000000000..e047e3a7b --- /dev/null +++ b/box_sdk_gen/schemas/skill_cards_metadata.py @@ -0,0 +1,58 @@ +from typing import Optional + +from typing import List + +from typing import Union + +from typing import Dict + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.keyword_skill_card import KeywordSkillCard + +from box_sdk_gen.schemas.timeline_skill_card import TimelineSkillCard + +from box_sdk_gen.schemas.transcript_skill_card import TranscriptSkillCard + +from box_sdk_gen.schemas.status_skill_card import StatusSkillCard + +from box_sdk_gen.box.errors import BoxSDKError + +class SkillCardsMetadata(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'can_edit': '$canEdit', 'id': '$id', 'parent': '$parent', 'scope': '$scope', 'template': '$template', 'type': '$type', 'type_version': '$typeVersion', 'version': '$version', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'$canEdit': 'can_edit', '$id': 'id', '$parent': 'parent', '$scope': 'scope', '$template': 'template', '$type': 'type', '$typeVersion': 'type_version', '$version': 'version', **BaseObject._json_to_fields_mapping} + def __init__(self, *, can_edit: Optional[bool] = None, id: Optional[str] = None, parent: Optional[str] = None, scope: Optional[str] = None, template: Optional[str] = None, type: Optional[str] = None, type_version: Optional[int] = None, version: Optional[int] = None, cards: Optional[List[Union[KeywordSkillCard, TimelineSkillCard, TranscriptSkillCard, StatusSkillCard]]] = None, **kwargs): + """ + :param can_edit: Whether the user can edit this metadata, defaults to None + :type can_edit: Optional[bool], optional + :param id: A UUID to identify the metadata object, defaults to None + :type id: Optional[str], optional + :param parent: An ID for the parent folder, defaults to None + :type parent: Optional[str], optional + :param scope: An ID for the scope in which this template +has been applied, defaults to None + :type scope: Optional[str], optional + :param template: The name of the template, defaults to None + :type template: Optional[str], optional + :param type: A unique identifier for the "type" of this instance. This is an internal +system property and should not be used by a client application., defaults to None + :type type: Optional[str], optional + :param type_version: The last-known version of the template of the object. This is an internal +system property and should not be used by a client application., defaults to None + :type type_version: Optional[int], optional + :param version: The version of the metadata object. Starts at 0 and increases every time +a user-defined property is modified., defaults to None + :type version: Optional[int], optional + :param cards: A list of Box Skill cards that have been applied to this file., defaults to None + :type cards: Optional[List[Union[KeywordSkillCard, TimelineSkillCard, TranscriptSkillCard, StatusSkillCard]]], optional + """ + super().__init__(**kwargs) + self.can_edit = can_edit + self.id = id + self.parent = parent + self.scope = scope + self.template = template + self.type = type + self.type_version = type_version + self.version = version + self.cards = cards \ No newline at end of file diff --git a/box_sdk_gen/schemas/skill_invocation.py b/box_sdk_gen/schemas/skill_invocation.py new file mode 100644 index 000000000..278fdbadc --- /dev/null +++ b/box_sdk_gen/schemas/skill_invocation.py @@ -0,0 +1,182 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Union + +from box_sdk_gen.schemas.file import File + +from box_sdk_gen.schemas.folder import Folder + +from box_sdk_gen.schemas.event import Event + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class SkillInvocationTypeField(str, Enum): + SKILL_INVOCATION = 'skill_invocation' + +class SkillInvocationSkillTypeField(str, Enum): + SKILL = 'skill' + +class SkillInvocationSkillField(BaseObject): + _discriminator = 'type', {'skill'} + def __init__(self, *, id: Optional[str] = None, type: Optional[SkillInvocationSkillTypeField] = None, name: Optional[str] = None, api_key: Optional[str] = None, **kwargs): + """ + :param id: The unique identifier for this skill, defaults to None + :type id: Optional[str], optional + :param type: `skill`, defaults to None + :type type: Optional[SkillInvocationSkillTypeField], optional + :param name: The name of the skill, defaults to None + :type name: Optional[str], optional + :param api_key: The client ID of the application, defaults to None + :type api_key: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.name = name + self.api_key = api_key + +class SkillInvocationTokenReadTokenTypeField(str, Enum): + BEARER = 'bearer' + +class SkillInvocationTokenReadField(BaseObject): + def __init__(self, *, access_token: Optional[str] = None, expires_in: Optional[int] = None, token_type: Optional[SkillInvocationTokenReadTokenTypeField] = None, restricted_to: Optional[str] = None, **kwargs): + """ + :param access_token: The requested access token., defaults to None + :type access_token: Optional[str], optional + :param expires_in: The time in seconds by which this token will expire., defaults to None + :type expires_in: Optional[int], optional + :param token_type: The type of access token returned., defaults to None + :type token_type: Optional[SkillInvocationTokenReadTokenTypeField], optional + :param restricted_to: The permissions that this access token permits, +providing a list of resources (files, folders, etc) +and the scopes permitted for each of those resources., defaults to None + :type restricted_to: Optional[str], optional + """ + super().__init__(**kwargs) + self.access_token = access_token + self.expires_in = expires_in + self.token_type = token_type + self.restricted_to = restricted_to + +class SkillInvocationTokenWriteTokenTypeField(str, Enum): + BEARER = 'bearer' + +class SkillInvocationTokenWriteField(BaseObject): + def __init__(self, *, access_token: Optional[str] = None, expires_in: Optional[int] = None, token_type: Optional[SkillInvocationTokenWriteTokenTypeField] = None, restricted_to: Optional[str] = None, **kwargs): + """ + :param access_token: The requested access token., defaults to None + :type access_token: Optional[str], optional + :param expires_in: The time in seconds by which this token will expire., defaults to None + :type expires_in: Optional[int], optional + :param token_type: The type of access token returned., defaults to None + :type token_type: Optional[SkillInvocationTokenWriteTokenTypeField], optional + :param restricted_to: The permissions that this access token permits, +providing a list of resources (files, folders, etc) +and the scopes permitted for each of those resources., defaults to None + :type restricted_to: Optional[str], optional + """ + super().__init__(**kwargs) + self.access_token = access_token + self.expires_in = expires_in + self.token_type = token_type + self.restricted_to = restricted_to + +class SkillInvocationTokenField(BaseObject): + def __init__(self, *, read: Optional[SkillInvocationTokenReadField] = None, write: Optional[SkillInvocationTokenWriteField] = None, **kwargs): + """ + :param read: The basics of an access token, defaults to None + :type read: Optional[SkillInvocationTokenReadField], optional + :param write: The basics of an access token, defaults to None + :type write: Optional[SkillInvocationTokenWriteField], optional + """ + super().__init__(**kwargs) + self.read = read + self.write = write + +class SkillInvocationStatusStateField(str, Enum): + INVOKED = 'invoked' + PROCESSING = 'processing' + SUCCESS = 'success' + TRANSIENT_FAILURE = 'transient_failure' + PERMANENT_FAILURE = 'permanent_failure' + +class SkillInvocationStatusField(BaseObject): + def __init__(self, *, state: Optional[SkillInvocationStatusStateField] = None, message: Optional[str] = None, error_code: Optional[str] = None, additional_info: Optional[str] = None, **kwargs): + """ + :param state: The state of this event. + +* `invoked` - Triggered the skill with event details to start + applying skill on the file. +* `processing` - Currently processing. +* `success` - Completed processing with a success. +* `transient_failure` - Encountered an issue which can be + retried. +* `permanent_failure` - Encountered a permanent issue and + retry would not help., defaults to None + :type state: Optional[SkillInvocationStatusStateField], optional + :param message: Status information, defaults to None + :type message: Optional[str], optional + :param error_code: Error code information, if error occurred., defaults to None + :type error_code: Optional[str], optional + :param additional_info: Additional status information., defaults to None + :type additional_info: Optional[str], optional + """ + super().__init__(**kwargs) + self.state = state + self.message = message + self.error_code = error_code + self.additional_info = additional_info + +class SkillInvocationEnterpriseTypeField(str, Enum): + ENTERPRISE = 'enterprise' + +class SkillInvocationEnterpriseField(BaseObject): + _discriminator = 'type', {'enterprise'} + def __init__(self, *, id: Optional[str] = None, type: Optional[SkillInvocationEnterpriseTypeField] = None, name: Optional[str] = None, **kwargs): + """ + :param id: The unique identifier for this enterprise., defaults to None + :type id: Optional[str], optional + :param type: `enterprise`, defaults to None + :type type: Optional[SkillInvocationEnterpriseTypeField], optional + :param name: The name of the enterprise, defaults to None + :type name: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.name = name + +class SkillInvocation(BaseObject): + _discriminator = 'type', {'skill_invocation'} + def __init__(self, *, type: Optional[SkillInvocationTypeField] = None, id: Optional[str] = None, skill: Optional[SkillInvocationSkillField] = None, token: Optional[SkillInvocationTokenField] = None, status: Optional[SkillInvocationStatusField] = None, created_at: Optional[DateTime] = None, trigger: Optional[str] = None, enterprise: Optional[SkillInvocationEnterpriseField] = None, source: Optional[Union[File, Folder]] = None, event: Optional[Event] = None, **kwargs): + """ + :param type: `skill_invocation`, defaults to None + :type type: Optional[SkillInvocationTypeField], optional + :param id: Unique identifier for the invocation request., defaults to None + :type id: Optional[str], optional + :param token: The read-only and read-write access tokens for this item, defaults to None + :type token: Optional[SkillInvocationTokenField], optional + :param status: The details status of this event., defaults to None + :type status: Optional[SkillInvocationStatusField], optional + :param created_at: The time this invocation was created., defaults to None + :type created_at: Optional[DateTime], optional + :param trigger: Action that triggered the invocation, defaults to None + :type trigger: Optional[str], optional + """ + super().__init__(**kwargs) + self.type = type + self.id = id + self.skill = skill + self.token = token + self.status = status + self.created_at = created_at + self.trigger = trigger + self.enterprise = enterprise + self.source = source + self.event = event \ No newline at end of file diff --git a/box_sdk_gen/schemas/status_skill_card.py b/box_sdk_gen/schemas/status_skill_card.py new file mode 100644 index 000000000..e933287aa --- /dev/null +++ b/box_sdk_gen/schemas/status_skill_card.py @@ -0,0 +1,116 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class StatusSkillCardTypeField(str, Enum): + SKILL_CARD = 'skill_card' + +class StatusSkillCardSkillCardTypeField(str, Enum): + STATUS = 'status' + +class StatusSkillCardSkillCardTitleField(BaseObject): + def __init__(self, message: str, *, code: Optional[str] = None, **kwargs): + """ + :param message: The actual title to show in the UI. + :type message: str + :param code: An optional identifier for the title., defaults to None + :type code: Optional[str], optional + """ + super().__init__(**kwargs) + self.message = message + self.code = code + +class StatusSkillCardStatusCodeField(str, Enum): + INVOKED = 'invoked' + PROCESSING = 'processing' + SUCCESS = 'success' + TRANSIENT_FAILURE = 'transient_failure' + PERMANENT_FAILURE = 'permanent_failure' + +class StatusSkillCardStatusField(BaseObject): + def __init__(self, code: StatusSkillCardStatusCodeField, *, message: Optional[str] = None, **kwargs): + """ + :param code: A code for the status of this Skill invocation. By +default each of these will have their own accompanied +messages. These can be adjusted by setting the `message` +value on this object. + :type code: StatusSkillCardStatusCodeField + :param message: A custom message that can be provided with this status. +This will be shown in the web app to the end user., defaults to None + :type message: Optional[str], optional + """ + super().__init__(**kwargs) + self.code = code + self.message = message + +class StatusSkillCardSkillTypeField(str, Enum): + SERVICE = 'service' + +class StatusSkillCardSkillField(BaseObject): + _discriminator = 'type', {'service'} + def __init__(self, id: str, *, type: StatusSkillCardSkillTypeField = StatusSkillCardSkillTypeField.SERVICE, **kwargs): + """ + :param id: A custom identifier that represent the service that +applied this metadata. + :type id: str + :param type: `service`, defaults to StatusSkillCardSkillTypeField.SERVICE + :type type: StatusSkillCardSkillTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class StatusSkillCardInvocationTypeField(str, Enum): + SKILL_INVOCATION = 'skill_invocation' + +class StatusSkillCardInvocationField(BaseObject): + _discriminator = 'type', {'skill_invocation'} + def __init__(self, id: str, *, type: StatusSkillCardInvocationTypeField = StatusSkillCardInvocationTypeField.SKILL_INVOCATION, **kwargs): + """ + :param id: A custom identifier that represent the instance of +the service that applied this metadata. For example, +if your `image-recognition-service` runs on multiple +nodes, this field can be used to identify the ID of +the node that was used to apply the metadata. + :type id: str + :param type: `skill_invocation`, defaults to StatusSkillCardInvocationTypeField.SKILL_INVOCATION + :type type: StatusSkillCardInvocationTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class StatusSkillCard(BaseObject): + _discriminator = 'skill_card_type', {'status'} + def __init__(self, status: StatusSkillCardStatusField, skill: StatusSkillCardSkillField, invocation: StatusSkillCardInvocationField, *, created_at: Optional[DateTime] = None, type: StatusSkillCardTypeField = StatusSkillCardTypeField.SKILL_CARD, skill_card_type: StatusSkillCardSkillCardTypeField = StatusSkillCardSkillCardTypeField.STATUS, skill_card_title: Optional[StatusSkillCardSkillCardTitleField] = None, **kwargs): + """ + :param status: Sets the status of the skill. This can be used to show a message to the user while the Skill is processing the data, or if it was not able to process the file. + :type status: StatusSkillCardStatusField + :param skill: The service that applied this metadata. + :type skill: StatusSkillCardSkillField + :param invocation: The invocation of this service, used to track +which instance of a service applied the metadata. + :type invocation: StatusSkillCardInvocationField + :param created_at: The optional date and time this card was created at., defaults to None + :type created_at: Optional[DateTime], optional + :param type: `skill_card`, defaults to StatusSkillCardTypeField.SKILL_CARD + :type type: StatusSkillCardTypeField, optional + :param skill_card_type: `status`, defaults to StatusSkillCardSkillCardTypeField.STATUS + :type skill_card_type: StatusSkillCardSkillCardTypeField, optional + :param skill_card_title: The title of the card., defaults to None + :type skill_card_title: Optional[StatusSkillCardSkillCardTitleField], optional + """ + super().__init__(**kwargs) + self.status = status + self.skill = skill + self.invocation = invocation + self.created_at = created_at + self.type = type + self.skill_card_type = skill_card_type + self.skill_card_title = skill_card_title \ No newline at end of file diff --git a/box_sdk_gen/schemas/storage_policies.py b/box_sdk_gen/schemas/storage_policies.py new file mode 100644 index 000000000..ef45378d5 --- /dev/null +++ b/box_sdk_gen/schemas/storage_policies.py @@ -0,0 +1,29 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.storage_policy import StoragePolicy + +from box_sdk_gen.box.errors import BoxSDKError + +class StoragePolicies(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, prev_marker: Optional[str] = None, entries: Optional[List[StoragePolicy]] = 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 + :param entries: A list of storage policies, defaults to None + :type entries: Optional[List[StoragePolicy]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.prev_marker = prev_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/storage_policy.py b/box_sdk_gen/schemas/storage_policy.py new file mode 100644 index 000000000..dfbc6dce5 --- /dev/null +++ b/box_sdk_gen/schemas/storage_policy.py @@ -0,0 +1,20 @@ +from typing import Optional + +from box_sdk_gen.schemas.storage_policy_mini import StoragePolicyMiniTypeField + +from box_sdk_gen.schemas.storage_policy_mini import StoragePolicyMini + +from box_sdk_gen.box.errors import BoxSDKError + +class StoragePolicy(StoragePolicyMini): + def __init__(self, id: str, *, name: Optional[str] = None, type: StoragePolicyMiniTypeField = StoragePolicyMiniTypeField.STORAGE_POLICY, **kwargs): + """ + :param id: The unique identifier for this storage policy + :type id: str + :param name: A descriptive name of the region, defaults to None + :type name: Optional[str], optional + :param type: `storage_policy`, defaults to StoragePolicyMiniTypeField.STORAGE_POLICY + :type type: StoragePolicyMiniTypeField, optional + """ + super().__init__(id=id, type=type, **kwargs) + self.name = name \ No newline at end of file diff --git a/box_sdk_gen/schemas/storage_policy_assignment.py b/box_sdk_gen/schemas/storage_policy_assignment.py new file mode 100644 index 000000000..e713589fb --- /dev/null +++ b/box_sdk_gen/schemas/storage_policy_assignment.py @@ -0,0 +1,39 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.storage_policy_mini import StoragePolicyMini + +from box_sdk_gen.box.errors import BoxSDKError + +class StoragePolicyAssignmentTypeField(str, Enum): + STORAGE_POLICY_ASSIGNMENT = 'storage_policy_assignment' + +class StoragePolicyAssignmentAssignedToField(BaseObject): + def __init__(self, *, id: Optional[str] = None, type: Optional[str] = None, **kwargs): + """ + :param id: The unique identifier for this object, defaults to None + :type id: Optional[str], optional + :param type: The type for this object, defaults to None + :type type: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class StoragePolicyAssignment(BaseObject): + _discriminator = 'type', {'storage_policy_assignment'} + def __init__(self, id: str, *, type: StoragePolicyAssignmentTypeField = StoragePolicyAssignmentTypeField.STORAGE_POLICY_ASSIGNMENT, storage_policy: Optional[StoragePolicyMini] = None, assigned_to: Optional[StoragePolicyAssignmentAssignedToField] = None, **kwargs): + """ + :param id: The unique identifier for a storage policy assignment. + :type id: str + :param type: `storage_policy_assignment`, defaults to StoragePolicyAssignmentTypeField.STORAGE_POLICY_ASSIGNMENT + :type type: StoragePolicyAssignmentTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.storage_policy = storage_policy + self.assigned_to = assigned_to \ No newline at end of file diff --git a/box_sdk_gen/schemas/storage_policy_assignments.py b/box_sdk_gen/schemas/storage_policy_assignments.py new file mode 100644 index 000000000..60c432d1d --- /dev/null +++ b/box_sdk_gen/schemas/storage_policy_assignments.py @@ -0,0 +1,29 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.storage_policy_assignment import StoragePolicyAssignment + +from box_sdk_gen.box.errors import BoxSDKError + +class StoragePolicyAssignments(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, prev_marker: Optional[str] = None, entries: Optional[List[StoragePolicyAssignment]] = 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 + :param entries: A list of storage policy assignments, defaults to None + :type entries: Optional[List[StoragePolicyAssignment]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.prev_marker = prev_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/storage_policy_mini.py b/box_sdk_gen/schemas/storage_policy_mini.py new file mode 100644 index 000000000..ea5de0d74 --- /dev/null +++ b/box_sdk_gen/schemas/storage_policy_mini.py @@ -0,0 +1,21 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class StoragePolicyMiniTypeField(str, Enum): + STORAGE_POLICY = 'storage_policy' + +class StoragePolicyMini(BaseObject): + _discriminator = 'type', {'storage_policy'} + def __init__(self, id: str, *, type: StoragePolicyMiniTypeField = StoragePolicyMiniTypeField.STORAGE_POLICY, **kwargs): + """ + :param id: The unique identifier for this storage policy + :type id: str + :param type: `storage_policy`, defaults to StoragePolicyMiniTypeField.STORAGE_POLICY + :type type: StoragePolicyMiniTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type \ No newline at end of file diff --git a/box_sdk_gen/schemas/task.py b/box_sdk_gen/schemas/task.py new file mode 100644 index 000000000..aebf8f337 --- /dev/null +++ b/box_sdk_gen/schemas/task.py @@ -0,0 +1,67 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.file_mini import FileMini + +from box_sdk_gen.schemas.task_assignments import TaskAssignments + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class TaskTypeField(str, Enum): + TASK = 'task' + +class TaskActionField(str, Enum): + REVIEW = 'review' + COMPLETE = 'complete' + +class TaskCompletionRuleField(str, Enum): + ALL_ASSIGNEES = 'all_assignees' + ANY_ASSIGNEE = 'any_assignee' + +class Task(BaseObject): + _discriminator = 'type', {'task'} + def __init__(self, *, id: Optional[str] = None, type: Optional[TaskTypeField] = None, item: Optional[FileMini] = None, due_at: Optional[DateTime] = None, action: Optional[TaskActionField] = None, message: Optional[str] = None, task_assignment_collection: Optional[TaskAssignments] = None, is_completed: Optional[bool] = None, created_by: Optional[UserMini] = None, created_at: Optional[DateTime] = None, completion_rule: Optional[TaskCompletionRuleField] = None, **kwargs): + """ + :param id: The unique identifier for this task, defaults to None + :type id: Optional[str], optional + :param type: `task`, defaults to None + :type type: Optional[TaskTypeField], optional + :param due_at: When the task is due, defaults to None + :type due_at: Optional[DateTime], optional + :param action: The type of task the task assignee will be prompted to +perform., defaults to None + :type action: Optional[TaskActionField], optional + :param message: A message that will be included with the task, defaults to None + :type message: Optional[str], optional + :param is_completed: Whether the task has been completed, defaults to None + :type is_completed: Optional[bool], optional + :param created_at: When the task object was created, defaults to None + :type created_at: Optional[DateTime], optional + :param completion_rule: Defines which assignees need to complete this task before the task +is considered completed. + +* `all_assignees` requires all assignees to review or +approve the the task in order for it to be considered completed. +* `any_assignee` accepts any one assignee to review or +approve the the task in order for it to be considered completed., defaults to None + :type completion_rule: Optional[TaskCompletionRuleField], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.item = item + self.due_at = due_at + self.action = action + self.message = message + self.task_assignment_collection = task_assignment_collection + self.is_completed = is_completed + self.created_by = created_by + self.created_at = created_at + self.completion_rule = completion_rule \ No newline at end of file diff --git a/box_sdk_gen/schemas/task_assignment.py b/box_sdk_gen/schemas/task_assignment.py new file mode 100644 index 000000000..6aa64e163 --- /dev/null +++ b/box_sdk_gen/schemas/task_assignment.py @@ -0,0 +1,58 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.file_mini import FileMini + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class TaskAssignmentTypeField(str, Enum): + TASK_ASSIGNMENT = 'task_assignment' + +class TaskAssignmentResolutionStateField(str, Enum): + COMPLETED = 'completed' + INCOMPLETE = 'incomplete' + APPROVED = 'approved' + REJECTED = 'rejected' + +class TaskAssignment(BaseObject): + _discriminator = 'type', {'task_assignment'} + def __init__(self, *, id: Optional[str] = None, type: Optional[TaskAssignmentTypeField] = None, item: Optional[FileMini] = None, assigned_to: Optional[UserMini] = None, message: Optional[str] = None, completed_at: Optional[DateTime] = None, assigned_at: Optional[DateTime] = None, reminded_at: Optional[DateTime] = None, resolution_state: Optional[TaskAssignmentResolutionStateField] = None, assigned_by: Optional[UserMini] = None, **kwargs): + """ + :param id: The unique identifier for this task assignment, defaults to None + :type id: Optional[str], optional + :param type: `task_assignment`, defaults to None + :type type: Optional[TaskAssignmentTypeField], optional + :param message: A message that will is included with the task +assignment. This is visible to the assigned user in the web and mobile +UI., defaults to None + :type message: Optional[str], optional + :param completed_at: The date at which this task assignment was +completed. This will be `null` if the task is not completed yet., defaults to None + :type completed_at: Optional[DateTime], optional + :param assigned_at: The date at which this task was assigned to the user., defaults to None + :type assigned_at: Optional[DateTime], optional + :param reminded_at: The date at which the assigned user was reminded of this task +assignment., defaults to None + :type reminded_at: Optional[DateTime], optional + :param resolution_state: The current state of the assignment. The available states depend on +the `action` value of the task object., defaults to None + :type resolution_state: Optional[TaskAssignmentResolutionStateField], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.item = item + self.assigned_to = assigned_to + self.message = message + self.completed_at = completed_at + self.assigned_at = assigned_at + self.reminded_at = reminded_at + self.resolution_state = resolution_state + self.assigned_by = assigned_by \ No newline at end of file diff --git a/box_sdk_gen/schemas/task_assignments.py b/box_sdk_gen/schemas/task_assignments.py new file mode 100644 index 000000000..029937b90 --- /dev/null +++ b/box_sdk_gen/schemas/task_assignments.py @@ -0,0 +1,21 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.task_assignment import TaskAssignment + +from box_sdk_gen.box.errors import BoxSDKError + +class TaskAssignments(BaseObject): + def __init__(self, *, total_count: Optional[int] = None, entries: Optional[List[TaskAssignment]] = None, **kwargs): + """ + :param total_count: The total number of items in this collection., defaults to None + :type total_count: Optional[int], optional + :param entries: A list of task assignments, defaults to None + :type entries: Optional[List[TaskAssignment]], optional + """ + super().__init__(**kwargs) + self.total_count = total_count + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/tasks.py b/box_sdk_gen/schemas/tasks.py new file mode 100644 index 000000000..42b106591 --- /dev/null +++ b/box_sdk_gen/schemas/tasks.py @@ -0,0 +1,23 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.task import Task + +from box_sdk_gen.box.errors import BoxSDKError + +class Tasks(BaseObject): + def __init__(self, *, total_count: Optional[int] = None, entries: Optional[List[Task]] = None, **kwargs): + """ + :param total_count: One greater than the offset of the last entry in the entire collection. +The total number of entries in the collection may be less than +`total_count`., defaults to None + :type total_count: Optional[int], optional + :param entries: A list of tasks, defaults to None + :type entries: Optional[List[Task]], optional + """ + super().__init__(**kwargs) + self.total_count = total_count + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/template_signer.py b/box_sdk_gen/schemas/template_signer.py new file mode 100644 index 000000000..37b9f16ec --- /dev/null +++ b/box_sdk_gen/schemas/template_signer.py @@ -0,0 +1,63 @@ +from enum import Enum + +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.template_signer_input import TemplateSignerInput + +from box_sdk_gen.box.errors import BoxSDKError + +class TemplateSignerRoleField(str, Enum): + SIGNER = 'signer' + APPROVER = 'approver' + FINAL_COPY_READER = 'final_copy_reader' + +class TemplateSigner(BaseObject): + def __init__(self, *, inputs: Optional[List[TemplateSignerInput]] = None, email: Optional[str] = None, role: Optional[TemplateSignerRoleField] = None, is_in_person: Optional[bool] = None, order: Optional[int] = None, signer_group_id: Optional[str] = None, label: Optional[str] = None, public_id: Optional[str] = None, is_password_required: Optional[bool] = None, is_phone_number_required: Optional[bool] = None, login_required: Optional[bool] = None, **kwargs): + """ + :param email: Email address of the signer, defaults to None + :type email: Optional[str], optional + :param role: Defines the role of the signer in the signature request. A role of +`signer` needs to sign the document, a role `approver` +approves the document and +a `final_copy_reader` role only +receives the final signed document and signing log., defaults to None + :type role: Optional[TemplateSignerRoleField], optional + :param is_in_person: Used in combination with an embed URL for a sender. +After the sender signs, they will be +redirected to the next `in_person` signer., defaults to None + :type is_in_person: Optional[bool], optional + :param order: Order of the signer, defaults to None + :type order: Optional[int], optional + :param signer_group_id: If provided, this value points signers that are assigned the same inputs and belongs to same signer group. +A signer group is not a Box Group. It is an entity that belongs to the template itself and can only be used +within Box Sign requests created from it., defaults to None + :type signer_group_id: Optional[str], optional + :param label: A placeholder label for the signer set by the template creator to differentiate between signers., defaults to None + :type label: Optional[str], optional + :param public_id: An identifier for the signer. This can be used to identify a signer within the template., defaults to None + :type public_id: Optional[str], optional + :param is_password_required: If true for signers with a defined email, the password provided when the template was created is used by default. +If true for signers without a specified / defined email, the creator needs to provide a password when using the template., defaults to None + :type is_password_required: Optional[bool], optional + :param is_phone_number_required: If true for signers with a defined email, the phone number provided when the template was created is used by default. +If true for signers without a specified / defined email, the template creator needs to provide a phone number when creating a request., defaults to None + :type is_phone_number_required: Optional[bool], optional + :param login_required: If true, the signer is required to login to access the document., defaults to None + :type login_required: Optional[bool], optional + """ + super().__init__(**kwargs) + self.inputs = inputs + self.email = email + self.role = role + self.is_in_person = is_in_person + self.order = order + self.signer_group_id = signer_group_id + self.label = label + self.public_id = public_id + self.is_password_required = is_password_required + self.is_phone_number_required = is_phone_number_required + self.login_required = login_required \ No newline at end of file diff --git a/box_sdk_gen/schemas/template_signer_input.py b/box_sdk_gen/schemas/template_signer_input.py new file mode 100644 index 000000000..355fe759f --- /dev/null +++ b/box_sdk_gen/schemas/template_signer_input.py @@ -0,0 +1,110 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from box_sdk_gen.internal.utils import Date + +from box_sdk_gen.schemas.sign_request_prefill_tag import SignRequestPrefillTag + +from box_sdk_gen.box.errors import BoxSDKError + +class TemplateSignerInputTypeField(str, Enum): + SIGNATURE = 'signature' + DATE = 'date' + TEXT = 'text' + CHECKBOX = 'checkbox' + ATTACHMENT = 'attachment' + RADIO = 'radio' + DROPDOWN = 'dropdown' + +class TemplateSignerInputContentTypeField(str, Enum): + SIGNATURE = 'signature' + INITIAL = 'initial' + STAMP = 'stamp' + DATE = 'date' + CHECKBOX = 'checkbox' + TEXT = 'text' + FULL_NAME = 'full_name' + FIRST_NAME = 'first_name' + LAST_NAME = 'last_name' + COMPANY = 'company' + TITLE = 'title' + EMAIL = 'email' + ATTACHMENT = 'attachment' + RADIO = 'radio' + DROPDOWN = 'dropdown' + +class TemplateSignerInputCoordinatesField(BaseObject): + def __init__(self, *, x: Optional[float] = None, y: Optional[float] = None, **kwargs): + """ + :param x: Relative x coordinate to the page the input is on, ranging from 0 to 1., defaults to None + :type x: Optional[float], optional + :param y: Relative y coordinate to the page the input is on, ranging from 0 to 1., defaults to None + :type y: Optional[float], optional + """ + super().__init__(**kwargs) + self.x = x + self.y = y + +class TemplateSignerInputDimensionsField(BaseObject): + def __init__(self, *, width: Optional[float] = None, height: Optional[float] = None, **kwargs): + """ + :param width: Relative width to the page the input is on, ranging from 0 to 1., defaults to None + :type width: Optional[float], optional + :param height: Relative height to the page the input is on, ranging from 0 to 1., defaults to None + :type height: Optional[float], optional + """ + super().__init__(**kwargs) + self.width = width + self.height = height + +class TemplateSignerInput(SignRequestPrefillTag): + def __init__(self, page_index: int, *, type: Optional[TemplateSignerInputTypeField] = None, content_type: Optional[TemplateSignerInputContentTypeField] = None, is_required: Optional[bool] = None, document_id: Optional[str] = None, dropdown_choices: Optional[List[str]] = None, group_id: Optional[str] = None, coordinates: Optional[TemplateSignerInputCoordinatesField] = None, dimensions: Optional[TemplateSignerInputDimensionsField] = None, label: Optional[str] = None, read_only: Optional[bool] = None, document_tag_id: Optional[str] = None, text_value: Optional[str] = None, checkbox_value: Optional[bool] = None, date_value: Optional[Date] = None, **kwargs): + """ + :param page_index: Index of page that the input is on. + :type page_index: int + :param type: Type of input, defaults to None + :type type: Optional[TemplateSignerInputTypeField], optional + :param content_type: Content type of input, defaults to None + :type content_type: Optional[TemplateSignerInputContentTypeField], optional + :param is_required: Whether or not the input is required., defaults to None + :type is_required: Optional[bool], optional + :param document_id: Document identifier., defaults to None + :type document_id: Optional[str], optional + :param dropdown_choices: When the input is of the type `dropdown` this values will be filled with all the dropdown options., defaults to None + :type dropdown_choices: Optional[List[str]], optional + :param group_id: When the input is of type `radio` they can be grouped to gather with this identifier., defaults to None + :type group_id: Optional[str], optional + :param coordinates: Where the input is located on a page., defaults to None + :type coordinates: Optional[TemplateSignerInputCoordinatesField], optional + :param dimensions: The size of the input., defaults to None + :type dimensions: Optional[TemplateSignerInputDimensionsField], optional + :param label: The label field is used especially for text, attachment, radio, and checkbox type inputs., defaults to None + :type label: Optional[str], optional + :param read_only: Whether this input was defined as read-only(immutable by signers) or not, defaults to None + :type read_only: Optional[bool], optional + :param document_tag_id: This references the ID of a specific tag contained in a file of the signature request., defaults to None + :type document_tag_id: Optional[str], optional + :param text_value: Text prefill value, defaults to None + :type text_value: Optional[str], optional + :param checkbox_value: Checkbox prefill value, defaults to None + :type checkbox_value: Optional[bool], optional + :param date_value: Date prefill value, defaults to None + :type date_value: Optional[Date], optional + """ + super().__init__(document_tag_id=document_tag_id, text_value=text_value, checkbox_value=checkbox_value, date_value=date_value, **kwargs) + self.page_index = page_index + self.type = type + self.content_type = content_type + self.is_required = is_required + self.document_id = document_id + self.dropdown_choices = dropdown_choices + self.group_id = group_id + self.coordinates = coordinates + self.dimensions = dimensions + self.label = label + self.read_only = read_only \ No newline at end of file diff --git a/box_sdk_gen/schemas/terms_of_service.py b/box_sdk_gen/schemas/terms_of_service.py new file mode 100644 index 000000000..171d19b3f --- /dev/null +++ b/box_sdk_gen/schemas/terms_of_service.py @@ -0,0 +1,67 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.terms_of_service_base import TermsOfServiceBaseTypeField + +from box_sdk_gen.schemas.terms_of_service_base import TermsOfServiceBase + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class TermsOfServiceStatusField(str, Enum): + ENABLED = 'enabled' + DISABLED = 'disabled' + +class TermsOfServiceEnterpriseTypeField(str, Enum): + ENTERPRISE = 'enterprise' + +class TermsOfServiceEnterpriseField(BaseObject): + _discriminator = 'type', {'enterprise'} + def __init__(self, *, id: Optional[str] = None, type: Optional[TermsOfServiceEnterpriseTypeField] = None, name: Optional[str] = None, **kwargs): + """ + :param id: The unique identifier for this enterprise., defaults to None + :type id: Optional[str], optional + :param type: `enterprise`, defaults to None + :type type: Optional[TermsOfServiceEnterpriseTypeField], optional + :param name: The name of the enterprise, defaults to None + :type name: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.name = name + +class TermsOfServiceTosTypeField(str, Enum): + MANAGED = 'managed' + EXTERNAL = 'external' + +class TermsOfService(TermsOfServiceBase): + def __init__(self, id: str, *, status: Optional[TermsOfServiceStatusField] = None, enterprise: Optional[TermsOfServiceEnterpriseField] = None, tos_type: Optional[TermsOfServiceTosTypeField] = None, text: Optional[str] = None, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, type: TermsOfServiceBaseTypeField = TermsOfServiceBaseTypeField.TERMS_OF_SERVICE, **kwargs): + """ + :param id: The unique identifier for this terms of service. + :type id: str + :param status: Whether these terms are enabled or not, defaults to None + :type status: Optional[TermsOfServiceStatusField], optional + :param tos_type: Whether to apply these terms to managed users or external users, defaults to None + :type tos_type: Optional[TermsOfServiceTosTypeField], optional + :param text: The text for your terms and conditions. This text could be +empty if the `status` is set to `disabled`., defaults to None + :type text: Optional[str], optional + :param created_at: When the legal item was created, defaults to None + :type created_at: Optional[DateTime], optional + :param modified_at: When the legal item was modified., defaults to None + :type modified_at: Optional[DateTime], optional + :param type: `terms_of_service`, defaults to TermsOfServiceBaseTypeField.TERMS_OF_SERVICE + :type type: TermsOfServiceBaseTypeField, optional + """ + super().__init__(id=id, type=type, **kwargs) + self.status = status + self.enterprise = enterprise + self.tos_type = tos_type + self.text = text + self.created_at = created_at + self.modified_at = modified_at \ No newline at end of file diff --git a/box_sdk_gen/schemas/terms_of_service_base.py b/box_sdk_gen/schemas/terms_of_service_base.py new file mode 100644 index 000000000..f8b0bda52 --- /dev/null +++ b/box_sdk_gen/schemas/terms_of_service_base.py @@ -0,0 +1,21 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class TermsOfServiceBaseTypeField(str, Enum): + TERMS_OF_SERVICE = 'terms_of_service' + +class TermsOfServiceBase(BaseObject): + _discriminator = 'type', {'terms_of_service'} + def __init__(self, id: str, *, type: TermsOfServiceBaseTypeField = TermsOfServiceBaseTypeField.TERMS_OF_SERVICE, **kwargs): + """ + :param id: The unique identifier for this terms of service. + :type id: str + :param type: `terms_of_service`, defaults to TermsOfServiceBaseTypeField.TERMS_OF_SERVICE + :type type: TermsOfServiceBaseTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type \ No newline at end of file diff --git a/box_sdk_gen/schemas/terms_of_service_user_status.py b/box_sdk_gen/schemas/terms_of_service_user_status.py new file mode 100644 index 000000000..244881317 --- /dev/null +++ b/box_sdk_gen/schemas/terms_of_service_user_status.py @@ -0,0 +1,40 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.terms_of_service_base import TermsOfServiceBase + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class TermsOfServiceUserStatusTypeField(str, Enum): + TERMS_OF_SERVICE_USER_STATUS = 'terms_of_service_user_status' + +class TermsOfServiceUserStatus(BaseObject): + _discriminator = 'type', {'terms_of_service_user_status'} + def __init__(self, id: str, *, type: TermsOfServiceUserStatusTypeField = TermsOfServiceUserStatusTypeField.TERMS_OF_SERVICE_USER_STATUS, tos: Optional[TermsOfServiceBase] = None, user: Optional[UserMini] = None, is_accepted: Optional[bool] = None, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, **kwargs): + """ + :param id: The unique identifier for this terms of service user status + :type id: str + :param type: `terms_of_service_user_status`, defaults to TermsOfServiceUserStatusTypeField.TERMS_OF_SERVICE_USER_STATUS + :type type: TermsOfServiceUserStatusTypeField, optional + :param is_accepted: If the user has accepted the terms of services, defaults to None + :type is_accepted: Optional[bool], optional + :param created_at: When the legal item was created, defaults to None + :type created_at: Optional[DateTime], optional + :param modified_at: When the legal item was modified., defaults to None + :type modified_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.tos = tos + self.user = user + self.is_accepted = is_accepted + self.created_at = created_at + self.modified_at = modified_at \ No newline at end of file diff --git a/box_sdk_gen/schemas/terms_of_service_user_statuses.py b/box_sdk_gen/schemas/terms_of_service_user_statuses.py new file mode 100644 index 000000000..be2d4a45e --- /dev/null +++ b/box_sdk_gen/schemas/terms_of_service_user_statuses.py @@ -0,0 +1,21 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.terms_of_service_user_status import TermsOfServiceUserStatus + +from box_sdk_gen.box.errors import BoxSDKError + +class TermsOfServiceUserStatuses(BaseObject): + def __init__(self, *, total_count: Optional[int] = None, entries: Optional[List[TermsOfServiceUserStatus]] = None, **kwargs): + """ + :param total_count: The total number of objects., defaults to None + :type total_count: Optional[int], optional + :param entries: A list of terms of service user statuses, defaults to None + :type entries: Optional[List[TermsOfServiceUserStatus]], optional + """ + super().__init__(**kwargs) + self.total_count = total_count + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/terms_of_services.py b/box_sdk_gen/schemas/terms_of_services.py new file mode 100644 index 000000000..b2376c5e0 --- /dev/null +++ b/box_sdk_gen/schemas/terms_of_services.py @@ -0,0 +1,21 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.terms_of_service import TermsOfService + +from box_sdk_gen.box.errors import BoxSDKError + +class TermsOfServices(BaseObject): + def __init__(self, *, total_count: Optional[int] = None, entries: Optional[List[TermsOfService]] = None, **kwargs): + """ + :param total_count: The total number of objects., defaults to None + :type total_count: Optional[int], optional + :param entries: A list of terms of service objects, defaults to None + :type entries: Optional[List[TermsOfService]], optional + """ + super().__init__(**kwargs) + self.total_count = total_count + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/timeline_skill_card.py b/box_sdk_gen/schemas/timeline_skill_card.py new file mode 100644 index 000000000..088b7b516 --- /dev/null +++ b/box_sdk_gen/schemas/timeline_skill_card.py @@ -0,0 +1,136 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class TimelineSkillCardTypeField(str, Enum): + SKILL_CARD = 'skill_card' + +class TimelineSkillCardSkillCardTypeField(str, Enum): + TIMELINE = 'timeline' + +class TimelineSkillCardSkillCardTitleField(BaseObject): + def __init__(self, message: str, *, code: Optional[str] = None, **kwargs): + """ + :param message: The actual title to show in the UI. + :type message: str + :param code: An optional identifier for the title., defaults to None + :type code: Optional[str], optional + """ + super().__init__(**kwargs) + self.message = message + self.code = code + +class TimelineSkillCardSkillTypeField(str, Enum): + SERVICE = 'service' + +class TimelineSkillCardSkillField(BaseObject): + _discriminator = 'type', {'service'} + def __init__(self, id: str, *, type: TimelineSkillCardSkillTypeField = TimelineSkillCardSkillTypeField.SERVICE, **kwargs): + """ + :param id: A custom identifier that represent the service that +applied this metadata. + :type id: str + :param type: `service`, defaults to TimelineSkillCardSkillTypeField.SERVICE + :type type: TimelineSkillCardSkillTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class TimelineSkillCardInvocationTypeField(str, Enum): + SKILL_INVOCATION = 'skill_invocation' + +class TimelineSkillCardInvocationField(BaseObject): + _discriminator = 'type', {'skill_invocation'} + def __init__(self, id: str, *, type: TimelineSkillCardInvocationTypeField = TimelineSkillCardInvocationTypeField.SKILL_INVOCATION, **kwargs): + """ + :param id: A custom identifier that represent the instance of +the service that applied this metadata. For example, +if your `image-recognition-service` runs on multiple +nodes, this field can be used to identify the ID of +the node that was used to apply the metadata. + :type id: str + :param type: `skill_invocation`, defaults to TimelineSkillCardInvocationTypeField.SKILL_INVOCATION + :type type: TimelineSkillCardInvocationTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class TimelineSkillCardEntriesAppearsField(BaseObject): + def __init__(self, *, start: Optional[int] = None, end: Optional[int] = None, **kwargs): + """ + :param start: The time in seconds when an +entry should start appearing on a timeline., defaults to None + :type start: Optional[int], optional + :param end: The time in seconds when an +entry should stop appearing on a timeline., defaults to None + :type end: Optional[int], optional + """ + super().__init__(**kwargs) + self.start = start + self.end = end + +class TimelineSkillCardEntriesField(BaseObject): + def __init__(self, *, text: Optional[str] = None, appears: Optional[List[TimelineSkillCardEntriesAppearsField]] = None, image_url: Optional[str] = None, **kwargs): + """ + :param text: The text of the entry. This would be the display +name for an item being placed on the timeline, for example the name +of the person who was detected in a video., defaults to None + :type text: Optional[str], optional + :param appears: Defines a list of timestamps for when this item should appear on the +timeline., defaults to None + :type appears: Optional[List[TimelineSkillCardEntriesAppearsField]], optional + :param image_url: The image to show on a for an entry that appears +on a timeline. This image URL is required for every entry. + +The image will be shown in a +list of items (for example faces), and clicking +the image will show the user where that entry +appears during the duration of this entry., defaults to None + :type image_url: Optional[str], optional + """ + super().__init__(**kwargs) + self.text = text + self.appears = appears + self.image_url = image_url + +class TimelineSkillCard(BaseObject): + _discriminator = 'skill_card_type', {'timeline'} + def __init__(self, skill: TimelineSkillCardSkillField, invocation: TimelineSkillCardInvocationField, entries: List[TimelineSkillCardEntriesField], *, created_at: Optional[DateTime] = None, type: TimelineSkillCardTypeField = TimelineSkillCardTypeField.SKILL_CARD, skill_card_type: TimelineSkillCardSkillCardTypeField = TimelineSkillCardSkillCardTypeField.TIMELINE, skill_card_title: Optional[TimelineSkillCardSkillCardTitleField] = None, duration: Optional[int] = None, **kwargs): + """ + :param skill: The service that applied this metadata. + :type skill: TimelineSkillCardSkillField + :param invocation: The invocation of this service, used to track +which instance of a service applied the metadata. + :type invocation: TimelineSkillCardInvocationField + :param entries: A list of entries on the timeline. + :type entries: List[TimelineSkillCardEntriesField] + :param created_at: The optional date and time this card was created at., defaults to None + :type created_at: Optional[DateTime], optional + :param type: `skill_card`, defaults to TimelineSkillCardTypeField.SKILL_CARD + :type type: TimelineSkillCardTypeField, optional + :param skill_card_type: `timeline`, defaults to TimelineSkillCardSkillCardTypeField.TIMELINE + :type skill_card_type: TimelineSkillCardSkillCardTypeField, optional + :param skill_card_title: The title of the card., defaults to None + :type skill_card_title: Optional[TimelineSkillCardSkillCardTitleField], optional + :param duration: An total duration in seconds of the timeline., defaults to None + :type duration: Optional[int], optional + """ + super().__init__(**kwargs) + self.skill = skill + self.invocation = invocation + self.entries = entries + self.created_at = created_at + self.type = type + self.skill_card_type = skill_card_type + self.skill_card_title = skill_card_title + self.duration = duration \ No newline at end of file diff --git a/box_sdk_gen/schemas/tracking_code.py b/box_sdk_gen/schemas/tracking_code.py new file mode 100644 index 000000000..71dc6fe41 --- /dev/null +++ b/box_sdk_gen/schemas/tracking_code.py @@ -0,0 +1,27 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class TrackingCodeTypeField(str, Enum): + TRACKING_CODE = 'tracking_code' + +class TrackingCode(BaseObject): + _discriminator = 'type', {'tracking_code'} + def __init__(self, *, type: Optional[TrackingCodeTypeField] = None, name: Optional[str] = None, value: Optional[str] = None, **kwargs): + """ + :param type: `tracking_code`, defaults to None + :type type: Optional[TrackingCodeTypeField], optional + :param name: The name of the tracking code, which must be preconfigured in +the Admin Console, defaults to None + :type name: Optional[str], optional + :param value: The value of the tracking code, defaults to None + :type value: Optional[str], optional + """ + super().__init__(**kwargs) + self.type = type + self.name = name + self.value = value \ No newline at end of file diff --git a/box_sdk_gen/schemas/transcript_skill_card.py b/box_sdk_gen/schemas/transcript_skill_card.py new file mode 100644 index 000000000..f96dc49d2 --- /dev/null +++ b/box_sdk_gen/schemas/transcript_skill_card.py @@ -0,0 +1,126 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class TranscriptSkillCardTypeField(str, Enum): + SKILL_CARD = 'skill_card' + +class TranscriptSkillCardSkillCardTypeField(str, Enum): + TRANSCRIPT = 'transcript' + +class TranscriptSkillCardSkillCardTitleField(BaseObject): + def __init__(self, message: str, *, code: Optional[str] = None, **kwargs): + """ + :param message: The actual title to show in the UI. + :type message: str + :param code: An optional identifier for the title., defaults to None + :type code: Optional[str], optional + """ + super().__init__(**kwargs) + self.message = message + self.code = code + +class TranscriptSkillCardSkillTypeField(str, Enum): + SERVICE = 'service' + +class TranscriptSkillCardSkillField(BaseObject): + _discriminator = 'type', {'service'} + def __init__(self, id: str, *, type: TranscriptSkillCardSkillTypeField = TranscriptSkillCardSkillTypeField.SERVICE, **kwargs): + """ + :param id: A custom identifier that represent the service that +applied this metadata. + :type id: str + :param type: `service`, defaults to TranscriptSkillCardSkillTypeField.SERVICE + :type type: TranscriptSkillCardSkillTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class TranscriptSkillCardInvocationTypeField(str, Enum): + SKILL_INVOCATION = 'skill_invocation' + +class TranscriptSkillCardInvocationField(BaseObject): + _discriminator = 'type', {'skill_invocation'} + def __init__(self, id: str, *, type: TranscriptSkillCardInvocationTypeField = TranscriptSkillCardInvocationTypeField.SKILL_INVOCATION, **kwargs): + """ + :param id: A custom identifier that represent the instance of +the service that applied this metadata. For example, +if your `image-recognition-service` runs on multiple +nodes, this field can be used to identify the ID of +the node that was used to apply the metadata. + :type id: str + :param type: `skill_invocation`, defaults to TranscriptSkillCardInvocationTypeField.SKILL_INVOCATION + :type type: TranscriptSkillCardInvocationTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class TranscriptSkillCardEntriesAppearsField(BaseObject): + def __init__(self, *, start: Optional[int] = None, **kwargs): + """ + :param start: The time in seconds when an +entry should start appearing on a timeline., defaults to None + :type start: Optional[int], optional + """ + super().__init__(**kwargs) + self.start = start + +class TranscriptSkillCardEntriesField(BaseObject): + def __init__(self, *, text: Optional[str] = None, appears: Optional[List[TranscriptSkillCardEntriesAppearsField]] = None, **kwargs): + """ + :param text: The text of the entry. This would be the transcribed text assigned +to the entry on the timeline., defaults to None + :type text: Optional[str], optional + :param appears: Defines when a transcribed bit of text appears. This only includes a +start time and no end time., defaults to None + :type appears: Optional[List[TranscriptSkillCardEntriesAppearsField]], optional + """ + super().__init__(**kwargs) + self.text = text + self.appears = appears + +class TranscriptSkillCard(BaseObject): + _discriminator = 'skill_card_type', {'transcript'} + def __init__(self, skill: TranscriptSkillCardSkillField, invocation: TranscriptSkillCardInvocationField, entries: List[TranscriptSkillCardEntriesField], *, created_at: Optional[DateTime] = None, type: TranscriptSkillCardTypeField = TranscriptSkillCardTypeField.SKILL_CARD, skill_card_type: TranscriptSkillCardSkillCardTypeField = TranscriptSkillCardSkillCardTypeField.TRANSCRIPT, skill_card_title: Optional[TranscriptSkillCardSkillCardTitleField] = None, duration: Optional[int] = None, **kwargs): + """ + :param skill: The service that applied this metadata. + :type skill: TranscriptSkillCardSkillField + :param invocation: The invocation of this service, used to track +which instance of a service applied the metadata. + :type invocation: TranscriptSkillCardInvocationField + :param entries: An list of entries for the card. This represents the individual entries of +the transcription. + :type entries: List[TranscriptSkillCardEntriesField] + :param created_at: The optional date and time this card was created at., defaults to None + :type created_at: Optional[DateTime], optional + :param type: `skill_card`, defaults to TranscriptSkillCardTypeField.SKILL_CARD + :type type: TranscriptSkillCardTypeField, optional + :param skill_card_type: `transcript`, defaults to TranscriptSkillCardSkillCardTypeField.TRANSCRIPT + :type skill_card_type: TranscriptSkillCardSkillCardTypeField, optional + :param skill_card_title: The title of the card., defaults to None + :type skill_card_title: Optional[TranscriptSkillCardSkillCardTitleField], optional + :param duration: An optional total duration in seconds. + +Used with a `skill_card_type` of `transcript` or +`timeline`., defaults to None + :type duration: Optional[int], optional + """ + super().__init__(**kwargs) + self.skill = skill + self.invocation = invocation + self.entries = entries + self.created_at = created_at + self.type = type + self.skill_card_type = skill_card_type + self.skill_card_title = skill_card_title + self.duration = duration \ No newline at end of file diff --git a/box_sdk_gen/schemas/trash_file.py b/box_sdk_gen/schemas/trash_file.py new file mode 100644 index 000000000..f71c9f789 --- /dev/null +++ b/box_sdk_gen/schemas/trash_file.py @@ -0,0 +1,144 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from typing import Dict + +from box_sdk_gen.schemas.file_version_mini import FileVersionMini + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.schemas.folder_mini import FolderMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class TrashFileTypeField(str, Enum): + FILE = 'file' + +class TrashFilePathCollectionEntriesTypeField(str, Enum): + FOLDER = 'folder' + +class TrashFilePathCollectionEntriesField(BaseObject): + _discriminator = 'type', {'folder'} + def __init__(self, *, type: Optional[TrashFilePathCollectionEntriesTypeField] = None, id: Optional[str] = None, sequence_id: Optional[str] = None, etag: Optional[str] = None, name: Optional[str] = None, **kwargs): + """ + :param type: `folder`, defaults to None + :type type: Optional[TrashFilePathCollectionEntriesTypeField], optional + :param id: The unique identifier that represent a folder., defaults to None + :type id: Optional[str], optional + :param sequence_id: This field is null for the Trash folder, defaults to None + :type sequence_id: Optional[str], optional + :param etag: This field is null for the Trash folder, defaults to None + :type etag: Optional[str], optional + :param name: The name of the Trash folder., defaults to None + :type name: Optional[str], optional + """ + super().__init__(**kwargs) + self.type = type + self.id = id + self.sequence_id = sequence_id + self.etag = etag + self.name = name + +class TrashFilePathCollectionField(BaseObject): + def __init__(self, total_count: int, entries: List[TrashFilePathCollectionEntriesField], **kwargs): + """ + :param total_count: The number of folders in this list. + :type total_count: int + :param entries: Array of folders for this item's path collection + :type entries: List[TrashFilePathCollectionEntriesField] + """ + super().__init__(**kwargs) + self.total_count = total_count + self.entries = entries + +class TrashFileItemStatusField(str, Enum): + ACTIVE = 'active' + TRASHED = 'trashed' + DELETED = 'deleted' + +class TrashFile(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'sha_1': 'sha1', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'sha1': 'sha_1', **BaseObject._json_to_fields_mapping} + _discriminator = 'type', {'file'} + def __init__(self, id: str, sequence_id: str, sha_1: str, description: str, size: int, path_collection: TrashFilePathCollectionField, created_at: DateTime, modified_at: DateTime, modified_by: UserMini, owned_by: UserMini, item_status: TrashFileItemStatusField, *, etag: Optional[str] = None, type: TrashFileTypeField = TrashFileTypeField.FILE, name: Optional[str] = None, file_version: Optional[FileVersionMini] = None, trashed_at: Optional[DateTime] = None, purged_at: Optional[DateTime] = None, content_created_at: Optional[DateTime] = None, content_modified_at: Optional[DateTime] = None, created_by: Optional[UserMini] = None, shared_link: Optional[str] = None, parent: Optional[FolderMini] = None, **kwargs): + """ + :param id: The unique identifier that represent 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`. + :type id: str + :param sha_1: The SHA1 hash of the file. This can be used to compare the contents +of a file on Box with a local file. + :type sha_1: str + :param description: The optional description of this file + :type description: str + :param size: The file size in bytes. Be careful parsing this integer as it can +get very large and cause an integer overflow. + :type size: int + :param created_at: The date and time when the file was created on Box. + :type created_at: DateTime + :param modified_at: The date and time when the file was last updated on Box. + :type modified_at: DateTime + :param item_status: Defines if this item has been deleted or not. + +* `active` when the item has is not in the trash +* `trashed` when the item has been moved to the trash but not deleted +* `deleted` when the item has been permanently deleted. + :type item_status: TrashFileItemStatusField + :param etag: The HTTP `etag` of this file. This can be used within some API +endpoints in the `If-Match` and `If-None-Match` headers to only +perform changes on the file if (no) changes have happened., defaults to None + :type etag: Optional[str], optional + :param type: `file`, defaults to TrashFileTypeField.FILE + :type type: TrashFileTypeField, optional + :param name: The name of the file, defaults to None + :type name: Optional[str], optional + :param trashed_at: The time at which this file was put in the trash., defaults to None + :type trashed_at: Optional[DateTime], optional + :param purged_at: The time at which this file is expected to be purged +from the trash., defaults to None + :type purged_at: Optional[DateTime], optional + :param content_created_at: The date and time at which this file was originally +created, which might be before it was uploaded to Box., defaults to None + :type content_created_at: Optional[DateTime], optional + :param content_modified_at: The date and time at which this file was last updated, +which might be before it was uploaded to Box., defaults to None + :type content_modified_at: Optional[DateTime], optional + :param shared_link: The shared link for this file. This will +be `null` if a file has been trashed, since the link will no longer +be active., defaults to None + :type shared_link: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.sequence_id = sequence_id + self.sha_1 = sha_1 + self.description = description + self.size = size + self.path_collection = path_collection + self.created_at = created_at + self.modified_at = modified_at + self.modified_by = modified_by + self.owned_by = owned_by + self.item_status = item_status + self.etag = etag + self.type = type + self.name = name + self.file_version = file_version + self.trashed_at = trashed_at + self.purged_at = purged_at + self.content_created_at = content_created_at + self.content_modified_at = content_modified_at + self.created_by = created_by + self.shared_link = shared_link + self.parent = parent \ No newline at end of file diff --git a/box_sdk_gen/schemas/trash_file_restored.py b/box_sdk_gen/schemas/trash_file_restored.py new file mode 100644 index 000000000..c6392eb1a --- /dev/null +++ b/box_sdk_gen/schemas/trash_file_restored.py @@ -0,0 +1,120 @@ +from enum import Enum + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Optional + +from typing import Dict + +from box_sdk_gen.schemas.file_version_mini import FileVersionMini + +from box_sdk_gen.schemas.folder_mini import FolderMini + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class TrashFileRestoredTypeField(str, Enum): + FILE = 'file' + +class TrashFileRestoredPathCollectionField(BaseObject): + def __init__(self, total_count: int, entries: List[FolderMini], **kwargs): + """ + :param total_count: The number of folders in this list. + :type total_count: int + :param entries: The parent folders for this item + :type entries: List[FolderMini] + """ + super().__init__(**kwargs) + self.total_count = total_count + self.entries = entries + +class TrashFileRestoredItemStatusField(str, Enum): + ACTIVE = 'active' + TRASHED = 'trashed' + DELETED = 'deleted' + +class TrashFileRestored(BaseObject): + _fields_to_json_mapping: Dict[str, str] = {'sha_1': 'sha1', **BaseObject._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'sha1': 'sha_1', **BaseObject._json_to_fields_mapping} + _discriminator = 'type', {'file'} + def __init__(self, id: str, sequence_id: str, sha_1: str, description: str, size: int, path_collection: TrashFileRestoredPathCollectionField, created_at: DateTime, modified_at: DateTime, modified_by: UserMini, owned_by: UserMini, item_status: TrashFileRestoredItemStatusField, *, etag: Optional[str] = None, type: TrashFileRestoredTypeField = TrashFileRestoredTypeField.FILE, name: Optional[str] = None, file_version: Optional[FileVersionMini] = None, trashed_at: Optional[str] = None, purged_at: Optional[str] = None, content_created_at: Optional[DateTime] = None, content_modified_at: Optional[DateTime] = None, created_by: Optional[UserMini] = None, shared_link: Optional[str] = None, parent: Optional[FolderMini] = None, **kwargs): + """ + :param id: The unique identifier that represent 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`. + :type id: str + :param sha_1: The SHA1 hash of the file. This can be used to compare the contents +of a file on Box with a local file. + :type sha_1: str + :param description: The optional description of this file + :type description: str + :param size: The file size in bytes. Be careful parsing this integer as it can +get very large and cause an integer overflow. + :type size: int + :param created_at: The date and time when the file was created on Box. + :type created_at: DateTime + :param modified_at: The date and time when the file was last updated on Box. + :type modified_at: DateTime + :param item_status: Defines if this item has been deleted or not. + +* `active` when the item has is not in the trash +* `trashed` when the item has been moved to the trash but not deleted +* `deleted` when the item has been permanently deleted. + :type item_status: TrashFileRestoredItemStatusField + :param etag: The HTTP `etag` of this file. This can be used within some API +endpoints in the `If-Match` and `If-None-Match` headers to only +perform changes on the file if (no) changes have happened., defaults to None + :type etag: Optional[str], optional + :param type: `file`, defaults to TrashFileRestoredTypeField.FILE + :type type: TrashFileRestoredTypeField, optional + :param name: The name of the file, defaults to None + :type name: Optional[str], optional + :param trashed_at: The time at which this file was put in the +trash - becomes `null` after restore., defaults to None + :type trashed_at: Optional[str], optional + :param purged_at: The time at which this file is expected to be purged +from the trash - becomes `null` after restore., defaults to None + :type purged_at: Optional[str], optional + :param content_created_at: The date and time at which this file was originally +created, which might be before it was uploaded to Box., defaults to None + :type content_created_at: Optional[DateTime], optional + :param content_modified_at: The date and time at which this file was last updated, +which might be before it was uploaded to Box., defaults to None + :type content_modified_at: Optional[DateTime], optional + :param shared_link: The shared link for this file. This will +be `null` if a file had been trashed, even though the original shared +link does become active again., defaults to None + :type shared_link: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.sequence_id = sequence_id + self.sha_1 = sha_1 + self.description = description + self.size = size + self.path_collection = path_collection + self.created_at = created_at + self.modified_at = modified_at + self.modified_by = modified_by + self.owned_by = owned_by + self.item_status = item_status + self.etag = etag + self.type = type + self.name = name + self.file_version = file_version + self.trashed_at = trashed_at + self.purged_at = purged_at + self.content_created_at = content_created_at + self.content_modified_at = content_modified_at + self.created_by = created_by + self.shared_link = shared_link + self.parent = parent \ No newline at end of file diff --git a/box_sdk_gen/schemas/trash_folder.py b/box_sdk_gen/schemas/trash_folder.py new file mode 100644 index 000000000..0b2dbcce5 --- /dev/null +++ b/box_sdk_gen/schemas/trash_folder.py @@ -0,0 +1,141 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.schemas.folder_mini import FolderMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class TrashFolderTypeField(str, Enum): + FOLDER = 'folder' + +class TrashFolderPathCollectionEntriesTypeField(str, Enum): + FOLDER = 'folder' + +class TrashFolderPathCollectionEntriesField(BaseObject): + _discriminator = 'type', {'folder'} + def __init__(self, *, type: Optional[TrashFolderPathCollectionEntriesTypeField] = None, id: Optional[str] = None, sequence_id: Optional[str] = None, etag: Optional[str] = None, name: Optional[str] = None, **kwargs): + """ + :param type: `folder`, defaults to None + :type type: Optional[TrashFolderPathCollectionEntriesTypeField], optional + :param id: The unique identifier that represent a folder., defaults to None + :type id: Optional[str], optional + :param sequence_id: This field is null for the Trash folder, defaults to None + :type sequence_id: Optional[str], optional + :param etag: This field is null for the Trash folder, defaults to None + :type etag: Optional[str], optional + :param name: The name of the Trash folder., defaults to None + :type name: Optional[str], optional + """ + super().__init__(**kwargs) + self.type = type + self.id = id + self.sequence_id = sequence_id + self.etag = etag + self.name = name + +class TrashFolderPathCollectionField(BaseObject): + def __init__(self, total_count: int, entries: List[TrashFolderPathCollectionEntriesField], **kwargs): + """ + :param total_count: The number of folders in this list. + :type total_count: int + :param entries: Array of folders for this item's path collection + :type entries: List[TrashFolderPathCollectionEntriesField] + """ + super().__init__(**kwargs) + self.total_count = total_count + self.entries = entries + +class TrashFolderItemStatusField(str, Enum): + ACTIVE = 'active' + TRASHED = 'trashed' + DELETED = 'deleted' + +class TrashFolder(BaseObject): + _discriminator = 'type', {'folder'} + def __init__(self, id: str, name: str, description: str, size: int, path_collection: TrashFolderPathCollectionField, created_by: UserMini, modified_by: UserMini, owned_by: UserMini, item_status: TrashFolderItemStatusField, *, etag: Optional[str] = None, type: TrashFolderTypeField = TrashFolderTypeField.FOLDER, sequence_id: Optional[str] = None, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, trashed_at: Optional[DateTime] = None, purged_at: Optional[DateTime] = None, content_created_at: Optional[DateTime] = None, content_modified_at: Optional[DateTime] = None, shared_link: Optional[str] = None, folder_upload_email: Optional[str] = None, parent: Optional[FolderMini] = None, **kwargs): + """ + :param id: The unique identifier that represent a folder. + +The ID for any folder can be determined +by visiting a folder in the web application +and copying the ID from the URL. For example, +for the URL `https://*.app.box.com/folders/123` +the `folder_id` is `123`. + :type id: str + :param name: The name of the folder. + :type name: str + :param size: The folder size in bytes. + +Be careful parsing this integer as its +value can get very large. + :type size: int + :param item_status: Defines if this item has been deleted or not. + +* `active` when the item has is not in the trash +* `trashed` when the item has been moved to the trash but not deleted +* `deleted` when the item has been permanently deleted. + :type item_status: TrashFolderItemStatusField + :param etag: The HTTP `etag` of this folder. This can be used within some API +endpoints in the `If-Match` and `If-None-Match` headers to only +perform changes on the folder if (no) changes have happened., defaults to None + :type etag: Optional[str], optional + :param type: `folder`, defaults to TrashFolderTypeField.FOLDER + :type type: TrashFolderTypeField, 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 + :type created_at: Optional[DateTime], optional + :param modified_at: The date and time when the folder was last updated. This value may +be `null` for some folders such as the root folder or the trash +folder., defaults to None + :type modified_at: Optional[DateTime], optional + :param trashed_at: The time at which this folder was put in the trash., defaults to None + :type trashed_at: Optional[DateTime], optional + :param purged_at: The time at which this folder is expected to be purged +from the trash., defaults to None + :type purged_at: Optional[DateTime], optional + :param content_created_at: The date and time at which this folder was originally +created., defaults to None + :type content_created_at: Optional[DateTime], optional + :param content_modified_at: The date and time at which this folder was last updated., defaults to None + :type content_modified_at: Optional[DateTime], optional + :param shared_link: The shared link for this folder. This will +be `null` if a folder has been trashed, since the link will no longer +be active., defaults to None + :type shared_link: Optional[str], optional + :param folder_upload_email: The folder upload email for this folder. This will +be `null` if a folder has been trashed, since the upload will no longer +work., defaults to None + :type folder_upload_email: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.name = name + self.description = description + self.size = size + self.path_collection = path_collection + self.created_by = created_by + self.modified_by = modified_by + self.owned_by = owned_by + self.item_status = item_status + self.etag = etag + self.type = type + self.sequence_id = sequence_id + self.created_at = created_at + self.modified_at = modified_at + self.trashed_at = trashed_at + self.purged_at = purged_at + self.content_created_at = content_created_at + self.content_modified_at = content_modified_at + self.shared_link = shared_link + self.folder_upload_email = folder_upload_email + self.parent = parent \ No newline at end of file diff --git a/box_sdk_gen/schemas/trash_folder_restored.py b/box_sdk_gen/schemas/trash_folder_restored.py new file mode 100644 index 000000000..06c1083fb --- /dev/null +++ b/box_sdk_gen/schemas/trash_folder_restored.py @@ -0,0 +1,117 @@ +from enum import Enum + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Optional + +from box_sdk_gen.schemas.folder_mini import FolderMini + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class TrashFolderRestoredTypeField(str, Enum): + FOLDER = 'folder' + +class TrashFolderRestoredPathCollectionField(BaseObject): + def __init__(self, total_count: int, entries: List[FolderMini], **kwargs): + """ + :param total_count: The number of folders in this list. + :type total_count: int + :param entries: The parent folders for this item + :type entries: List[FolderMini] + """ + super().__init__(**kwargs) + self.total_count = total_count + self.entries = entries + +class TrashFolderRestoredItemStatusField(str, Enum): + ACTIVE = 'active' + TRASHED = 'trashed' + DELETED = 'deleted' + +class TrashFolderRestored(BaseObject): + _discriminator = 'type', {'folder'} + def __init__(self, *, id: Optional[str] = None, etag: Optional[str] = None, type: Optional[TrashFolderRestoredTypeField] = None, sequence_id: Optional[str] = None, name: Optional[str] = None, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, description: Optional[str] = None, size: Optional[int] = None, path_collection: Optional[TrashFolderRestoredPathCollectionField] = None, created_by: Optional[UserMini] = None, modified_by: Optional[UserMini] = None, trashed_at: Optional[str] = None, purged_at: Optional[str] = None, content_created_at: Optional[DateTime] = None, content_modified_at: Optional[DateTime] = None, owned_by: Optional[UserMini] = None, shared_link: Optional[str] = None, folder_upload_email: Optional[str] = None, parent: Optional[FolderMini] = None, item_status: Optional[TrashFolderRestoredItemStatusField] = None, **kwargs): + """ + :param id: The unique identifier that represent a folder. + +The ID for any folder can be determined +by visiting a folder in the web application +and copying the ID from the URL. For example, +for the URL `https://*.app.box.com/folders/123` +the `folder_id` is `123`., defaults to None + :type id: Optional[str], optional + :param etag: The HTTP `etag` of this folder. This can be used within some API +endpoints in the `If-Match` and `If-None-Match` headers to only +perform changes on the folder if (no) changes have happened., defaults to None + :type etag: Optional[str], optional + :param type: `folder`, defaults to None + :type type: Optional[TrashFolderRestoredTypeField], optional + :param name: The name of the folder., defaults to None + :type name: Optional[str], 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 + :type created_at: Optional[DateTime], optional + :param modified_at: The date and time when the folder was last updated. This value may +be `null` for some folders such as the root folder or the trash +folder., defaults to None + :type modified_at: Optional[DateTime], optional + :param size: The folder size in bytes. + +Be careful parsing this integer as its +value can get very large., defaults to None + :type size: Optional[int], optional + :param trashed_at: The time at which this folder was put in the +trash - becomes `null` after restore., defaults to None + :type trashed_at: Optional[str], optional + :param purged_at: The time at which this folder is expected to be purged +from the trash - becomes `null` after restore., defaults to None + :type purged_at: Optional[str], optional + :param content_created_at: The date and time at which this folder was originally +created., defaults to None + :type content_created_at: Optional[DateTime], optional + :param content_modified_at: The date and time at which this folder was last updated., defaults to None + :type content_modified_at: Optional[DateTime], optional + :param shared_link: The shared link for this file. This will +be `null` if a folder had been trashed, even though the original shared +link does become active again., defaults to None + :type shared_link: Optional[str], optional + :param folder_upload_email: The folder upload email for this folder. This will +be `null` if a folder has been trashed, even though the original upload +email does become active again., defaults to None + :type folder_upload_email: Optional[str], optional + :param item_status: Defines if this item has been deleted or not. + +* `active` when the item has is not in the trash +* `trashed` when the item has been moved to the trash but not deleted +* `deleted` when the item has been permanently deleted., defaults to None + :type item_status: Optional[TrashFolderRestoredItemStatusField], optional + """ + super().__init__(**kwargs) + self.id = id + self.etag = etag + self.type = type + self.sequence_id = sequence_id + self.name = name + self.created_at = created_at + self.modified_at = modified_at + self.description = description + self.size = size + self.path_collection = path_collection + self.created_by = created_by + self.modified_by = modified_by + self.trashed_at = trashed_at + self.purged_at = purged_at + self.content_created_at = content_created_at + self.content_modified_at = content_modified_at + self.owned_by = owned_by + self.shared_link = shared_link + self.folder_upload_email = folder_upload_email + self.parent = parent + self.item_status = item_status \ No newline at end of file diff --git a/box_sdk_gen/schemas/trash_web_link.py b/box_sdk_gen/schemas/trash_web_link.py new file mode 100644 index 000000000..5be7e6047 --- /dev/null +++ b/box_sdk_gen/schemas/trash_web_link.py @@ -0,0 +1,116 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from box_sdk_gen.schemas.folder_mini import FolderMini + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class TrashWebLinkTypeField(str, Enum): + WEB_LINK = 'web_link' + +class TrashWebLinkPathCollectionEntriesTypeField(str, Enum): + FOLDER = 'folder' + +class TrashWebLinkPathCollectionEntriesField(BaseObject): + _discriminator = 'type', {'folder'} + def __init__(self, *, type: Optional[TrashWebLinkPathCollectionEntriesTypeField] = None, id: Optional[str] = None, sequence_id: Optional[str] = None, etag: Optional[str] = None, name: Optional[str] = None, **kwargs): + """ + :param type: `folder`, defaults to None + :type type: Optional[TrashWebLinkPathCollectionEntriesTypeField], optional + :param id: The unique identifier that represent a folder., defaults to None + :type id: Optional[str], optional + :param sequence_id: This field is null for the Trash folder, defaults to None + :type sequence_id: Optional[str], optional + :param etag: This field is null for the Trash folder, defaults to None + :type etag: Optional[str], optional + :param name: The name of the Trash folder., defaults to None + :type name: Optional[str], optional + """ + super().__init__(**kwargs) + self.type = type + self.id = id + self.sequence_id = sequence_id + self.etag = etag + self.name = name + +class TrashWebLinkPathCollectionField(BaseObject): + def __init__(self, total_count: int, entries: List[TrashWebLinkPathCollectionEntriesField], **kwargs): + """ + :param total_count: The number of folders in this list. + :type total_count: int + :param entries: Array of folders for this item's path collection + :type entries: List[TrashWebLinkPathCollectionEntriesField] + """ + super().__init__(**kwargs) + self.total_count = total_count + self.entries = entries + +class TrashWebLinkItemStatusField(str, Enum): + ACTIVE = 'active' + TRASHED = 'trashed' + DELETED = 'deleted' + +class TrashWebLink(BaseObject): + _discriminator = 'type', {'web_link'} + def __init__(self, *, type: Optional[TrashWebLinkTypeField] = None, id: Optional[str] = None, sequence_id: Optional[str] = None, etag: Optional[str] = None, name: Optional[str] = None, url: Optional[str] = None, parent: Optional[FolderMini] = None, description: Optional[str] = None, path_collection: Optional[TrashWebLinkPathCollectionField] = None, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, trashed_at: Optional[DateTime] = None, purged_at: Optional[DateTime] = None, created_by: Optional[UserMini] = None, modified_by: Optional[UserMini] = None, owned_by: Optional[UserMini] = None, shared_link: Optional[str] = None, item_status: Optional[TrashWebLinkItemStatusField] = None, **kwargs): + """ + :param type: `web_link`, defaults to None + :type type: Optional[TrashWebLinkTypeField], optional + :param id: The unique identifier for this web link, defaults to None + :type id: Optional[str], optional + :param etag: The entity tag of this web link. Used with `If-Match` +headers., defaults to None + :type etag: Optional[str], optional + :param name: The name of the web link, defaults to None + :type name: Optional[str], optional + :param url: The URL this web link points to, defaults to None + :type url: Optional[str], optional + :param description: The description accompanying the web link. This is +visible within the Box web application., defaults to None + :type description: Optional[str], optional + :param created_at: When this file was created on Box’s servers., defaults to None + :type created_at: Optional[DateTime], optional + :param modified_at: When this file was last updated on the Box +servers., defaults to None + :type modified_at: Optional[DateTime], optional + :param trashed_at: When this file was last moved to the trash., defaults to None + :type trashed_at: Optional[DateTime], optional + :param purged_at: When this file will be permanently deleted., defaults to None + :type purged_at: Optional[DateTime], optional + :param shared_link: The shared link for this bookmark. This will +be `null` if a bookmark has been trashed, since the link will no longer +be active., defaults to None + :type shared_link: Optional[str], optional + :param item_status: Whether this item is deleted or not. Values include `active`, +`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[TrashWebLinkItemStatusField], optional + """ + super().__init__(**kwargs) + self.type = type + self.id = id + self.sequence_id = sequence_id + self.etag = etag + self.name = name + self.url = url + self.parent = parent + self.description = description + self.path_collection = path_collection + self.created_at = created_at + self.modified_at = modified_at + self.trashed_at = trashed_at + self.purged_at = purged_at + self.created_by = created_by + self.modified_by = modified_by + self.owned_by = owned_by + self.shared_link = shared_link + self.item_status = item_status \ No newline at end of file diff --git a/box_sdk_gen/schemas/trash_web_link_restored.py b/box_sdk_gen/schemas/trash_web_link_restored.py new file mode 100644 index 000000000..945851270 --- /dev/null +++ b/box_sdk_gen/schemas/trash_web_link_restored.py @@ -0,0 +1,93 @@ +from enum import Enum + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Optional + +from box_sdk_gen.schemas.folder_mini import FolderMini + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class TrashWebLinkRestoredTypeField(str, Enum): + WEB_LINK = 'web_link' + +class TrashWebLinkRestoredPathCollectionField(BaseObject): + def __init__(self, total_count: int, entries: List[FolderMini], **kwargs): + """ + :param total_count: The number of folders in this list. + :type total_count: int + :param entries: The parent folders for this item + :type entries: List[FolderMini] + """ + super().__init__(**kwargs) + self.total_count = total_count + self.entries = entries + +class TrashWebLinkRestoredItemStatusField(str, Enum): + ACTIVE = 'active' + TRASHED = 'trashed' + DELETED = 'deleted' + +class TrashWebLinkRestored(BaseObject): + _discriminator = 'type', {'web_link'} + def __init__(self, sequence_id: str, path_collection: TrashWebLinkRestoredPathCollectionField, *, type: Optional[TrashWebLinkRestoredTypeField] = None, id: Optional[str] = None, etag: Optional[str] = None, name: Optional[str] = None, url: Optional[str] = None, parent: Optional[FolderMini] = None, description: Optional[str] = None, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, trashed_at: Optional[str] = None, purged_at: Optional[str] = None, created_by: Optional[UserMini] = None, modified_by: Optional[UserMini] = None, owned_by: Optional[UserMini] = None, shared_link: Optional[str] = None, item_status: Optional[TrashWebLinkRestoredItemStatusField] = None, **kwargs): + """ + :param type: `web_link`, defaults to None + :type type: Optional[TrashWebLinkRestoredTypeField], optional + :param id: The unique identifier for this web link, defaults to None + :type id: Optional[str], optional + :param etag: The entity tag of this web link. Used with `If-Match` +headers., defaults to None + :type etag: Optional[str], optional + :param name: The name of the web link, defaults to None + :type name: Optional[str], optional + :param url: The URL this web link points to, defaults to None + :type url: Optional[str], optional + :param description: The description accompanying the web link. This is +visible within the Box web application., defaults to None + :type description: Optional[str], optional + :param created_at: When this file was created on Box’s servers., defaults to None + :type created_at: Optional[DateTime], optional + :param modified_at: When this file was last updated on the Box +servers., defaults to None + :type modified_at: Optional[DateTime], optional + :param trashed_at: The time at which this bookmark was put in the +trash - becomes `null` after restore., defaults to None + :type trashed_at: Optional[str], optional + :param purged_at: The time at which this bookmark will be permanently +deleted - becomes `null` after restore., defaults to None + :type purged_at: Optional[str], optional + :param shared_link: The shared link for this bookmark. This will +be `null` if a bookmark had been trashed, even though the original shared +link does become active again., defaults to None + :type shared_link: Optional[str], optional + :param item_status: Whether this item is deleted or not. Values include `active`, +`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[TrashWebLinkRestoredItemStatusField], optional + """ + super().__init__(**kwargs) + self.sequence_id = sequence_id + self.path_collection = path_collection + self.type = type + self.id = id + self.etag = etag + self.name = name + self.url = url + self.parent = parent + self.description = description + self.created_at = created_at + self.modified_at = modified_at + self.trashed_at = trashed_at + self.purged_at = purged_at + self.created_by = created_by + self.modified_by = modified_by + self.owned_by = owned_by + self.shared_link = shared_link + self.item_status = item_status \ No newline at end of file diff --git a/box_sdk_gen/schemas/upload_part.py b/box_sdk_gen/schemas/upload_part.py new file mode 100644 index 000000000..e0ea8211a --- /dev/null +++ b/box_sdk_gen/schemas/upload_part.py @@ -0,0 +1,26 @@ +from typing import Optional + +from typing import Dict + +from box_sdk_gen.schemas.upload_part_mini import UploadPartMini + +from box_sdk_gen.box.errors import BoxSDKError + +class UploadPart(UploadPartMini): + _fields_to_json_mapping: Dict[str, str] = {'sha_1': 'sha1', **UploadPartMini._fields_to_json_mapping} + _json_to_fields_mapping: Dict[str, str] = {'sha1': 'sha_1', **UploadPartMini._json_to_fields_mapping} + def __init__(self, *, sha_1: Optional[str] = None, part_id: Optional[str] = None, offset: Optional[int] = None, size: Optional[int] = None, **kwargs): + """ + :param sha_1: The SHA1 hash of the chunk., defaults to None + :type sha_1: Optional[str], optional + :param part_id: The unique ID of the chunk., defaults to None + :type part_id: Optional[str], optional + :param offset: The offset of the chunk within the file +in bytes. The lower bound of the position +of the chunk within the file., defaults to None + :type offset: Optional[int], optional + :param size: The size of the chunk in bytes., defaults to None + :type size: Optional[int], optional + """ + super().__init__(part_id=part_id, offset=offset, size=size, **kwargs) + self.sha_1 = sha_1 \ No newline at end of file diff --git a/box_sdk_gen/schemas/upload_part_mini.py b/box_sdk_gen/schemas/upload_part_mini.py new file mode 100644 index 000000000..eb52ff680 --- /dev/null +++ b/box_sdk_gen/schemas/upload_part_mini.py @@ -0,0 +1,22 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class UploadPartMini(BaseObject): + def __init__(self, *, part_id: Optional[str] = None, offset: Optional[int] = None, size: Optional[int] = None, **kwargs): + """ + :param part_id: The unique ID of the chunk., defaults to None + :type part_id: Optional[str], optional + :param offset: The offset of the chunk within the file +in bytes. The lower bound of the position +of the chunk within the file., defaults to None + :type offset: Optional[int], optional + :param size: The size of the chunk in bytes., defaults to None + :type size: Optional[int], optional + """ + super().__init__(**kwargs) + self.part_id = part_id + self.offset = offset + self.size = size \ No newline at end of file diff --git a/box_sdk_gen/schemas/upload_parts.py b/box_sdk_gen/schemas/upload_parts.py new file mode 100644 index 000000000..6a94fcfd0 --- /dev/null +++ b/box_sdk_gen/schemas/upload_parts.py @@ -0,0 +1,63 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from box_sdk_gen.schemas.upload_part import UploadPart + +from box_sdk_gen.box.errors import BoxSDKError + +class UploadPartsOrderDirectionField(str, Enum): + ASC = 'ASC' + DESC = 'DESC' + +class UploadPartsOrderField(BaseObject): + def __init__(self, *, by: Optional[str] = None, direction: Optional[UploadPartsOrderDirectionField] = None, **kwargs): + """ + :param by: The field to order by, defaults to None + :type by: Optional[str], optional + :param direction: The direction to order by, either ascending or descending, defaults to None + :type direction: Optional[UploadPartsOrderDirectionField], optional + """ + super().__init__(**kwargs) + self.by = by + self.direction = direction + +class UploadParts(BaseObject): + def __init__(self, *, total_count: Optional[int] = None, limit: Optional[int] = None, offset: Optional[int] = None, order: Optional[List[UploadPartsOrderField]] = None, entries: Optional[List[UploadPart]] = None, **kwargs): + """ + :param total_count: One greater than the offset of the last entry in the entire collection. +The total number of entries in the collection may be less than +`total_count`. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type total_count: Optional[int], optional + :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 offset: The 0-based offset of the first entry in this set. This will be the same +as the `offset` query parameter. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type offset: Optional[int], optional + :param order: The order by which items are returned. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type order: Optional[List[UploadPartsOrderField]], optional + :param entries: A list of uploaded chunks for an upload +session, defaults to None + :type entries: Optional[List[UploadPart]], optional + """ + super().__init__(**kwargs) + self.total_count = total_count + self.limit = limit + self.offset = offset + self.order = order + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/upload_session.py b/box_sdk_gen/schemas/upload_session.py new file mode 100644 index 000000000..0a8657751 --- /dev/null +++ b/box_sdk_gen/schemas/upload_session.py @@ -0,0 +1,70 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class UploadSessionTypeField(str, Enum): + UPLOAD_SESSION = 'upload_session' + +class UploadSessionSessionEndpointsField(BaseObject): + def __init__(self, *, upload_part: Optional[str] = None, commit: Optional[str] = None, abort: Optional[str] = None, list_parts: Optional[str] = None, status: Optional[str] = None, log_event: Optional[str] = None, **kwargs): + """ + :param upload_part: The URL to upload parts to, defaults to None + :type upload_part: Optional[str], optional + :param commit: The URL used to commit the file, defaults to None + :type commit: Optional[str], optional + :param abort: The URL for used to abort the session., defaults to None + :type abort: Optional[str], optional + :param list_parts: The URL users to list all parts., defaults to None + :type list_parts: Optional[str], optional + :param status: The URL used to get the status of the upload., defaults to None + :type status: Optional[str], optional + :param log_event: The URL used to get the upload log from., defaults to None + :type log_event: Optional[str], optional + """ + super().__init__(**kwargs) + self.upload_part = upload_part + self.commit = commit + self.abort = abort + self.list_parts = list_parts + self.status = status + self.log_event = log_event + +class UploadSession(BaseObject): + _discriminator = 'type', {'upload_session'} + def __init__(self, *, id: Optional[str] = None, type: Optional[UploadSessionTypeField] = None, session_expires_at: Optional[DateTime] = None, part_size: Optional[int] = None, total_parts: Optional[int] = None, num_parts_processed: Optional[int] = None, session_endpoints: Optional[UploadSessionSessionEndpointsField] = None, **kwargs): + """ + :param id: The unique identifier for this session, defaults to None + :type id: Optional[str], optional + :param type: `upload_session`, defaults to None + :type type: Optional[UploadSessionTypeField], optional + :param session_expires_at: The date and time when this session expires., defaults to None + :type session_expires_at: Optional[DateTime], optional + :param part_size: The size in bytes that must be used for all parts of of the +upload. + +Only the last part is allowed to be of a smaller size., defaults to None + :type part_size: Optional[int], optional + :param total_parts: The total number of parts expected in this upload session, +as determined by the file size and part size., defaults to None + :type total_parts: Optional[int], optional + :param num_parts_processed: The number of parts that have been uploaded and processed +by the server. This starts at `0`. + +When committing a file files, inspecting this property can +provide insight if all parts have been uploaded correctly., defaults to None + :type num_parts_processed: Optional[int], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.session_expires_at = session_expires_at + self.part_size = part_size + self.total_parts = total_parts + self.num_parts_processed = num_parts_processed + self.session_endpoints = session_endpoints \ No newline at end of file diff --git a/box_sdk_gen/schemas/upload_url.py b/box_sdk_gen/schemas/upload_url.py new file mode 100644 index 000000000..a57e3cf40 --- /dev/null +++ b/box_sdk_gen/schemas/upload_url.py @@ -0,0 +1,18 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class UploadUrl(BaseObject): + def __init__(self, *, upload_url: Optional[str] = None, upload_token: Optional[str] = None, **kwargs): + """ + :param upload_url: A URL for an upload session that can be used to upload +the file., defaults to None + :type upload_url: Optional[str], optional + :param upload_token: An optional access token to use to upload the file, defaults to None + :type upload_token: Optional[str], optional + """ + super().__init__(**kwargs) + self.upload_url = upload_url + self.upload_token = upload_token \ No newline at end of file diff --git a/box_sdk_gen/schemas/uploaded_part.py b/box_sdk_gen/schemas/uploaded_part.py new file mode 100644 index 000000000..0540506a0 --- /dev/null +++ b/box_sdk_gen/schemas/uploaded_part.py @@ -0,0 +1,12 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.upload_part import UploadPart + +from box_sdk_gen.box.errors import BoxSDKError + +class UploadedPart(BaseObject): + def __init__(self, *, part: Optional[UploadPart] = None, **kwargs): + super().__init__(**kwargs) + self.part = part \ No newline at end of file diff --git a/box_sdk_gen/schemas/user.py b/box_sdk_gen/schemas/user.py new file mode 100644 index 000000000..5858e2965 --- /dev/null +++ b/box_sdk_gen/schemas/user.py @@ -0,0 +1,90 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.user_base import UserBaseTypeField + +from box_sdk_gen.schemas.user_base import UserBase + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class UserStatusField(str, Enum): + ACTIVE = 'active' + INACTIVE = 'inactive' + CANNOT_DELETE_EDIT = 'cannot_delete_edit' + CANNOT_DELETE_EDIT_UPLOAD = 'cannot_delete_edit_upload' + +class UserNotificationEmailField(BaseObject): + def __init__(self, *, email: Optional[str] = None, is_confirmed: Optional[bool] = None, **kwargs): + """ + :param email: The email address to send the notifications to., defaults to None + :type email: Optional[str], optional + :param is_confirmed: Specifies if this email address has been confirmed., defaults to None + :type is_confirmed: Optional[bool], optional + """ + super().__init__(**kwargs) + self.email = email + self.is_confirmed = is_confirmed + +class User(UserMini): + def __init__(self, id: str, *, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, language: Optional[str] = None, timezone: Optional[str] = None, space_amount: Optional[int] = None, space_used: Optional[int] = None, max_upload_size: Optional[int] = None, status: Optional[UserStatusField] = None, job_title: Optional[str] = None, phone: Optional[str] = None, address: Optional[str] = None, avatar_url: Optional[str] = None, notification_email: Optional[UserNotificationEmailField] = None, name: Optional[str] = None, login: Optional[str] = None, type: UserBaseTypeField = UserBaseTypeField.USER, **kwargs): + """ + :param id: The unique identifier for this user + :type id: str + :param created_at: When the user object was created, defaults to None + :type created_at: Optional[DateTime], optional + :param modified_at: When the user object was last modified, defaults to None + :type modified_at: Optional[DateTime], optional + :param language: The language of the user, formatted in modified version of the +[ISO 639-1](/guides/api-calls/language-codes) format., defaults to None + :type language: Optional[str], optional + :param timezone: The user's timezone, defaults to None + :type timezone: Optional[str], optional + :param space_amount: The user’s total available space amount in bytes, defaults to None + :type space_amount: Optional[int], optional + :param space_used: The amount of space in use by the user, defaults to None + :type space_used: Optional[int], optional + :param max_upload_size: The maximum individual file size in bytes the user can have, defaults to None + :type max_upload_size: Optional[int], optional + :param status: The user's account status, defaults to None + :type status: Optional[UserStatusField], optional + :param job_title: The user’s job title, defaults to None + :type job_title: Optional[str], optional + :param phone: The user’s phone number, defaults to None + :type phone: Optional[str], optional + :param address: The user’s address, defaults to None + :type address: Optional[str], optional + :param avatar_url: URL of the user’s avatar image, defaults to None + :type avatar_url: Optional[str], optional + :param notification_email: An alternate notification email address to which email +notifications are sent. When it's confirmed, this will be +the email address to which notifications are sent instead of +to the primary email address., defaults to None + :type notification_email: Optional[UserNotificationEmailField], optional + :param name: The display name of this user, defaults to None + :type name: Optional[str], optional + :param login: The primary email address of this user, defaults to None + :type login: Optional[str], optional + :param type: `user`, defaults to UserBaseTypeField.USER + :type type: UserBaseTypeField, optional + """ + super().__init__(id=id, name=name, login=login, type=type, **kwargs) + self.created_at = created_at + self.modified_at = modified_at + self.language = language + self.timezone = timezone + self.space_amount = space_amount + self.space_used = space_used + self.max_upload_size = max_upload_size + self.status = status + self.job_title = job_title + self.phone = phone + self.address = address + self.avatar_url = avatar_url + self.notification_email = notification_email \ No newline at end of file diff --git a/box_sdk_gen/schemas/user_avatar.py b/box_sdk_gen/schemas/user_avatar.py new file mode 100644 index 000000000..c6985dcd0 --- /dev/null +++ b/box_sdk_gen/schemas/user_avatar.py @@ -0,0 +1,29 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class UserAvatarPicUrlsField(BaseObject): + def __init__(self, *, small: Optional[str] = None, large: Optional[str] = None, preview: Optional[str] = None, **kwargs): + """ + :param small: The location of a small-sized avatar., defaults to None + :type small: Optional[str], optional + :param large: The location of a large-sized avatar., defaults to None + :type large: Optional[str], optional + :param preview: The location of the avatar preview., defaults to None + :type preview: Optional[str], optional + """ + super().__init__(**kwargs) + self.small = small + self.large = large + self.preview = preview + +class UserAvatar(BaseObject): + def __init__(self, *, pic_urls: Optional[UserAvatarPicUrlsField] = None, **kwargs): + """ + :param pic_urls: Represents an object with user avatar URLs., defaults to None + :type pic_urls: Optional[UserAvatarPicUrlsField], optional + """ + super().__init__(**kwargs) + self.pic_urls = pic_urls \ No newline at end of file diff --git a/box_sdk_gen/schemas/user_base.py b/box_sdk_gen/schemas/user_base.py new file mode 100644 index 000000000..7f834fb43 --- /dev/null +++ b/box_sdk_gen/schemas/user_base.py @@ -0,0 +1,21 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class UserBaseTypeField(str, Enum): + USER = 'user' + +class UserBase(BaseObject): + _discriminator = 'type', {'user'} + def __init__(self, id: str, *, type: UserBaseTypeField = UserBaseTypeField.USER, **kwargs): + """ + :param id: The unique identifier for this user + :type id: str + :param type: `user`, defaults to UserBaseTypeField.USER + :type type: UserBaseTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type \ No newline at end of file diff --git a/box_sdk_gen/schemas/user_collaborations.py b/box_sdk_gen/schemas/user_collaborations.py new file mode 100644 index 000000000..04925408a --- /dev/null +++ b/box_sdk_gen/schemas/user_collaborations.py @@ -0,0 +1,26 @@ +from typing import Optional + +from box_sdk_gen.schemas.user_base import UserBaseTypeField + +from box_sdk_gen.schemas.user_base import UserBase + +from box_sdk_gen.box.errors import BoxSDKError + +class UserCollaborations(UserBase): + def __init__(self, id: str, *, name: Optional[str] = None, login: Optional[str] = None, is_active: Optional[bool] = None, type: UserBaseTypeField = UserBaseTypeField.USER, **kwargs): + """ + :param id: The unique identifier for this user + :type id: str + :param name: The display name of this user. If the collaboration status is `pending`, an empty string is returned., defaults to None + :type name: Optional[str], optional + :param login: The primary email address of this user. If the collaboration status is `pending`, an empty string is returned., defaults to None + :type login: Optional[str], optional + :param is_active: If set to `false`, the user is either deactivated or deleted., defaults to None + :type is_active: Optional[bool], optional + :param type: `user`, defaults to UserBaseTypeField.USER + :type type: UserBaseTypeField, optional + """ + super().__init__(id=id, type=type, **kwargs) + self.name = name + self.login = login + self.is_active = is_active \ No newline at end of file diff --git a/box_sdk_gen/schemas/user_full.py b/box_sdk_gen/schemas/user_full.py new file mode 100644 index 000000000..321fe7e2d --- /dev/null +++ b/box_sdk_gen/schemas/user_full.py @@ -0,0 +1,135 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from box_sdk_gen.schemas.user_base import UserBaseTypeField + +from box_sdk_gen.schemas.user_base import UserBase + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.internal.utils import DateTime + +from box_sdk_gen.schemas.user import UserStatusField + +from box_sdk_gen.schemas.user import UserNotificationEmailField + +from box_sdk_gen.schemas.user import User + +from box_sdk_gen.schemas.tracking_code import TrackingCode + +from box_sdk_gen.box.errors import BoxSDKError + +class UserFullRoleField(str, Enum): + ADMIN = 'admin' + COADMIN = 'coadmin' + USER = 'user' + +class UserFullEnterpriseTypeField(str, Enum): + ENTERPRISE = 'enterprise' + +class UserFullEnterpriseField(BaseObject): + _discriminator = 'type', {'enterprise'} + def __init__(self, *, id: Optional[str] = None, type: Optional[UserFullEnterpriseTypeField] = None, name: Optional[str] = None, **kwargs): + """ + :param id: The unique identifier for this enterprise., defaults to None + :type id: Optional[str], optional + :param type: `enterprise`, defaults to None + :type type: Optional[UserFullEnterpriseTypeField], optional + :param name: The name of the enterprise, defaults to None + :type name: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.name = name + +class UserFull(User): + def __init__(self, id: str, *, role: Optional[UserFullRoleField] = None, tracking_codes: Optional[List[TrackingCode]] = None, can_see_managed_users: Optional[bool] = None, is_sync_enabled: Optional[bool] = None, is_external_collab_restricted: Optional[bool] = None, is_exempt_from_device_limits: Optional[bool] = None, is_exempt_from_login_verification: Optional[bool] = None, enterprise: Optional[UserFullEnterpriseField] = None, my_tags: Optional[List[str]] = None, hostname: Optional[str] = None, is_platform_access_only: Optional[bool] = None, external_app_user_id: Optional[str] = None, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, language: Optional[str] = None, timezone: Optional[str] = None, space_amount: Optional[int] = None, space_used: Optional[int] = None, max_upload_size: Optional[int] = None, status: Optional[UserStatusField] = None, job_title: Optional[str] = None, phone: Optional[str] = None, address: Optional[str] = None, avatar_url: Optional[str] = None, notification_email: Optional[UserNotificationEmailField] = None, name: Optional[str] = None, login: Optional[str] = None, type: UserBaseTypeField = UserBaseTypeField.USER, **kwargs): + """ + :param id: The unique identifier for this user + :type id: str + :param role: The user’s enterprise role, defaults to None + :type role: Optional[UserFullRoleField], optional + :param tracking_codes: Tracking codes allow an admin to generate reports from the +admin console and assign an attribute to a specific group +of users. This setting must be enabled for an enterprise +before it can be used., defaults to None + :type tracking_codes: Optional[List[TrackingCode]], optional + :param can_see_managed_users: Whether the user can see other enterprise users in their contact list, defaults to None + :type can_see_managed_users: Optional[bool], optional + :param is_sync_enabled: Whether the user can use Box Sync, defaults to None + :type is_sync_enabled: Optional[bool], optional + :param is_external_collab_restricted: Whether the user is allowed to collaborate with users outside their +enterprise, defaults to None + :type is_external_collab_restricted: Optional[bool], optional + :param is_exempt_from_device_limits: Whether to exempt the user from Enterprise device limits, defaults to None + :type is_exempt_from_device_limits: Optional[bool], optional + :param is_exempt_from_login_verification: Whether the user must use two-factor authentication, defaults to None + :type is_exempt_from_login_verification: Optional[bool], optional + :param my_tags: Tags for all files and folders owned by the user. Values returned +will only contain tags that were set by the requester., defaults to None + :type my_tags: Optional[List[str]], optional + :param hostname: The root (protocol, subdomain, domain) of any links that need to be +generated for the user, defaults to None + :type hostname: Optional[str], optional + :param is_platform_access_only: Whether the user is an App User, defaults to None + :type is_platform_access_only: Optional[bool], optional + :param external_app_user_id: An external identifier for an app user, which can be used to look up +the user. This can be used to tie user IDs from external identity +providers to Box users., defaults to None + :type external_app_user_id: Optional[str], optional + :param created_at: When the user object was created, defaults to None + :type created_at: Optional[DateTime], optional + :param modified_at: When the user object was last modified, defaults to None + :type modified_at: Optional[DateTime], optional + :param language: The language of the user, formatted in modified version of the +[ISO 639-1](/guides/api-calls/language-codes) format., defaults to None + :type language: Optional[str], optional + :param timezone: The user's timezone, defaults to None + :type timezone: Optional[str], optional + :param space_amount: The user’s total available space amount in bytes, defaults to None + :type space_amount: Optional[int], optional + :param space_used: The amount of space in use by the user, defaults to None + :type space_used: Optional[int], optional + :param max_upload_size: The maximum individual file size in bytes the user can have, defaults to None + :type max_upload_size: Optional[int], optional + :param status: The user's account status, defaults to None + :type status: Optional[UserStatusField], optional + :param job_title: The user’s job title, defaults to None + :type job_title: Optional[str], optional + :param phone: The user’s phone number, defaults to None + :type phone: Optional[str], optional + :param address: The user’s address, defaults to None + :type address: Optional[str], optional + :param avatar_url: URL of the user’s avatar image, defaults to None + :type avatar_url: Optional[str], optional + :param notification_email: An alternate notification email address to which email +notifications are sent. When it's confirmed, this will be +the email address to which notifications are sent instead of +to the primary email address., defaults to None + :type notification_email: Optional[UserNotificationEmailField], optional + :param name: The display name of this user, defaults to None + :type name: Optional[str], optional + :param login: The primary email address of this user, defaults to None + :type login: Optional[str], optional + :param type: `user`, defaults to UserBaseTypeField.USER + :type type: UserBaseTypeField, optional + """ + super().__init__(id=id, created_at=created_at, modified_at=modified_at, language=language, timezone=timezone, space_amount=space_amount, space_used=space_used, max_upload_size=max_upload_size, status=status, job_title=job_title, phone=phone, address=address, avatar_url=avatar_url, notification_email=notification_email, name=name, login=login, type=type, **kwargs) + self.role = role + self.tracking_codes = tracking_codes + self.can_see_managed_users = can_see_managed_users + self.is_sync_enabled = is_sync_enabled + self.is_external_collab_restricted = is_external_collab_restricted + self.is_exempt_from_device_limits = is_exempt_from_device_limits + self.is_exempt_from_login_verification = is_exempt_from_login_verification + self.enterprise = enterprise + self.my_tags = my_tags + self.hostname = hostname + self.is_platform_access_only = is_platform_access_only + self.external_app_user_id = external_app_user_id \ No newline at end of file diff --git a/box_sdk_gen/schemas/user_integration_mappings.py b/box_sdk_gen/schemas/user_integration_mappings.py new file mode 100644 index 000000000..f6f20eb0a --- /dev/null +++ b/box_sdk_gen/schemas/user_integration_mappings.py @@ -0,0 +1,23 @@ +from typing import Optional + +from box_sdk_gen.schemas.user_base import UserBaseTypeField + +from box_sdk_gen.schemas.user_base import UserBase + +from box_sdk_gen.box.errors import BoxSDKError + +class UserIntegrationMappings(UserBase): + def __init__(self, id: str, *, name: Optional[str] = None, login: Optional[str] = None, type: UserBaseTypeField = UserBaseTypeField.USER, **kwargs): + """ + :param id: The unique identifier for this user + :type id: str + :param name: The display name of this user, defaults to None + :type name: Optional[str], optional + :param login: The primary email address of this user, defaults to None + :type login: Optional[str], optional + :param type: `user`, defaults to UserBaseTypeField.USER + :type type: UserBaseTypeField, optional + """ + super().__init__(id=id, type=type, **kwargs) + self.name = name + self.login = login \ No newline at end of file diff --git a/box_sdk_gen/schemas/user_mini.py b/box_sdk_gen/schemas/user_mini.py new file mode 100644 index 000000000..250a45f2c --- /dev/null +++ b/box_sdk_gen/schemas/user_mini.py @@ -0,0 +1,23 @@ +from typing import Optional + +from box_sdk_gen.schemas.user_base import UserBaseTypeField + +from box_sdk_gen.schemas.user_base import UserBase + +from box_sdk_gen.box.errors import BoxSDKError + +class UserMini(UserBase): + def __init__(self, id: str, *, name: Optional[str] = None, login: Optional[str] = None, type: UserBaseTypeField = UserBaseTypeField.USER, **kwargs): + """ + :param id: The unique identifier for this user + :type id: str + :param name: The display name of this user, defaults to None + :type name: Optional[str], optional + :param login: The primary email address of this user, defaults to None + :type login: Optional[str], optional + :param type: `user`, defaults to UserBaseTypeField.USER + :type type: UserBaseTypeField, optional + """ + super().__init__(id=id, type=type, **kwargs) + self.name = name + self.login = login \ No newline at end of file diff --git a/box_sdk_gen/schemas/users.py b/box_sdk_gen/schemas/users.py new file mode 100644 index 000000000..29e0e9042 --- /dev/null +++ b/box_sdk_gen/schemas/users.py @@ -0,0 +1,68 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from box_sdk_gen.schemas.user_full import UserFull + +from box_sdk_gen.box.errors import BoxSDKError + +class UsersOrderDirectionField(str, Enum): + ASC = 'ASC' + DESC = 'DESC' + +class UsersOrderField(BaseObject): + def __init__(self, *, by: Optional[str] = None, direction: Optional[UsersOrderDirectionField] = None, **kwargs): + """ + :param by: The field to order by, defaults to None + :type by: Optional[str], optional + :param direction: The direction to order by, either ascending or descending, defaults to None + :type direction: Optional[UsersOrderDirectionField], optional + """ + super().__init__(**kwargs) + self.by = by + self.direction = direction + +class Users(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, prev_marker: Optional[str] = None, total_count: Optional[int] = None, offset: Optional[int] = None, order: Optional[List[UsersOrderField]] = None, entries: Optional[List[UserFull]] = 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 + :param total_count: One greater than the offset of the last entry in the entire collection. +The total number of entries in the collection may be less than +`total_count`. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type total_count: Optional[int], optional + :param offset: The 0-based offset of the first entry in this set. This will be the same +as the `offset` query parameter. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type offset: Optional[int], optional + :param order: The order by which items are returned. + +This field is only returned for calls that use offset-based pagination. +For marker-based paginated APIs, this field will be omitted., defaults to None + :type order: Optional[List[UsersOrderField]], optional + :param entries: A list of users, defaults to None + :type entries: Optional[List[UserFull]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.prev_marker = prev_marker + self.total_count = total_count + self.offset = offset + self.order = order + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/v2025_r0/__init__.py b/box_sdk_gen/schemas/v2025_r0/__init__.py new file mode 100644 index 000000000..5c06d33dc --- /dev/null +++ b/box_sdk_gen/schemas/v2025_r0/__init__.py @@ -0,0 +1,39 @@ +from box_sdk_gen.schemas.v2025_r0.client_error_v2025_r0 import * + +from box_sdk_gen.schemas.v2025_r0.doc_gen_batch_base_v2025_r0 import * + +from box_sdk_gen.schemas.v2025_r0.doc_gen_document_generation_data_v2025_r0 import * + +from box_sdk_gen.schemas.v2025_r0.doc_gen_job_base_v2025_r0 import * + +from box_sdk_gen.schemas.v2025_r0.doc_gen_tag_v2025_r0 import * + +from box_sdk_gen.schemas.v2025_r0.doc_gen_tags_v2025_r0 import * + +from box_sdk_gen.schemas.v2025_r0.doc_gen_tags_processing_message_v2025_r0 import * + +from box_sdk_gen.schemas.v2025_r0.enterprise_reference_v2025_r0 import * + +from box_sdk_gen.schemas.v2025_r0.file_reference_v2025_r0 import * + +from box_sdk_gen.schemas.v2025_r0.doc_gen_template_create_request_v2025_r0 import * + +from box_sdk_gen.schemas.v2025_r0.doc_gen_template_base_v2025_r0 import * + +from box_sdk_gen.schemas.v2025_r0.doc_gen_template_v2025_r0 import * + +from box_sdk_gen.schemas.v2025_r0.doc_gen_templates_v2025_r0 import * + +from box_sdk_gen.schemas.v2025_r0.file_version_base_v2025_r0 import * + +from box_sdk_gen.schemas.v2025_r0.doc_gen_job_v2025_r0 import * + +from box_sdk_gen.schemas.v2025_r0.doc_gen_jobs_v2025_r0 import * + +from box_sdk_gen.schemas.v2025_r0.doc_gen_batch_create_request_v2025_r0 import * + +from box_sdk_gen.schemas.v2025_r0.user_base_v2025_r0 import * + +from box_sdk_gen.schemas.v2025_r0.doc_gen_job_full_v2025_r0 import * + +from box_sdk_gen.schemas.v2025_r0.doc_gen_jobs_full_v2025_r0 import * \ No newline at end of file diff --git a/box_sdk_gen/schemas/v2025_r0/client_error_v2025_r0.py b/box_sdk_gen/schemas/v2025_r0/client_error_v2025_r0.py new file mode 100644 index 000000000..e48033d9a --- /dev/null +++ b/box_sdk_gen/schemas/v2025_r0/client_error_v2025_r0.py @@ -0,0 +1,69 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class ClientErrorV2025R0TypeField(str, Enum): + ERROR = 'error' + +class ClientErrorV2025R0CodeField(str, Enum): + CREATED = 'created' + ACCEPTED = 'accepted' + NO_CONTENT = 'no_content' + REDIRECT = 'redirect' + NOT_MODIFIED = 'not_modified' + BAD_REQUEST = 'bad_request' + UNAUTHORIZED = 'unauthorized' + FORBIDDEN = 'forbidden' + NOT_FOUND = 'not_found' + METHOD_NOT_ALLOWED = 'method_not_allowed' + CONFLICT = 'conflict' + PRECONDITION_FAILED = 'precondition_failed' + TOO_MANY_REQUESTS = 'too_many_requests' + INTERNAL_SERVER_ERROR = 'internal_server_error' + UNAVAILABLE = 'unavailable' + ITEM_NAME_INVALID = 'item_name_invalid' + INSUFFICIENT_SCOPE = 'insufficient_scope' + +class ClientErrorV2025R0ContextInfoField(BaseObject): + def __init__(self, *, message: Optional[str] = None, **kwargs): + """ + :param message: More details on the error., defaults to None + :type message: Optional[str], optional + """ + super().__init__(**kwargs) + self.message = message + +class ClientErrorV2025R0(BaseObject): + _discriminator = 'type', {'error'} + def __init__(self, *, type: Optional[ClientErrorV2025R0TypeField] = None, status: Optional[int] = None, code: Optional[ClientErrorV2025R0CodeField] = None, message: Optional[str] = None, context_info: Optional[ClientErrorV2025R0ContextInfoField] = None, help_url: Optional[str] = None, request_id: Optional[str] = None, **kwargs): + """ + :param type: error, defaults to None + :type type: Optional[ClientErrorV2025R0TypeField], optional + :param status: The HTTP status of the response., defaults to None + :type status: Optional[int], optional + :param code: A Box-specific error code, defaults to None + :type code: Optional[ClientErrorV2025R0CodeField], optional + :param message: A short message describing the error., defaults to None + :type message: Optional[str], optional + :param context_info: A free-form object that contains additional context +about the error. The possible fields are defined on +a per-endpoint basis. `message` is only one example., defaults to None + :type context_info: Optional[ClientErrorV2025R0ContextInfoField], optional + :param help_url: A URL that links to more information about why this error occurred., defaults to None + :type help_url: Optional[str], optional + :param request_id: A unique identifier for this response, which can be used +when contacting Box support., defaults to None + :type request_id: Optional[str], optional + """ + super().__init__(**kwargs) + self.type = type + self.status = status + self.code = code + self.message = message + self.context_info = context_info + self.help_url = help_url + self.request_id = request_id \ No newline at end of file diff --git a/box_sdk_gen/schemas/v2025_r0/doc_gen_batch_base_v2025_r0.py b/box_sdk_gen/schemas/v2025_r0/doc_gen_batch_base_v2025_r0.py new file mode 100644 index 000000000..8620dd292 --- /dev/null +++ b/box_sdk_gen/schemas/v2025_r0/doc_gen_batch_base_v2025_r0.py @@ -0,0 +1,21 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class DocGenBatchBaseV2025R0TypeField(str, Enum): + DOCGEN_BATCH = 'docgen_batch' + +class DocGenBatchBaseV2025R0(BaseObject): + _discriminator = 'type', {'docgen_batch'} + def __init__(self, id: str, *, type: DocGenBatchBaseV2025R0TypeField = DocGenBatchBaseV2025R0TypeField.DOCGEN_BATCH, **kwargs): + """ + :param id: The unique identifier that represents a Box Doc Gen batch. + :type id: str + :param type: `docgen_batch`, defaults to DocGenBatchBaseV2025R0TypeField.DOCGEN_BATCH + :type type: DocGenBatchBaseV2025R0TypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type \ No newline at end of file diff --git a/box_sdk_gen/schemas/v2025_r0/doc_gen_batch_create_request_v2025_r0.py b/box_sdk_gen/schemas/v2025_r0/doc_gen_batch_create_request_v2025_r0.py new file mode 100644 index 000000000..c2e839281 --- /dev/null +++ b/box_sdk_gen/schemas/v2025_r0/doc_gen_batch_create_request_v2025_r0.py @@ -0,0 +1,47 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import Optional + +from typing import List + +from box_sdk_gen.schemas.v2025_r0.file_reference_v2025_r0 import FileReferenceV2025R0 + +from box_sdk_gen.schemas.v2025_r0.file_version_base_v2025_r0 import FileVersionBaseV2025R0 + +from box_sdk_gen.schemas.v2025_r0.doc_gen_document_generation_data_v2025_r0 import DocGenDocumentGenerationDataV2025R0 + +from box_sdk_gen.box.errors import BoxSDKError + +class DocGenBatchCreateRequestV2025R0DestinationFolderTypeField(str, Enum): + FOLDER = 'folder' + +class DocGenBatchCreateRequestV2025R0DestinationFolderField(BaseObject): + _discriminator = 'type', {'folder'} + def __init__(self, id: str, *, type: DocGenBatchCreateRequestV2025R0DestinationFolderTypeField = DocGenBatchCreateRequestV2025R0DestinationFolderTypeField.FOLDER, **kwargs): + """ + :param id: ID of the folder + :type id: str + :param type: `folder`, defaults to DocGenBatchCreateRequestV2025R0DestinationFolderTypeField.FOLDER + :type type: DocGenBatchCreateRequestV2025R0DestinationFolderTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class DocGenBatchCreateRequestV2025R0(BaseObject): + def __init__(self, file: FileReferenceV2025R0, input_source: str, destination_folder: DocGenBatchCreateRequestV2025R0DestinationFolderField, output_type: str, document_generation_data: List[DocGenDocumentGenerationDataV2025R0], *, file_version: Optional[FileVersionBaseV2025R0] = None, **kwargs): + """ + :param input_source: Source of input. The value has to be `api` for all the API-based document generation requests. + :type input_source: str + :param output_type: Type of the output file. + :type output_type: str + """ + super().__init__(**kwargs) + self.file = file + self.input_source = input_source + self.destination_folder = destination_folder + self.output_type = output_type + self.document_generation_data = document_generation_data + self.file_version = file_version \ No newline at end of file diff --git a/box_sdk_gen/schemas/v2025_r0/doc_gen_document_generation_data_v2025_r0.py b/box_sdk_gen/schemas/v2025_r0/doc_gen_document_generation_data_v2025_r0.py new file mode 100644 index 000000000..2f6fec982 --- /dev/null +++ b/box_sdk_gen/schemas/v2025_r0/doc_gen_document_generation_data_v2025_r0.py @@ -0,0 +1,15 @@ +from typing import Dict + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class DocGenDocumentGenerationDataV2025R0(BaseObject): + def __init__(self, generated_file_name: str, user_input: Dict, **kwargs): + """ + :param generated_file_name: File name of the output file. + :type generated_file_name: str + """ + super().__init__(**kwargs) + self.generated_file_name = generated_file_name + self.user_input = user_input \ No newline at end of file diff --git a/box_sdk_gen/schemas/v2025_r0/doc_gen_job_base_v2025_r0.py b/box_sdk_gen/schemas/v2025_r0/doc_gen_job_base_v2025_r0.py new file mode 100644 index 000000000..e83a0c8ea --- /dev/null +++ b/box_sdk_gen/schemas/v2025_r0/doc_gen_job_base_v2025_r0.py @@ -0,0 +1,21 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class DocGenJobBaseV2025R0TypeField(str, Enum): + DOCGEN_JOB = 'docgen_job' + +class DocGenJobBaseV2025R0(BaseObject): + _discriminator = 'type', {'docgen_job'} + def __init__(self, id: str, *, type: DocGenJobBaseV2025R0TypeField = DocGenJobBaseV2025R0TypeField.DOCGEN_JOB, **kwargs): + """ + :param id: The unique identifier that represent a Box Doc Gen job. + :type id: str + :param type: `docgen_job`, defaults to DocGenJobBaseV2025R0TypeField.DOCGEN_JOB + :type type: DocGenJobBaseV2025R0TypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type \ No newline at end of file diff --git a/box_sdk_gen/schemas/v2025_r0/doc_gen_job_full_v2025_r0.py b/box_sdk_gen/schemas/v2025_r0/doc_gen_job_full_v2025_r0.py new file mode 100644 index 000000000..3d852755a --- /dev/null +++ b/box_sdk_gen/schemas/v2025_r0/doc_gen_job_full_v2025_r0.py @@ -0,0 +1,43 @@ +from typing import Optional + +from box_sdk_gen.schemas.v2025_r0.doc_gen_job_base_v2025_r0 import DocGenJobBaseV2025R0TypeField + +from box_sdk_gen.schemas.v2025_r0.doc_gen_job_base_v2025_r0 import DocGenJobBaseV2025R0 + +from box_sdk_gen.schemas.v2025_r0.doc_gen_batch_base_v2025_r0 import DocGenBatchBaseV2025R0 + +from box_sdk_gen.schemas.v2025_r0.file_reference_v2025_r0 import FileReferenceV2025R0 + +from box_sdk_gen.schemas.v2025_r0.file_version_base_v2025_r0 import FileVersionBaseV2025R0 + +from box_sdk_gen.schemas.v2025_r0.doc_gen_job_v2025_r0 import DocGenJobV2025R0StatusField + +from box_sdk_gen.schemas.v2025_r0.doc_gen_job_v2025_r0 import DocGenJobV2025R0 + +from box_sdk_gen.schemas.v2025_r0.user_base_v2025_r0 import UserBaseV2025R0 + +from box_sdk_gen.schemas.v2025_r0.enterprise_reference_v2025_r0 import EnterpriseReferenceV2025R0 + +from box_sdk_gen.box.errors import BoxSDKError + +class DocGenJobFullV2025R0(DocGenJobV2025R0): + def __init__(self, created_by: UserBaseV2025R0, enterprise: EnterpriseReferenceV2025R0, source: str, batch: DocGenBatchBaseV2025R0, template_file: FileReferenceV2025R0, template_file_version: FileVersionBaseV2025R0, status: DocGenJobV2025R0StatusField, output_type: str, id: str, *, created_at: Optional[str] = None, output_file: Optional[Optional[FileReferenceV2025R0]] = None, output_file_version: Optional[Optional[FileVersionBaseV2025R0]] = None, type: DocGenJobBaseV2025R0TypeField = DocGenJobBaseV2025R0TypeField.DOCGEN_JOB, **kwargs): + """ + :param source: Source of the request. + :type source: str + :param status: Status of the job. + :type status: DocGenJobV2025R0StatusField + :param output_type: Type of the generated file. + :type output_type: str + :param id: The unique identifier that represent a Box Doc Gen job. + :type id: str + :param created_at: Time of job creation., defaults to None + :type created_at: Optional[str], optional + :param type: `docgen_job`, defaults to DocGenJobBaseV2025R0TypeField.DOCGEN_JOB + :type type: DocGenJobBaseV2025R0TypeField, optional + """ + super().__init__(batch=batch, template_file=template_file, template_file_version=template_file_version, status=status, output_type=output_type, id=id, output_file=output_file, output_file_version=output_file_version, type=type, **kwargs) + self.created_by = created_by + self.enterprise = enterprise + self.source = source + self.created_at = created_at \ No newline at end of file diff --git a/box_sdk_gen/schemas/v2025_r0/doc_gen_job_v2025_r0.py b/box_sdk_gen/schemas/v2025_r0/doc_gen_job_v2025_r0.py new file mode 100644 index 000000000..5e1de96f6 --- /dev/null +++ b/box_sdk_gen/schemas/v2025_r0/doc_gen_job_v2025_r0.py @@ -0,0 +1,43 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.schemas.v2025_r0.doc_gen_job_base_v2025_r0 import DocGenJobBaseV2025R0TypeField + +from box_sdk_gen.schemas.v2025_r0.doc_gen_job_base_v2025_r0 import DocGenJobBaseV2025R0 + +from box_sdk_gen.schemas.v2025_r0.doc_gen_batch_base_v2025_r0 import DocGenBatchBaseV2025R0 + +from box_sdk_gen.schemas.v2025_r0.file_reference_v2025_r0 import FileReferenceV2025R0 + +from box_sdk_gen.schemas.v2025_r0.file_version_base_v2025_r0 import FileVersionBaseV2025R0 + +from box_sdk_gen.box.errors import BoxSDKError + +class DocGenJobV2025R0StatusField(str, Enum): + SUBMITTED = 'submitted' + COMPLETED = 'completed' + FAILED = 'failed' + COMPLETED_WITH_ERROR = 'completed_with_error' + PENDING = 'pending' + +class DocGenJobV2025R0(DocGenJobBaseV2025R0): + def __init__(self, batch: DocGenBatchBaseV2025R0, template_file: FileReferenceV2025R0, template_file_version: FileVersionBaseV2025R0, status: DocGenJobV2025R0StatusField, output_type: str, id: str, *, output_file: Optional[Optional[FileReferenceV2025R0]] = None, output_file_version: Optional[Optional[FileVersionBaseV2025R0]] = None, type: DocGenJobBaseV2025R0TypeField = DocGenJobBaseV2025R0TypeField.DOCGEN_JOB, **kwargs): + """ + :param status: Status of the job. + :type status: DocGenJobV2025R0StatusField + :param output_type: Type of the generated file. + :type output_type: str + :param id: The unique identifier that represent a Box Doc Gen job. + :type id: str + :param type: `docgen_job`, defaults to DocGenJobBaseV2025R0TypeField.DOCGEN_JOB + :type type: DocGenJobBaseV2025R0TypeField, optional + """ + super().__init__(id=id, type=type, **kwargs) + self.batch = batch + self.template_file = template_file + self.template_file_version = template_file_version + self.status = status + self.output_type = output_type + self.output_file = output_file + self.output_file_version = output_file_version \ No newline at end of file diff --git a/box_sdk_gen/schemas/v2025_r0/doc_gen_jobs_full_v2025_r0.py b/box_sdk_gen/schemas/v2025_r0/doc_gen_jobs_full_v2025_r0.py new file mode 100644 index 000000000..a43387258 --- /dev/null +++ b/box_sdk_gen/schemas/v2025_r0/doc_gen_jobs_full_v2025_r0.py @@ -0,0 +1,29 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.v2025_r0.doc_gen_job_full_v2025_r0 import DocGenJobFullV2025R0 + +from box_sdk_gen.box.errors import BoxSDKError + +class DocGenJobsFullV2025R0(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, prev_marker: Optional[str] = None, entries: Optional[List[DocGenJobFullV2025R0]] = 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 + :param entries: List of jobs., defaults to None + :type entries: Optional[List[DocGenJobFullV2025R0]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.prev_marker = prev_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/v2025_r0/doc_gen_jobs_v2025_r0.py b/box_sdk_gen/schemas/v2025_r0/doc_gen_jobs_v2025_r0.py new file mode 100644 index 000000000..d538184e0 --- /dev/null +++ b/box_sdk_gen/schemas/v2025_r0/doc_gen_jobs_v2025_r0.py @@ -0,0 +1,29 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.v2025_r0.doc_gen_job_v2025_r0 import DocGenJobV2025R0 + +from box_sdk_gen.box.errors import BoxSDKError + +class DocGenJobsV2025R0(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, prev_marker: Optional[str] = None, entries: Optional[List[DocGenJobV2025R0]] = 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 + :param entries: List of jobs., defaults to None + :type entries: Optional[List[DocGenJobV2025R0]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.prev_marker = prev_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/v2025_r0/doc_gen_tag_v2025_r0.py b/box_sdk_gen/schemas/v2025_r0/doc_gen_tag_v2025_r0.py new file mode 100644 index 000000000..f12bbe71e --- /dev/null +++ b/box_sdk_gen/schemas/v2025_r0/doc_gen_tag_v2025_r0.py @@ -0,0 +1,30 @@ +from enum import Enum + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class DocGenTagV2025R0TagTypeField(str, Enum): + TEXT = 'text' + ARITHMETIC = 'arithmetic' + CONDITIONAL = 'conditional' + FOR_LOOP = 'for-loop' + TABLE_LOOP = 'table-loop' + IMAGE = 'image' + +class DocGenTagV2025R0(BaseObject): + def __init__(self, tag_content: str, tag_type: DocGenTagV2025R0TagTypeField, json_paths: List[str], **kwargs): + """ + :param tag_content: The content of the tag. + :type tag_content: str + :param tag_type: Type of the tag. + :type tag_type: DocGenTagV2025R0TagTypeField + :param json_paths: List of the paths. + :type json_paths: List[str] + """ + super().__init__(**kwargs) + self.tag_content = tag_content + self.tag_type = tag_type + self.json_paths = json_paths \ No newline at end of file diff --git a/box_sdk_gen/schemas/v2025_r0/doc_gen_tags_processing_message_v2025_r0.py b/box_sdk_gen/schemas/v2025_r0/doc_gen_tags_processing_message_v2025_r0.py new file mode 100644 index 000000000..3e8c824c2 --- /dev/null +++ b/box_sdk_gen/schemas/v2025_r0/doc_gen_tags_processing_message_v2025_r0.py @@ -0,0 +1,12 @@ +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class DocGenTagsProcessingMessageV2025R0(BaseObject): + def __init__(self, message: str, **kwargs): + """ + :param message: A message informing the user that document tags are still being processed. + :type message: str + """ + super().__init__(**kwargs) + self.message = message \ No newline at end of file diff --git a/box_sdk_gen/schemas/v2025_r0/doc_gen_tags_v2025_r0.py b/box_sdk_gen/schemas/v2025_r0/doc_gen_tags_v2025_r0.py new file mode 100644 index 000000000..81b17a98b --- /dev/null +++ b/box_sdk_gen/schemas/v2025_r0/doc_gen_tags_v2025_r0.py @@ -0,0 +1,29 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.v2025_r0.doc_gen_tag_v2025_r0 import DocGenTagV2025R0 + +from box_sdk_gen.box.errors import BoxSDKError + +class DocGenTagsV2025R0(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, prev_marker: Optional[str] = None, entries: Optional[List[DocGenTagV2025R0]] = 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 + :param entries: List of tags., defaults to None + :type entries: Optional[List[DocGenTagV2025R0]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.prev_marker = prev_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/v2025_r0/doc_gen_template_base_v2025_r0.py b/box_sdk_gen/schemas/v2025_r0/doc_gen_template_base_v2025_r0.py new file mode 100644 index 000000000..12c9de1d5 --- /dev/null +++ b/box_sdk_gen/schemas/v2025_r0/doc_gen_template_base_v2025_r0.py @@ -0,0 +1,12 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.v2025_r0.file_reference_v2025_r0 import FileReferenceV2025R0 + +from box_sdk_gen.box.errors import BoxSDKError + +class DocGenTemplateBaseV2025R0(BaseObject): + def __init__(self, *, file: Optional[FileReferenceV2025R0] = None, **kwargs): + super().__init__(**kwargs) + self.file = file \ No newline at end of file diff --git a/box_sdk_gen/schemas/v2025_r0/doc_gen_template_create_request_v2025_r0.py b/box_sdk_gen/schemas/v2025_r0/doc_gen_template_create_request_v2025_r0.py new file mode 100644 index 000000000..f021a28c3 --- /dev/null +++ b/box_sdk_gen/schemas/v2025_r0/doc_gen_template_create_request_v2025_r0.py @@ -0,0 +1,10 @@ +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.v2025_r0.file_reference_v2025_r0 import FileReferenceV2025R0 + +from box_sdk_gen.box.errors import BoxSDKError + +class DocGenTemplateCreateRequestV2025R0(BaseObject): + def __init__(self, file: FileReferenceV2025R0, **kwargs): + super().__init__(**kwargs) + self.file = file \ No newline at end of file diff --git a/box_sdk_gen/schemas/v2025_r0/doc_gen_template_v2025_r0.py b/box_sdk_gen/schemas/v2025_r0/doc_gen_template_v2025_r0.py new file mode 100644 index 000000000..100732956 --- /dev/null +++ b/box_sdk_gen/schemas/v2025_r0/doc_gen_template_v2025_r0.py @@ -0,0 +1,16 @@ +from typing import Optional + +from box_sdk_gen.schemas.v2025_r0.file_reference_v2025_r0 import FileReferenceV2025R0 + +from box_sdk_gen.schemas.v2025_r0.doc_gen_template_base_v2025_r0 import DocGenTemplateBaseV2025R0 + +from box_sdk_gen.box.errors import BoxSDKError + +class DocGenTemplateV2025R0(DocGenTemplateBaseV2025R0): + def __init__(self, *, file_name: Optional[str] = None, file: Optional[FileReferenceV2025R0] = None, **kwargs): + """ + :param file_name: The name of the template, defaults to None + :type file_name: Optional[str], optional + """ + super().__init__(file=file, **kwargs) + self.file_name = file_name \ No newline at end of file diff --git a/box_sdk_gen/schemas/v2025_r0/doc_gen_templates_v2025_r0.py b/box_sdk_gen/schemas/v2025_r0/doc_gen_templates_v2025_r0.py new file mode 100644 index 000000000..34c3079a1 --- /dev/null +++ b/box_sdk_gen/schemas/v2025_r0/doc_gen_templates_v2025_r0.py @@ -0,0 +1,29 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.v2025_r0.doc_gen_template_v2025_r0 import DocGenTemplateV2025R0 + +from box_sdk_gen.box.errors import BoxSDKError + +class DocGenTemplatesV2025R0(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, prev_marker: Optional[str] = None, entries: Optional[List[DocGenTemplateV2025R0]] = 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 + :param entries: A list of templates., defaults to None + :type entries: Optional[List[DocGenTemplateV2025R0]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.prev_marker = prev_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/v2025_r0/enterprise_reference_v2025_r0.py b/box_sdk_gen/schemas/v2025_r0/enterprise_reference_v2025_r0.py new file mode 100644 index 000000000..cc30d0467 --- /dev/null +++ b/box_sdk_gen/schemas/v2025_r0/enterprise_reference_v2025_r0.py @@ -0,0 +1,23 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class EnterpriseReferenceV2025R0TypeField(str, Enum): + ENTERPRISE = 'enterprise' + +class EnterpriseReferenceV2025R0(BaseObject): + _discriminator = 'type', {'enterprise'} + def __init__(self, *, id: Optional[str] = None, type: Optional[EnterpriseReferenceV2025R0TypeField] = None, **kwargs): + """ + :param id: The unique identifier for this enterprise, defaults to None + :type id: Optional[str], optional + :param type: `enterprise`, defaults to None + :type type: Optional[EnterpriseReferenceV2025R0TypeField], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type \ No newline at end of file diff --git a/box_sdk_gen/schemas/v2025_r0/file_reference_v2025_r0.py b/box_sdk_gen/schemas/v2025_r0/file_reference_v2025_r0.py new file mode 100644 index 000000000..b9b422ccd --- /dev/null +++ b/box_sdk_gen/schemas/v2025_r0/file_reference_v2025_r0.py @@ -0,0 +1,21 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class FileReferenceV2025R0TypeField(str, Enum): + FILE = 'file' + +class FileReferenceV2025R0(BaseObject): + _discriminator = 'type', {'file'} + def __init__(self, id: str, *, type: FileReferenceV2025R0TypeField = FileReferenceV2025R0TypeField.FILE, **kwargs): + """ + :param id: ID of the object + :type id: str + :param type: `file`, defaults to FileReferenceV2025R0TypeField.FILE + :type type: FileReferenceV2025R0TypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type \ No newline at end of file diff --git a/box_sdk_gen/schemas/v2025_r0/file_version_base_v2025_r0.py b/box_sdk_gen/schemas/v2025_r0/file_version_base_v2025_r0.py new file mode 100644 index 000000000..7f101654d --- /dev/null +++ b/box_sdk_gen/schemas/v2025_r0/file_version_base_v2025_r0.py @@ -0,0 +1,21 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class FileVersionBaseV2025R0TypeField(str, Enum): + FILE_VERSION = 'file_version' + +class FileVersionBaseV2025R0(BaseObject): + _discriminator = 'type', {'file_version'} + def __init__(self, id: str, *, type: FileVersionBaseV2025R0TypeField = FileVersionBaseV2025R0TypeField.FILE_VERSION, **kwargs): + """ + :param id: The unique identifier that represent a file version. + :type id: str + :param type: `file_version`, defaults to FileVersionBaseV2025R0TypeField.FILE_VERSION + :type type: FileVersionBaseV2025R0TypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type \ No newline at end of file diff --git a/box_sdk_gen/schemas/v2025_r0/user_base_v2025_r0.py b/box_sdk_gen/schemas/v2025_r0/user_base_v2025_r0.py new file mode 100644 index 000000000..579a6e9a9 --- /dev/null +++ b/box_sdk_gen/schemas/v2025_r0/user_base_v2025_r0.py @@ -0,0 +1,21 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class UserBaseV2025R0TypeField(str, Enum): + USER = 'user' + +class UserBaseV2025R0(BaseObject): + _discriminator = 'type', {'user'} + def __init__(self, id: str, *, type: UserBaseV2025R0TypeField = UserBaseV2025R0TypeField.USER, **kwargs): + """ + :param id: The unique identifier for this user + :type id: str + :param type: user, defaults to UserBaseV2025R0TypeField.USER + :type type: UserBaseV2025R0TypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type \ No newline at end of file diff --git a/box_sdk_gen/schemas/watermark.py b/box_sdk_gen/schemas/watermark.py new file mode 100644 index 000000000..f3220c169 --- /dev/null +++ b/box_sdk_gen/schemas/watermark.py @@ -0,0 +1,24 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class WatermarkWatermarkField(BaseObject): + def __init__(self, *, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, **kwargs): + """ + :param created_at: When this watermark was created, defaults to None + :type created_at: Optional[DateTime], optional + :param modified_at: When this task was modified, defaults to None + :type modified_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.created_at = created_at + self.modified_at = modified_at + +class Watermark(BaseObject): + def __init__(self, *, watermark: Optional[WatermarkWatermarkField] = None, **kwargs): + super().__init__(**kwargs) + self.watermark = watermark \ No newline at end of file diff --git a/box_sdk_gen/schemas/web_link.py b/box_sdk_gen/schemas/web_link.py new file mode 100644 index 000000000..3d72f9143 --- /dev/null +++ b/box_sdk_gen/schemas/web_link.py @@ -0,0 +1,194 @@ +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from enum import Enum + +from typing import Optional + +from box_sdk_gen.schemas.web_link_base import WebLinkBaseTypeField + +from box_sdk_gen.schemas.web_link_base import WebLinkBase + +from box_sdk_gen.schemas.web_link_mini import WebLinkMini + +from box_sdk_gen.schemas.folder_mini import FolderMini + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class WebLinkPathCollectionField(BaseObject): + def __init__(self, total_count: int, entries: List[FolderMini], **kwargs): + """ + :param total_count: The number of folders in this list. + :type total_count: int + :param entries: The parent folders for this item + :type entries: List[FolderMini] + """ + super().__init__(**kwargs) + self.total_count = total_count + self.entries = entries + +class WebLinkSharedLinkAccessField(str, Enum): + OPEN = 'open' + COMPANY = 'company' + COLLABORATORS = 'collaborators' + +class WebLinkSharedLinkEffectiveAccessField(str, Enum): + OPEN = 'open' + COMPANY = 'company' + COLLABORATORS = 'collaborators' + +class WebLinkSharedLinkEffectivePermissionField(str, Enum): + CAN_EDIT = 'can_edit' + CAN_DOWNLOAD = 'can_download' + CAN_PREVIEW = 'can_preview' + NO_ACCESS = 'no_access' + +class WebLinkSharedLinkPermissionsField(BaseObject): + def __init__(self, can_download: bool, can_preview: bool, can_edit: bool, **kwargs): + """ + :param can_download: Defines if the shared link allows for the item to be downloaded. For +shared links on folders, this also applies to any items in the folder. + +This value can be set to `true` when the effective access level is +set to `open` or `company`, not `collaborators`. + :type can_download: bool + :param can_preview: Defines if the shared link allows for the item to be previewed. + +This value is always `true`. For shared links on folders this also +applies to any items in the folder. + :type can_preview: bool + :param can_edit: Defines if the shared link allows for the item to be edited. + +This value can only be `true` if `can_download` is also `true` and if +the item has a type of `file`. + :type can_edit: bool + """ + super().__init__(**kwargs) + self.can_download = can_download + self.can_preview = can_preview + self.can_edit = can_edit + +class WebLinkSharedLinkField(BaseObject): + def __init__(self, url: str, effective_access: WebLinkSharedLinkEffectiveAccessField, effective_permission: WebLinkSharedLinkEffectivePermissionField, is_password_enabled: bool, download_count: int, preview_count: int, *, download_url: Optional[str] = None, vanity_url: Optional[str] = None, vanity_name: Optional[str] = None, access: Optional[WebLinkSharedLinkAccessField] = None, unshared_at: Optional[DateTime] = None, permissions: Optional[WebLinkSharedLinkPermissionsField] = None, **kwargs): + """ + :param url: The URL that can be used to access the item on Box. + +This URL will display the item in Box's preview UI where the file +can be downloaded if allowed. + +This URL will continue to work even when a custom `vanity_url` +has been set for this shared link. + :type url: str + :param effective_access: The effective access level for the shared link. This can be a more +restrictive access level than the value in the `access` field when the +enterprise settings restrict the allowed access levels. + :type effective_access: WebLinkSharedLinkEffectiveAccessField + :param effective_permission: The effective permissions for this shared link. +These result in the more restrictive combination of +the share link permissions and the item permissions set +by the administrator, the owner, and any ancestor item +such as a folder. + :type effective_permission: WebLinkSharedLinkEffectivePermissionField + :param is_password_enabled: Defines if the shared link requires a password to access the item. + :type is_password_enabled: bool + :param download_count: The number of times this item has been downloaded. + :type download_count: int + :param preview_count: The number of times this item has been previewed. + :type preview_count: int + :param download_url: A URL that can be used to download the file. This URL can be used in +a browser to download the file. This URL includes the file +extension so that the file will be saved with the right file type. + +This property will be `null` for folders., defaults to None + :type download_url: Optional[str], optional + :param vanity_url: The "Custom URL" that can also be used to preview the item on Box. Custom +URLs can only be created or modified in the Box Web application., defaults to None + :type vanity_url: Optional[str], optional + :param vanity_name: The custom name of a shared link, as used in the `vanity_url` field., defaults to None + :type vanity_name: Optional[str], optional + :param access: The access level for this shared link. + +* `open` - provides access to this item to anyone with this link +* `company` - only provides access to this item to people the same company +* `collaborators` - only provides access to this item to people who are + collaborators on this item + +If this field is omitted when creating the shared link, the access level +will be set to the default access level specified by the enterprise admin., defaults to None + :type access: Optional[WebLinkSharedLinkAccessField], optional + :param unshared_at: The date and time when this link will be unshared. This field can only be +set by users with paid accounts., defaults to None + :type unshared_at: Optional[DateTime], optional + :param permissions: Defines if this link allows a user to preview, edit, and download an item. +These permissions refer to the shared link only and +do not supersede permissions applied to the item itself., defaults to None + :type permissions: Optional[WebLinkSharedLinkPermissionsField], optional + """ + super().__init__(**kwargs) + self.url = url + self.effective_access = effective_access + self.effective_permission = effective_permission + self.is_password_enabled = is_password_enabled + self.download_count = download_count + self.preview_count = preview_count + self.download_url = download_url + self.vanity_url = vanity_url + self.vanity_name = vanity_name + self.access = access + self.unshared_at = unshared_at + self.permissions = permissions + +class WebLinkItemStatusField(str, Enum): + ACTIVE = 'active' + TRASHED = 'trashed' + DELETED = 'deleted' + +class WebLink(WebLinkMini): + def __init__(self, id: str, *, parent: Optional[FolderMini] = None, description: Optional[str] = None, path_collection: Optional[WebLinkPathCollectionField] = None, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, trashed_at: Optional[DateTime] = None, purged_at: Optional[DateTime] = None, created_by: Optional[UserMini] = None, modified_by: Optional[UserMini] = None, owned_by: Optional[UserMini] = None, shared_link: Optional[WebLinkSharedLinkField] = None, item_status: Optional[WebLinkItemStatusField] = None, url: Optional[str] = None, sequence_id: Optional[str] = None, name: Optional[str] = None, type: WebLinkBaseTypeField = WebLinkBaseTypeField.WEB_LINK, etag: Optional[str] = None, **kwargs): + """ + :param id: The unique identifier for this web link + :type id: str + :param description: The description accompanying the web link. This is +visible within the Box web application., defaults to None + :type description: Optional[str], optional + :param created_at: When this file was created on Box’s servers., defaults to None + :type created_at: Optional[DateTime], optional + :param modified_at: When this file was last updated on the Box +servers., defaults to None + :type modified_at: Optional[DateTime], optional + :param trashed_at: When this file was moved to the trash., defaults to None + :type trashed_at: Optional[DateTime], optional + :param purged_at: When this file will be permanently deleted., defaults to None + :type purged_at: Optional[DateTime], optional + :param item_status: Whether this item is deleted or not. Values include `active`, +`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 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 + :type name: Optional[str], optional + :param type: `web_link`, defaults to WebLinkBaseTypeField.WEB_LINK + :type type: WebLinkBaseTypeField, optional + :param etag: The entity tag of this web link. Used with `If-Match` +headers., defaults to None + :type etag: Optional[str], optional + """ + super().__init__(id=id, url=url, sequence_id=sequence_id, name=name, type=type, etag=etag, **kwargs) + self.parent = parent + self.description = description + self.path_collection = path_collection + self.created_at = created_at + self.modified_at = modified_at + self.trashed_at = trashed_at + self.purged_at = purged_at + self.created_by = created_by + self.modified_by = modified_by + self.owned_by = owned_by + self.shared_link = shared_link + self.item_status = item_status \ No newline at end of file diff --git a/box_sdk_gen/schemas/web_link_base.py b/box_sdk_gen/schemas/web_link_base.py new file mode 100644 index 000000000..75526861a --- /dev/null +++ b/box_sdk_gen/schemas/web_link_base.py @@ -0,0 +1,27 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class WebLinkBaseTypeField(str, Enum): + WEB_LINK = 'web_link' + +class WebLinkBase(BaseObject): + _discriminator = 'type', {'web_link'} + def __init__(self, id: str, *, type: WebLinkBaseTypeField = WebLinkBaseTypeField.WEB_LINK, etag: Optional[str] = None, **kwargs): + """ + :param id: The unique identifier for this web link + :type id: str + :param type: `web_link`, defaults to WebLinkBaseTypeField.WEB_LINK + :type type: WebLinkBaseTypeField, optional + :param etag: The entity tag of this web link. Used with `If-Match` +headers., defaults to None + :type etag: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.etag = etag \ No newline at end of file diff --git a/box_sdk_gen/schemas/web_link_mini.py b/box_sdk_gen/schemas/web_link_mini.py new file mode 100644 index 000000000..e108f4670 --- /dev/null +++ b/box_sdk_gen/schemas/web_link_mini.py @@ -0,0 +1,27 @@ +from typing import Optional + +from box_sdk_gen.schemas.web_link_base import WebLinkBaseTypeField + +from box_sdk_gen.schemas.web_link_base import WebLinkBase + +from box_sdk_gen.box.errors import BoxSDKError + +class WebLinkMini(WebLinkBase): + def __init__(self, id: str, *, url: Optional[str] = None, sequence_id: Optional[str] = None, name: Optional[str] = None, type: WebLinkBaseTypeField = WebLinkBaseTypeField.WEB_LINK, etag: Optional[str] = None, **kwargs): + """ + :param id: The unique identifier for this web link + :type id: str + :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 + :type name: Optional[str], optional + :param type: `web_link`, defaults to WebLinkBaseTypeField.WEB_LINK + :type type: WebLinkBaseTypeField, optional + :param etag: The entity tag of this web link. Used with `If-Match` +headers., defaults to None + :type etag: Optional[str], optional + """ + super().__init__(id=id, type=type, etag=etag, **kwargs) + self.url = url + self.sequence_id = sequence_id + self.name = name \ No newline at end of file diff --git a/box_sdk_gen/schemas/webhook.py b/box_sdk_gen/schemas/webhook.py new file mode 100644 index 000000000..0f50b3fe7 --- /dev/null +++ b/box_sdk_gen/schemas/webhook.py @@ -0,0 +1,83 @@ +from enum import Enum + +from typing import Optional + +from typing import List + +from box_sdk_gen.schemas.webhook_mini import WebhookMiniTypeField + +from box_sdk_gen.schemas.webhook_mini import WebhookMiniTargetField + +from box_sdk_gen.schemas.webhook_mini import WebhookMini + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class WebhookTriggersField(str, Enum): + FILE_UPLOADED = 'FILE.UPLOADED' + FILE_PREVIEWED = 'FILE.PREVIEWED' + FILE_DOWNLOADED = 'FILE.DOWNLOADED' + FILE_TRASHED = 'FILE.TRASHED' + FILE_DELETED = 'FILE.DELETED' + FILE_RESTORED = 'FILE.RESTORED' + FILE_COPIED = 'FILE.COPIED' + FILE_MOVED = 'FILE.MOVED' + FILE_LOCKED = 'FILE.LOCKED' + FILE_UNLOCKED = 'FILE.UNLOCKED' + FILE_RENAMED = 'FILE.RENAMED' + COMMENT_CREATED = 'COMMENT.CREATED' + COMMENT_UPDATED = 'COMMENT.UPDATED' + COMMENT_DELETED = 'COMMENT.DELETED' + TASK_ASSIGNMENT_CREATED = 'TASK_ASSIGNMENT.CREATED' + TASK_ASSIGNMENT_UPDATED = 'TASK_ASSIGNMENT.UPDATED' + METADATA_INSTANCE_CREATED = 'METADATA_INSTANCE.CREATED' + METADATA_INSTANCE_UPDATED = 'METADATA_INSTANCE.UPDATED' + METADATA_INSTANCE_DELETED = 'METADATA_INSTANCE.DELETED' + FOLDER_CREATED = 'FOLDER.CREATED' + FOLDER_RENAMED = 'FOLDER.RENAMED' + FOLDER_DOWNLOADED = 'FOLDER.DOWNLOADED' + FOLDER_RESTORED = 'FOLDER.RESTORED' + FOLDER_DELETED = 'FOLDER.DELETED' + FOLDER_COPIED = 'FOLDER.COPIED' + FOLDER_MOVED = 'FOLDER.MOVED' + FOLDER_TRASHED = 'FOLDER.TRASHED' + WEBHOOK_DELETED = 'WEBHOOK.DELETED' + COLLABORATION_CREATED = 'COLLABORATION.CREATED' + COLLABORATION_ACCEPTED = 'COLLABORATION.ACCEPTED' + COLLABORATION_REJECTED = 'COLLABORATION.REJECTED' + COLLABORATION_REMOVED = 'COLLABORATION.REMOVED' + COLLABORATION_UPDATED = 'COLLABORATION.UPDATED' + SHARED_LINK_DELETED = 'SHARED_LINK.DELETED' + SHARED_LINK_CREATED = 'SHARED_LINK.CREATED' + SHARED_LINK_UPDATED = 'SHARED_LINK.UPDATED' + SIGN_REQUEST_COMPLETED = 'SIGN_REQUEST.COMPLETED' + SIGN_REQUEST_DECLINED = 'SIGN_REQUEST.DECLINED' + SIGN_REQUEST_EXPIRED = 'SIGN_REQUEST.EXPIRED' + SIGN_REQUEST_SIGNER_EMAIL_BOUNCED = 'SIGN_REQUEST.SIGNER_EMAIL_BOUNCED' + +class Webhook(WebhookMini): + def __init__(self, *, created_by: Optional[UserMini] = None, created_at: Optional[DateTime] = None, address: Optional[str] = None, triggers: Optional[List[WebhookTriggersField]] = None, id: Optional[str] = None, type: Optional[WebhookMiniTypeField] = None, target: Optional[WebhookMiniTargetField] = None, **kwargs): + """ + :param created_at: A timestamp identifying the time that +the webhook was created., defaults to None + :type created_at: Optional[DateTime], optional + :param address: The URL that is notified by this webhook, defaults to None + :type address: Optional[str], optional + :param triggers: An array of event names that this webhook is +to be triggered for, defaults to None + :type triggers: Optional[List[WebhookTriggersField]], optional + :param id: The unique identifier for this webhook., defaults to None + :type id: Optional[str], optional + :param type: `webhook`, defaults to None + :type type: Optional[WebhookMiniTypeField], optional + :param target: The item that will trigger the webhook, defaults to None + :type target: Optional[WebhookMiniTargetField], optional + """ + super().__init__(id=id, type=type, target=target, **kwargs) + self.created_by = created_by + self.created_at = created_at + self.address = address + self.triggers = triggers \ No newline at end of file diff --git a/box_sdk_gen/schemas/webhook_invocation.py b/box_sdk_gen/schemas/webhook_invocation.py new file mode 100644 index 000000000..2b810e595 --- /dev/null +++ b/box_sdk_gen/schemas/webhook_invocation.py @@ -0,0 +1,85 @@ +from enum import Enum + +from typing import Optional + +from typing import Union + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.webhook import Webhook + +from box_sdk_gen.schemas.user_mini import UserMini + +from box_sdk_gen.schemas.file import File + +from box_sdk_gen.schemas.folder import Folder + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class WebhookInvocationTypeField(str, Enum): + WEBHOOK_EVENT = 'webhook_event' + +class WebhookInvocationTriggerField(str, Enum): + FILE_UPLOADED = 'FILE.UPLOADED' + FILE_PREVIEWED = 'FILE.PREVIEWED' + FILE_DOWNLOADED = 'FILE.DOWNLOADED' + FILE_TRASHED = 'FILE.TRASHED' + FILE_DELETED = 'FILE.DELETED' + FILE_RESTORED = 'FILE.RESTORED' + FILE_COPIED = 'FILE.COPIED' + FILE_MOVED = 'FILE.MOVED' + FILE_LOCKED = 'FILE.LOCKED' + FILE_UNLOCKED = 'FILE.UNLOCKED' + FILE_RENAMED = 'FILE.RENAMED' + COMMENT_CREATED = 'COMMENT.CREATED' + COMMENT_UPDATED = 'COMMENT.UPDATED' + COMMENT_DELETED = 'COMMENT.DELETED' + TASK_ASSIGNMENT_CREATED = 'TASK_ASSIGNMENT.CREATED' + TASK_ASSIGNMENT_UPDATED = 'TASK_ASSIGNMENT.UPDATED' + METADATA_INSTANCE_CREATED = 'METADATA_INSTANCE.CREATED' + METADATA_INSTANCE_UPDATED = 'METADATA_INSTANCE.UPDATED' + METADATA_INSTANCE_DELETED = 'METADATA_INSTANCE.DELETED' + FOLDER_CREATED = 'FOLDER.CREATED' + FOLDER_RENAMED = 'FOLDER.RENAMED' + FOLDER_DOWNLOADED = 'FOLDER.DOWNLOADED' + FOLDER_RESTORED = 'FOLDER.RESTORED' + FOLDER_DELETED = 'FOLDER.DELETED' + FOLDER_COPIED = 'FOLDER.COPIED' + FOLDER_MOVED = 'FOLDER.MOVED' + FOLDER_TRASHED = 'FOLDER.TRASHED' + WEBHOOK_DELETED = 'WEBHOOK.DELETED' + COLLABORATION_CREATED = 'COLLABORATION.CREATED' + COLLABORATION_ACCEPTED = 'COLLABORATION.ACCEPTED' + COLLABORATION_REJECTED = 'COLLABORATION.REJECTED' + COLLABORATION_REMOVED = 'COLLABORATION.REMOVED' + COLLABORATION_UPDATED = 'COLLABORATION.UPDATED' + SHARED_LINK_DELETED = 'SHARED_LINK.DELETED' + SHARED_LINK_CREATED = 'SHARED_LINK.CREATED' + SHARED_LINK_UPDATED = 'SHARED_LINK.UPDATED' + SIGN_REQUEST_COMPLETED = 'SIGN_REQUEST.COMPLETED' + SIGN_REQUEST_DECLINED = 'SIGN_REQUEST.DECLINED' + SIGN_REQUEST_EXPIRED = 'SIGN_REQUEST.EXPIRED' + SIGN_REQUEST_SIGNER_EMAIL_BOUNCED = 'SIGN_REQUEST.SIGNER_EMAIL_BOUNCED' + +class WebhookInvocation(BaseObject): + _discriminator = 'type', {'webhook_event'} + def __init__(self, *, id: Optional[str] = None, type: Optional[WebhookInvocationTypeField] = None, webhook: Optional[Webhook] = None, created_by: Optional[UserMini] = None, created_at: Optional[DateTime] = None, trigger: Optional[WebhookInvocationTriggerField] = None, source: Optional[Union[File, Folder]] = None, **kwargs): + """ + :param id: The unique identifier for this webhook invocation, defaults to None + :type id: Optional[str], optional + :param type: `webhook_event`, defaults to None + :type type: Optional[WebhookInvocationTypeField], optional + :param created_at: A timestamp identifying the time that +the webhook event was triggered., defaults to None + :type created_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.webhook = webhook + self.created_by = created_by + self.created_at = created_at + self.trigger = trigger + self.source = source \ No newline at end of file diff --git a/box_sdk_gen/schemas/webhook_mini.py b/box_sdk_gen/schemas/webhook_mini.py new file mode 100644 index 000000000..533e7ce22 --- /dev/null +++ b/box_sdk_gen/schemas/webhook_mini.py @@ -0,0 +1,43 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class WebhookMiniTypeField(str, Enum): + WEBHOOK = 'webhook' + +class WebhookMiniTargetTypeField(str, Enum): + FILE = 'file' + FOLDER = 'folder' + +class WebhookMiniTargetField(BaseObject): + _discriminator = 'type', {'file', 'folder'} + def __init__(self, *, id: Optional[str] = None, type: Optional[WebhookMiniTargetTypeField] = None, **kwargs): + """ + :param id: The ID of the item to trigger a webhook, defaults to None + :type id: Optional[str], optional + :param type: The type of item to trigger a webhook, defaults to None + :type type: Optional[WebhookMiniTargetTypeField], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + +class WebhookMini(BaseObject): + _discriminator = 'type', {'webhook'} + def __init__(self, *, id: Optional[str] = None, type: Optional[WebhookMiniTypeField] = None, target: Optional[WebhookMiniTargetField] = None, **kwargs): + """ + :param id: The unique identifier for this webhook., defaults to None + :type id: Optional[str], optional + :param type: `webhook`, defaults to None + :type type: Optional[WebhookMiniTypeField], optional + :param target: The item that will trigger the webhook, defaults to None + :type target: Optional[WebhookMiniTargetField], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.target = target \ No newline at end of file diff --git a/box_sdk_gen/schemas/webhooks.py b/box_sdk_gen/schemas/webhooks.py new file mode 100644 index 000000000..3b5d8d6f5 --- /dev/null +++ b/box_sdk_gen/schemas/webhooks.py @@ -0,0 +1,29 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.webhook_mini import WebhookMini + +from box_sdk_gen.box.errors import BoxSDKError + +class Webhooks(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, prev_marker: Optional[str] = None, entries: Optional[List[WebhookMini]] = 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 + :param entries: A list of webhooks, defaults to None + :type entries: Optional[List[WebhookMini]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.prev_marker = prev_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/workflow.py b/box_sdk_gen/schemas/workflow.py new file mode 100644 index 000000000..9918624bf --- /dev/null +++ b/box_sdk_gen/schemas/workflow.py @@ -0,0 +1,209 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from box_sdk_gen.schemas.workflow_mini import WorkflowMiniTypeField + +from box_sdk_gen.schemas.workflow_mini import WorkflowMini + +from box_sdk_gen.schemas.user_base import UserBase + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class WorkflowFlowsTypeField(str, Enum): + FLOW = 'flow' + +class WorkflowFlowsTriggerTypeField(str, Enum): + TRIGGER = 'trigger' + +class WorkflowFlowsTriggerTriggerTypeField(str, Enum): + WORKFLOW_MANUAL_START = 'WORKFLOW_MANUAL_START' + +class WorkflowFlowsTriggerScopeTypeField(str, Enum): + TRIGGER_SCOPE = 'trigger_scope' + +class WorkflowFlowsTriggerScopeObjectTypeField(str, Enum): + FOLDER = 'folder' + +class WorkflowFlowsTriggerScopeObjectField(BaseObject): + _discriminator = 'type', {'folder'} + def __init__(self, *, type: Optional[WorkflowFlowsTriggerScopeObjectTypeField] = None, id: Optional[str] = None, **kwargs): + """ + :param type: The type of the object, defaults to None + :type type: Optional[WorkflowFlowsTriggerScopeObjectTypeField], optional + :param id: The id of the object, defaults to None + :type id: Optional[str], optional + """ + super().__init__(**kwargs) + self.type = type + self.id = id + +class WorkflowFlowsTriggerScopeField(BaseObject): + _discriminator = 'type', {'trigger_scope'} + def __init__(self, *, type: Optional[WorkflowFlowsTriggerScopeTypeField] = None, ref: Optional[str] = None, object: Optional[WorkflowFlowsTriggerScopeObjectField] = None, **kwargs): + """ + :param type: The trigger scope's resource type, defaults to None + :type type: Optional[WorkflowFlowsTriggerScopeTypeField], optional + :param ref: Indicates the path of the condition value to check, defaults to None + :type ref: Optional[str], optional + :param object: The object the `ref` points to, defaults to None + :type object: Optional[WorkflowFlowsTriggerScopeObjectField], optional + """ + super().__init__(**kwargs) + self.type = type + self.ref = ref + self.object = object + +class WorkflowFlowsTriggerField(BaseObject): + _discriminator = 'type', {'trigger'} + def __init__(self, *, type: Optional[WorkflowFlowsTriggerTypeField] = None, trigger_type: Optional[WorkflowFlowsTriggerTriggerTypeField] = None, scope: Optional[List[WorkflowFlowsTriggerScopeField]] = None, **kwargs): + """ + :param type: The trigger's resource type, defaults to None + :type type: Optional[WorkflowFlowsTriggerTypeField], optional + :param trigger_type: The type of trigger selected for this flow, defaults to None + :type trigger_type: Optional[WorkflowFlowsTriggerTriggerTypeField], optional + :param scope: List of trigger scopes, defaults to None + :type scope: Optional[List[WorkflowFlowsTriggerScopeField]], optional + """ + super().__init__(**kwargs) + self.type = type + self.trigger_type = trigger_type + self.scope = scope + +class WorkflowFlowsOutcomesTypeField(str, Enum): + OUTCOME = 'outcome' + +class WorkflowFlowsOutcomesActionTypeField(str, Enum): + ADD_METADATA = 'add_metadata' + ASSIGN_TASK = 'assign_task' + COPY_FILE = 'copy_file' + COPY_FOLDER = 'copy_folder' + CREATE_FOLDER = 'create_folder' + DELETE_FILE = 'delete_file' + DELETE_FOLDER = 'delete_folder' + LOCK_FILE = 'lock_file' + MOVE_FILE = 'move_file' + MOVE_FOLDER = 'move_folder' + REMOVE_WATERMARK_FILE = 'remove_watermark_file' + RENAME_FOLDER = 'rename_folder' + RESTORE_FOLDER = 'restore_folder' + SHARE_FILE = 'share_file' + SHARE_FOLDER = 'share_folder' + UNLOCK_FILE = 'unlock_file' + UPLOAD_FILE = 'upload_file' + WAIT_FOR_TASK = 'wait_for_task' + WATERMARK_FILE = 'watermark_file' + GO_BACK_TO_STEP = 'go_back_to_step' + APPLY_FILE_CLASSIFICATION = 'apply_file_classification' + APPLY_FOLDER_CLASSIFICATION = 'apply_folder_classification' + SEND_NOTIFICATION = 'send_notification' + +class WorkflowFlowsOutcomesIfRejectedTypeField(str, Enum): + OUTCOME = 'outcome' + +class WorkflowFlowsOutcomesIfRejectedActionTypeField(str, Enum): + ADD_METADATA = 'add_metadata' + ASSIGN_TASK = 'assign_task' + COPY_FILE = 'copy_file' + COPY_FOLDER = 'copy_folder' + CREATE_FOLDER = 'create_folder' + DELETE_FILE = 'delete_file' + DELETE_FOLDER = 'delete_folder' + LOCK_FILE = 'lock_file' + MOVE_FILE = 'move_file' + MOVE_FOLDER = 'move_folder' + REMOVE_WATERMARK_FILE = 'remove_watermark_file' + RENAME_FOLDER = 'rename_folder' + RESTORE_FOLDER = 'restore_folder' + SHARE_FILE = 'share_file' + SHARE_FOLDER = 'share_folder' + UNLOCK_FILE = 'unlock_file' + UPLOAD_FILE = 'upload_file' + WAIT_FOR_TASK = 'wait_for_task' + WATERMARK_FILE = 'watermark_file' + GO_BACK_TO_STEP = 'go_back_to_step' + APPLY_FILE_CLASSIFICATION = 'apply_file_classification' + APPLY_FOLDER_CLASSIFICATION = 'apply_folder_classification' + SEND_NOTIFICATION = 'send_notification' + +class WorkflowFlowsOutcomesIfRejectedField(BaseObject): + _discriminator = 'type', {'outcome'} + def __init__(self, *, id: Optional[str] = None, type: Optional[WorkflowFlowsOutcomesIfRejectedTypeField] = None, name: Optional[str] = None, action_type: Optional[WorkflowFlowsOutcomesIfRejectedActionTypeField] = None, **kwargs): + """ + :param id: The identifier of the outcome, defaults to None + :type id: Optional[str], optional + :param type: The outcomes resource type, defaults to None + :type type: Optional[WorkflowFlowsOutcomesIfRejectedTypeField], optional + :param name: The name of the outcome, defaults to None + :type name: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.name = name + self.action_type = action_type + +class WorkflowFlowsOutcomesField(BaseObject): + _discriminator = 'type', {'outcome'} + def __init__(self, *, id: Optional[str] = None, type: Optional[WorkflowFlowsOutcomesTypeField] = None, name: Optional[str] = None, action_type: Optional[WorkflowFlowsOutcomesActionTypeField] = None, if_rejected: Optional[List[WorkflowFlowsOutcomesIfRejectedField]] = None, **kwargs): + """ + :param id: The identifier of the outcome, defaults to None + :type id: Optional[str], optional + :param type: The outcomes resource type, defaults to None + :type type: Optional[WorkflowFlowsOutcomesTypeField], optional + :param name: The name of the outcome, defaults to None + :type name: Optional[str], optional + :param if_rejected: If `action_type` is `assign_task` and the task is rejected, returns a +list of outcomes to complete, defaults to None + :type if_rejected: Optional[List[WorkflowFlowsOutcomesIfRejectedField]], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.name = name + self.action_type = action_type + self.if_rejected = if_rejected + +class WorkflowFlowsField(BaseObject): + _discriminator = 'type', {'flow'} + def __init__(self, *, id: Optional[str] = None, type: Optional[WorkflowFlowsTypeField] = None, trigger: Optional[WorkflowFlowsTriggerField] = None, outcomes: Optional[List[WorkflowFlowsOutcomesField]] = None, created_at: Optional[DateTime] = None, created_by: Optional[UserBase] = None, **kwargs): + """ + :param id: The identifier of the flow, defaults to None + :type id: Optional[str], optional + :param type: The flow's resource type, defaults to None + :type type: Optional[WorkflowFlowsTypeField], optional + :param created_at: When this flow was created, defaults to None + :type created_at: Optional[DateTime], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.trigger = trigger + self.outcomes = outcomes + self.created_at = created_at + self.created_by = created_by + +class Workflow(WorkflowMini): + def __init__(self, *, flows: Optional[List[WorkflowFlowsField]] = None, id: Optional[str] = None, type: Optional[WorkflowMiniTypeField] = None, name: Optional[str] = None, description: Optional[str] = None, is_enabled: Optional[bool] = None, **kwargs): + """ + :param flows: A list of flows assigned to a workflow., defaults to None + :type flows: Optional[List[WorkflowFlowsField]], optional + :param id: The unique identifier for the workflow, defaults to None + :type id: Optional[str], optional + :param type: `workflow`, defaults to None + :type type: Optional[WorkflowMiniTypeField], optional + :param name: The name of the workflow, defaults to None + :type name: Optional[str], optional + :param description: The description for a workflow., defaults to None + :type description: Optional[str], optional + :param is_enabled: Specifies if this workflow is enabled, defaults to None + :type is_enabled: Optional[bool], optional + """ + super().__init__(id=id, type=type, name=name, description=description, is_enabled=is_enabled, **kwargs) + self.flows = flows \ No newline at end of file diff --git a/box_sdk_gen/schemas/workflow_full.py b/box_sdk_gen/schemas/workflow_full.py new file mode 100644 index 000000000..aac7ed86b --- /dev/null +++ b/box_sdk_gen/schemas/workflow_full.py @@ -0,0 +1,43 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.schemas.workflow_mini import WorkflowMiniTypeField + +from box_sdk_gen.schemas.workflow_mini import WorkflowMini + +from box_sdk_gen.schemas.workflow import WorkflowFlowsField + +from box_sdk_gen.schemas.workflow import Workflow + +from box_sdk_gen.schemas.user_base import UserBase + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class WorkflowFull(Workflow): + def __init__(self, *, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, created_by: Optional[UserBase] = None, modified_by: Optional[UserBase] = None, flows: Optional[List[WorkflowFlowsField]] = None, id: Optional[str] = None, type: Optional[WorkflowMiniTypeField] = None, name: Optional[str] = None, description: Optional[str] = None, is_enabled: Optional[bool] = None, **kwargs): + """ + :param created_at: The date and time when the workflow was created on Box, defaults to None + :type created_at: Optional[DateTime], optional + :param modified_at: The date and time when the workflow was last updated on Box, defaults to None + :type modified_at: Optional[DateTime], optional + :param flows: A list of flows assigned to a workflow., defaults to None + :type flows: Optional[List[WorkflowFlowsField]], optional + :param id: The unique identifier for the workflow, defaults to None + :type id: Optional[str], optional + :param type: `workflow`, defaults to None + :type type: Optional[WorkflowMiniTypeField], optional + :param name: The name of the workflow, defaults to None + :type name: Optional[str], optional + :param description: The description for a workflow., defaults to None + :type description: Optional[str], optional + :param is_enabled: Specifies if this workflow is enabled, defaults to None + :type is_enabled: Optional[bool], optional + """ + super().__init__(flows=flows, id=id, type=type, name=name, description=description, is_enabled=is_enabled, **kwargs) + self.created_at = created_at + self.modified_at = modified_at + self.created_by = created_by + self.modified_by = modified_by \ No newline at end of file diff --git a/box_sdk_gen/schemas/workflow_mini.py b/box_sdk_gen/schemas/workflow_mini.py new file mode 100644 index 000000000..1d177e31e --- /dev/null +++ b/box_sdk_gen/schemas/workflow_mini.py @@ -0,0 +1,32 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class WorkflowMiniTypeField(str, Enum): + WORKFLOW = 'workflow' + +class WorkflowMini(BaseObject): + _discriminator = 'type', {'workflow'} + def __init__(self, *, id: Optional[str] = None, type: Optional[WorkflowMiniTypeField] = None, name: Optional[str] = None, description: Optional[str] = None, is_enabled: Optional[bool] = None, **kwargs): + """ + :param id: The unique identifier for the workflow, defaults to None + :type id: Optional[str], optional + :param type: `workflow`, defaults to None + :type type: Optional[WorkflowMiniTypeField], optional + :param name: The name of the workflow, defaults to None + :type name: Optional[str], optional + :param description: The description for a workflow., defaults to None + :type description: Optional[str], optional + :param is_enabled: Specifies if this workflow is enabled, defaults to None + :type is_enabled: Optional[bool], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.name = name + self.description = description + self.is_enabled = is_enabled \ No newline at end of file diff --git a/box_sdk_gen/schemas/workflows.py b/box_sdk_gen/schemas/workflows.py new file mode 100644 index 000000000..e37cd825c --- /dev/null +++ b/box_sdk_gen/schemas/workflows.py @@ -0,0 +1,29 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.workflow import Workflow + +from box_sdk_gen.box.errors import BoxSDKError + +class Workflows(BaseObject): + def __init__(self, *, limit: Optional[int] = None, next_marker: Optional[str] = None, prev_marker: Optional[str] = None, entries: Optional[List[Workflow]] = 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 + :param entries: A list of workflows, defaults to None + :type entries: Optional[List[Workflow]], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.prev_marker = prev_marker + self.entries = entries \ No newline at end of file diff --git a/box_sdk_gen/schemas/zip_download.py b/box_sdk_gen/schemas/zip_download.py new file mode 100644 index 000000000..f20b41fba --- /dev/null +++ b/box_sdk_gen/schemas/zip_download.py @@ -0,0 +1,83 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.internal.utils import DateTime + +class ZipDownloadNameConflictsTypeField(str, Enum): + FILE = 'file' + FOLDER = 'folder' + +class ZipDownloadNameConflictsField(BaseObject): + _discriminator = 'type', {'file', 'folder'} + def __init__(self, *, id: Optional[str] = None, type: Optional[ZipDownloadNameConflictsTypeField] = None, original_name: Optional[str] = None, download_name: Optional[str] = None, **kwargs): + """ + :param id: The identifier of the item, defaults to None + :type id: Optional[str], optional + :param type: The type of this item, defaults to None + :type type: Optional[ZipDownloadNameConflictsTypeField], optional + :param original_name: The original name of this item, defaults to None + :type original_name: Optional[str], optional + :param download_name: The new name of this item as it will appear in the +downloaded `zip` archive., defaults to None + :type download_name: Optional[str], optional + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.original_name = original_name + self.download_name = download_name + +class ZipDownload(BaseObject): + def __init__(self, *, download_url: Optional[str] = None, status_url: Optional[str] = None, expires_at: Optional[DateTime] = None, name_conflicts: Optional[List[List[ZipDownloadNameConflictsField]]] = None, **kwargs): + """ + :param download_url: The URL that can be used to download the `zip` archive. A `Get` request to +this URL will start streaming the items requested. By default, this URL +is only valid for a few seconds, until the `expires_at` time, unless a +download is started after which it is valid for the duration of the +download. + +It is important to note that the domain and path of this URL might change +between API calls, and therefore it's important to use this URL as-is., defaults to None + :type download_url: Optional[str], optional + :param status_url: The URL that can be used to get the status of the `zip` archive being +downloaded. A `Get` request to this URL will return the number of files +in the archive as well as the number of items already downloaded or +skipped. By default, this URL is only valid for a few seconds, until the +`expires_at` time, unless a download is started after which the URL is +valid for 12 hours from the start of the download. + +It is important to note that the domain and path of this URL might change +between API calls, and therefore it's important to use this URL as-is., defaults to None + :type status_url: Optional[str], optional + :param expires_at: The time and date when this archive will expire. After this time the +`status_url` and `download_url` will return an error. + +By default, these URLs are only valid for a few seconds, unless a download +is started after which the `download_url` is valid for the duration of the +download, and the `status_url` is valid for 12 hours from the start of the +download., defaults to None + :type expires_at: Optional[DateTime], optional + :param name_conflicts: A list of conflicts that occurred when trying to create the archive. This +would occur when multiple items have been requested with the +same name. + +To solve these conflicts, the API will automatically rename an item +and return a mapping between the original item's name and its new +name. + +For every conflict, both files will be renamed and therefore this list +will always be a multiple of 2., defaults to None + :type name_conflicts: Optional[List[List[ZipDownloadNameConflictsField]]], optional + """ + super().__init__(**kwargs) + self.download_url = download_url + self.status_url = status_url + self.expires_at = expires_at + self.name_conflicts = name_conflicts \ No newline at end of file diff --git a/box_sdk_gen/schemas/zip_download_request.py b/box_sdk_gen/schemas/zip_download_request.py new file mode 100644 index 000000000..ec45c69b8 --- /dev/null +++ b/box_sdk_gen/schemas/zip_download_request.py @@ -0,0 +1,41 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from typing import List + +from typing import Optional + +from box_sdk_gen.box.errors import BoxSDKError + +class ZipDownloadRequestItemsTypeField(str, Enum): + FILE = 'file' + FOLDER = 'folder' + +class ZipDownloadRequestItemsField(BaseObject): + _discriminator = 'type', {'file', 'folder'} + def __init__(self, type: ZipDownloadRequestItemsTypeField, id: str, **kwargs): + """ + :param type: The type of the item to add to the archive. + :type type: ZipDownloadRequestItemsTypeField + :param id: The identifier of the item to add to the archive. When this item is +a folder then this can not be the root folder with ID `0`. + :type id: str + """ + super().__init__(**kwargs) + self.type = type + self.id = id + +class ZipDownloadRequest(BaseObject): + def __init__(self, items: List[ZipDownloadRequestItemsField], *, download_file_name: Optional[str] = None, **kwargs): + """ + :param items: A list of items to add to the `zip` archive. These can +be folders or files. + :type items: List[ZipDownloadRequestItemsField] + :param download_file_name: The optional name of the `zip` archive. This name will be appended by the +`.zip` file extension, for example `January Financials.zip`., defaults to None + :type download_file_name: Optional[str], optional + """ + super().__init__(**kwargs) + self.items = items + self.download_file_name = download_file_name \ No newline at end of file diff --git a/box_sdk_gen/schemas/zip_download_status.py b/box_sdk_gen/schemas/zip_download_status.py new file mode 100644 index 000000000..8136ed0a5 --- /dev/null +++ b/box_sdk_gen/schemas/zip_download_status.py @@ -0,0 +1,39 @@ +from enum import Enum + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + +class ZipDownloadStatusStateField(str, Enum): + IN_PROGRESS = 'in_progress' + FAILED = 'failed' + SUCCEEDED = 'succeeded' + +class ZipDownloadStatus(BaseObject): + def __init__(self, *, total_file_count: Optional[int] = None, downloaded_file_count: Optional[int] = None, skipped_file_count: Optional[int] = None, skipped_folder_count: Optional[int] = None, state: Optional[ZipDownloadStatusStateField] = None, **kwargs): + """ + :param total_file_count: The total number of files in the archive., defaults to None + :type total_file_count: Optional[int], optional + :param downloaded_file_count: The number of files that have already been downloaded., defaults to None + :type downloaded_file_count: Optional[int], optional + :param skipped_file_count: The number of files that have been skipped as they could not be +downloaded. In many cases this is due to permission issues that have +surfaced between the creation of the request for the archive and the +archive being downloaded., defaults to None + :type skipped_file_count: Optional[int], optional + :param skipped_folder_count: The number of folders that have been skipped as they could not be +downloaded. In many cases this is due to permission issues that have +surfaced between the creation of the request for the archive and the +archive being downloaded., defaults to None + :type skipped_folder_count: Optional[int], optional + :param state: The state of the archive being downloaded., defaults to None + :type state: Optional[ZipDownloadStatusStateField], optional + """ + super().__init__(**kwargs) + self.total_file_count = total_file_count + self.downloaded_file_count = downloaded_file_count + self.skipped_file_count = skipped_file_count + self.skipped_folder_count = skipped_folder_count + self.state = state \ No newline at end of file diff --git a/box_sdk_gen/serialization/__init__.py b/box_sdk_gen/serialization/__init__.py new file mode 100644 index 000000000..b12dd5924 --- /dev/null +++ b/box_sdk_gen/serialization/__init__.py @@ -0,0 +1 @@ +from box_sdk_gen.serialization.json import * \ No newline at end of file diff --git a/box_sdk_gen/serialization/json.py b/box_sdk_gen/serialization/json.py new file mode 100644 index 000000000..cd464a227 --- /dev/null +++ b/box_sdk_gen/serialization/json.py @@ -0,0 +1,62 @@ +import json +from typing import Dict, Union, Type +from urllib.parse import urlencode + +from ..internal.base_object import BaseObject + +SerializedData = Dict + + +def json_to_serialized_data(data: str) -> SerializedData: + return json.loads(data) + + +def sd_to_json(data: SerializedData) -> str: + return json.dumps(data) + + +def sd_to_url_params(data: SerializedData) -> str: + return urlencode(data) + + +def get_sd_value_by_key(data: SerializedData, key: str): + return data.get(key) + + +def serialize(obj: Union[BaseObject, dict, list]) -> SerializedData: + if isinstance(obj, dict): + obj = BaseObject(**obj).to_dict() + if isinstance(obj, BaseObject): + obj = obj.to_dict() + if isinstance(obj, list): + obj = [element.to_dict() if isinstance(element, BaseObject) else element for element in obj] + return obj + + +def get_origin(tp): + return getattr(tp, '__origin__', None) + +def deserialize(value: SerializedData, type: Type[BaseObject]): + if get_origin(type) == Union: + type = BaseObject._deserialize_union('', value, type) + obj = type.from_dict(value) + obj._raw_data = value + return obj + + +def sanitized_value() -> str: + return '---[redacted]---' + + +def sanitize_serialized_data(sd: SerializedData, keys_to_sanitize: Dict[str, str]) -> SerializedData: + if not isinstance(sd, Dict): + return sd + sanitized_dictionary = {} + for key, value in sd.items(): + if key.lower() in keys_to_sanitize and isinstance(value, str): + sanitized_dictionary[key] = sanitized_value() + elif isinstance(value, Dict): + sanitized_dictionary[key] = sanitize_serialized_data(value, keys_to_sanitize) + else: + sanitized_dictionary[key] = value + return sanitized_dictionary diff --git a/pytest.ini b/pytest.ini index 0cd3c7748..892e75461 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,5 +1,5 @@ [pytest] -addopts = --strict --showlocals -r a --tb=long --ignore=test/integration_new/ +addopts = --strict --showlocals -r a --tb=long --ignore=test/integration_new/ --ignore=test/test_gen/ xfail_strict = True junit_suite_name = boxsdk testpaths = test/ diff --git a/setup.py b/setup.py index 6245fc7db..3e70cc83c 100644 --- a/setup.py +++ b/setup.py @@ -55,6 +55,7 @@ def main(): install_requires = [ 'attrs>=17.3.0', 'urllib3', + 'dataclasses', 'requests>=2.4.3,<3', 'requests-toolbelt>=0.4.0', 'python-dateutil', # To be removed after dropping Python 3.6 @@ -62,7 +63,7 @@ def main(): redis_requires = ['redis>=2.10.3'] jwt_requires = ['pyjwt>=1.7.0', 'cryptography>=3'] coveralls_requires = ['coveralls'] - dev_requires = ['tox<=3.28.0'] + dev_requires = ['tox'] gh_requires = ['tox-gh-actions'] test_requires = [ 'bottle', @@ -73,6 +74,7 @@ def main(): 'pytest-timeout<3.0.0', 'pytest-cov<5.0.0', 'pytest-lazy-fixture<1.0.0', + 'pytest-rerunfailures', 'pytz', 'urllib3<2' ] diff --git a/test/commons.py b/test/commons.py new file mode 100644 index 000000000..c8a1b1676 --- /dev/null +++ b/test/commons.py @@ -0,0 +1,139 @@ +from box_sdk_gen.internal.utils import to_string + +from typing import List + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.managers.folders import CreateFolderParent + +from box_sdk_gen.internal.utils import ByteStream + +from box_sdk_gen.schemas.files import Files + +from box_sdk_gen.managers.uploads import UploadFileAttributes + +from box_sdk_gen.managers.uploads import UploadFileAttributesParentField + +from box_sdk_gen.schemas.terms_of_services import TermsOfServices + +from box_sdk_gen.managers.terms_of_services import CreateTermsOfServiceStatus + +from box_sdk_gen.managers.terms_of_services import CreateTermsOfServiceTosType + +from box_sdk_gen.schemas.classification_template import ClassificationTemplateFieldsOptionsField + +from box_sdk_gen.managers.classifications import AddClassificationRequestBody + +from box_sdk_gen.managers.classifications import AddClassificationRequestBodyDataField + +from box_sdk_gen.managers.classifications import AddClassificationRequestBodyDataStaticConfigField + +from box_sdk_gen.managers.classifications import AddClassificationRequestBodyDataStaticConfigClassificationField + +from box_sdk_gen.managers.classifications import CreateClassificationTemplateFields + +from box_sdk_gen.schemas.shield_information_barrier import ShieldInformationBarrier + +from box_sdk_gen.schemas.shield_information_barriers import ShieldInformationBarriers + +from box_sdk_gen.schemas.enterprise_base import EnterpriseBase + +from box_sdk_gen.internal.utils import decode_base_64 + +from box_sdk_gen.internal.utils import get_env_var + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import generate_byte_stream + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.classification_template import ClassificationTemplate + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.terms_of_service import TermsOfService + +from box_sdk_gen.networking.auth import Authentication + +from box_sdk_gen.box.ccg_auth import BoxCCGAuth + +from box_sdk_gen.box.ccg_auth import CCGConfig + +from box_sdk_gen.internal.utils import is_browser + +def get_ccg_auth() -> BoxCCGAuth: + ccg_config: CCGConfig = CCGConfig(client_id=get_env_var('CLIENT_ID'), client_secret=get_env_var('CLIENT_SECRET'), enterprise_id=get_env_var('ENTERPRISE_ID')) + auth: BoxCCGAuth = BoxCCGAuth(config=ccg_config) + return auth + +from box_sdk_gen.box.jwt_auth import BoxJWTAuth + +from box_sdk_gen.box.jwt_auth import JWTConfig + +def get_jwt_auth() -> BoxJWTAuth: + jwt_config: JWTConfig = JWTConfig.from_config_json_string(decode_base_64(get_env_var('JWT_CONFIG_BASE_64'))) + auth: BoxJWTAuth = BoxJWTAuth(config=jwt_config) + return auth + +def get_default_client_with_user_subject(user_id: str) -> BoxClient: + if is_browser(): + ccg_auth: BoxCCGAuth = get_ccg_auth() + ccg_auth_user: BoxCCGAuth = ccg_auth.with_user_subject(user_id) + return BoxClient(auth=ccg_auth_user) + auth: BoxJWTAuth = get_jwt_auth() + auth_user: BoxJWTAuth = auth.with_user_subject(user_id) + return BoxClient(auth=auth_user) + +def get_default_client() -> BoxClient: + client: BoxClient = BoxClient(auth=get_ccg_auth() if is_browser() else get_jwt_auth()) + return client + +def create_new_folder() -> FolderFull: + client: BoxClient = get_default_client() + new_folder_name: str = get_uuid() + return client.folders.create_folder(new_folder_name, CreateFolderParent(id='0')) + +def upload_new_file() -> FileFull: + client: BoxClient = get_default_client() + new_file_name: str = ''.join([get_uuid(), '.pdf']) + file_content_stream: ByteStream = generate_byte_stream(1024 * 1024) + uploaded_files: Files = client.uploads.upload_file(UploadFileAttributes(name=new_file_name, parent=UploadFileAttributesParentField(id='0')), file_content_stream) + return uploaded_files.entries[0] + +def get_or_create_terms_of_services() -> TermsOfService: + client: BoxClient = get_default_client() + tos: TermsOfServices = client.terms_of_services.get_terms_of_service() + number_of_tos: int = len(tos.entries) + if number_of_tos >= 1: + first_tos: TermsOfService = tos.entries[0] + if to_string(first_tos.tos_type) == 'managed': + return first_tos + if number_of_tos >= 2: + second_tos: TermsOfService = tos.entries[1] + if to_string(second_tos.tos_type) == 'managed': + return second_tos + return client.terms_of_services.create_terms_of_service(CreateTermsOfServiceStatus.DISABLED, 'Test TOS', tos_type=CreateTermsOfServiceTosType.MANAGED) + +def get_or_create_classification(classification_template: ClassificationTemplate) -> ClassificationTemplateFieldsOptionsField: + client: BoxClient = get_default_client() + classifications: List[ClassificationTemplateFieldsOptionsField] = classification_template.fields[0].options + current_number_of_classifications: int = len(classifications) + if current_number_of_classifications == 0: + classification_template_with_new_classification: ClassificationTemplate = client.classifications.add_classification([AddClassificationRequestBody(data=AddClassificationRequestBodyDataField(key=get_uuid(), static_config=AddClassificationRequestBodyDataStaticConfigField(classification=AddClassificationRequestBodyDataStaticConfigClassificationField(color_id=3, classification_definition='Some description'))))]) + return classification_template_with_new_classification.fields[0].options[0] + return classifications[0] + +def get_or_create_classification_template() -> ClassificationTemplate: + client: BoxClient = get_default_client() + try: + return client.classifications.get_classification_template() + except Exception: + return client.classifications.create_classification_template([CreateClassificationTemplateFields(options=[])]) + +def get_or_create_shield_information_barrier(client: BoxClient, enterprise_id: str) -> ShieldInformationBarrier: + barriers: ShieldInformationBarriers = client.shield_information_barriers.get_shield_information_barriers() + number_of_barriers: int = len(barriers.entries) + if number_of_barriers == 0: + return client.shield_information_barriers.create_shield_information_barrier(EnterpriseBase(id=enterprise_id)) + return barriers.entries[number_of_barriers - 1] \ No newline at end of file diff --git a/test/test_gen/__init__.py b/test/test_gen/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/test/test_gen/ai.py b/test/test_gen/ai.py new file mode 100644 index 000000000..a80d3c275 --- /dev/null +++ b/test/test_gen/ai.py @@ -0,0 +1,188 @@ +from typing import Optional + +from typing import Union + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.managers.ai import GetAiAgentDefaultConfigMode + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.ai_response_full import AiResponseFull + +from box_sdk_gen.managers.ai import CreateAiAskMode + +from box_sdk_gen.schemas.ai_item_ask import AiItemAsk + +from box_sdk_gen.schemas.ai_item_ask import AiItemAskTypeField + +from box_sdk_gen.schemas.ai_response import AiResponse + +from box_sdk_gen.managers.ai import CreateAiTextGenItems + +from box_sdk_gen.managers.ai import CreateAiTextGenItemsTypeField + +from box_sdk_gen.schemas.ai_dialogue_history import AiDialogueHistory + +from box_sdk_gen.schemas.files import Files + +from box_sdk_gen.managers.uploads import UploadFileAttributes + +from box_sdk_gen.managers.uploads import UploadFileAttributesParentField + +from box_sdk_gen.schemas.ai_item_base import AiItemBase + +from box_sdk_gen.schemas.ai_extract_structured_response import AiExtractStructuredResponse + +from box_sdk_gen.managers.ai import CreateAiExtractStructuredFields + +from box_sdk_gen.managers.ai import CreateAiExtractStructuredFieldsOptionsField + +from box_sdk_gen.schemas.metadata_template import MetadataTemplate + +from box_sdk_gen.managers.metadata_templates import CreateMetadataTemplateFields + +from box_sdk_gen.managers.metadata_templates import CreateMetadataTemplateFieldsTypeField + +from box_sdk_gen.managers.metadata_templates import CreateMetadataTemplateFieldsOptionsField + +from box_sdk_gen.managers.ai import CreateAiExtractStructuredMetadataTemplate + +from box_sdk_gen.managers.metadata_templates import DeleteMetadataTemplateScope + +from test.commons import get_default_client + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import string_to_byte_stream + +from box_sdk_gen.internal.utils import delay_in_seconds + +from box_sdk_gen.internal.utils import generate_byte_stream + +from box_sdk_gen.internal.utils import date_time_from_string + +from box_sdk_gen.internal.utils import date_time_to_string + +from box_sdk_gen.internal.utils import get_value_from_object_raw_data + +from test.commons import upload_new_file + +from box_sdk_gen.schemas.ai_agent_ask import AiAgentAsk + +from box_sdk_gen.schemas.ai_agent_text_gen import AiAgentTextGen + +from box_sdk_gen.schemas.ai_agent_extract import AiAgentExtract + +from box_sdk_gen.schemas.ai_agent_extract_structured import AiAgentExtractStructured + +from box_sdk_gen.schemas.ai_agent_long_text_tool import AiAgentLongTextTool + +client: BoxClient = get_default_client() + +def testAskAISingleItem(): + ai_ask_agent_config: AiAgentAsk = client.ai.get_ai_agent_default_config(GetAiAgentDefaultConfigMode.ASK, language='en-US') + file_to_ask: FileFull = upload_new_file() + response: Optional[AiResponseFull] = client.ai.create_ai_ask(CreateAiAskMode.SINGLE_ITEM_QA, 'which direction sun rises', [AiItemAsk(id=file_to_ask.id, type=AiItemAskTypeField.FILE, content='Sun rises in the East')], ai_agent=ai_ask_agent_config) + assert 'East' in response.answer + assert response.completion_reason == 'done' + client.files.delete_file_by_id(file_to_ask.id) + +def testAskAIMultipleItems(): + file_to_ask_1: FileFull = upload_new_file() + file_to_ask_2: FileFull = upload_new_file() + response: Optional[AiResponseFull] = client.ai.create_ai_ask(CreateAiAskMode.MULTIPLE_ITEM_QA, 'Which direction sun rises?', [AiItemAsk(id=file_to_ask_1.id, type=AiItemAskTypeField.FILE, content='Earth goes around the sun'), AiItemAsk(id=file_to_ask_2.id, type=AiItemAskTypeField.FILE, content='Sun rises in the East in the morning')]) + assert 'East' in response.answer + assert response.completion_reason == 'done' + client.files.delete_file_by_id(file_to_ask_1.id) + client.files.delete_file_by_id(file_to_ask_2.id) + +def testAITextGenWithDialogueHistory(): + file_to_ask: FileFull = upload_new_file() + ai_text_gen_agent_config: AiAgentTextGen = client.ai.get_ai_agent_default_config(GetAiAgentDefaultConfigMode.TEXT_GEN, language='en-US') + response: AiResponse = client.ai.create_ai_text_gen('Parapharse the document.s', [CreateAiTextGenItems(id=file_to_ask.id, type=CreateAiTextGenItemsTypeField.FILE, content='The Earth goes around the sun. Sun rises in the East in the morning.')], dialogue_history=[AiDialogueHistory(prompt='What does the earth go around?', answer='The sun', created_at=date_time_from_string('2021-01-01T00:00:00Z')), AiDialogueHistory(prompt='On Earth, where does the sun rise?', answer='East', created_at=date_time_from_string('2021-01-01T00:00:00Z'))], ai_agent=ai_text_gen_agent_config) + assert 'sun' in response.answer + assert response.completion_reason == 'done' + client.files.delete_file_by_id(file_to_ask.id) + +def testGettingAIAskAgentConfig(): + ai_ask_config: Union[AiAgentAsk, AiAgentTextGen, AiAgentExtract, AiAgentExtractStructured] = client.ai.get_ai_agent_default_config(GetAiAgentDefaultConfigMode.ASK, language='en-US') + assert ai_ask_config.type == 'ai_agent_ask' + assert not ai_ask_config.basic_text.model == '' + assert not ai_ask_config.basic_text.prompt_template == '' + assert ai_ask_config.basic_text.num_tokens_for_completion > -1 + assert not ai_ask_config.basic_text.llm_endpoint_params == None + assert not ai_ask_config.basic_text_multi.model == '' + assert not ai_ask_config.basic_text_multi.prompt_template == '' + assert ai_ask_config.basic_text_multi.num_tokens_for_completion > -1 + assert not ai_ask_config.basic_text_multi.llm_endpoint_params == None + assert not ai_ask_config.long_text.model == '' + assert not ai_ask_config.long_text.prompt_template == '' + assert ai_ask_config.long_text.num_tokens_for_completion > -1 + assert not ai_ask_config.long_text.embeddings.model == '' + assert not ai_ask_config.long_text.embeddings.strategy.id == '' + assert not ai_ask_config.long_text.llm_endpoint_params == None + assert not ai_ask_config.long_text_multi.model == '' + assert not ai_ask_config.long_text_multi.prompt_template == '' + assert ai_ask_config.long_text_multi.num_tokens_for_completion > -1 + assert not ai_ask_config.long_text_multi.embeddings.model == '' + assert not ai_ask_config.long_text_multi.embeddings.strategy.id == '' + assert not ai_ask_config.long_text_multi.llm_endpoint_params == None + +def testGettingAITextGenAgentConfig(): + ai_text_gen_config: Union[AiAgentAsk, AiAgentTextGen, AiAgentExtract, AiAgentExtractStructured] = client.ai.get_ai_agent_default_config(GetAiAgentDefaultConfigMode.TEXT_GEN, language='en-US') + assert ai_text_gen_config.type == 'ai_agent_text_gen' + assert not ai_text_gen_config.basic_gen.llm_endpoint_params == None + assert not ai_text_gen_config.basic_gen.model == '' + assert not ai_text_gen_config.basic_gen.prompt_template == '' + assert ai_text_gen_config.basic_gen.num_tokens_for_completion > -1 + assert not ai_text_gen_config.basic_gen.content_template == '' + assert not ai_text_gen_config.basic_gen.embeddings.model == '' + assert not ai_text_gen_config.basic_gen.embeddings.strategy.id == '' + +def testAIExtract(): + ai_extract_agent_config: AiAgentExtract = client.ai.get_ai_agent_default_config(GetAiAgentDefaultConfigMode.EXTRACT, language='en-US') + long_text_config_with_no_embeddings: AiAgentLongTextTool = AiAgentLongTextTool(system_message=ai_extract_agent_config.long_text.system_message, prompt_template=ai_extract_agent_config.long_text.prompt_template, model=ai_extract_agent_config.long_text.model, num_tokens_for_completion=ai_extract_agent_config.long_text.num_tokens_for_completion, llm_endpoint_params=ai_extract_agent_config.long_text.llm_endpoint_params) + agent_ignoring_overriding_embeddings_model: AiAgentExtract = AiAgentExtract(basic_text=ai_extract_agent_config.basic_text, long_text=long_text_config_with_no_embeddings) + uploaded_files: Files = client.uploads.upload_file(UploadFileAttributes(name=''.join([get_uuid(), '.txt']), parent=UploadFileAttributesParentField(id='0')), string_to_byte_stream('My name is John Doe. I live in San Francisco. I was born in 1990. I work at Box.')) + file: FileFull = uploaded_files.entries[0] + delay_in_seconds(5) + response: AiResponse = client.ai.create_ai_extract('firstName, lastName, location, yearOfBirth, company', [AiItemBase(id=file.id)], ai_agent=agent_ignoring_overriding_embeddings_model) + expected_response: str = '{"firstName": "John", "lastName": "Doe", "location": "San Francisco", "yearOfBirth": "1990", "company": "Box"}' + assert response.answer == expected_response + assert response.completion_reason == 'done' + client.files.delete_file_by_id(file.id) + +def testAIExtractStructuredWithFields(): + ai_extract_structured_agent_config: AiAgentExtractStructured = client.ai.get_ai_agent_default_config(GetAiAgentDefaultConfigMode.EXTRACT_STRUCTURED, language='en-US') + long_text_config_with_no_embeddings: AiAgentLongTextTool = AiAgentLongTextTool(system_message=ai_extract_structured_agent_config.long_text.system_message, prompt_template=ai_extract_structured_agent_config.long_text.prompt_template, model=ai_extract_structured_agent_config.long_text.model, num_tokens_for_completion=ai_extract_structured_agent_config.long_text.num_tokens_for_completion, llm_endpoint_params=ai_extract_structured_agent_config.long_text.llm_endpoint_params) + agent_ignoring_overriding_embeddings_model: AiAgentExtractStructured = AiAgentExtractStructured(basic_text=ai_extract_structured_agent_config.basic_text, long_text=long_text_config_with_no_embeddings) + uploaded_files: Files = client.uploads.upload_file(UploadFileAttributes(name=''.join([get_uuid(), '.txt']), parent=UploadFileAttributesParentField(id='0')), string_to_byte_stream('My name is John Doe. I was born in 4th July 1990. I am 34 years old. My hobby is guitar.')) + file: FileFull = uploaded_files.entries[0] + delay_in_seconds(5) + response: AiExtractStructuredResponse = client.ai.create_ai_extract_structured([AiItemBase(id=file.id)], fields=[CreateAiExtractStructuredFields(key='firstName', display_name='First name', description='Person first name', prompt='What is the your first name?', type='string'), CreateAiExtractStructuredFields(key='lastName', display_name='Last name', description='Person last name', prompt='What is the your last name?', type='string'), CreateAiExtractStructuredFields(key='dateOfBirth', display_name='Birth date', description='Person date of birth', prompt='What is the date of your birth?', type='date'), CreateAiExtractStructuredFields(key='age', display_name='Age', description='Person age', prompt='How old are you?', type='float'), CreateAiExtractStructuredFields(key='hobby', display_name='Hobby', description='Person hobby', prompt='What is your hobby?', type='multiSelect', options=[CreateAiExtractStructuredFieldsOptionsField(key='guitar'), CreateAiExtractStructuredFieldsOptionsField(key='books')])], ai_agent=agent_ignoring_overriding_embeddings_model) + assert to_string(get_value_from_object_raw_data(response, 'answer.hobby')) == to_string(['guitar']) + assert to_string(get_value_from_object_raw_data(response, 'answer.firstName')) == 'John' + assert to_string(get_value_from_object_raw_data(response, 'answer.lastName')) == 'Doe' + assert to_string(get_value_from_object_raw_data(response, 'answer.dateOfBirth')) == '1990-07-04' + assert to_string(get_value_from_object_raw_data(response, 'answer.age')) == '34' + assert response.completion_reason == 'done' + client.files.delete_file_by_id(file.id) + +def testAIExtractStructuredWithMetadataTemplate(): + uploaded_files: Files = client.uploads.upload_file(UploadFileAttributes(name=''.join([get_uuid(), '.txt']), parent=UploadFileAttributesParentField(id='0')), string_to_byte_stream('My name is John Doe. I was born in 4th July 1990. I am 34 years old. My hobby is guitar.')) + file: FileFull = uploaded_files.entries[0] + delay_in_seconds(5) + template_key: str = ''.join(['key', get_uuid()]) + template: MetadataTemplate = client.metadata_templates.create_metadata_template('enterprise', template_key, template_key=template_key, fields=[CreateMetadataTemplateFields(key='firstName', display_name='First name', description='Person first name', type=CreateMetadataTemplateFieldsTypeField.STRING), CreateMetadataTemplateFields(key='lastName', display_name='Last name', description='Person last name', type=CreateMetadataTemplateFieldsTypeField.STRING), CreateMetadataTemplateFields(key='dateOfBirth', display_name='Birth date', description='Person date of birth', type=CreateMetadataTemplateFieldsTypeField.DATE), CreateMetadataTemplateFields(key='age', display_name='Age', description='Person age', type=CreateMetadataTemplateFieldsTypeField.FLOAT), CreateMetadataTemplateFields(key='hobby', display_name='Hobby', description='Person hobby', type=CreateMetadataTemplateFieldsTypeField.MULTISELECT, options=[CreateMetadataTemplateFieldsOptionsField(key='guitar'), CreateMetadataTemplateFieldsOptionsField(key='books')])]) + response: AiExtractStructuredResponse = client.ai.create_ai_extract_structured([AiItemBase(id=file.id)], metadata_template=CreateAiExtractStructuredMetadataTemplate(template_key=template_key, scope='enterprise')) + assert to_string(get_value_from_object_raw_data(response, 'answer.firstName')) == 'John' + assert to_string(get_value_from_object_raw_data(response, 'answer.lastName')) == 'Doe' + assert to_string(get_value_from_object_raw_data(response, 'answer.dateOfBirth')) == '1990-07-04T00:00:00Z' + assert to_string(get_value_from_object_raw_data(response, 'answer.age')) == '34' + assert to_string(get_value_from_object_raw_data(response, 'answer.hobby')) == to_string(['guitar']) + assert response.completion_reason == 'done' + client.metadata_templates.delete_metadata_template(DeleteMetadataTemplateScope.ENTERPRISE, template.template_key) + client.files.delete_file_by_id(file.id) \ No newline at end of file diff --git a/test/test_gen/ai_studio.py b/test/test_gen/ai_studio.py new file mode 100644 index 000000000..4ae045c9c --- /dev/null +++ b/test/test_gen/ai_studio.py @@ -0,0 +1,64 @@ +from box_sdk_gen.internal.utils import to_string + +from typing import Optional + +from box_sdk_gen.schemas.ai_single_agent_response_full import AiSingleAgentResponseFull + +from box_sdk_gen.schemas.ai_studio_agent_ask import AiStudioAgentAsk + +from box_sdk_gen.schemas.ai_multiple_agent_response import AiMultipleAgentResponse + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.ai_response_full import AiResponseFull + +from box_sdk_gen.managers.ai import CreateAiAskMode + +from box_sdk_gen.schemas.ai_item_ask import AiItemAsk + +from box_sdk_gen.schemas.ai_item_ask import AiItemAskTypeField + +from box_sdk_gen.box.developer_token_auth import BoxDeveloperTokenAuth + +from box_sdk_gen.client import BoxClient + +from test.commons import get_default_client + +from test.commons import upload_new_file + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.schemas.ai_agent_reference import AiAgentReference + +client: BoxClient = get_default_client() + +def testAiStudioCRUD(): + agent_name: str = get_uuid() + created_agent: AiSingleAgentResponseFull = client.ai_studio.create_ai_agent(agent_name, 'enabled', ask=AiStudioAgentAsk(access_state='enabled', description='desc1')) + assert created_agent.name == agent_name + agents: AiMultipleAgentResponse = client.ai_studio.get_ai_agents() + num_agents: int = len(agents.entries) + assert to_string(agents.entries[0].type) == 'ai_agent' + retrieved_agent: AiSingleAgentResponseFull = client.ai_studio.get_ai_agent_by_id(created_agent.id, fields=['ask']) + assert retrieved_agent.name == agent_name + assert to_string(retrieved_agent.access_state) == 'enabled' + assert to_string(retrieved_agent.ask.access_state) == 'enabled' + assert retrieved_agent.ask.description == 'desc1' + updated_agent: AiSingleAgentResponseFull = client.ai_studio.update_ai_agent_by_id(created_agent.id, agent_name, 'enabled', ask=AiStudioAgentAsk(access_state='disabled', description='desc2')) + assert to_string(updated_agent.access_state) == 'enabled' + assert to_string(updated_agent.ask.access_state) == 'disabled' + assert updated_agent.ask.description == 'desc2' + client.ai_studio.delete_ai_agent_by_id(created_agent.id) + agents_after_delete: AiMultipleAgentResponse = client.ai_studio.get_ai_agents() + assert len(agents_after_delete.entries) == num_agents - 1 + +def testUseAIAgentReferenceInAIAsk(): + agent_name: str = get_uuid() + created_agent: AiSingleAgentResponseFull = client.ai_studio.create_ai_agent(agent_name, 'enabled', ask=AiStudioAgentAsk(access_state='enabled', description='desc1')) + file_to_ask: FileFull = upload_new_file() + response: Optional[AiResponseFull] = client.ai.create_ai_ask(CreateAiAskMode.SINGLE_ITEM_QA, 'which direction sun rises', [AiItemAsk(id=file_to_ask.id, type=AiItemAskTypeField.FILE, content='Sun rises in the East')], ai_agent=AiAgentReference(id=created_agent.id)) + assert 'East' in response.answer + assert response.completion_reason == 'done' + assert len(response.ai_agent_info.models) > 0 + client.files.delete_file_by_id(file_to_ask.id) + client.ai_studio.delete_ai_agent_by_id(created_agent.id) \ No newline at end of file diff --git a/test/test_gen/app_item_associations.py b/test/test_gen/app_item_associations.py new file mode 100644 index 000000000..3fd189272 --- /dev/null +++ b/test/test_gen/app_item_associations.py @@ -0,0 +1,45 @@ +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 \ No newline at end of file diff --git a/test/test_gen/auth.py b/test/test_gen/auth.py new file mode 100644 index 000000000..8867ca3fb --- /dev/null +++ b/test/test_gen/auth.py @@ -0,0 +1,239 @@ +import pytest + +from box_sdk_gen.schemas.user_full import UserFull + +from box_sdk_gen.schemas.files import Files + +from box_sdk_gen.managers.uploads import UploadFileAttributes + +from box_sdk_gen.managers.uploads import UploadFileAttributesParentField + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.access_token import AccessToken + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.managers.folders import CreateFolderParent + +from box_sdk_gen.internal.utils import decode_base_64 + +from box_sdk_gen.internal.utils import get_env_var + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import buffer_equals + +from box_sdk_gen.internal.utils import read_byte_stream + +from box_sdk_gen.internal.utils import generate_byte_buffer + +from box_sdk_gen.internal.utils import generate_byte_stream + +from box_sdk_gen.internal.utils import decode_base_64_byte_stream + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.box.ccg_auth import BoxCCGAuth + +from box_sdk_gen.box.ccg_auth import CCGConfig + +from box_sdk_gen.box.developer_token_auth import BoxDeveloperTokenAuth + +from box_sdk_gen.box.developer_token_auth import DeveloperTokenConfig + +from box_sdk_gen.box.oauth import BoxOAuth + +from box_sdk_gen.box.oauth import OAuthConfig + +from box_sdk_gen.box.token_storage import InMemoryTokenStorage + +from box_sdk_gen.box.jwt_auth import BoxJWTAuth + +from box_sdk_gen.box.jwt_auth import JWTConfig + +def test_jwt_auth(): + user_id: str = get_env_var('USER_ID') + enterprise_id: str = get_env_var('ENTERPRISE_ID') + jwt_config: JWTConfig = JWTConfig.from_config_json_string(decode_base_64(get_env_var('JWT_CONFIG_BASE_64'))) + auth: BoxJWTAuth = BoxJWTAuth(config=jwt_config) + user_auth: BoxJWTAuth = auth.with_user_subject(user_id) + user_client: BoxClient = BoxClient(auth=user_auth) + current_user: UserFull = user_client.users.get_user_me() + assert current_user.id == user_id + enterprise_auth: BoxJWTAuth = auth.with_enterprise_subject(enterprise_id) + enterprise_client: BoxClient = BoxClient(auth=enterprise_auth) + new_user: UserFull = enterprise_client.users.get_user_me(fields=['enterprise']) + assert not new_user.enterprise == None + assert new_user.enterprise.id == enterprise_id + assert not new_user.id == user_id + +def test_jwt_auth_downscope(): + jwt_config: JWTConfig = JWTConfig.from_config_json_string(decode_base_64(get_env_var('JWT_CONFIG_BASE_64'))) + auth: BoxJWTAuth = BoxJWTAuth(config=jwt_config) + parent_client: BoxClient = BoxClient(auth=auth) + uploaded_files: Files = parent_client.uploads.upload_file(UploadFileAttributes(name=get_uuid(), parent=UploadFileAttributesParentField(id='0')), generate_byte_stream(1024 * 1024)) + file: FileFull = uploaded_files.entries[0] + resource_path: str = ''.join(['https://api.box.com/2.0/files/', file.id]) + downscoped_token: AccessToken = auth.downscope_token(['item_rename', 'item_preview'], resource=resource_path) + assert not downscoped_token.access_token == None + downscoped_client: BoxClient = BoxClient(auth=BoxDeveloperTokenAuth(token=downscoped_token.access_token)) + downscoped_client.files.update_file_by_id(file.id, name=get_uuid()) + with pytest.raises(Exception): + downscoped_client.files.delete_file_by_id(file.id) + parent_client.files.delete_file_by_id(file.id) + +def test_jwt_downscope_token_succeeds_if_no_token_available(): + jwt_config: JWTConfig = JWTConfig.from_config_json_string(decode_base_64(get_env_var('JWT_CONFIG_BASE_64'))) + auth: BoxJWTAuth = BoxJWTAuth(config=jwt_config) + downscoped_token: AccessToken = auth.downscope_token(['root_readonly']) + assert not downscoped_token.access_token == None + downscoped_client: BoxClient = BoxClient(auth=BoxDeveloperTokenAuth(token=downscoped_token.access_token)) + with pytest.raises(Exception): + downscoped_client.uploads.upload_file(UploadFileAttributes(name=get_uuid(), parent=UploadFileAttributesParentField(id='0')), generate_byte_stream(1024 * 1024)) + +def test_jwt_auth_revoke(): + jwt_config: JWTConfig = JWTConfig.from_config_json_string(decode_base_64(get_env_var('JWT_CONFIG_BASE_64'))) + auth: BoxJWTAuth = BoxJWTAuth(config=jwt_config) + token_from_storage_before_revoke: AccessToken = auth.retrieve_token() + assert not token_from_storage_before_revoke == None + auth.revoke_token() + token_from_storage_after_revoke: AccessToken = auth.retrieve_token() + assert not token_from_storage_before_revoke.access_token == token_from_storage_after_revoke.access_token + +def test_oauth_auth_authorizeUrl(): + config: OAuthConfig = OAuthConfig(client_id='OAUTH_CLIENT_ID', client_secret='OAUTH_CLIENT_SECRET') + auth: BoxOAuth = BoxOAuth(config=config) + auth_url: str = auth.get_authorize_url() + assert auth_url == 'https://account.box.com/api/oauth2/authorize?client_id=OAUTH_CLIENT_ID&response_type=code' or auth_url == 'https://account.box.com/api/oauth2/authorize?response_type=code&client_id=OAUTH_CLIENT_ID' + +def test_oauth_downscope_token_succeeds_if_no_token_available(): + config: OAuthConfig = OAuthConfig(client_id=get_env_var('CLIENT_ID'), client_secret=get_env_var('CLIENT_SECRET')) + auth: BoxOAuth = BoxOAuth(config=config) + resource_path: str = ''.join(['https://api.box.com/2.0/files/12345']) + with pytest.raises(Exception): + auth.downscope_token(['item_rename', 'item_preview'], resource=resource_path) + +def test_ccg_auth(): + user_id: str = get_env_var('USER_ID') + enterprise_id: str = get_env_var('ENTERPRISE_ID') + ccg_config: CCGConfig = CCGConfig(client_id=get_env_var('CLIENT_ID'), client_secret=get_env_var('CLIENT_SECRET'), enterprise_id=enterprise_id, user_id=user_id) + auth: BoxCCGAuth = BoxCCGAuth(config=ccg_config) + user_auth: BoxCCGAuth = auth.with_user_subject(user_id) + user_client: BoxClient = BoxClient(auth=user_auth) + current_user: UserFull = user_client.users.get_user_me() + assert current_user.id == user_id + enterprise_auth: BoxCCGAuth = auth.with_enterprise_subject(enterprise_id) + enterprise_client: BoxClient = BoxClient(auth=enterprise_auth) + new_user: UserFull = enterprise_client.users.get_user_me(fields=['enterprise']) + assert not new_user.enterprise == None + assert new_user.enterprise.id == enterprise_id + assert not new_user.id == user_id + +def test_ccg_auth_downscope(): + ccg_config: CCGConfig = CCGConfig(client_id=get_env_var('CLIENT_ID'), client_secret=get_env_var('CLIENT_SECRET'), user_id=get_env_var('USER_ID')) + auth: BoxCCGAuth = BoxCCGAuth(config=ccg_config) + parent_client: BoxClient = BoxClient(auth=auth) + folder: FolderFull = parent_client.folders.create_folder(get_uuid(), CreateFolderParent(id='0')) + resource_path: str = ''.join(['https://api.box.com/2.0/folders/', folder.id]) + downscoped_token: AccessToken = auth.downscope_token(['item_rename', 'item_preview'], resource=resource_path) + assert not downscoped_token.access_token == None + downscoped_client: BoxClient = BoxClient(auth=BoxDeveloperTokenAuth(token=downscoped_token.access_token)) + downscoped_client.folders.update_folder_by_id(folder.id, name=get_uuid()) + with pytest.raises(Exception): + downscoped_client.folders.delete_folder_by_id(folder.id) + parent_client.folders.delete_folder_by_id(folder.id) + +def test_ccg_downscope_token_succeeds_if_no_token_available(): + ccg_config: CCGConfig = CCGConfig(client_id=get_env_var('CLIENT_ID'), client_secret=get_env_var('CLIENT_SECRET'), user_id=get_env_var('USER_ID')) + auth: BoxCCGAuth = BoxCCGAuth(config=ccg_config) + downscoped_token: AccessToken = auth.downscope_token(['root_readonly']) + assert not downscoped_token.access_token == None + downscoped_client: BoxClient = BoxClient(auth=BoxDeveloperTokenAuth(token=downscoped_token.access_token)) + with pytest.raises(Exception): + downscoped_client.uploads.upload_file(UploadFileAttributes(name=get_uuid(), parent=UploadFileAttributesParentField(id='0')), generate_byte_stream(1024 * 1024)) + +def test_ccg_auth_revoke(): + ccg_config: CCGConfig = CCGConfig(client_id=get_env_var('CLIENT_ID'), client_secret=get_env_var('CLIENT_SECRET'), user_id=get_env_var('USER_ID')) + auth: BoxCCGAuth = BoxCCGAuth(config=ccg_config) + token_from_storage_before_revoke: AccessToken = auth.retrieve_token() + assert not token_from_storage_before_revoke == None + auth.revoke_token() + token_from_storage_after_revoke: AccessToken = auth.retrieve_token() + assert not token_from_storage_before_revoke.access_token == token_from_storage_after_revoke.access_token + +def test_developer_downscope_token_succeeds_if_no_token_available(): + developer_token_config: DeveloperTokenConfig = DeveloperTokenConfig(client_id=get_env_var('CLIENT_ID'), client_secret=get_env_var('CLIENT_SECRET')) + auth: BoxDeveloperTokenAuth = BoxDeveloperTokenAuth(token='', config=developer_token_config) + resource_path: str = ''.join(['https://api.box.com/2.0/folders/12345']) + with pytest.raises(Exception): + auth.downscope_token(['item_rename', 'item_preview'], resource=resource_path) + +def get_access_token() -> AccessToken: + user_id: str = get_env_var('USER_ID') + enterprise_id: str = get_env_var('ENTERPRISE_ID') + ccg_config: CCGConfig = CCGConfig(client_id=get_env_var('CLIENT_ID'), client_secret=get_env_var('CLIENT_SECRET'), enterprise_id=enterprise_id, user_id=user_id) + auth: BoxCCGAuth = BoxCCGAuth(config=ccg_config) + auth_user: BoxCCGAuth = auth.with_user_subject(user_id) + return auth_user.retrieve_token() + +def test_developer_token_auth_revoke(): + developer_token_config: DeveloperTokenConfig = DeveloperTokenConfig(client_id=get_env_var('CLIENT_ID'), client_secret=get_env_var('CLIENT_SECRET')) + token: AccessToken = get_access_token() + auth: BoxDeveloperTokenAuth = BoxDeveloperTokenAuth(token=token.access_token, config=developer_token_config) + token_from_storage_before_revoke: AccessToken = auth.retrieve_token() + assert not token_from_storage_before_revoke == None + auth.revoke_token() + with pytest.raises(Exception): + auth.retrieve_token() + +def test_developer_token_auth_downscope(): + developer_token_config: DeveloperTokenConfig = DeveloperTokenConfig(client_id=get_env_var('CLIENT_ID'), client_secret=get_env_var('CLIENT_SECRET')) + token: AccessToken = get_access_token() + auth: BoxDeveloperTokenAuth = BoxDeveloperTokenAuth(token=token.access_token, config=developer_token_config) + parent_client: BoxClient = BoxClient(auth=auth) + folder: FolderFull = parent_client.folders.create_folder(get_uuid(), CreateFolderParent(id='0')) + resource_path: str = ''.join(['https://api.box.com/2.0/folders/', folder.id]) + downscoped_token: AccessToken = auth.downscope_token(['item_rename', 'item_preview'], resource=resource_path) + assert not downscoped_token.access_token == None + downscoped_client: BoxClient = BoxClient(auth=BoxDeveloperTokenAuth(token=downscoped_token.access_token)) + downscoped_client.folders.update_folder_by_id(folder.id, name=get_uuid()) + with pytest.raises(Exception): + downscoped_client.folders.delete_folder_by_id(folder.id) + parent_client.folders.delete_folder_by_id(folder.id) + +def test_developer_token_auth(): + user_id: str = get_env_var('USER_ID') + token: AccessToken = get_access_token() + dev_auth: BoxDeveloperTokenAuth = BoxDeveloperTokenAuth(token=token.access_token) + client: BoxClient = BoxClient(auth=dev_auth) + current_user: UserFull = client.users.get_user_me() + assert current_user.id == user_id + +def test_oauth_auth_revoke(): + token: AccessToken = get_access_token() + token_storage: InMemoryTokenStorage = InMemoryTokenStorage(token=token) + config: OAuthConfig = OAuthConfig(client_id=get_env_var('CLIENT_ID'), client_secret=get_env_var('CLIENT_SECRET'), token_storage=token_storage) + auth: BoxOAuth = BoxOAuth(config=config) + client: BoxClient = BoxClient(auth=auth) + client.users.get_user_me() + auth.revoke_token() + with pytest.raises(Exception): + client.users.get_user_me() + +def test_oauth_auth_downscope(): + token: AccessToken = get_access_token() + token_storage: InMemoryTokenStorage = InMemoryTokenStorage(token=token) + config: OAuthConfig = OAuthConfig(client_id=get_env_var('CLIENT_ID'), client_secret=get_env_var('CLIENT_SECRET'), token_storage=token_storage) + auth: BoxOAuth = BoxOAuth(config=config) + parent_client: BoxClient = BoxClient(auth=auth) + uploaded_files: Files = parent_client.uploads.upload_file(UploadFileAttributes(name=get_uuid(), parent=UploadFileAttributesParentField(id='0')), generate_byte_stream(1024 * 1024)) + file: FileFull = uploaded_files.entries[0] + resource_path: str = ''.join(['https://api.box.com/2.0/files/', file.id]) + downscoped_token: AccessToken = auth.downscope_token(['item_rename', 'item_preview'], resource=resource_path) + assert not downscoped_token.access_token == None + downscoped_client: BoxClient = BoxClient(auth=BoxDeveloperTokenAuth(token=downscoped_token.access_token)) + downscoped_client.files.update_file_by_id(file.id, name=get_uuid()) + with pytest.raises(Exception): + downscoped_client.files.delete_file_by_id(file.id) + parent_client.files.delete_file_by_id(file.id) \ No newline at end of file diff --git a/test/test_gen/avatars.py b/test/test_gen/avatars.py new file mode 100644 index 000000000..ae0e95cb8 --- /dev/null +++ b/test/test_gen/avatars.py @@ -0,0 +1,39 @@ +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.user_full import UserFull + +from box_sdk_gen.schemas.user_avatar import UserAvatar + +from box_sdk_gen.internal.utils import ByteStream + +from box_sdk_gen.internal.utils import decode_base_64 + +from box_sdk_gen.internal.utils import get_env_var + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import buffer_equals + +from box_sdk_gen.internal.utils import read_byte_stream + +from box_sdk_gen.internal.utils import generate_byte_buffer + +from box_sdk_gen.internal.utils import decode_base_64_byte_stream + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def testAvatars(): + user: UserFull = client.users.get_user_me() + created_avatar: UserAvatar = client.avatars.create_user_avatar(user.id, decode_base_64_byte_stream('iVBORw0KGgoAAAANSUhEUgAAAQAAAAEAAQMAAABmvDolAAAAA1BMVEW10NBjBBbqAAAAH0lEQVRoge3BAQ0AAADCoPdPbQ43oAAAAAAAAAAAvg0hAAABmmDh1QAAAABJRU5ErkJggg=='), pic_file_name='avatar.png', pic_content_type='image/png') + assert not created_avatar.pic_urls.small == None + assert not created_avatar.pic_urls.large == None + assert not created_avatar.pic_urls.preview == None + response: ByteStream = client.avatars.get_user_avatar(user.id) + assert buffer_equals(read_byte_stream(response), generate_byte_buffer(0)) == False + client.avatars.delete_user_avatar(user.id) + with pytest.raises(Exception): + client.avatars.get_user_avatar(user.id) \ No newline at end of file diff --git a/test/test_gen/box_network_client.py b/test/test_gen/box_network_client.py new file mode 100644 index 000000000..26e27d66c --- /dev/null +++ b/test/test_gen/box_network_client.py @@ -0,0 +1,1219 @@ +import pytest +import json +from collections import OrderedDict +from io import BytesIO, RawIOBase, UnsupportedOperation, SEEK_SET +from unittest import mock +from unittest.mock import Mock, patch +from requests import Session, Response, RequestException + +from box_sdk_gen import ( + NetworkSession, + BoxAPIError, + Authentication, + BoxSDKError, + BoxClient, + ResponseFormat, + DataSanitizer, +) +from box_sdk_gen.networking.box_network_client import ( + BoxNetworkClient, + USER_AGENT_HEADER, + X_BOX_UA_HEADER, + APIRequest, + APIResponse, +) +from box_sdk_gen.networking import ( + FetchOptions, + MultipartItem, + FetchResponse, + BoxRetryStrategy, +) +from box_sdk_gen.networking.proxy_config import ProxyConfig + + +@pytest.fixture +def mock_requests_session(): + return Mock(Session) + + +@pytest.fixture +def mock_byte_stream(): + return BytesIO(b"123") + + +@pytest.fixture +def mock_non_seekable_stream(): + return NonSeekableStream(b"123") + + +class NonSeekableStream(RawIOBase): + def __init__(self, data: bytes): + self._buffer = BytesIO(data) + + def read(self, size=-1): + return self._buffer.read(size) + + def seekable(self) -> bool: + return False + + def seek(self, offset, whence=SEEK_SET): + raise UnsupportedOperation("Stream is not seekable") + + +@pytest.fixture +def response_202(): + response = Mock(Response) + response.url = 'https://example.com' + response.status_code = 202 + response.ok = True + response.text = "" + response.content = None + response.headers = { + "content-type": "text/html", + } + return response + + +@pytest.fixture +def response_202_with_retry_after(): + response = Mock(Response) + response.url = 'https://example.com' + response.status_code = 202 + response.ok = True + response.text = "" + response.content = b'' + response.headers = {"Retry-After": "0"} + return response + + +@pytest.fixture +def response_500(): + response = Mock(Response) + response.url = 'https://example.com' + response.status_code = 500 + response.ok = False + response.text = "" + response.content = b'' + response.headers = {"Retry-After": "0"} + return response + + +@pytest.fixture +def response_401(): + response = Mock(Response) + response.url = 'https://example.com' + response.status_code = 401 + response.ok = False + response.text = "" + response.content = b'' + response.headers = {} + return response + + +@pytest.fixture +def response_429(): + response = Mock(Response) + response.url = 'https://example.com' + response.status_code = 429 + response.ok = False + response.text = "" + response.content = b'' + response.headers = {} + return response + + +@pytest.fixture +def response_200(): + response = Mock(Response) + response.url = 'https://example.com' + response.status_code = 200 + response.ok = True + response.headers = {} + response.text = "" + response.content = b'' + return response + + +@pytest.fixture +def response_302(): + response = Mock(Response) + response.url = 'https://example.com' + response.status_code = 302 + response.ok = True + response.headers = { + "location": "https://example.com/redirected", + "content-length": "0", + } + response.text = "" + response.content = b'' + return response + + +@pytest.fixture +def response_failure_no_status(): + response = Mock(Response) + response.url = 'https://example.com' + response.ok = False + response.text = "" + response.content = b'' + response.headers = {"Retry-After": "0"} + return response + + +@pytest.fixture +def token_mock(): + return "token123" + + +@pytest.fixture +def token2_mock(): + return "new_token321" + + +@pytest.fixture +def network_session_mock(): + return NetworkSession() + + +@pytest.fixture +def network_client(mock_requests_session): + return BoxNetworkClient(mock_requests_session) + + +@pytest.fixture +def data_sanitizer(): + return DataSanitizer() + + +def reauthenticate_mock(auth, token): + auth.retrieve_authorization_header.return_value = f"Bearer {token}" + + +@pytest.fixture +def authentication_mock(token_mock, token2_mock): + auth = Mock(Authentication) + auth.retrieve_authorization_header.return_value = f"Bearer {token_mock}" + auth.refresh_token = lambda network_session: reauthenticate_mock(auth, token2_mock) + return auth + + +def test_use_session_and_max_attempts_from_network_session( + network_client, mock_requests_session, response_500 +): + mock_requests_session.request.return_value = response_500 + + network_session = NetworkSession(retry_strategy=BoxRetryStrategy(max_attempts=3)) + + options = FetchOptions( + url="https://example.com", + method="GET", + network_session=network_session, + ) + + with pytest.raises(BoxAPIError): + network_client.fetch(options) + + assert mock_requests_session.request.call_count == 3 + + +def test_use_default_session_and_max_attempts_when_network_session_not_provided( + network_client, mock_requests_session, response_500, network_session_mock +): + mock_requests_session.request.return_value = response_500 + with patch("requests.Session", return_value=mock_requests_session): + options = FetchOptions(url="https://example.com", method="GET") + + with pytest.raises(BoxAPIError): + network_client.fetch(options) + + assert mock_requests_session.request.call_count == 5 + + +def test_prepare_headers(network_client, authentication_mock, token_mock): + network_session = NetworkSession(additional_headers={"additional_header": "test"}) + options = FetchOptions( + url="https://example.com", + method="GET", + network_session=network_session, + headers={"header": "test"}, + auth=authentication_mock, + ) + + headers = network_client._prepare_headers(options) + + assert headers == { + "Authorization": f"Bearer {token_mock}", + "header": "test", + "additional_header": "test", + "User-Agent": USER_AGENT_HEADER, + "X-Box-UA": X_BOX_UA_HEADER, + } + + +def test_prepare_headers_reauthenticate( + network_client, authentication_mock, token2_mock +): + network_session = NetworkSession(additional_headers={"additional_header": "test"}) + options = FetchOptions( + url="https://example.com", + method="GET", + network_session=network_session, + headers={"header": "test"}, + auth=authentication_mock, + ) + + headers = network_client._prepare_headers(options, reauthenticate=True) + + assert headers == { + "Authorization": f"Bearer {token2_mock}", + "header": "test", + "additional_header": "test", + "User-Agent": USER_AGENT_HEADER, + "X-Box-UA": X_BOX_UA_HEADER, + } + + +@pytest.mark.parametrize( + "content_type, data, expected_body", + [ + ("application/json", {"key": "value"}, '{"key": "value"}'), + ("application/json-patch+json", {"key": "value"}, '{"key": "value"}'), + ("application/x-www-form-urlencoded", {"key": "value"}, "key=value"), + ("multipart/form-data", mock_byte_stream, mock_byte_stream), + ("application/octet-stream", mock_byte_stream, mock_byte_stream), + ], +) +def test_prepare_body_valid_content_type( + network_client, content_type, data, expected_body, mock_byte_stream +): + body = network_client._prepare_body(content_type, data) + assert body == expected_body + + +def test_prepare_body_invalid_content_type(network_client): + with pytest.raises(Exception): + network_client._prepare_body("invalid_content_type", {}) + + +def test_prepare_json_request(network_client): + options = FetchOptions( + url="https://example.com", + method="POST", + data={"key": "value"}, + headers={"header": "test"}, + params={"param": "value"}, + content_type="application/json", + ) + + api_request = network_client._prepare_request(options=options) + + assert api_request == APIRequest( + method="POST", + url="https://example.com", + headers={ + "header": "test", + "User-Agent": USER_AGENT_HEADER, + "X-Box-UA": X_BOX_UA_HEADER, + "Content-Type": "application/json", + }, + params={"param": "value"}, + data='{"key": "value"}', + ) + + +def test_prepare_multipart_request(network_client, mock_byte_stream): + options = FetchOptions( + url="https://example.com", + method="POST", + data={"key": "value"}, + content_type="multipart/form-data", + multipart_data=[ + MultipartItem(part_name="attributes", data={"name": "file.pdf"}), + MultipartItem( + part_name="file", file_stream=mock_byte_stream, file_name="file.pdf" + ), + ], + ) + + api_request = network_client._prepare_request(options=options) + + assert api_request.method == "POST" + assert api_request.url == "https://example.com" + assert api_request.headers["User-Agent"] == USER_AGENT_HEADER + assert api_request.headers["X-Box-UA"] == X_BOX_UA_HEADER + assert api_request.headers["Content-Type"].startswith( + "multipart/form-data; boundary=" + ) + assert api_request.params == {} + assert api_request.data.fields == OrderedDict( + [ + ("attributes", '{"name": "file.pdf"}'), + ("file", ("file.pdf", mock_byte_stream, None)), + ] + ) + + +def test_make_request(network_client, mock_requests_session, response_200): + request_params = { + "method": "POST", + "url": "https://example.com", + "headers": { + "header": "test", + "User-Agent": USER_AGENT_HEADER, + "X-Box-UA": X_BOX_UA_HEADER, + "Content-Type": "application/json", + }, + "params": {"param": "value"}, + "data": '{"key": "value"}', + "allow_redirects": True, + } + mock_requests_session.request.return_value = response_200 + api_request = APIRequest(**request_params) + + api_response = network_client._make_request(api_request) + + assert api_response == APIResponse( + network_response=response_200, + reauthentication_needed=False, + raised_exception=None, + ) + assert mock_requests_session.request.call_count == 1 + mock_requests_session.request.assert_called_once_with(**request_params, stream=True, timeout=(5, 60)) + + +def test_make_request_unauthorised(network_client, mock_requests_session, response_401): + mock_requests_session.request.return_value = response_401 + api_request = APIRequest( + "GET", "https://example.com", headers={}, params={}, data="" + ) + api_response = network_client._make_request(api_request) + + assert api_response == APIResponse( + network_response=response_401, + reauthentication_needed=False, + raised_exception=None, + ) + assert mock_requests_session.request.call_count == 1 + + +@pytest.mark.parametrize( + "exc_message, expected_reauthentication_needed", + [ + ("Connection cancelled", False), + ( + "Connection broken: ConnectionResetError(54, 'Connection reset by peer')", + False, + ), + ( + "SSLError(SSLEOFError(8, 'EOF occurred in violation of protocol (_ssl.c:2396)')))", + True, + ), + ], +) +def test_make_request_network_exception( + network_client, mock_requests_session, exc_message, expected_reauthentication_needed +): + requests_exception = RequestException(exc_message) + mock_requests_session.request.side_effect = [requests_exception] + api_request = APIRequest( + "GET", "https://example.com", headers={}, params={}, data="" + ) + api_response = network_client._make_request(api_request) + + assert api_response == APIResponse( + network_response=None, + reauthentication_needed=expected_reauthentication_needed, + raised_exception=requests_exception, + ) + + +def test_fetch_successfully_retry_network_exception( + network_client, mock_requests_session, network_session_mock, response_200 +): + requests_exception = RequestException("Connection cancelled") + mock_requests_session.request.side_effect = [requests_exception, response_200] + + with patch("time.sleep"): + response = network_client.fetch( + FetchOptions( + method="get", + url="https://example.com", + network_session=network_session_mock, + ) + ) + assert response.status == 200 + + +def test_fetch_make_only_one_retry_for_network_exception( + network_client, mock_requests_session, network_session_mock +): + requests_exception = RequestException("Connection cancelled") + mock_requests_session.request.side_effect = [requests_exception, requests_exception] + + with patch("time.sleep"): + with pytest.raises(BoxSDKError, match="Connection cancelled"): + network_client.fetch( + FetchOptions( + method="get", + url="https://example.com", + network_session=network_session_mock, + ) + ) + + assert mock_requests_session.request.call_count == 2 + + +def test_fetch_get_json_format_response_success( + network_client, mock_requests_session, network_session_mock, response_200 +): + response_200.text = '{"id": "123456"}' + mock_requests_session.request.return_value = response_200 + + fetch_response = network_client.fetch( + FetchOptions( + method="get", + url="https://example.com", + network_session=network_session_mock, + response_format=ResponseFormat.JSON, + ) + ) + + assert fetch_response.status == 200 + assert fetch_response.data == {"id": "123456"} + assert fetch_response.headers == {} + + +def test_fetch_get_binary_format_response_success( + network_client, mock_requests_session, network_session_mock, response_200 +): + content = b"binary data" + response_200.iter_content.return_value = BytesIO(content) + mock_requests_session.request.return_value = response_200 + + fetch_response = network_client.fetch( + FetchOptions( + method="get", + url="https://example.com", + network_session=network_session_mock, + response_format=ResponseFormat.BINARY, + ) + ) + + assert fetch_response.status == 200 + assert fetch_response.content.read() == content + assert fetch_response.headers == {} + + +@pytest.mark.parametrize("retryable_status_code", [429, 500, 503]) +def test_retryable_status_codes( + network_client, + mock_requests_session, + network_session_mock, + response_200, + retryable_status_code, + response_failure_no_status, +): + response_failure_no_status.status_code = retryable_status_code + response_200.text = '{"id": "123456"}' + mock_requests_session.request.side_effect = [ + response_failure_no_status, + response_failure_no_status, + response_200, + ] + + fetch_response = network_client.fetch( + FetchOptions( + method="get", + url="https://example.com", + network_session=network_session_mock, + ) + ) + assert fetch_response.status == 200 + assert fetch_response.data == {"id": "123456"} + assert mock_requests_session.request.call_count == 3 + + +@pytest.mark.parametrize("retryable_status_code", [429, 500, 503]) +def test_retryable_status_codes_with_invalid__response_body( + network_client, + mock_requests_session, + network_session_mock, + response_200, + retryable_status_code, + response_failure_no_status, +): + response_failure_no_status.status_code = retryable_status_code + response_failure_no_status.text = 'Invalid JSON' + response_200.text = '{"id": "123456"}' + mock_requests_session.request.side_effect = [ + response_failure_no_status, + response_failure_no_status, + response_200, + ] + + fetch_response = network_client.fetch( + FetchOptions( + method="get", + url="https://example.com", + network_session=network_session_mock, + response_format=ResponseFormat.JSON, + ) + ) + assert fetch_response.status == 200 + assert fetch_response.data == {"id": "123456"} + assert mock_requests_session.request.call_count == 3 + + +def test_status_code_202_with_no_retry_after_header( + network_client, mock_requests_session, network_session_mock, response_202 +): + mock_requests_session.request.return_value = response_202 + + fetch_response = network_client.fetch( + FetchOptions( + method="get", + url="https://example.com", + network_session=network_session_mock, + ) + ) + assert fetch_response.status == 202 + assert fetch_response.data == {} + + +def test_retryable_status_code_202( + network_client, + mock_requests_session, + network_session_mock, + response_202_with_retry_after, + response_200, +): + response_200.text = '{"id": "123456"}' + response_200.headers = {"Retry-After": "0"} + mock_requests_session.request.side_effect = [ + response_202_with_retry_after, + response_202_with_retry_after, + response_200, + ] + + with patch("time.sleep"): + fetch_response = network_client.fetch( + FetchOptions( + method="get", + url="https://example.com", + network_session=network_session_mock, + ) + ) + + assert fetch_response.status == 200 + assert fetch_response.data == {"id": "123456"} + assert mock_requests_session.request.call_count == 3 + + +def test_202_should_be_returned_if_retry_limit_is_reached( + network_client, + mock_requests_session, + network_session_mock, + response_202_with_retry_after, +): + network_session_mock.MAX_ATTEMPTS = 5 + mock_requests_session.request.return_value = response_202_with_retry_after + + with patch("time.sleep"): + fetch_response = network_client.fetch( + FetchOptions( + method="get", + url="https://example.com", + network_session=network_session_mock, + ) + ) + + assert fetch_response.status == 202 + assert fetch_response.data == {} + + +@pytest.mark.parametrize("not_retryable_status_code", [404, 403, 400]) +def test_not_retryable_status_codes( + network_client, + mock_requests_session, + network_session_mock, + not_retryable_status_code, + response_failure_no_status, + response_200, +): + response_failure_no_status.status_code = not_retryable_status_code + mock_requests_session.request.side_effect = [ + response_failure_no_status, + response_failure_no_status, + response_200, + ] + + with pytest.raises(BoxSDKError, match=f"Status code: {not_retryable_status_code}"): + network_client.fetch( + FetchOptions( + method="get", + url="https://example.com", + network_session=network_session_mock, + ) + ) + + assert mock_requests_session.request.call_count == 1 + + +def test_retrying_401_response_with_new_token_and_auth_provided( + network_client, + mock_requests_session, + network_session_mock, + response_401, + response_200, + authentication_mock, + token_mock, + token2_mock, +): + response_200.text = '{"id": "123456"}' + mock_requests_session.request.side_effect = [response_401, response_200] + + with patch("time.sleep"): + fetch_response = network_client.fetch( + FetchOptions( + url="https://example.com", + method="GET", + network_session=network_session_mock, + auth=authentication_mock, + ) + ) + + assert mock_requests_session.request.call_count == 2 + mock_requests_session.request.assert_has_calls( + [ + mock.call( + method="GET", + url="https://example.com", + headers={ + "Authorization": f"Bearer {token_mock}", + "User-Agent": USER_AGENT_HEADER, + "X-Box-UA": X_BOX_UA_HEADER, + "Content-Type": "application/json", + }, + params={}, + data=None, + stream=True, + allow_redirects=True, + timeout=(5, 60), + ), + mock.call( + method="GET", + url="https://example.com", + headers={ + "Authorization": f"Bearer {token2_mock}", + "User-Agent": USER_AGENT_HEADER, + "X-Box-UA": X_BOX_UA_HEADER, + "Content-Type": "application/json", + }, + params={}, + data=None, + stream=True, + allow_redirects=True, + timeout=(5, 60), + ), + ], + ) + assert fetch_response.status == 200 + assert fetch_response.data == {"id": "123456"} + + +def test_not_retrying_401_when_auth_not_provided( + network_client, + mock_requests_session, + network_session_mock, + response_401, + response_200, + authentication_mock, +): + mock_requests_session.request.side_effect = [response_401, response_200] + + with pytest.raises(BoxSDKError, match="Status code: 401"): + network_client.fetch( + FetchOptions( + url="https://example.com", + method="GET", + network_session=network_session_mock, + ) + ) + + assert mock_requests_session.request.call_count == 1 + mock_requests_session.request.assert_called_once_with( + method="GET", + url="https://example.com", + headers={ + "User-Agent": USER_AGENT_HEADER, + "X-Box-UA": X_BOX_UA_HEADER, + "Content-Type": "application/json", + }, + params={}, + data=None, + stream=True, + allow_redirects=True, + timeout=(5, 60), + ) + + +def test_reaching_retry_limit( + network_client, + mock_requests_session, + network_session_mock, + response_202_with_retry_after, +): + network_session_mock.MAX_ATTEMPTS = 5 + mock_requests_session.request.return_value = response_202_with_retry_after + + with pytest.raises(BoxSDKError, match="Status code: 202"): + network_client.fetch( + FetchOptions( + method="get", + url="https://example.com", + network_session=network_session_mock, + ) + ) + assert mock_requests_session.request.call_count == 5 + + +def test_reaching_retry_limit( + network_client, mock_requests_session, network_session_mock, response_500 +): + network_session_mock.MAX_ATTEMPTS = 5 + mock_requests_session.request.return_value = response_500 + + with pytest.raises(BoxSDKError, match="Status code: 500"): + network_client.fetch( + FetchOptions( + method="get", + url="https://example.com", + network_session=network_session_mock, + ) + ) + assert mock_requests_session.request.call_count == 5 + + +def test_get_retry_after_time_use_retry_after_header_value(network_session_mock): + fetch_options = FetchOptions( + url="example.com", method="GET", network_session=network_session_mock + ) + fetch_response = FetchResponse(status=200, headers={'Retry-After': '213'}) + for attempt_number in range(1, 5): + sleep_time = network_session_mock.retry_strategy.retry_after( + fetch_options, fetch_response, attempt_number + ) + assert sleep_time == 213 + + +def test_get_retry_after_time_use_exponential_backoff(network_session_mock): + fetch_options = FetchOptions( + url="example.com", method="GET", network_session=network_session_mock + ) + fetch_response = FetchResponse(status=200, headers={}) + for attempt_number in range(1, 5): + sleep_time = network_session_mock.retry_strategy.retry_after( + fetch_options, fetch_response, attempt_number + ) + assert sleep_time > 0 + + +def test_pass_retry_after_header_to_get_retry_after_time_method( + network_client, + mock_requests_session, + network_session_mock, + response_429, + response_200, +): + response_429.headers = {"Retry-After": "123"} + mock_requests_session.request.side_effect = [response_429, response_200] + + with patch("time.sleep") as sleep_mock: + network_client.fetch( + FetchOptions( + method="get", + url="https://example.com", + network_session=network_session_mock, + ) + ) + assert mock_requests_session.request.call_count == 2 + sleep_mock.assert_called_once_with(123) + + +def test_raising_api_error_with_valid_json_body(network_client, data_sanitizer): + client_error_response = Mock(Response) + client_error_response.status_code = 400 + client_error_response.ok = False + client_error_response.headers = {} + client_error_response.text = """{ + "type": "error", + "code": "item_name_invalid", + "context_info": { + "message": "Something went wrong." + }, + "help_url": "https://developer.box.com/guides/api-calls/permissions-and-errors/common-errors/", + "message": "Method Not Allowed", + "request_id": "abcdef123456", + "status": 400 + }""" + client_error_response.json.return_value = json.loads(client_error_response.text) + + request = APIRequest( + method="POST", + url="https://example.com", + headers={ + "header": "test", + "User-Agent": USER_AGENT_HEADER, + "X-Box-UA": X_BOX_UA_HEADER, + "Content-Type": "application/json", + }, + params={"param": "value"}, + data='{"key": "value"}', + ) + + response = APIResponse( + network_response=client_error_response, + reauthentication_needed=False, + raised_exception=None, + ) + try: + network_client._raise_on_unsuccessful_request(request, response, data_sanitizer) + except BoxAPIError as e: + assert e.request_info.method == request.method + assert e.request_info.url == request.url + assert e.request_info.query_params == request.params + assert e.request_info.headers == request.headers + assert e.request_info.body == request.data + + assert e.response_info.status_code == client_error_response.status_code + assert e.response_info.headers == client_error_response.headers + assert e.response_info.body == { + "type": "error", + "code": "item_name_invalid", + "context_info": {"message": "Something went wrong."}, + "help_url": ( + "https://developer.box.com/guides/api-calls/permissions-and-errors/common-errors/" + ), + "message": "Method Not Allowed", + "request_id": "abcdef123456", + "status": 400, + } + assert e.response_info.raw_body == client_error_response.text + assert e.response_info.code == "item_name_invalid" + assert e.response_info.context_info == {"message": "Something went wrong."} + assert e.response_info.request_id == "abcdef123456" + assert ( + e.response_info.help_url + == "https://developer.box.com/guides/api-calls/permissions-and-errors/common-errors/" + ) + + assert e.message == "400 Method Not Allowed; Request ID: abcdef123456" + assert e.error is None + assert e.name == "BoxAPIError" + + +def test_sensitive_data_are_sanitized_from_box_api_error( + network_client, data_sanitizer +): + client_error_response = Mock(Response) + client_error_response.status_code = 400 + client_error_response.ok = False + client_error_response.headers = {'token': 'my_token'} + client_error_response.text = """{ + "client_secret": "secret", + "password": "change-me", + "message": "Method Not Allowed", + "request_id": "abcdef123456", + "status": 400 + }""" + client_error_response.json.return_value = json.loads(client_error_response.text) + + request = APIRequest( + method="POST", + url="https://example.com", + headers={ + "header": "test", + "User-Agent": USER_AGENT_HEADER, + "X-Box-UA": X_BOX_UA_HEADER, + "Content-Type": "application/json", + "Authorization": "Bearer acbdef123456", + }, + params={"param": "value"}, + data='{"key": "value"}', + ) + + response = APIResponse( + network_response=client_error_response, + reauthentication_needed=False, + raised_exception=None, + ) + try: + network_client._raise_on_unsuccessful_request(request, response, data_sanitizer) + except BoxAPIError as e: + exception_message = str(e) + assert "Authorization': '---[redacted]---'" in exception_message + assert "client_secret': '---[redacted]---'" in exception_message + assert "password': '---[redacted]---'" in exception_message + assert "token': '---[redacted]---'" in exception_message + assert "message': 'Method Not Allowed'" in exception_message + + +@pytest.mark.parametrize('response_body', ['', 'Invalid json', 123]) +def test_raising_api_error_without_valid_json_body( + network_client, response_body, data_sanitizer +): + client_error_response = Mock(Response) + client_error_response.status_code = 400 + client_error_response.ok = False + client_error_response.headers = {} + client_error_response.text = response_body + + request = APIRequest( + method="POST", + url="https://example.com", + headers={ + "header": "test", + "User-Agent": USER_AGENT_HEADER, + "X-Box-UA": X_BOX_UA_HEADER, + "Content-Type": "application/json", + }, + params={"param": "value"}, + data='{"key": "value"}', + ) + + response = APIResponse( + network_response=client_error_response, + reauthentication_needed=False, + raised_exception=None, + ) + try: + network_client._raise_on_unsuccessful_request(request, response, data_sanitizer) + except BoxAPIError as e: + assert e.request_info.method == request.method + assert e.request_info.url == request.url + assert e.request_info.query_params == request.params + assert e.request_info.headers == request.headers + assert e.request_info.body == request.data + + assert e.response_info.status_code == client_error_response.status_code + assert e.response_info.headers == client_error_response.headers + assert e.response_info.body == {} + assert e.response_info.raw_body == client_error_response.text + assert e.response_info.code is None + assert e.response_info.context_info == {} + assert e.response_info.request_id is None + assert e.response_info.help_url is None + + assert e.error is None + assert e.name == "BoxAPIError" + + +def test_raising_exception_raised_by_network_layer(network_client, data_sanitizer): + requests_exception = RequestException("Something went wrong") + request = APIRequest( + method="POST", + url="https://example.com", + headers={ + "header": "test", + "User-Agent": USER_AGENT_HEADER, + "X-Box-UA": X_BOX_UA_HEADER, + "Content-Type": "application/json", + }, + params={"param": "value"}, + data='{"key": "value"}', + ) + + response = APIResponse( + network_response=None, + reauthentication_needed=False, + raised_exception=requests_exception, + ) + + try: + network_client._raise_on_unsuccessful_request(request, response, data_sanitizer) + except BoxSDKError as e: + assert e.message == "Something went wrong" + assert e.error == requests_exception + assert e.name == "BoxSDKError" + + +def test_proxy_config(): + client = BoxClient(auth=None).with_proxy( + ProxyConfig(url="http://127.0.0.1:3128/", username="user", password="pass") + ) + assert client.network_session.proxy_url == "http://user:pass@127.0.0.1:3128/" + requests_session = client.network_session.network_client.requests_session + assert requests_session.proxies["http"] == "http://user:pass@127.0.0.1:3128/" + assert requests_session.proxies["https"] == "http://user:pass@127.0.0.1:3128/" + + +@pytest.mark.parametrize( + "response_body, expected_json", + [ + ('', {}), + ('Invalid json', {}), + (123, {}), + ('{"name": "John"}', {'name': 'John'}), + ], +) +def test_read_json_body(response_body, expected_json): + assert BoxNetworkClient._read_json_body(response_body) == expected_json + + +def test_get_options_stream_position(network_client, mock_byte_stream): + mock_byte_stream.seek(1) + options = FetchOptions( + url="https://example.com", + method="POST", + data={"key": "value"}, + file_stream=mock_byte_stream, + ) + + assert network_client._get_options_stream_position(options) == 1 + + +def test_get_multipart_stream_position(network_client, mock_byte_stream): + mock_byte_stream.seek(1) + options = FetchOptions( + url="https://example.com", + method="POST", + data={"key": "value"}, + content_type="multipart/form-data", + multipart_data=[ + MultipartItem(part_name="attributes", data={"name": "file.pdf"}), + MultipartItem( + part_name="file", file_stream=mock_byte_stream, file_name="file.pdf" + ), + ], + ) + + assert network_client._get_multipart_stream_positions(options) == {"file": 1} + + +def test_get_multipart_stream_position_empty(network_client): + options = FetchOptions( + url="https://example.com", + method="POST", + data={"key": "value"}, + content_type="multipart/form-data", + multipart_data=[ + MultipartItem(part_name="attributes", data={"name": "file.pdf"}), + ], + ) + + assert network_client._get_multipart_stream_positions(options) == {} + + +def test_reset_options_stream(network_client, mock_byte_stream): + options = FetchOptions( + url="https://example.com", + method="POST", + data={"key": "value"}, + content_type="multipart/form-data", + file_stream=mock_byte_stream, + ) + + mock_byte_stream.seek(1) + original_position = network_client._get_options_stream_position(options) + mock_byte_stream.seek(2) + + network_client._reset_options_stream(options, original_position, None) + + assert options.file_stream.tell() == 1 + + +def test_reset_options_stream_non_seekable_stream( + network_client, mock_non_seekable_stream +): + options = FetchOptions( + url="https://example.com", + method="POST", + data={"key": "value"}, + content_type="multipart/form-data", + file_stream=mock_non_seekable_stream, + ) + + original_position = network_client._get_options_stream_position(options) + + with pytest.raises(BoxSDKError): + network_client._reset_options_stream(options, original_position, None) + + +def test_reset_multipart_stream(network_client, mock_byte_stream): + options = FetchOptions( + url="https://example.com", + method="POST", + data={"key": "value"}, + content_type="multipart/form-data", + multipart_data=[ + MultipartItem(part_name="attributes", data={"name": "file.pdf"}), + MultipartItem( + part_name="file", file_stream=mock_byte_stream, file_name="file.pdf" + ), + ], + ) + + mock_byte_stream.seek(1) + original_positions = network_client._get_multipart_stream_positions(options) + mock_byte_stream.seek(2) + + network_client._reset_multipart_streams(options, original_positions, None) + + assert options.multipart_data[1].file_stream.tell() == 1 + + +def test_reset_multipart_non_seekable_stream(network_client, mock_non_seekable_stream): + options = FetchOptions( + url="https://example.com", + method="POST", + data={"key": "value"}, + content_type="multipart/form-data", + multipart_data=[ + MultipartItem(part_name="attributes", data={"name": "file.pdf"}), + MultipartItem( + part_name="file", + file_stream=mock_non_seekable_stream, + file_name="file.pdf", + ), + ], + ) + + original_positions = network_client._get_multipart_stream_positions(options) + + with pytest.raises(BoxSDKError): + network_client._reset_multipart_streams(options, original_positions, None) + + +def test_disable_follow_redirects( + network_client, + mock_requests_session, + network_session_mock, + response_302, + response_200, +): + mock_requests_session.request.side_effect = [response_302, response_200] + + network_client.fetch( + FetchOptions( + url="https://example.com", + method="GET", + network_session=network_session_mock, + follow_redirects=False, + ) + ) + + assert mock_requests_session.request.call_count == 1 + mock_requests_session.request.assert_called_once_with( + method="GET", + url="https://example.com", + headers={ + "User-Agent": USER_AGENT_HEADER, + "X-Box-UA": X_BOX_UA_HEADER, + "Content-Type": "application/json", + }, + params={}, + data=None, + stream=True, + allow_redirects=False, + timeout=(5, 60), + ) diff --git a/test/test_gen/chunked_uploads.py b/test/test_gen/chunked_uploads.py new file mode 100644 index 000000000..25ecf557f --- /dev/null +++ b/test/test_gen/chunked_uploads.py @@ -0,0 +1,166 @@ +from typing import List + +from box_sdk_gen.internal.utils import to_string + +from typing import Optional + +from box_sdk_gen.internal.utils import Buffer + +from box_sdk_gen.internal.utils import HashName + +from box_sdk_gen.internal.utils import Iterator + +from box_sdk_gen.internal.utils import generate_byte_stream_from_buffer + +from box_sdk_gen.internal.utils import hex_to_base_64 + +from box_sdk_gen.internal.utils import iterate_chunks + +from box_sdk_gen.internal.utils import read_byte_stream + +from box_sdk_gen.internal.utils import reduce_iterator + +from box_sdk_gen.internal.utils import Hash + +from box_sdk_gen.internal.utils import buffer_length + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import generate_byte_stream + +from box_sdk_gen.internal.utils import ByteStream + +from test.commons import get_default_client + +from box_sdk_gen.schemas.file import File + +from box_sdk_gen.schemas.upload_session import UploadSession + +from box_sdk_gen.schemas.upload_part import UploadPart + +from box_sdk_gen.schemas.upload_parts import UploadParts + +from box_sdk_gen.schemas.uploaded_part import UploadedPart + +from box_sdk_gen.schemas.files import Files + +from box_sdk_gen.client import BoxClient + +client: BoxClient = get_default_client() + +class _TestPartAccumulator: + def __init__(self, last_index: int, parts: List[UploadPart], file_size: int, file_hash: Hash, *, upload_part_url: str = '', upload_session_id: str = ''): + self.last_index = last_index + self.parts = parts + self.file_size = file_size + self.file_hash = file_hash + self.upload_part_url = upload_part_url + self.upload_session_id = upload_session_id + +def _reducer_by_id(acc: _TestPartAccumulator, chunk: ByteStream) -> _TestPartAccumulator: + last_index: int = acc.last_index + parts: List[UploadPart] = acc.parts + chunk_buffer: Buffer = read_byte_stream(chunk) + hash: Hash = Hash(algorithm=HashName.SHA1) + hash.update_hash(chunk_buffer) + sha_1: str = hash.digest_hash('base64') + digest: str = ''.join(['sha=', sha_1]) + chunk_size: int = buffer_length(chunk_buffer) + bytes_start: int = last_index + 1 + bytes_end: int = last_index + chunk_size + content_range: str = ''.join(['bytes ', to_string(bytes_start), '-', to_string(bytes_end), '/', to_string(acc.file_size)]) + uploaded_part: UploadedPart = client.chunked_uploads.upload_file_part(acc.upload_session_id, generate_byte_stream_from_buffer(chunk_buffer), digest, content_range) + part: UploadPart = uploaded_part.part + part_sha_1: str = hex_to_base_64(part.sha_1) + assert part_sha_1 == sha_1 + assert part.size == chunk_size + assert part.offset == bytes_start + acc.file_hash.update_hash(chunk_buffer) + return _TestPartAccumulator(last_index=bytes_end, parts=parts + [part], file_size=acc.file_size, upload_session_id=acc.upload_session_id, file_hash=acc.file_hash) + +def testChunkedManualProcessById(): + file_size: int = (20 * 1024) * 1024 + file_byte_stream: ByteStream = generate_byte_stream(file_size) + file_name: str = get_uuid() + parent_folder_id: str = '0' + upload_session: UploadSession = client.chunked_uploads.create_file_upload_session(parent_folder_id, file_size, file_name) + upload_session_id: str = upload_session.id + part_size: int = upload_session.part_size + total_parts: int = upload_session.total_parts + assert part_size * total_parts >= file_size + assert upload_session.num_parts_processed == 0 + file_hash: Hash = Hash(algorithm=HashName.SHA1) + chunks_iterator: Iterator = iterate_chunks(file_byte_stream, part_size, file_size) + results: _TestPartAccumulator = reduce_iterator(chunks_iterator, _reducer_by_id, _TestPartAccumulator(last_index=-1, parts=[], file_size=file_size, upload_session_id=upload_session_id, file_hash=file_hash)) + parts: List[UploadPart] = results.parts + processed_session_parts: UploadParts = client.chunked_uploads.get_file_upload_session_parts(upload_session_id) + assert processed_session_parts.total_count == total_parts + processed_session: UploadSession = client.chunked_uploads.get_file_upload_session_by_id(upload_session_id) + assert processed_session.id == upload_session_id + sha_1: str = file_hash.digest_hash('base64') + digest: str = ''.join(['sha=', sha_1]) + committed_session: Optional[Files] = client.chunked_uploads.create_file_upload_session_commit(upload_session_id, parts, digest) + assert committed_session.entries[0].name == file_name + client.chunked_uploads.delete_file_upload_session_by_id(upload_session_id) + +def _reducer_by_url(acc: _TestPartAccumulator, chunk: ByteStream) -> _TestPartAccumulator: + last_index: int = acc.last_index + parts: List[UploadPart] = acc.parts + chunk_buffer: Buffer = read_byte_stream(chunk) + hash: Hash = Hash(algorithm=HashName.SHA1) + hash.update_hash(chunk_buffer) + sha_1: str = hash.digest_hash('base64') + digest: str = ''.join(['sha=', sha_1]) + chunk_size: int = buffer_length(chunk_buffer) + bytes_start: int = last_index + 1 + bytes_end: int = last_index + chunk_size + content_range: str = ''.join(['bytes ', to_string(bytes_start), '-', to_string(bytes_end), '/', to_string(acc.file_size)]) + uploaded_part: UploadedPart = client.chunked_uploads.upload_file_part_by_url(acc.upload_part_url, generate_byte_stream_from_buffer(chunk_buffer), digest, content_range) + part: UploadPart = uploaded_part.part + part_sha_1: str = hex_to_base_64(part.sha_1) + assert part_sha_1 == sha_1 + assert part.size == chunk_size + assert part.offset == bytes_start + acc.file_hash.update_hash(chunk_buffer) + return _TestPartAccumulator(last_index=bytes_end, parts=parts + [part], file_size=acc.file_size, upload_part_url=acc.upload_part_url, file_hash=acc.file_hash) + +def testChunkedManualProcessByUrl(): + file_size: int = (20 * 1024) * 1024 + file_byte_stream: ByteStream = generate_byte_stream(file_size) + file_name: str = get_uuid() + parent_folder_id: str = '0' + upload_session: UploadSession = client.chunked_uploads.create_file_upload_session(parent_folder_id, file_size, file_name) + upload_part_url: str = upload_session.session_endpoints.upload_part + commit_url: str = upload_session.session_endpoints.commit + list_parts_url: str = upload_session.session_endpoints.list_parts + status_url: str = upload_session.session_endpoints.status + abort_url: str = upload_session.session_endpoints.abort + upload_session_id: str = upload_session.id + part_size: int = upload_session.part_size + total_parts: int = upload_session.total_parts + assert part_size * total_parts >= file_size + assert upload_session.num_parts_processed == 0 + file_hash: Hash = Hash(algorithm=HashName.SHA1) + chunks_iterator: Iterator = iterate_chunks(file_byte_stream, part_size, file_size) + results: _TestPartAccumulator = reduce_iterator(chunks_iterator, _reducer_by_url, _TestPartAccumulator(last_index=-1, parts=[], file_size=file_size, upload_part_url=upload_part_url, file_hash=file_hash)) + parts: List[UploadPart] = results.parts + processed_session_parts: UploadParts = client.chunked_uploads.get_file_upload_session_parts_by_url(list_parts_url) + assert processed_session_parts.total_count == total_parts + processed_session: UploadSession = client.chunked_uploads.get_file_upload_session_by_url(status_url) + assert processed_session.id == upload_session_id + sha_1: str = file_hash.digest_hash('base64') + digest: str = ''.join(['sha=', sha_1]) + committed_session: Optional[Files] = client.chunked_uploads.create_file_upload_session_commit_by_url(commit_url, parts, digest) + assert committed_session.entries[0].name == file_name + client.chunked_uploads.delete_file_upload_session_by_url(abort_url) + +def testChunkedUploadConvenienceMethod(): + file_size: int = (20 * 1024) * 1024 + file_byte_stream: ByteStream = generate_byte_stream(file_size) + file_name: str = get_uuid() + parent_folder_id: str = '0' + uploaded_file: File = client.chunked_uploads.upload_big_file(file_byte_stream, file_name, file_size, parent_folder_id) + assert uploaded_file.name == file_name + assert uploaded_file.size == file_size + assert uploaded_file.parent.id == parent_folder_id + client.files.delete_file_by_id(uploaded_file.id) \ No newline at end of file diff --git a/test/test_gen/classifications.py b/test/test_gen/classifications.py new file mode 100644 index 000000000..d4e2d4a06 --- /dev/null +++ b/test/test_gen/classifications.py @@ -0,0 +1,40 @@ +from typing import List + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.classification_template import ClassificationTemplateFieldsOptionsField + +from box_sdk_gen.managers.classifications import UpdateClassificationRequestBody + +from box_sdk_gen.managers.classifications import UpdateClassificationRequestBodyDataField + +from box_sdk_gen.managers.classifications import UpdateClassificationRequestBodyDataStaticConfigField + +from box_sdk_gen.managers.classifications import UpdateClassificationRequestBodyDataStaticConfigClassificationField + +from box_sdk_gen.internal.utils import get_uuid + +from test.commons import get_default_client + +from test.commons import get_or_create_classification_template + +from test.commons import get_or_create_classification + +from box_sdk_gen.schemas.classification_template import ClassificationTemplate + +client: BoxClient = get_default_client() + +def testClassifications(): + classification_template: ClassificationTemplate = get_or_create_classification_template() + classification: ClassificationTemplateFieldsOptionsField = get_or_create_classification(classification_template) + assert not classification.key == '' + assert not classification.static_config.classification.color_id == 100 + assert not classification.static_config.classification.classification_definition == '' + updated_classification_name: str = get_uuid() + updated_classification_description: str = get_uuid() + classification_template_with_updated_classification: ClassificationTemplate = client.classifications.update_classification([UpdateClassificationRequestBody(enum_option_key=classification.key, data=UpdateClassificationRequestBodyDataField(key=updated_classification_name, static_config=UpdateClassificationRequestBodyDataStaticConfigField(classification=UpdateClassificationRequestBodyDataStaticConfigClassificationField(color_id=2, classification_definition=updated_classification_description))))]) + updated_classifications: List[ClassificationTemplateFieldsOptionsField] = classification_template_with_updated_classification.fields[0].options + updated_classification: ClassificationTemplateFieldsOptionsField = updated_classifications[0] + assert updated_classification.key == updated_classification_name + assert updated_classification.static_config.classification.color_id == 2 + assert updated_classification.static_config.classification.classification_definition == updated_classification_description \ No newline at end of file diff --git a/test/test_gen/client.py b/test/test_gen/client.py new file mode 100644 index 000000000..738e61ede --- /dev/null +++ b/test/test_gen/client.py @@ -0,0 +1,130 @@ +from box_sdk_gen.internal.utils import to_string + +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.serialization.json import SerializedData + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.managers.folders import CreateFolderParent + +from box_sdk_gen.internal.utils import ByteStream + +from box_sdk_gen.internal.utils import Buffer + +from box_sdk_gen.schemas.files import Files + +from box_sdk_gen.managers.uploads import UploadFileAttributes + +from box_sdk_gen.managers.uploads import UploadFileAttributesParentField + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.user_full import UserFull + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import generate_byte_stream + +from box_sdk_gen.internal.utils import buffer_equals + +from box_sdk_gen.internal.utils import generate_byte_buffer + +from box_sdk_gen.internal.utils import generate_byte_stream_from_buffer + +from box_sdk_gen.internal.utils import read_byte_stream + +from test.commons import get_default_client + +from box_sdk_gen.networking.fetch_options import FetchOptions + +from box_sdk_gen.networking.fetch_options import MultipartItem + +from box_sdk_gen.networking.fetch_response import FetchResponse + +from box_sdk_gen.networking.base_urls import BaseUrls + +from box_sdk_gen.serialization.json import json_to_serialized_data + +from box_sdk_gen.serialization.json import get_sd_value_by_key + +client: BoxClient = get_default_client() + +def testMakeRequestJsonCRUD(): + new_folder_name: str = get_uuid() + request_body_post: str = ''.join(['{"name": "', new_folder_name, '", "parent": { "id": "0"}}']) + create_folder_response: FetchResponse = client.make_request(FetchOptions(method='post', url='https://api.box.com/2.0/folders', data=json_to_serialized_data(request_body_post))) + assert create_folder_response.status == 201 + created_folder: SerializedData = create_folder_response.data + assert get_sd_value_by_key(created_folder, 'name') == new_folder_name + updated_name: str = get_uuid() + request_body_put: str = ''.join(['{"name": "', updated_name, '"}']) + update_folder_response: FetchResponse = client.make_request(FetchOptions(method='put', url=''.join(['https://api.box.com/2.0/folders/', get_sd_value_by_key(created_folder, 'id')]), data=json_to_serialized_data(request_body_put))) + assert update_folder_response.status == 200 + updated_folder: SerializedData = update_folder_response.data + assert get_sd_value_by_key(updated_folder, 'name') == updated_name + assert get_sd_value_by_key(updated_folder, 'id') == get_sd_value_by_key(created_folder, 'id') + get_folder_response: FetchResponse = client.make_request(FetchOptions(url=''.join(['https://api.box.com/2.0/folders/', get_sd_value_by_key(created_folder, 'id')]), method='GET')) + assert get_folder_response.status == 200 + received_folder: SerializedData = get_folder_response.data + assert get_sd_value_by_key(received_folder, 'name') == updated_name + assert get_sd_value_by_key(received_folder, 'id') == get_sd_value_by_key(updated_folder, 'id') + delete_folder_response: FetchResponse = client.make_request(FetchOptions(url=''.join(['https://api.box.com/2.0/folders/', get_sd_value_by_key(received_folder, 'id')]), method='DELETE')) + assert delete_folder_response.status == 204 + +def testMakeRequestMultipart(): + new_folder_name: str = get_uuid() + new_folder: FolderFull = client.folders.create_folder(new_folder_name, CreateFolderParent(id='0')) + new_folder_id: str = new_folder.id + new_file_name: str = ''.join([get_uuid(), '.pdf']) + file_content_stream: ByteStream = generate_byte_stream(1024 * 1024) + multipart_attributes: str = ''.join(['{"name": "', new_file_name, '", "parent": { "id":', new_folder_id, '}}']) + upload_file_response: FetchResponse = client.make_request(FetchOptions(method='POST', url='https://upload.box.com/api/2.0/files/content', content_type='multipart/form-data', multipart_data=[MultipartItem(part_name='attributes', data=json_to_serialized_data(multipart_attributes)), MultipartItem(part_name='file', file_stream=file_content_stream)])) + assert upload_file_response.status == 201 + client.folders.delete_folder_by_id(new_folder_id, recursive=True) + +def testMakeRequestBinaryFormat(): + new_file_name: str = get_uuid() + file_buffer: Buffer = generate_byte_buffer(1024 * 1024) + file_content_stream: ByteStream = generate_byte_stream_from_buffer(file_buffer) + uploaded_files: Files = client.uploads.upload_file(UploadFileAttributes(name=new_file_name, parent=UploadFileAttributesParentField(id='0')), file_content_stream) + uploaded_file: FileFull = uploaded_files.entries[0] + download_file_response: FetchResponse = client.make_request(FetchOptions(method='GET', url=''.join(['https://api.box.com/2.0/files/', uploaded_file.id, '/content']), response_format=ResponseFormat.BINARY)) + assert download_file_response.status == 200 + assert buffer_equals(read_byte_stream(download_file_response.content), file_buffer) + client.files.delete_file_by_id(uploaded_file.id) + +def testWithAsUserHeader(): + user_name: str = get_uuid() + created_user: UserFull = client.users.create_user(user_name, is_platform_access_only=True) + as_user_client: BoxClient = client.with_as_user_header(created_user.id) + admin_user: UserFull = client.users.get_user_me() + assert not to_string(admin_user.name) == user_name + app_user: UserFull = as_user_client.users.get_user_me() + assert to_string(app_user.name) == user_name + client.users.delete_user_by_id(created_user.id) + +def testWithSuppressedNotifications(): + new_client: BoxClient = client.with_suppressed_notifications() + user: UserFull = new_client.users.get_user_me() + assert not user.id == '' + +def testWithExtraHeaders(): + user_name: str = get_uuid() + created_user: UserFull = client.users.create_user(user_name, is_platform_access_only=True) + as_user_client: BoxClient = client.with_extra_headers(extra_headers={'As-User': created_user.id}) + admin_user: UserFull = client.users.get_user_me() + assert not to_string(admin_user.name) == user_name + app_user: UserFull = as_user_client.users.get_user_me() + assert to_string(app_user.name) == user_name + client.users.delete_user_by_id(created_user.id) + +def testWithCustomBaseUrls(): + new_base_urls: BaseUrls = BaseUrls(base_url='https://box.com/', upload_url='https://box.com/', oauth_2_url='https://box.com/') + custom_base_client: BoxClient = client.with_custom_base_urls(new_base_urls) + with pytest.raises(Exception): + custom_base_client.users.get_user_me() \ No newline at end of file diff --git a/test/test_gen/collaboration_allowlist_entries.py b/test/test_gen/collaboration_allowlist_entries.py new file mode 100644 index 000000000..02945241d --- /dev/null +++ b/test/test_gen/collaboration_allowlist_entries.py @@ -0,0 +1,33 @@ +from box_sdk_gen.internal.utils import to_string + +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.collaboration_allowlist_entries import CollaborationAllowlistEntries + +from box_sdk_gen.schemas.collaboration_allowlist_entry import CollaborationAllowlistEntry + +from box_sdk_gen.managers.collaboration_allowlist_entries import CreateCollaborationWhitelistEntryDirection + +from test.commons import get_default_client + +from box_sdk_gen.internal.utils import get_uuid + +client: BoxClient = get_default_client() + +def testCollaborationAllowlistEntries(): + allowlist: CollaborationAllowlistEntries = client.collaboration_allowlist_entries.get_collaboration_whitelist_entries() + assert len(allowlist.entries) >= 0 + domain: str = ''.join([get_uuid(), 'example.com']) + new_entry: CollaborationAllowlistEntry = client.collaboration_allowlist_entries.create_collaboration_whitelist_entry(domain, CreateCollaborationWhitelistEntryDirection.INBOUND) + assert to_string(new_entry.type) == 'collaboration_whitelist_entry' + assert to_string(new_entry.direction) == 'inbound' + assert new_entry.domain == domain + entry: CollaborationAllowlistEntry = client.collaboration_allowlist_entries.get_collaboration_whitelist_entry_by_id(new_entry.id) + assert entry.id == new_entry.id + assert to_string(entry.direction) == to_string(new_entry.direction) + assert entry.domain == domain + client.collaboration_allowlist_entries.delete_collaboration_whitelist_entry_by_id(entry.id) + with pytest.raises(Exception): + client.collaboration_allowlist_entries.get_collaboration_whitelist_entry_by_id(entry.id) \ No newline at end of file diff --git a/test/test_gen/collaboration_allowlist_exempt_targets.py b/test/test_gen/collaboration_allowlist_exempt_targets.py new file mode 100644 index 000000000..315d43427 --- /dev/null +++ b/test/test_gen/collaboration_allowlist_exempt_targets.py @@ -0,0 +1,34 @@ +from box_sdk_gen.internal.utils import to_string + +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.collaboration_allowlist_exempt_targets import CollaborationAllowlistExemptTargets + +from box_sdk_gen.schemas.user_full import UserFull + +from box_sdk_gen.schemas.collaboration_allowlist_exempt_target import CollaborationAllowlistExemptTarget + +from box_sdk_gen.managers.collaboration_allowlist_exempt_targets import CreateCollaborationWhitelistExemptTargetUser + +from box_sdk_gen.internal.utils import get_uuid + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def testCollaborationAllowlistExemptTargets(): + exempt_targets: CollaborationAllowlistExemptTargets = client.collaboration_allowlist_exempt_targets.get_collaboration_whitelist_exempt_targets() + assert len(exempt_targets.entries) >= 0 + user: UserFull = client.users.create_user(get_uuid(), login=''.join([get_uuid(), '@boxdemo.com']), is_platform_access_only=True) + new_exempt_target: CollaborationAllowlistExemptTarget = client.collaboration_allowlist_exempt_targets.create_collaboration_whitelist_exempt_target(CreateCollaborationWhitelistExemptTargetUser(id=user.id)) + assert to_string(new_exempt_target.type) == 'collaboration_whitelist_exempt_target' + assert new_exempt_target.user.id == user.id + exempt_target: CollaborationAllowlistExemptTarget = client.collaboration_allowlist_exempt_targets.get_collaboration_whitelist_exempt_target_by_id(new_exempt_target.id) + assert exempt_target.id == new_exempt_target.id + assert exempt_target.user.id == user.id + client.collaboration_allowlist_exempt_targets.delete_collaboration_whitelist_exempt_target_by_id(exempt_target.id) + with pytest.raises(Exception): + client.collaboration_allowlist_exempt_targets.get_collaboration_whitelist_exempt_target_by_id(exempt_target.id) + client.users.delete_user_by_id(user.id) \ No newline at end of file diff --git a/test/test_gen/collections.py b/test/test_gen/collections.py new file mode 100644 index 000000000..2b6a68530 --- /dev/null +++ b/test/test_gen/collections.py @@ -0,0 +1,36 @@ +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.collections import Collections + +from box_sdk_gen.schemas.collection import Collection + +from box_sdk_gen.schemas.items_offset_paginated import ItemsOffsetPaginated + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.managers.folders import CreateFolderParent + +from box_sdk_gen.managers.folders import UpdateFolderByIdCollections + +from box_sdk_gen.internal.utils import get_uuid + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def testCollections(): + collections: Collections = client.collections.get_collections() + favourite_collection: Collection = client.collections.get_collection_by_id(collections.entries[0].id) + assert to_string(favourite_collection.type) == 'collection' + assert to_string(favourite_collection.collection_type) == 'favorites' + collection_items: ItemsOffsetPaginated = client.collections.get_collection_items(favourite_collection.id) + folder: FolderFull = client.folders.create_folder(get_uuid(), CreateFolderParent(id='0')) + client.folders.update_folder_by_id(folder.id, collections=[UpdateFolderByIdCollections(id=favourite_collection.id)]) + collection_items_after_update: ItemsOffsetPaginated = client.collections.get_collection_items(favourite_collection.id) + assert collection_items_after_update.total_count > 0 + client.folders.update_folder_by_id(folder.id, collections=[]) + collection_items_after_remove: ItemsOffsetPaginated = client.collections.get_collection_items(favourite_collection.id) + assert collection_items_after_remove.total_count == collection_items.total_count + client.folders.delete_folder_by_id(folder.id) \ No newline at end of file diff --git a/test/test_gen/comments.py b/test/test_gen/comments.py new file mode 100644 index 000000000..50d7bb384 --- /dev/null +++ b/test/test_gen/comments.py @@ -0,0 +1,56 @@ +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.internal.utils import ByteStream + +from box_sdk_gen.schemas.files import Files + +from box_sdk_gen.managers.uploads import UploadFileAttributes + +from box_sdk_gen.managers.uploads import UploadFileAttributesParentField + +from box_sdk_gen.schemas.comments import Comments + +from box_sdk_gen.schemas.comment_full import CommentFull + +from box_sdk_gen.managers.comments import CreateCommentItem + +from box_sdk_gen.managers.comments import CreateCommentItemTypeField + +from box_sdk_gen.internal.utils import generate_byte_stream + +from box_sdk_gen.internal.utils import get_uuid + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def testComments(): + file_size: int = 256 + file_name: str = get_uuid() + file_byte_stream: ByteStream = generate_byte_stream(file_size) + parent_id: str = '0' + uploaded_files: Files = client.uploads.upload_file(UploadFileAttributes(name=file_name, parent=UploadFileAttributesParentField(id=parent_id)), file_byte_stream) + file_id: str = uploaded_files.entries[0].id + comments: Comments = client.comments.get_file_comments(file_id) + assert comments.total_count == 0 + message: str = 'Hello there!' + new_comment: CommentFull = client.comments.create_comment(message, CreateCommentItem(id=file_id, type=CreateCommentItemTypeField.FILE)) + assert new_comment.message == message + assert new_comment.is_reply_comment == False + assert new_comment.item.id == file_id + new_reply_comment: CommentFull = client.comments.create_comment(message, CreateCommentItem(id=new_comment.id, type=CreateCommentItemTypeField.COMMENT)) + assert new_reply_comment.message == message + assert new_reply_comment.is_reply_comment == True + new_message: str = 'Hi!' + client.comments.update_comment_by_id(new_reply_comment.id, message=new_message) + new_comments: Comments = client.comments.get_file_comments(file_id) + assert new_comments.total_count == 2 + assert new_comments.entries[1].message == new_message + received_comment: CommentFull = client.comments.get_comment_by_id(new_comment.id) + assert received_comment.message == new_comment.message + client.comments.delete_comment_by_id(new_comment.id) + with pytest.raises(Exception): + client.comments.get_comment_by_id(new_comment.id) + client.files.delete_file_by_id(file_id) \ No newline at end of file diff --git a/test/test_gen/device_pinners.py b/test/test_gen/device_pinners.py new file mode 100644 index 000000000..463e8db2e --- /dev/null +++ b/test/test_gen/device_pinners.py @@ -0,0 +1,25 @@ +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.device_pinners import DevicePinners + +from box_sdk_gen.managers.device_pinners import GetEnterpriseDevicePinnersDirection + +from test.commons import get_default_client + +from box_sdk_gen.internal.utils import get_env_var + +client: BoxClient = get_default_client() + +def testDevicePinners(): + enterprise_id: str = get_env_var('ENTERPRISE_ID') + device_pinners: DevicePinners = client.device_pinners.get_enterprise_device_pinners(enterprise_id) + assert len(device_pinners.entries) >= 0 + device_pinners_in_desc_direction: DevicePinners = client.device_pinners.get_enterprise_device_pinners(enterprise_id, direction=GetEnterpriseDevicePinnersDirection.DESC) + assert len(device_pinners_in_desc_direction.entries) >= 0 + device_pinner_id: str = '123456' + with pytest.raises(Exception): + client.device_pinners.get_device_pinner_by_id(device_pinner_id) + with pytest.raises(Exception): + client.device_pinners.delete_device_pinner_by_id(device_pinner_id) \ No newline at end of file diff --git a/test/test_gen/docgen.py b/test/test_gen/docgen.py new file mode 100644 index 000000000..3f99b5f68 --- /dev/null +++ b/test/test_gen/docgen.py @@ -0,0 +1,77 @@ +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.schemas.v2025_r0.doc_gen_template_base_v2025_r0 import DocGenTemplateBaseV2025R0 + +from box_sdk_gen.schemas.v2025_r0.file_reference_v2025_r0 import FileReferenceV2025R0 + +from box_sdk_gen.schemas.v2025_r0.doc_gen_batch_base_v2025_r0 import DocGenBatchBaseV2025R0 + +from box_sdk_gen.managers.docgen import CreateDocgenBatchV2025R0DestinationFolder + +from box_sdk_gen.schemas.v2025_r0.doc_gen_document_generation_data_v2025_r0 import DocGenDocumentGenerationDataV2025R0 + +from box_sdk_gen.schemas.v2025_r0.doc_gen_jobs_v2025_r0 import DocGenJobsV2025R0 + +from box_sdk_gen.schemas.v2025_r0.doc_gen_jobs_full_v2025_r0 import DocGenJobsFullV2025R0 + +from box_sdk_gen.schemas.v2025_r0.doc_gen_job_full_v2025_r0 import DocGenJobFullV2025R0 + +from box_sdk_gen.schemas.v2025_r0.doc_gen_job_v2025_r0 import DocGenJobV2025R0 + +from test.commons import get_default_client + +from test.commons import upload_new_file + +from test.commons import create_new_folder + +client: BoxClient = get_default_client() + +def testDocgenBatchAndJobs(): + uploaded_file: FileFull = upload_new_file() + folder: FolderFull = create_new_folder() + created_docgen_template: DocGenTemplateBaseV2025R0 = client.docgen_template.create_docgen_template_v2025_r0(FileReferenceV2025R0(id=uploaded_file.id)) + docgen_batch: DocGenBatchBaseV2025R0 = client.docgen.create_docgen_batch_v2025_r0(FileReferenceV2025R0(id=uploaded_file.id), 'api', CreateDocgenBatchV2025R0DestinationFolder(id=folder.id), 'pdf', [DocGenDocumentGenerationDataV2025R0(generated_file_name='test', user_input={'abc': 'xyz'})]) + assert not docgen_batch.id == '' + assert to_string(docgen_batch.type) == 'docgen_batch' + docgen_batch_jobs: DocGenJobsV2025R0 = client.docgen.get_docgen_batch_job_by_id_v2025_r0(docgen_batch.id) + assert len(docgen_batch_jobs.entries) >= 1 + assert not docgen_batch_jobs.entries[0].id == '' + assert to_string(docgen_batch_jobs.entries[0].type) == 'docgen_job' + assert docgen_batch_jobs.entries[0].output_type == 'pdf' + assert not to_string(docgen_batch_jobs.entries[0].status) == '' + assert docgen_batch_jobs.entries[0].template_file.id == uploaded_file.id + assert docgen_batch_jobs.entries[0].batch.id == docgen_batch.id + docgen_jobs: DocGenJobsFullV2025R0 = client.docgen.get_docgen_jobs_v2025_r0(limit=500) + assert len(docgen_jobs.entries) >= 1 + assert not docgen_jobs.entries[0].batch.id == '' + assert not docgen_jobs.entries[0].created_by.id == '' + assert not docgen_jobs.entries[0].enterprise.id == '' + assert not docgen_jobs.entries[0].id == '' + assert not docgen_jobs.entries[0].output_type == '' + assert not docgen_jobs.entries[0].source == '' + assert not to_string(docgen_jobs.entries[0].status) == '' + assert to_string(docgen_jobs.entries[0].template_file.type) == 'file' + assert not docgen_jobs.entries[0].template_file.id == '' + assert to_string(docgen_jobs.entries[0].template_file_version.type) == 'file_version' + assert not docgen_jobs.entries[0].template_file_version.id == '' + assert to_string(docgen_jobs.entries[0].type) == 'docgen_job' + index_of_item: int = 0 + docgen_job_item_from_list: DocGenJobFullV2025R0 = docgen_jobs.entries[index_of_item] + docgen_job: DocGenJobV2025R0 = client.docgen.get_docgen_job_by_id_v2025_r0(docgen_job_item_from_list.id) + assert not docgen_job.batch.id == '' + assert not docgen_job.id == '' + assert not docgen_job.output_type == '' + assert not to_string(docgen_job.status) == '' + assert to_string(docgen_job.template_file.type) == 'file' + assert not docgen_job.template_file.id == '' + assert to_string(docgen_job.template_file_version.type) == 'file_version' + assert not docgen_job.template_file_version.id == '' + assert to_string(docgen_job.type) == 'docgen_job' + client.folders.delete_folder_by_id(folder.id) + client.files.delete_file_by_id(uploaded_file.id) \ No newline at end of file diff --git a/test/test_gen/docgen_template.py b/test/test_gen/docgen_template.py new file mode 100644 index 000000000..e581c0a23 --- /dev/null +++ b/test/test_gen/docgen_template.py @@ -0,0 +1,34 @@ +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.v2025_r0.doc_gen_template_base_v2025_r0 import DocGenTemplateBaseV2025R0 + +from box_sdk_gen.schemas.v2025_r0.file_reference_v2025_r0 import FileReferenceV2025R0 + +from box_sdk_gen.schemas.v2025_r0.doc_gen_templates_v2025_r0 import DocGenTemplatesV2025R0 + +from box_sdk_gen.schemas.v2025_r0.doc_gen_template_v2025_r0 import DocGenTemplateV2025R0 + +from box_sdk_gen.schemas.v2025_r0.doc_gen_tags_v2025_r0 import DocGenTagsV2025R0 + +from box_sdk_gen.schemas.v2025_r0.doc_gen_jobs_v2025_r0 import DocGenJobsV2025R0 + +from test.commons import get_default_client + +from test.commons import upload_new_file + +client: BoxClient = get_default_client() + +def testDocgenTemplateCRUD(): + file: FileFull = upload_new_file() + created_docgen_template: DocGenTemplateBaseV2025R0 = client.docgen_template.create_docgen_template_v2025_r0(FileReferenceV2025R0(id=file.id)) + docgen_templates: DocGenTemplatesV2025R0 = client.docgen_template.get_docgen_templates_v2025_r0() + assert len(docgen_templates.entries) > 0 + fetched_docgen_template: DocGenTemplateV2025R0 = client.docgen_template.get_docgen_template_by_id_v2025_r0(created_docgen_template.file.id) + assert fetched_docgen_template.file.id == created_docgen_template.file.id + docgen_template_tags: DocGenTagsV2025R0 = client.docgen_template.get_docgen_template_tags_v2025_r0(fetched_docgen_template.file.id) + docgen_template_jobs: DocGenJobsV2025R0 = client.docgen_template.get_docgen_template_job_by_id_v2025_r0(fetched_docgen_template.file.id) + assert len(docgen_template_jobs.entries) == 0 + client.docgen_template.delete_docgen_template_by_id_v2025_r0(created_docgen_template.file.id) + client.files.delete_file_by_id(file.id) \ No newline at end of file diff --git a/test/test_gen/downloads.py b/test/test_gen/downloads.py new file mode 100644 index 000000000..91d97d3f5 --- /dev/null +++ b/test/test_gen/downloads.py @@ -0,0 +1,73 @@ +from typing import Optional + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.internal.utils import Buffer + +from box_sdk_gen.internal.utils import ByteStream + +from box_sdk_gen.schemas.files import Files + +from box_sdk_gen.managers.uploads import UploadFileAttributes + +from box_sdk_gen.managers.uploads import UploadFileAttributesParentField + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.internal.utils import OutputStream + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import generate_byte_buffer + +from box_sdk_gen.internal.utils import generate_byte_stream_from_buffer + +from box_sdk_gen.internal.utils import buffer_equals + +from box_sdk_gen.internal.utils import read_byte_stream + +from box_sdk_gen.internal.utils import get_file_output_stream + +from box_sdk_gen.internal.utils import close_file_output_stream + +from box_sdk_gen.internal.utils import read_buffer_from_file + +from test.commons import get_default_client + +from test.commons import upload_new_file + +from box_sdk_gen.networking.fetch_options import FetchOptions + +from box_sdk_gen.networking.fetch_response import FetchResponse + +client: BoxClient = get_default_client() + +def test_download_file(): + new_file_name: str = get_uuid() + file_buffer: Buffer = generate_byte_buffer(1024 * 1024) + file_content_stream: ByteStream = generate_byte_stream_from_buffer(file_buffer) + uploaded_files: Files = client.uploads.upload_file(UploadFileAttributes(name=new_file_name, parent=UploadFileAttributesParentField(id='0')), file_content_stream) + uploaded_file: FileFull = uploaded_files.entries[0] + downloaded_file_content: Optional[ByteStream] = client.downloads.download_file(uploaded_file.id) + assert buffer_equals(read_byte_stream(downloaded_file_content), file_buffer) + client.files.delete_file_by_id(uploaded_file.id) + +def test_get_download_url(): + uploaded_file: FileFull = upload_new_file() + download_url: str = client.downloads.get_download_file_url(uploaded_file.id) + assert not download_url == None + assert 'https://' in download_url + client.files.delete_file_by_id(uploaded_file.id) + +def test_download_file_to_output_stream(): + new_file_name: str = get_uuid() + file_buffer: Buffer = generate_byte_buffer(1024 * 1024) + file_content_stream: ByteStream = generate_byte_stream_from_buffer(file_buffer) + uploaded_files: Files = client.uploads.upload_file(UploadFileAttributes(name=new_file_name, parent=UploadFileAttributesParentField(id='0')), file_content_stream) + uploaded_file: FileFull = uploaded_files.entries[0] + file_output_stream: OutputStream = get_file_output_stream(new_file_name) + client.downloads.download_file_to_output_stream(uploaded_file.id, file_output_stream) + close_file_output_stream(file_output_stream) + downloaded_file_content: Buffer = read_buffer_from_file(new_file_name) + assert buffer_equals(downloaded_file_content, file_buffer) + client.files.delete_file_by_id(uploaded_file.id) \ No newline at end of file diff --git a/test/test_gen/email_aliases.py b/test/test_gen/email_aliases.py new file mode 100644 index 000000000..00a90cd05 --- /dev/null +++ b/test/test_gen/email_aliases.py @@ -0,0 +1,29 @@ +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.user_full import UserFull + +from box_sdk_gen.schemas.email_aliases import EmailAliases + +from box_sdk_gen.schemas.email_alias import EmailAlias + +from box_sdk_gen.internal.utils import get_uuid + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def testEmailAliases(): + new_user_name: str = get_uuid() + new_user_login: str = ''.join([get_uuid(), '@boxdemo.com']) + new_user: UserFull = client.users.create_user(new_user_name, login=new_user_login) + aliases: EmailAliases = client.email_aliases.get_user_email_aliases(new_user.id) + assert aliases.total_count == 0 + new_alias_email: str = ''.join([new_user.id, '@boxdemo.com']) + new_alias: EmailAlias = client.email_aliases.create_user_email_alias(new_user.id, new_alias_email) + updated_aliases: EmailAliases = client.email_aliases.get_user_email_aliases(new_user.id) + assert updated_aliases.total_count == 1 + assert updated_aliases.entries[0].email == new_alias_email + client.email_aliases.delete_user_email_alias_by_id(new_user.id, new_alias.id) + final_aliases: EmailAliases = client.email_aliases.get_user_email_aliases(new_user.id) + assert final_aliases.total_count == 0 + client.users.delete_user_by_id(new_user.id) \ No newline at end of file diff --git a/test/test_gen/events.py b/test/test_gen/events.py new file mode 100644 index 000000000..fbe99a834 --- /dev/null +++ b/test/test_gen/events.py @@ -0,0 +1,78 @@ +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.events import Events + +from box_sdk_gen.schemas.event import Event + +from box_sdk_gen.managers.events import GetEventsStreamType + +from box_sdk_gen.managers.events import GetEventsEventType + +from box_sdk_gen.schemas.realtime_servers import RealtimeServers + +from box_sdk_gen.schemas.realtime_server import RealtimeServer + +from box_sdk_gen.internal.utils import DateTime + +from test.commons import get_default_client + +from box_sdk_gen.schemas.event_source import EventSource + +from box_sdk_gen.schemas.file import File + +from box_sdk_gen.schemas.folder import Folder + +from box_sdk_gen.schemas.user import User + +from box_sdk_gen.internal.utils import date_time_from_string + +client: BoxClient = get_default_client() + +def testEvents(): + events: Events = client.events.get_events() + assert len(events.entries) > 0 + first_event: Event = events.entries[0] + assert to_string(first_event.created_by.type) == 'user' + assert not to_string(first_event.event_type) == '' + +def testEventUpload(): + events: Events = client.events.get_events(stream_type=GetEventsStreamType.ADMIN_LOGS, event_type=[GetEventsEventType.UPLOAD]) + assert len(events.entries) > 0 + first_event: Event = events.entries[0] + assert to_string(first_event.event_type) == 'UPLOAD' + source: EventSource = first_event.source + assert to_string(source.item_type) == 'file' or to_string(source.item_type) == 'folder' + assert not source.item_id == '' + assert not source.item_name == '' + +def testEventDeleteUser(): + events: Events = client.events.get_events(stream_type=GetEventsStreamType.ADMIN_LOGS, event_type=[GetEventsEventType.DELETE_USER]) + assert len(events.entries) > 0 + first_event: Event = events.entries[0] + assert to_string(first_event.event_type) == 'DELETE_USER' + source: User = first_event.source + assert to_string(source.type) == 'user' + assert not source.id == '' + +def testEventSourceFileOrFolder(): + events: Events = client.events.get_events(stream_type=GetEventsStreamType.CHANGES) + assert len(events.entries) > 0 + first_event: Event = events.entries[0] + source: File = first_event.source + assert (to_string(source.type) == 'file' or to_string(source.type) == 'folder') or to_string(source.type) == 'collaboration' + assert not source.id == '' + +def testGetEventsWithLongPolling(): + servers: RealtimeServers = client.events.get_events_with_long_polling() + assert len(servers.entries) > 0 + server: RealtimeServer = servers.entries[0] + assert to_string(server.type) == 'realtime_server' + assert not server.url == '' + +def testGetEventsWithDateFilters(): + created_after_date: DateTime = date_time_from_string('2024-06-09T00:00:00Z') + created_before_date: DateTime = date_time_from_string('2025-06-09T00:00:00Z') + servers: Events = client.events.get_events(stream_type=GetEventsStreamType.ADMIN_LOGS, limit=1, created_after=created_after_date, created_before=created_before_date) + assert len(servers.entries) == 1 \ No newline at end of file diff --git a/test/test_gen/file_classifications.py b/test/test_gen/file_classifications.py new file mode 100644 index 000000000..a8ea88718 --- /dev/null +++ b/test/test_gen/file_classifications.py @@ -0,0 +1,61 @@ +from typing import List + +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.classification_template import ClassificationTemplateFieldsOptionsField + +from box_sdk_gen.managers.classifications import AddClassificationRequestBody + +from box_sdk_gen.managers.classifications import AddClassificationRequestBodyDataField + +from box_sdk_gen.managers.classifications import AddClassificationRequestBodyDataStaticConfigField + +from box_sdk_gen.managers.classifications import AddClassificationRequestBodyDataStaticConfigClassificationField + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.classification import Classification + +from box_sdk_gen.managers.file_classifications import UpdateClassificationOnFileRequestBody + +from box_sdk_gen.internal.utils import get_uuid + +from test.commons import get_default_client + +from test.commons import upload_new_file + +from test.commons import get_or_create_classification_template + +from test.commons import get_or_create_classification + +from box_sdk_gen.schemas.classification_template import ClassificationTemplate + +client: BoxClient = get_default_client() + +def get_or_create_second_classification(classification_template: ClassificationTemplate) -> ClassificationTemplateFieldsOptionsField: + classifications: List[ClassificationTemplateFieldsOptionsField] = classification_template.fields[0].options + current_number_of_classifications: int = len(classifications) + if current_number_of_classifications == 1: + classification_template_with_new_classification: ClassificationTemplate = client.classifications.add_classification([AddClassificationRequestBody(data=AddClassificationRequestBodyDataField(key=get_uuid(), static_config=AddClassificationRequestBodyDataStaticConfigField(classification=AddClassificationRequestBodyDataStaticConfigClassificationField(color_id=4, classification_definition='Other description'))))]) + return classification_template_with_new_classification.fields[0].options[1] + return classifications[1] + +def testFileClassifications(): + classification_template: ClassificationTemplate = get_or_create_classification_template() + classification: ClassificationTemplateFieldsOptionsField = get_or_create_classification(classification_template) + file: FileFull = upload_new_file() + with pytest.raises(Exception): + client.file_classifications.get_classification_on_file(file.id) + created_file_classification: Classification = client.file_classifications.add_classification_to_file(file.id, box_security_classification_key=classification.key) + assert created_file_classification.box_security_classification_key == classification.key + file_classification: Classification = client.file_classifications.get_classification_on_file(file.id) + assert file_classification.box_security_classification_key == classification.key + second_classification: ClassificationTemplateFieldsOptionsField = get_or_create_second_classification(classification_template) + updated_file_classification: Classification = client.file_classifications.update_classification_on_file(file.id, [UpdateClassificationOnFileRequestBody(value=second_classification.key)]) + assert updated_file_classification.box_security_classification_key == second_classification.key + client.file_classifications.delete_classification_from_file(file.id) + with pytest.raises(Exception): + client.file_classifications.get_classification_on_file(file.id) + client.files.delete_file_by_id(file.id) \ No newline at end of file diff --git a/test/test_gen/file_metadata.py b/test/test_gen/file_metadata.py new file mode 100644 index 000000000..5bfd9f195 --- /dev/null +++ b/test/test_gen/file_metadata.py @@ -0,0 +1,98 @@ +from box_sdk_gen.internal.utils import to_string + +from typing import List + +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.metadata_template import MetadataTemplate + +from box_sdk_gen.managers.metadata_templates import CreateMetadataTemplateFields + +from box_sdk_gen.managers.metadata_templates import CreateMetadataTemplateFieldsTypeField + +from box_sdk_gen.managers.metadata_templates import CreateMetadataTemplateFieldsOptionsField + +from box_sdk_gen.schemas.metadata_full import MetadataFull + +from box_sdk_gen.managers.file_metadata import CreateFileMetadataByIdScope + +from box_sdk_gen.managers.file_metadata import UpdateFileMetadataByIdScope + +from box_sdk_gen.managers.file_metadata import UpdateFileMetadataByIdRequestBody + +from box_sdk_gen.managers.file_metadata import UpdateFileMetadataByIdRequestBodyOpField + +from box_sdk_gen.managers.file_metadata import DeleteFileMetadataByIdScope + +from box_sdk_gen.managers.metadata_templates import DeleteMetadataTemplateScope + +from box_sdk_gen.schemas.metadatas import Metadatas + +from box_sdk_gen.managers.file_metadata import GetFileMetadataByIdScope + +from box_sdk_gen.internal.utils import generate_byte_stream + +from box_sdk_gen.internal.utils import get_uuid + +from test.commons import get_default_client + +from test.commons import upload_new_file + +client: BoxClient = get_default_client() + +def testUpdatingFileMetadata(): + file: FileFull = upload_new_file() + template_key: str = ''.join(['key', get_uuid()]) + template: MetadataTemplate = client.metadata_templates.create_metadata_template('enterprise', template_key, template_key=template_key, fields=[CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.STRING, key='name', display_name='name'), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.FLOAT, key='age', display_name='age'), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.DATE, key='birthDate', display_name='birthDate'), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.ENUM, key='countryCode', display_name='countryCode', options=[CreateMetadataTemplateFieldsOptionsField(key='US'), CreateMetadataTemplateFieldsOptionsField(key='CA')]), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.MULTISELECT, key='sports', display_name='sports', options=[CreateMetadataTemplateFieldsOptionsField(key='basketball'), CreateMetadataTemplateFieldsOptionsField(key='football'), CreateMetadataTemplateFieldsOptionsField(key='tennis')])]) + created_metadata: MetadataFull = client.file_metadata.create_file_metadata_by_id(file.id, CreateFileMetadataByIdScope.ENTERPRISE, template_key, {'name': 'John', 'age': 23, 'birthDate': '2001-01-03T02:20:50.520Z', 'countryCode': 'US', 'sports': ['basketball', 'tennis']}) + updated_metadata: MetadataFull = client.file_metadata.update_file_metadata_by_id(file.id, UpdateFileMetadataByIdScope.ENTERPRISE, template_key, [UpdateFileMetadataByIdRequestBody(op=UpdateFileMetadataByIdRequestBodyOpField.REPLACE, path='/name', value='Jack'), UpdateFileMetadataByIdRequestBody(op=UpdateFileMetadataByIdRequestBodyOpField.REPLACE, path='/age', value=24), UpdateFileMetadataByIdRequestBody(op=UpdateFileMetadataByIdRequestBodyOpField.REPLACE, path='/birthDate', value='2000-01-03T02:20:50.520Z'), UpdateFileMetadataByIdRequestBody(op=UpdateFileMetadataByIdRequestBodyOpField.REPLACE, path='/countryCode', value='CA'), UpdateFileMetadataByIdRequestBody(op=UpdateFileMetadataByIdRequestBodyOpField.REPLACE, path='/sports', value=['football'])]) + assert to_string(updated_metadata.template) == template_key + assert to_string(updated_metadata.extra_data.get('name')) == 'Jack' + assert to_string(updated_metadata.extra_data.get('age')) == '24' + assert to_string(updated_metadata.extra_data.get('birthDate')) == '2000-01-03T02:20:50.520Z' + assert to_string(updated_metadata.extra_data.get('countryCode')) == 'CA' + sports: List[str] = updated_metadata.extra_data.get('sports') + assert sports[0] == 'football' + client.file_metadata.delete_file_metadata_by_id(file.id, DeleteFileMetadataByIdScope.ENTERPRISE, template_key) + client.metadata_templates.delete_metadata_template(DeleteMetadataTemplateScope.ENTERPRISE, template_key) + client.files.delete_file_by_id(file.id) + +def testGlobalFileMetadata(): + file: FileFull = upload_new_file() + file_metadata: Metadatas = client.file_metadata.get_file_metadata(file.id) + assert len(file_metadata.entries) == 0 + created_metadata: MetadataFull = client.file_metadata.create_file_metadata_by_id(file.id, CreateFileMetadataByIdScope.GLOBAL, 'properties', {'abc': 'xyz'}) + assert to_string(created_metadata.template) == 'properties' + assert to_string(created_metadata.scope) == 'global' + assert created_metadata.version == 0 + received_metadata: MetadataFull = client.file_metadata.get_file_metadata_by_id(file.id, GetFileMetadataByIdScope.GLOBAL, 'properties') + assert to_string(received_metadata.extra_data.get('abc')) == 'xyz' + new_value: str = 'bar' + client.file_metadata.update_file_metadata_by_id(file.id, UpdateFileMetadataByIdScope.GLOBAL, 'properties', [UpdateFileMetadataByIdRequestBody(op=UpdateFileMetadataByIdRequestBodyOpField.REPLACE, path='/abc', value=new_value)]) + received_updated_metadata: MetadataFull = client.file_metadata.get_file_metadata_by_id(file.id, GetFileMetadataByIdScope.GLOBAL, 'properties') + assert to_string(received_updated_metadata.extra_data.get('abc')) == new_value + client.file_metadata.delete_file_metadata_by_id(file.id, DeleteFileMetadataByIdScope.GLOBAL, 'properties') + with pytest.raises(Exception): + client.file_metadata.get_file_metadata_by_id(file.id, GetFileMetadataByIdScope.GLOBAL, 'properties') + client.files.delete_file_by_id(file.id) + +def testEnterpriseFileMetadata(): + file: FileFull = upload_new_file() + template_key: str = ''.join(['key', get_uuid()]) + client.metadata_templates.create_metadata_template('enterprise', template_key, template_key=template_key, fields=[CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.STRING, key='name', display_name='name'), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.FLOAT, key='age', display_name='age'), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.DATE, key='birthDate', display_name='birthDate'), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.ENUM, key='countryCode', display_name='countryCode', options=[CreateMetadataTemplateFieldsOptionsField(key='US'), CreateMetadataTemplateFieldsOptionsField(key='CA')]), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.MULTISELECT, key='sports', display_name='sports', options=[CreateMetadataTemplateFieldsOptionsField(key='basketball'), CreateMetadataTemplateFieldsOptionsField(key='football'), CreateMetadataTemplateFieldsOptionsField(key='tennis')])]) + created_metadata: MetadataFull = client.file_metadata.create_file_metadata_by_id(file.id, CreateFileMetadataByIdScope.ENTERPRISE, template_key, {'name': 'John', 'age': 23, 'birthDate': '2001-01-03T02:20:50.520Z', 'countryCode': 'US', 'sports': ['basketball', 'tennis']}) + assert to_string(created_metadata.template) == template_key + assert to_string(created_metadata.extra_data.get('name')) == 'John' + assert to_string(created_metadata.extra_data.get('age')) == '23' + assert to_string(created_metadata.extra_data.get('birthDate')) == '2001-01-03T02:20:50.520Z' + assert to_string(created_metadata.extra_data.get('countryCode')) == 'US' + sports: List[str] = created_metadata.extra_data.get('sports') + assert sports[0] == 'basketball' + assert sports[1] == 'tennis' + client.file_metadata.delete_file_metadata_by_id(file.id, DeleteFileMetadataByIdScope.ENTERPRISE, template_key) + client.metadata_templates.delete_metadata_template(DeleteMetadataTemplateScope.ENTERPRISE, template_key) + client.files.delete_file_by_id(file.id) \ No newline at end of file diff --git a/test/test_gen/file_requests.py b/test/test_gen/file_requests.py new file mode 100644 index 000000000..ae293672b --- /dev/null +++ b/test/test_gen/file_requests.py @@ -0,0 +1,34 @@ +from box_sdk_gen.internal.utils import to_string + +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.file_request import FileRequest + +from box_sdk_gen.managers.file_requests import CreateFileRequestCopyFolder + +from box_sdk_gen.managers.file_requests import CreateFileRequestCopyFolderTypeField + +from box_sdk_gen.internal.utils import get_env_var + +from test.commons import get_default_client_with_user_subject + +def testGetCopyUpdateDeleteFileRequest(): + file_request_id: str = get_env_var('BOX_FILE_REQUEST_ID') + user_id: str = get_env_var('USER_ID') + client: BoxClient = get_default_client_with_user_subject(user_id) + file_request: FileRequest = client.file_requests.get_file_request_by_id(file_request_id) + assert file_request.id == file_request_id + assert to_string(file_request.type) == 'file_request' + copied_file_request: FileRequest = client.file_requests.create_file_request_copy(file_request_id, CreateFileRequestCopyFolder(id=file_request.folder.id, type=CreateFileRequestCopyFolderTypeField.FOLDER)) + assert not copied_file_request.id == file_request_id + assert copied_file_request.title == file_request.title + assert copied_file_request.description == file_request.description + updated_file_request: FileRequest = client.file_requests.update_file_request_by_id(copied_file_request.id, title='updated title', description='updated description') + assert updated_file_request.id == copied_file_request.id + assert updated_file_request.title == 'updated title' + assert updated_file_request.description == 'updated description' + client.file_requests.delete_file_request_by_id(updated_file_request.id) + with pytest.raises(Exception): + client.file_requests.get_file_request_by_id(updated_file_request.id) \ No newline at end of file diff --git a/test/test_gen/file_version_legal_holds.py b/test/test_gen/file_version_legal_holds.py new file mode 100644 index 000000000..5737594c6 --- /dev/null +++ b/test/test_gen/file_version_legal_holds.py @@ -0,0 +1,24 @@ +import pytest + +from box_sdk_gen.schemas.file_version_legal_holds import FileVersionLegalHolds + +from box_sdk_gen.internal.utils import generate_byte_stream + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.client import BoxClient + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def testGetFileVersionLegalHolds(): + policy_id: str = '1234567890' + file_version_legal_holds: FileVersionLegalHolds = client.file_version_legal_holds.get_file_version_legal_holds(policy_id) + file_version_legal_holds_count: int = len(file_version_legal_holds.entries) + assert file_version_legal_holds_count >= 0 + +def testGetFileVersionLegalHoldById(): + file_version_legal_hold_id: str = '987654321' + with pytest.raises(Exception): + client.file_version_legal_holds.get_file_version_legal_hold_by_id(file_version_legal_hold_id) \ No newline at end of file diff --git a/test/test_gen/file_version_retentions.py b/test/test_gen/file_version_retentions.py new file mode 100644 index 000000000..1419c0e5f --- /dev/null +++ b/test/test_gen/file_version_retentions.py @@ -0,0 +1,72 @@ +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.schemas.retention_policy import RetentionPolicy + +from box_sdk_gen.managers.retention_policies import CreateRetentionPolicyPolicyType + +from box_sdk_gen.managers.retention_policies import CreateRetentionPolicyDispositionAction + +from box_sdk_gen.managers.retention_policies import CreateRetentionPolicyRetentionType + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.schemas.retention_policy_assignment import RetentionPolicyAssignment + +from box_sdk_gen.managers.retention_policy_assignments import CreateRetentionPolicyAssignmentAssignTo + +from box_sdk_gen.managers.retention_policy_assignments import CreateRetentionPolicyAssignmentAssignToTypeField + +from box_sdk_gen.schemas.files import Files + +from box_sdk_gen.managers.uploads import UploadFileAttributes + +from box_sdk_gen.managers.uploads import UploadFileAttributesParentField + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.managers.uploads import UploadFileVersionAttributes + +from box_sdk_gen.schemas.file_version_retentions import FileVersionRetentions + +from box_sdk_gen.schemas.file_version_retention import FileVersionRetention + +from box_sdk_gen.internal.utils import generate_byte_stream + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.client import BoxClient + +from test.commons import create_new_folder + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def testCreateUpdateGetDeleteRetentionPolicy(): + description: str = get_uuid() + retention_policy: RetentionPolicy = client.retention_policies.create_retention_policy(get_uuid(), CreateRetentionPolicyPolicyType.FINITE, CreateRetentionPolicyDispositionAction.REMOVE_RETENTION, description=description, retention_length='1', retention_type=CreateRetentionPolicyRetentionType.MODIFIABLE, can_owner_extend_retention=False) + assert retention_policy.description == description + assert retention_policy.can_owner_extend_retention == False + assert to_string(retention_policy.retention_type) == 'modifiable' + folder: FolderFull = create_new_folder() + retention_policy_assignment: RetentionPolicyAssignment = client.retention_policy_assignments.create_retention_policy_assignment(retention_policy.id, CreateRetentionPolicyAssignmentAssignTo(id=folder.id, type=CreateRetentionPolicyAssignmentAssignToTypeField.FOLDER)) + assert retention_policy_assignment.retention_policy.id == retention_policy.id + assert retention_policy_assignment.assigned_to.id == folder.id + assert to_string(retention_policy_assignment.assigned_to.type) == to_string(folder.type) + files: Files = client.uploads.upload_file(UploadFileAttributes(name=get_uuid(), parent=UploadFileAttributesParentField(id=folder.id)), generate_byte_stream(10)) + file: FileFull = files.entries[0] + new_files: Files = client.uploads.upload_file_version(file.id, UploadFileVersionAttributes(name=file.name), generate_byte_stream(20)) + new_file: FileFull = new_files.entries[0] + assert new_file.id == file.id + file_version_retentions: FileVersionRetentions = client.file_version_retentions.get_file_version_retentions() + file_version_retentions_count: int = len(file_version_retentions.entries) + assert file_version_retentions_count >= 0 + if file_version_retentions_count == 0: + client.retention_policies.delete_retention_policy_by_id(retention_policy.id) + client.folders.delete_folder_by_id(folder.id, recursive=True) + return None + file_version_retention: FileVersionRetention = file_version_retentions.entries[0] + file_version_retention_by_id: FileVersionRetention = client.file_version_retentions.get_file_version_retention_by_id(file_version_retention.id) + assert file_version_retention_by_id.id == file_version_retention.id + client.retention_policies.delete_retention_policy_by_id(retention_policy.id) + client.folders.delete_folder_by_id(folder.id, recursive=True) \ No newline at end of file diff --git a/test/test_gen/file_versions.py b/test/test_gen/file_versions.py new file mode 100644 index 000000000..c44b5dbbc --- /dev/null +++ b/test/test_gen/file_versions.py @@ -0,0 +1,77 @@ +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.files import Files + +from box_sdk_gen.managers.uploads import UploadFileAttributes + +from box_sdk_gen.managers.uploads import UploadFileAttributesParentField + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.managers.uploads import UploadFileVersionAttributes + +from box_sdk_gen.schemas.file_versions import FileVersions + +from box_sdk_gen.schemas.file_version_full import FileVersionFull + +from box_sdk_gen.managers.file_versions import PromoteFileVersionType + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import generate_byte_stream + +from box_sdk_gen.internal.utils import create_null + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def testCreateListGetPromoteFileVersion(): + old_name: str = get_uuid() + new_name: str = get_uuid() + files: Files = client.uploads.upload_file(UploadFileAttributes(name=old_name, parent=UploadFileAttributesParentField(id='0')), generate_byte_stream(10)) + file: FileFull = files.entries[0] + assert file.name == old_name + assert file.size == 10 + new_files: Files = client.uploads.upload_file_version(file.id, UploadFileVersionAttributes(name=new_name), generate_byte_stream(20)) + new_file: FileFull = new_files.entries[0] + assert new_file.name == new_name + assert new_file.size == 20 + file_versions: FileVersions = client.file_versions.get_file_versions(file.id) + assert file_versions.total_count == 1 + file_version: FileVersionFull = client.file_versions.get_file_version_by_id(file.id, file_versions.entries[0].id) + assert file_version.id == file_versions.entries[0].id + client.file_versions.promote_file_version(file.id, id=file_versions.entries[0].id, type=PromoteFileVersionType.FILE_VERSION) + file_with_promoted_version: FileFull = client.files.get_file_by_id(file.id) + assert file_with_promoted_version.name == old_name + assert file_with_promoted_version.size == 10 + client.file_versions.delete_file_version_by_id(file.id, file_version.id) + client.files.delete_file_by_id(file.id) + +def testRemoveAndRestoreFileVersion(): + old_name: str = get_uuid() + new_name: str = get_uuid() + files: Files = client.uploads.upload_file(UploadFileAttributes(name=old_name, parent=UploadFileAttributesParentField(id='0')), generate_byte_stream(10)) + file: FileFull = files.entries[0] + client.uploads.upload_file_version(file.id, UploadFileVersionAttributes(name=new_name), generate_byte_stream(20)) + file_versions: FileVersions = client.file_versions.get_file_versions(file.id) + assert file_versions.total_count == 1 + file_version: FileVersionFull = client.file_versions.get_file_version_by_id(file.id, file_versions.entries[0].id, fields=['trashed_at', 'trashed_by', 'restored_at', 'restored_by']) + assert file_version.trashed_at == None + assert file_version.trashed_by == None + assert file_version.restored_at == None + assert file_version.restored_by == None + client.file_versions.delete_file_version_by_id(file.id, file_version.id) + deleted_file_version: FileVersionFull = client.file_versions.get_file_version_by_id(file.id, file_versions.entries[0].id, fields=['trashed_at', 'trashed_by', 'restored_at', 'restored_by']) + assert not deleted_file_version.trashed_at == None + assert not deleted_file_version.trashed_by == None + assert deleted_file_version.restored_at == None + assert deleted_file_version.restored_by == None + client.file_versions.update_file_version_by_id(file.id, file_version.id, trashed_at=create_null()) + restored_file_version: FileVersionFull = client.file_versions.get_file_version_by_id(file.id, file_versions.entries[0].id, fields=['trashed_at', 'trashed_by', 'restored_at', 'restored_by']) + assert restored_file_version.trashed_at == None + assert restored_file_version.trashed_by == None + assert not restored_file_version.restored_at == None + assert not restored_file_version.restored_by == None + client.file_versions.delete_file_version_by_id(file.id, file_version.id) + client.files.delete_file_by_id(file.id) \ No newline at end of file diff --git a/test/test_gen/file_watermarks.py b/test/test_gen/file_watermarks.py new file mode 100644 index 000000000..93820cabd --- /dev/null +++ b/test/test_gen/file_watermarks.py @@ -0,0 +1,36 @@ +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.files import Files + +from box_sdk_gen.managers.uploads import UploadFileAttributes + +from box_sdk_gen.managers.uploads import UploadFileAttributesParentField + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.watermark import Watermark + +from box_sdk_gen.managers.file_watermarks import UpdateFileWatermarkWatermark + +from box_sdk_gen.managers.file_watermarks import UpdateFileWatermarkWatermarkImprintField + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import generate_byte_stream + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def testCreateGetDeleteFileWatermark(): + file_name: str = ''.join([get_uuid(), '.txt']) + uploaded_files: Files = client.uploads.upload_file(UploadFileAttributes(name=file_name, parent=UploadFileAttributesParentField(id='0')), generate_byte_stream(10)) + file: FileFull = uploaded_files.entries[0] + created_watermark: Watermark = client.file_watermarks.update_file_watermark(file.id, UpdateFileWatermarkWatermark(imprint=UpdateFileWatermarkWatermarkImprintField.DEFAULT)) + watermark: Watermark = client.file_watermarks.get_file_watermark(file.id) + client.file_watermarks.delete_file_watermark(file.id) + with pytest.raises(Exception): + client.file_watermarks.get_file_watermark(file.id) + client.files.delete_file_by_id(file.id) \ No newline at end of file diff --git a/test/test_gen/files.py b/test/test_gen/files.py new file mode 100644 index 000000000..aac529135 --- /dev/null +++ b/test/test_gen/files.py @@ -0,0 +1,117 @@ +from typing import Optional + +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.files import Files + +from box_sdk_gen.managers.uploads import UploadFileAttributes + +from box_sdk_gen.managers.uploads import UploadFileAttributesParentField + +from box_sdk_gen.managers.files import GetFileThumbnailUrlExtension + +from box_sdk_gen.internal.utils import Buffer + +from box_sdk_gen.managers.files import GetFileThumbnailByIdExtension + +from box_sdk_gen.schemas.trash_file import TrashFile + +from box_sdk_gen.managers.files import UpdateFileByIdLock + +from box_sdk_gen.managers.files import UpdateFileByIdLockAccessField + +from box_sdk_gen.managers.files import CopyFileParent + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import generate_byte_stream + +from box_sdk_gen.internal.utils import read_byte_stream + +from box_sdk_gen.internal.utils import generate_byte_stream_from_buffer + +from box_sdk_gen.internal.utils import generate_byte_buffer + +from box_sdk_gen.internal.utils import buffer_equals + +from box_sdk_gen.internal.utils import ByteStream + +from box_sdk_gen.internal.utils import create_null + +from test.commons import upload_new_file + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def upload_file(file_name: str, file_stream: ByteStream) -> FileFull: + uploaded_files: Files = client.uploads.upload_file(UploadFileAttributes(name=file_name, parent=UploadFileAttributesParentField(id='0')), file_stream) + return uploaded_files.entries[0] + +def testGetFileThumbnailUrl(): + thumbnail_file_name: str = get_uuid() + thumbnail_content_stream: ByteStream = generate_byte_stream(1024 * 1024) + thumbnail_file: FileFull = upload_file(thumbnail_file_name, thumbnail_content_stream) + download_url: str = client.files.get_file_thumbnail_url(thumbnail_file.id, GetFileThumbnailUrlExtension.PNG) + assert not download_url == None + assert 'https://' in download_url + client.files.delete_file_by_id(thumbnail_file.id) + +def testGetFileThumbnail(): + thumbnail_file_name: str = get_uuid() + thumbnail_buffer: Buffer = generate_byte_buffer(1024 * 1024) + thumbnail_content_stream: ByteStream = generate_byte_stream_from_buffer(thumbnail_buffer) + thumbnail_file: FileFull = upload_file(thumbnail_file_name, thumbnail_content_stream) + thumbnail: Optional[ByteStream] = client.files.get_file_thumbnail_by_id(thumbnail_file.id, GetFileThumbnailByIdExtension.PNG) + assert not buffer_equals(read_byte_stream(thumbnail), thumbnail_buffer) == True + client.files.delete_file_by_id(thumbnail_file.id) + +def testGetFileFullExtraFields(): + new_file_name: str = get_uuid() + file_stream: ByteStream = generate_byte_stream(1024 * 1024) + uploaded_file: FileFull = upload_file(new_file_name, file_stream) + file: FileFull = client.files.get_file_by_id(uploaded_file.id, fields=['is_externally_owned', 'has_collaborations']) + assert file.is_externally_owned == False + assert file.has_collaborations == False + client.files.delete_file_by_id(file.id) + +def testCreateGetAndDeleteFile(): + new_file_name: str = get_uuid() + updated_content_stream: ByteStream = generate_byte_stream(1024 * 1024) + uploaded_file: FileFull = upload_file(new_file_name, updated_content_stream) + file: FileFull = client.files.get_file_by_id(uploaded_file.id) + with pytest.raises(Exception): + client.files.get_file_by_id(uploaded_file.id, fields=['name'], extra_headers={'if-none-match': file.etag}) + assert file.name == new_file_name + client.files.delete_file_by_id(uploaded_file.id) + trashed_file: TrashFile = client.trashed_files.get_trashed_file_by_id(uploaded_file.id) + assert file.id == trashed_file.id + +def testUpdateFile(): + file_to_update: FileFull = upload_new_file() + updated_name: str = get_uuid() + updated_file: FileFull = client.files.update_file_by_id(file_to_update.id, name=updated_name, description='Updated description') + assert updated_file.name == updated_name + assert updated_file.description == 'Updated description' + client.files.delete_file_by_id(updated_file.id) + +def testFileLock(): + file: FileFull = upload_new_file() + file_with_lock: FileFull = client.files.update_file_by_id(file.id, lock=UpdateFileByIdLock(access=UpdateFileByIdLockAccessField.LOCK), fields=['lock']) + assert not file_with_lock.lock == None + file_without_lock: FileFull = client.files.update_file_by_id(file.id, lock=create_null(), fields=['lock']) + assert file_without_lock.lock == None + client.files.delete_file_by_id(file.id) + +def testCopyFile(): + file_origin: FileFull = upload_new_file() + copied_file_name: str = get_uuid() + copied_file: FileFull = client.files.copy_file(file_origin.id, CopyFileParent(id='0'), name=copied_file_name) + assert copied_file.parent.id == '0' + assert copied_file.name == copied_file_name + client.files.delete_file_by_id(file_origin.id) + client.files.delete_file_by_id(copied_file.id) \ No newline at end of file diff --git a/test/test_gen/folder_classifications.py b/test/test_gen/folder_classifications.py new file mode 100644 index 000000000..11fe3e313 --- /dev/null +++ b/test/test_gen/folder_classifications.py @@ -0,0 +1,61 @@ +from typing import List + +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.classification_template import ClassificationTemplateFieldsOptionsField + +from box_sdk_gen.managers.classifications import AddClassificationRequestBody + +from box_sdk_gen.managers.classifications import AddClassificationRequestBodyDataField + +from box_sdk_gen.managers.classifications import AddClassificationRequestBodyDataStaticConfigField + +from box_sdk_gen.managers.classifications import AddClassificationRequestBodyDataStaticConfigClassificationField + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.schemas.classification import Classification + +from box_sdk_gen.managers.folder_classifications import UpdateClassificationOnFolderRequestBody + +from box_sdk_gen.internal.utils import get_uuid + +from test.commons import get_default_client + +from test.commons import create_new_folder + +from test.commons import get_or_create_classification_template + +from test.commons import get_or_create_classification + +from box_sdk_gen.schemas.classification_template import ClassificationTemplate + +client: BoxClient = get_default_client() + +def get_or_create_second_classification(classification_template: ClassificationTemplate) -> ClassificationTemplateFieldsOptionsField: + classifications: List[ClassificationTemplateFieldsOptionsField] = classification_template.fields[0].options + current_number_of_classifications: int = len(classifications) + if current_number_of_classifications == 1: + classification_template_with_new_classification: ClassificationTemplate = client.classifications.add_classification([AddClassificationRequestBody(data=AddClassificationRequestBodyDataField(key=get_uuid(), static_config=AddClassificationRequestBodyDataStaticConfigField(classification=AddClassificationRequestBodyDataStaticConfigClassificationField(color_id=4, classification_definition='Other description'))))]) + return classification_template_with_new_classification.fields[0].options[1] + return classifications[1] + +def testFolderClassifications(): + classification_template: ClassificationTemplate = get_or_create_classification_template() + classification: ClassificationTemplateFieldsOptionsField = get_or_create_classification(classification_template) + folder: FolderFull = create_new_folder() + with pytest.raises(Exception): + client.folder_classifications.get_classification_on_folder(folder.id) + created_folder_classification: Classification = client.folder_classifications.add_classification_to_folder(folder.id, box_security_classification_key=classification.key) + assert created_folder_classification.box_security_classification_key == classification.key + folder_classification: Classification = client.folder_classifications.get_classification_on_folder(folder.id) + assert folder_classification.box_security_classification_key == classification.key + second_classification: ClassificationTemplateFieldsOptionsField = get_or_create_second_classification(classification_template) + updated_folder_classification: Classification = client.folder_classifications.update_classification_on_folder(folder.id, [UpdateClassificationOnFolderRequestBody(value=second_classification.key)]) + assert updated_folder_classification.box_security_classification_key == second_classification.key + client.folder_classifications.delete_classification_from_folder(folder.id) + with pytest.raises(Exception): + client.folder_classifications.get_classification_on_folder(folder.id) + client.folders.delete_folder_by_id(folder.id) \ No newline at end of file diff --git a/test/test_gen/folder_locks.py b/test/test_gen/folder_locks.py new file mode 100644 index 000000000..2c2825150 --- /dev/null +++ b/test/test_gen/folder_locks.py @@ -0,0 +1,36 @@ +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.schemas.folder_locks import FolderLocks + +from box_sdk_gen.schemas.folder_lock import FolderLock + +from box_sdk_gen.managers.folder_locks import CreateFolderLockLockedOperations + +from box_sdk_gen.managers.folder_locks import CreateFolderLockFolder + +from box_sdk_gen.internal.utils import get_uuid + +from test.commons import get_default_client + +from test.commons import create_new_folder + +client: BoxClient = get_default_client() + +def testFolderLocks(): + folder: FolderFull = create_new_folder() + folder_locks: FolderLocks = client.folder_locks.get_folder_locks(folder.id) + assert len(folder_locks.entries) == 0 + folder_lock: FolderLock = client.folder_locks.create_folder_lock(CreateFolderLockFolder(id=folder.id, type='folder'), locked_operations=CreateFolderLockLockedOperations(move=True, delete=True)) + assert folder_lock.folder.id == folder.id + assert folder_lock.locked_operations.move == True + assert folder_lock.locked_operations.delete == True + client.folder_locks.delete_folder_lock_by_id(folder_lock.id) + with pytest.raises(Exception): + client.folder_locks.delete_folder_lock_by_id(folder_lock.id) + new_folder_locks: FolderLocks = client.folder_locks.get_folder_locks(folder.id) + assert len(new_folder_locks.entries) == 0 + client.folders.delete_folder_by_id(folder.id) \ No newline at end of file diff --git a/test/test_gen/folder_metadata.py b/test/test_gen/folder_metadata.py new file mode 100644 index 000000000..56275df90 --- /dev/null +++ b/test/test_gen/folder_metadata.py @@ -0,0 +1,96 @@ +from box_sdk_gen.internal.utils import to_string + +from typing import List + +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.schemas.metadata_template import MetadataTemplate + +from box_sdk_gen.managers.metadata_templates import CreateMetadataTemplateFields + +from box_sdk_gen.managers.metadata_templates import CreateMetadataTemplateFieldsTypeField + +from box_sdk_gen.managers.metadata_templates import CreateMetadataTemplateFieldsOptionsField + +from box_sdk_gen.schemas.metadata_full import MetadataFull + +from box_sdk_gen.managers.folder_metadata import CreateFolderMetadataByIdScope + +from box_sdk_gen.managers.folder_metadata import UpdateFolderMetadataByIdScope + +from box_sdk_gen.managers.folder_metadata import UpdateFolderMetadataByIdRequestBody + +from box_sdk_gen.managers.folder_metadata import UpdateFolderMetadataByIdRequestBodyOpField + +from box_sdk_gen.managers.folder_metadata import DeleteFolderMetadataByIdScope + +from box_sdk_gen.managers.metadata_templates import DeleteMetadataTemplateScope + +from box_sdk_gen.schemas.metadatas import Metadatas + +from box_sdk_gen.managers.folder_metadata import GetFolderMetadataByIdScope + +from box_sdk_gen.internal.utils import get_uuid + +from test.commons import get_default_client + +from test.commons import create_new_folder + +client: BoxClient = get_default_client() + +def testUpdatingFolderMetadata(): + folder: FolderFull = create_new_folder() + template_key: str = ''.join(['key', get_uuid()]) + template: MetadataTemplate = client.metadata_templates.create_metadata_template('enterprise', template_key, template_key=template_key, fields=[CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.STRING, key='name', display_name='name'), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.FLOAT, key='age', display_name='age'), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.DATE, key='birthDate', display_name='birthDate'), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.ENUM, key='countryCode', display_name='countryCode', options=[CreateMetadataTemplateFieldsOptionsField(key='US'), CreateMetadataTemplateFieldsOptionsField(key='CA')]), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.MULTISELECT, key='sports', display_name='sports', options=[CreateMetadataTemplateFieldsOptionsField(key='basketball'), CreateMetadataTemplateFieldsOptionsField(key='football'), CreateMetadataTemplateFieldsOptionsField(key='tennis')])]) + created_metadata: MetadataFull = client.folder_metadata.create_folder_metadata_by_id(folder.id, CreateFolderMetadataByIdScope.ENTERPRISE, template_key, {'name': 'John', 'age': 23, 'birthDate': '2001-01-03T02:20:50.520Z', 'countryCode': 'US', 'sports': ['basketball', 'tennis']}) + updated_metadata: MetadataFull = client.folder_metadata.update_folder_metadata_by_id(folder.id, UpdateFolderMetadataByIdScope.ENTERPRISE, template_key, [UpdateFolderMetadataByIdRequestBody(op=UpdateFolderMetadataByIdRequestBodyOpField.REPLACE, path='/name', value='Jack'), UpdateFolderMetadataByIdRequestBody(op=UpdateFolderMetadataByIdRequestBodyOpField.REPLACE, path='/age', value=24), UpdateFolderMetadataByIdRequestBody(op=UpdateFolderMetadataByIdRequestBodyOpField.REPLACE, path='/birthDate', value='2000-01-03T02:20:50.520Z'), UpdateFolderMetadataByIdRequestBody(op=UpdateFolderMetadataByIdRequestBodyOpField.REPLACE, path='/countryCode', value='CA'), UpdateFolderMetadataByIdRequestBody(op=UpdateFolderMetadataByIdRequestBodyOpField.REPLACE, path='/sports', value=['football'])]) + assert to_string(updated_metadata.template) == template_key + assert to_string(updated_metadata.extra_data.get('name')) == 'Jack' + assert to_string(updated_metadata.extra_data.get('age')) == '24' + assert to_string(updated_metadata.extra_data.get('birthDate')) == '2000-01-03T02:20:50.520Z' + assert to_string(updated_metadata.extra_data.get('countryCode')) == 'CA' + sports: List[str] = updated_metadata.extra_data.get('sports') + assert sports[0] == 'football' + client.folder_metadata.delete_folder_metadata_by_id(folder.id, DeleteFolderMetadataByIdScope.ENTERPRISE, template_key) + client.metadata_templates.delete_metadata_template(DeleteMetadataTemplateScope.ENTERPRISE, template_key) + client.folders.delete_folder_by_id(folder.id) + +def testGlobalFolderMetadata(): + folder: FolderFull = create_new_folder() + folder_metadata: Metadatas = client.folder_metadata.get_folder_metadata(folder.id) + assert len(folder_metadata.entries) == 0 + created_metadata: MetadataFull = client.folder_metadata.create_folder_metadata_by_id(folder.id, CreateFolderMetadataByIdScope.GLOBAL, 'properties', {'abc': 'xyz'}) + assert to_string(created_metadata.template) == 'properties' + assert to_string(created_metadata.scope) == 'global' + assert created_metadata.version == 0 + received_metadata: MetadataFull = client.folder_metadata.get_folder_metadata_by_id(folder.id, GetFolderMetadataByIdScope.GLOBAL, 'properties') + assert to_string(received_metadata.extra_data.get('abc')) == 'xyz' + new_value: str = 'bar' + client.folder_metadata.update_folder_metadata_by_id(folder.id, UpdateFolderMetadataByIdScope.GLOBAL, 'properties', [UpdateFolderMetadataByIdRequestBody(op=UpdateFolderMetadataByIdRequestBodyOpField.REPLACE, path='/abc', value=new_value)]) + received_updated_metadata: MetadataFull = client.folder_metadata.get_folder_metadata_by_id(folder.id, GetFolderMetadataByIdScope.GLOBAL, 'properties') + assert to_string(received_updated_metadata.extra_data.get('abc')) == new_value + client.folder_metadata.delete_folder_metadata_by_id(folder.id, DeleteFolderMetadataByIdScope.GLOBAL, 'properties') + with pytest.raises(Exception): + client.folder_metadata.get_folder_metadata_by_id(folder.id, GetFolderMetadataByIdScope.GLOBAL, 'properties') + client.folders.delete_folder_by_id(folder.id) + +def testEnterpriseFolderMetadata(): + folder: FolderFull = create_new_folder() + template_key: str = ''.join(['key', get_uuid()]) + template: MetadataTemplate = client.metadata_templates.create_metadata_template('enterprise', template_key, template_key=template_key, fields=[CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.STRING, key='name', display_name='name'), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.FLOAT, key='age', display_name='age'), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.DATE, key='birthDate', display_name='birthDate'), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.ENUM, key='countryCode', display_name='countryCode', options=[CreateMetadataTemplateFieldsOptionsField(key='US'), CreateMetadataTemplateFieldsOptionsField(key='CA')]), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.MULTISELECT, key='sports', display_name='sports', options=[CreateMetadataTemplateFieldsOptionsField(key='basketball'), CreateMetadataTemplateFieldsOptionsField(key='football'), CreateMetadataTemplateFieldsOptionsField(key='tennis')])]) + created_metadata: MetadataFull = client.folder_metadata.create_folder_metadata_by_id(folder.id, CreateFolderMetadataByIdScope.ENTERPRISE, template_key, {'name': 'John', 'age': 23, 'birthDate': '2001-01-03T02:20:50.520Z', 'countryCode': 'US', 'sports': ['basketball', 'tennis']}) + assert to_string(created_metadata.template) == template_key + assert to_string(created_metadata.extra_data.get('name')) == 'John' + assert to_string(created_metadata.extra_data.get('age')) == '23' + assert to_string(created_metadata.extra_data.get('birthDate')) == '2001-01-03T02:20:50.520Z' + assert to_string(created_metadata.extra_data.get('countryCode')) == 'US' + sports: List[str] = created_metadata.extra_data.get('sports') + assert sports[0] == 'basketball' + assert sports[1] == 'tennis' + client.folder_metadata.delete_folder_metadata_by_id(folder.id, DeleteFolderMetadataByIdScope.ENTERPRISE, template_key) + client.metadata_templates.delete_metadata_template(DeleteMetadataTemplateScope.ENTERPRISE, template_key) + client.folders.delete_folder_by_id(folder.id) \ No newline at end of file diff --git a/test/test_gen/folder_watermarks.py b/test/test_gen/folder_watermarks.py new file mode 100644 index 000000000..e2857a854 --- /dev/null +++ b/test/test_gen/folder_watermarks.py @@ -0,0 +1,29 @@ +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.managers.folders import CreateFolderParent + +from box_sdk_gen.schemas.watermark import Watermark + +from box_sdk_gen.managers.folder_watermarks import UpdateFolderWatermarkWatermark + +from box_sdk_gen.managers.folder_watermarks import UpdateFolderWatermarkWatermarkImprintField + +from box_sdk_gen.internal.utils import get_uuid + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def testCreateGetDeleteFolderWatermark(): + folder_name: str = get_uuid() + folder: FolderFull = client.folders.create_folder(folder_name, CreateFolderParent(id='0')) + created_watermark: Watermark = client.folder_watermarks.update_folder_watermark(folder.id, UpdateFolderWatermarkWatermark(imprint=UpdateFolderWatermarkWatermarkImprintField.DEFAULT)) + watermark: Watermark = client.folder_watermarks.get_folder_watermark(folder.id) + client.folder_watermarks.delete_folder_watermark(folder.id) + with pytest.raises(Exception): + client.folder_watermarks.get_folder_watermark(folder.id) + client.folders.delete_folder_by_id(folder.id) \ No newline at end of file diff --git a/test/test_gen/folders.py b/test/test_gen/folders.py new file mode 100644 index 000000000..dde55f159 --- /dev/null +++ b/test/test_gen/folders.py @@ -0,0 +1,67 @@ +from box_sdk_gen.internal.utils import to_string + +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.managers.folders import CreateFolderParent + +from box_sdk_gen.managers.folders import CopyFolderParent + +from box_sdk_gen.managers.folders import UpdateFolderByIdParent + +from box_sdk_gen.schemas.items import Items + +from box_sdk_gen.internal.utils import get_uuid + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def test_get_folder_info(): + root_folder: FolderFull = client.folders.get_folder_by_id('0') + assert root_folder.id == '0' + assert root_folder.name == 'All Files' + assert to_string(root_folder.type) == 'folder' + +def test_get_folder_full_info_with_extra_fields(): + root_folder: FolderFull = client.folders.get_folder_by_id('0', fields=['has_collaborations', 'tags']) + assert root_folder.id == '0' + assert root_folder.has_collaborations == False + tags_length: int = len(root_folder.tags) + assert tags_length == 0 + +def test_create_and_delete_folder(): + new_folder_name: str = get_uuid() + new_folder: FolderFull = client.folders.create_folder(new_folder_name, CreateFolderParent(id='0')) + created_folder: FolderFull = client.folders.get_folder_by_id(new_folder.id) + assert created_folder.name == new_folder_name + client.folders.delete_folder_by_id(new_folder.id) + with pytest.raises(Exception): + client.folders.get_folder_by_id(new_folder.id) + +def test_update_folder(): + folder_to_update_name: str = get_uuid() + folder_to_update: FolderFull = client.folders.create_folder(folder_to_update_name, CreateFolderParent(id='0')) + updated_name: str = get_uuid() + updated_folder: FolderFull = client.folders.update_folder_by_id(folder_to_update.id, name=updated_name, description='Updated description') + assert updated_folder.name == updated_name + assert updated_folder.description == 'Updated description' + client.folders.delete_folder_by_id(updated_folder.id) + +def test_copy_move_folder_and_list_folder_items(): + folder_origin_name: str = get_uuid() + folder_origin: FolderFull = client.folders.create_folder(folder_origin_name, CreateFolderParent(id='0')) + copied_folder_name: str = get_uuid() + copied_folder: FolderFull = client.folders.copy_folder(folder_origin.id, CopyFolderParent(id='0'), name=copied_folder_name) + assert copied_folder.parent.id == '0' + moved_folder_name: str = get_uuid() + moved_folder: FolderFull = client.folders.update_folder_by_id(copied_folder.id, name=moved_folder_name, parent=UpdateFolderByIdParent(id=folder_origin.id)) + assert moved_folder.parent.id == folder_origin.id + folder_items: Items = client.folders.get_folder_items(folder_origin.id) + assert folder_items.entries[0].id == moved_folder.id + assert folder_items.entries[0].name == moved_folder_name + client.folders.delete_folder_by_id(moved_folder.id) + client.folders.delete_folder_by_id(folder_origin.id) \ No newline at end of file diff --git a/test/test_gen/groups.py b/test/test_gen/groups.py new file mode 100644 index 000000000..df914f009 --- /dev/null +++ b/test/test_gen/groups.py @@ -0,0 +1,32 @@ +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.groups import Groups + +from box_sdk_gen.schemas.group_full import GroupFull + +from box_sdk_gen.internal.utils import get_uuid + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def test_get_groups(): + groups: Groups = client.groups.get_groups() + assert groups.total_count >= 0 + +def test_create_get_delete_group(): + group_name: str = get_uuid() + group_description: str = 'Group description' + group: GroupFull = client.groups.create_group(group_name, description=group_description) + assert group.name == group_name + group_by_id: GroupFull = client.groups.get_group_by_id(group.id, fields=['id', 'name', 'description', 'group_type']) + assert group_by_id.id == group.id + assert group_by_id.description == group_description + updated_group_name: str = get_uuid() + updated_group: GroupFull = client.groups.update_group_by_id(group.id, name=updated_group_name) + assert updated_group.name == updated_group_name + client.groups.delete_group_by_id(group.id) + with pytest.raises(Exception): + client.groups.get_group_by_id(group.id) \ No newline at end of file diff --git a/test/test_gen/integration_mappings.py b/test/test_gen/integration_mappings.py new file mode 100644 index 000000000..c298088ff --- /dev/null +++ b/test/test_gen/integration_mappings.py @@ -0,0 +1,92 @@ +from box_sdk_gen.internal.utils import to_string + +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.managers.folders import CreateFolderParent + +from box_sdk_gen.managers.user_collaborations import CreateCollaborationItem + +from box_sdk_gen.managers.user_collaborations import CreateCollaborationItemTypeField + +from box_sdk_gen.managers.user_collaborations import CreateCollaborationAccessibleBy + +from box_sdk_gen.managers.user_collaborations import CreateCollaborationAccessibleByTypeField + +from box_sdk_gen.managers.user_collaborations import CreateCollaborationRole + +from box_sdk_gen.schemas.integration_mappings import IntegrationMappings + +from box_sdk_gen.schemas.integration_mapping_partner_item_slack import IntegrationMappingPartnerItemSlack + +from box_sdk_gen.schemas.integration_mapping_box_item_slack import IntegrationMappingBoxItemSlack + +from box_sdk_gen.schemas.integration_mapping import IntegrationMapping + +from box_sdk_gen.schemas.integration_mapping_partner_item_teams_create_request import IntegrationMappingPartnerItemTeamsCreateRequest + +from box_sdk_gen.schemas.integration_mapping_partner_item_teams_create_request import IntegrationMappingPartnerItemTeamsCreateRequestTypeField + +from box_sdk_gen.schemas.folder_reference import FolderReference + +from box_sdk_gen.internal.utils import generate_byte_stream + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import get_env_var + +from box_sdk_gen.internal.utils import to_string + +from test.commons import get_default_client + +from test.commons import get_default_client_with_user_subject + +client: BoxClient = get_default_client() + +def testSlackIntegrationMappings(): + user_id: str = get_env_var('USER_ID') + slack_automation_user_id: str = get_env_var('SLACK_AUTOMATION_USER_ID') + slack_org_id: str = get_env_var('SLACK_ORG_ID') + slack_partner_item_id: str = get_env_var('SLACK_PARTNER_ITEM_ID') + user_client: BoxClient = get_default_client_with_user_subject(user_id) + folder: FolderFull = user_client.folders.create_folder(get_uuid(), CreateFolderParent(id='0')) + user_client.user_collaborations.create_collaboration(CreateCollaborationItem(type=CreateCollaborationItemTypeField.FOLDER, id=folder.id), CreateCollaborationAccessibleBy(type=CreateCollaborationAccessibleByTypeField.USER, id=slack_automation_user_id), CreateCollaborationRole.CO_OWNER) + slack_integrations: IntegrationMappings = user_client.integration_mappings.get_slack_integration_mapping() + if len(slack_integrations.entries) == 0: + user_client.integration_mappings.create_slack_integration_mapping(IntegrationMappingPartnerItemSlack(id=slack_partner_item_id, slack_org_id=slack_org_id), IntegrationMappingBoxItemSlack(id=folder.id)) + slack_mappings: IntegrationMappings = user_client.integration_mappings.get_slack_integration_mapping() + assert len(slack_mappings.entries) >= 1 + slack_integration_mapping: IntegrationMapping = slack_mappings.entries[0] + assert to_string(slack_integration_mapping.integration_type) == 'slack' + assert to_string(slack_integration_mapping.type) == 'integration_mapping' + assert to_string(slack_integration_mapping.box_item.type) == 'folder' + assert slack_integration_mapping.partner_item.id == slack_partner_item_id + assert slack_integration_mapping.partner_item.slack_workspace_id == slack_org_id + assert to_string(slack_integration_mapping.partner_item.type) == 'channel' + updated_slack_mapping: IntegrationMapping = user_client.integration_mappings.update_slack_integration_mapping_by_id(slack_integration_mapping.id, box_item=IntegrationMappingBoxItemSlack(id=folder.id)) + assert to_string(updated_slack_mapping.box_item.type) == 'folder' + assert updated_slack_mapping.box_item.id == folder.id + if len(slack_mappings.entries) > 2: + user_client.integration_mappings.delete_slack_integration_mapping_by_id(slack_integration_mapping.id) + user_client.folders.delete_folder_by_id(folder.id) + +def testTeamsIntegrationMappings(): + folder: FolderFull = client.folders.create_folder(get_uuid(), CreateFolderParent(id='0')) + tenant_id: str = '1' + team_id: str = '2' + partner_item_id: str = '3' + user_id: str = get_env_var('USER_ID') + user_client: BoxClient = get_default_client_with_user_subject(user_id) + with pytest.raises(Exception): + user_client.integration_mappings.create_teams_integration_mapping(IntegrationMappingPartnerItemTeamsCreateRequest(type=IntegrationMappingPartnerItemTeamsCreateRequestTypeField.CHANNEL, id=partner_item_id, tenant_id=tenant_id, team_id=team_id), FolderReference(id=folder.id)) + with pytest.raises(Exception): + user_client.integration_mappings.get_teams_integration_mapping() + integration_mapping_id: str = '123456' + with pytest.raises(Exception): + user_client.integration_mappings.update_teams_integration_mapping_by_id(integration_mapping_id, box_item=FolderReference(id='1234567')) + with pytest.raises(Exception): + user_client.integration_mappings.delete_teams_integration_mapping_by_id(integration_mapping_id) + client.folders.delete_folder_by_id(folder.id) \ No newline at end of file diff --git a/test/test_gen/invites.py b/test/test_gen/invites.py new file mode 100644 index 000000000..1e9862206 --- /dev/null +++ b/test/test_gen/invites.py @@ -0,0 +1,29 @@ +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.user_full import UserFull + +from box_sdk_gen.schemas.invite import Invite + +from box_sdk_gen.managers.invites import CreateInviteEnterprise + +from box_sdk_gen.managers.invites import CreateInviteActionableBy + +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 testInvites(): + user_id: str = get_env_var('USER_ID') + client: BoxClient = get_default_client_with_user_subject(user_id) + current_user: UserFull = client.users.get_user_me(fields=['enterprise']) + email: str = get_env_var('BOX_EXTERNAL_USER_EMAIL') + invitation: Invite = client.invites.create_invite(CreateInviteEnterprise(id=current_user.enterprise.id), CreateInviteActionableBy(login=email)) + assert to_string(invitation.type) == 'invite' + assert invitation.invited_to.id == current_user.enterprise.id + assert invitation.actionable_by.login == email + get_invitation: Invite = client.invites.get_invite_by_id(invitation.id) + assert get_invitation.id == invitation.id \ No newline at end of file diff --git a/test/test_gen/legal_hold_policies.py b/test/test_gen/legal_hold_policies.py new file mode 100644 index 000000000..0542627cd --- /dev/null +++ b/test/test_gen/legal_hold_policies.py @@ -0,0 +1,45 @@ +from box_sdk_gen.internal.utils import DateTime + +from box_sdk_gen.schemas.legal_hold_policy import LegalHoldPolicy + +from box_sdk_gen.schemas.legal_hold_policies import LegalHoldPolicies + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import date_time_from_string + +from box_sdk_gen.internal.utils import date_time_to_string + +from box_sdk_gen.client import BoxClient + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def testCreateNotOngoingLegalHoldPolicy(): + legal_hold_policy_name: str = get_uuid() + legal_hold_description: str = 'test description' + filter_started_at: DateTime = date_time_from_string('2021-01-01T00:00:00-08:00') + filter_ended_at: DateTime = date_time_from_string('2022-01-01T00:00:00-08:00') + legal_hold_policy: LegalHoldPolicy = client.legal_hold_policies.create_legal_hold_policy(legal_hold_policy_name, description=legal_hold_description, filter_started_at=filter_started_at, filter_ended_at=filter_ended_at, is_ongoing=False) + assert legal_hold_policy.policy_name == legal_hold_policy_name + assert legal_hold_policy.description == legal_hold_description + assert date_time_to_string(legal_hold_policy.filter_started_at) == date_time_to_string(filter_started_at) + assert date_time_to_string(legal_hold_policy.filter_ended_at) == date_time_to_string(filter_ended_at) + client.legal_hold_policies.delete_legal_hold_policy_by_id(legal_hold_policy.id) + +def testCreateUpdateGetDeleteLegalHoldPolicy(): + legal_hold_policy_name: str = get_uuid() + legal_hold_description: str = 'test description' + legal_hold_policy: LegalHoldPolicy = client.legal_hold_policies.create_legal_hold_policy(legal_hold_policy_name, description=legal_hold_description, is_ongoing=True) + assert legal_hold_policy.policy_name == legal_hold_policy_name + assert legal_hold_policy.description == legal_hold_description + legal_hold_policy_id: str = legal_hold_policy.id + legal_hold_policy_by_id: LegalHoldPolicy = client.legal_hold_policies.get_legal_hold_policy_by_id(legal_hold_policy_id) + assert legal_hold_policy_by_id.id == legal_hold_policy_id + legal_hold_policies: LegalHoldPolicies = client.legal_hold_policies.get_legal_hold_policies() + assert len(legal_hold_policies.entries) > 0 + updated_legal_hold_policy_name: str = get_uuid() + updated_legal_hold_policy: LegalHoldPolicy = client.legal_hold_policies.update_legal_hold_policy_by_id(legal_hold_policy_id, policy_name=updated_legal_hold_policy_name) + assert updated_legal_hold_policy.policy_name == updated_legal_hold_policy_name + client.legal_hold_policies.delete_legal_hold_policy_by_id(legal_hold_policy_id) \ No newline at end of file diff --git a/test/test_gen/legal_hold_policy_assignments.py b/test/test_gen/legal_hold_policy_assignments.py new file mode 100644 index 000000000..e7bf5b2e8 --- /dev/null +++ b/test/test_gen/legal_hold_policy_assignments.py @@ -0,0 +1,57 @@ +from box_sdk_gen.internal.utils import to_string + +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.legal_hold_policy import LegalHoldPolicy + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.legal_hold_policy_assignment import LegalHoldPolicyAssignment + +from box_sdk_gen.managers.legal_hold_policy_assignments import CreateLegalHoldPolicyAssignmentAssignTo + +from box_sdk_gen.managers.legal_hold_policy_assignments import CreateLegalHoldPolicyAssignmentAssignToTypeField + +from box_sdk_gen.schemas.legal_hold_policy_assignments import LegalHoldPolicyAssignments + +from box_sdk_gen.schemas.files_on_hold import FilesOnHold + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import generate_byte_stream + +from test.commons import get_default_client + +from test.commons import upload_new_file + +client: BoxClient = get_default_client() + +def testLegalHoldPolicyAssignments(): + legal_hold_policy_name: str = get_uuid() + legal_hold_description: str = 'test description' + legal_hold_policy: LegalHoldPolicy = client.legal_hold_policies.create_legal_hold_policy(legal_hold_policy_name, description=legal_hold_description, is_ongoing=True) + legal_hold_policy_id: str = legal_hold_policy.id + file: FileFull = upload_new_file() + file_id: str = file.id + legal_hold_policy_assignment: LegalHoldPolicyAssignment = client.legal_hold_policy_assignments.create_legal_hold_policy_assignment(legal_hold_policy_id, CreateLegalHoldPolicyAssignmentAssignTo(type=CreateLegalHoldPolicyAssignmentAssignToTypeField.FILE, id=file_id)) + assert to_string(legal_hold_policy_assignment.legal_hold_policy.type) == 'legal_hold_policy' + assert legal_hold_policy_assignment.assigned_to.id == file_id + assert to_string(legal_hold_policy_assignment.assigned_to.type) == 'file' + legal_hold_policy_assignment_id: str = legal_hold_policy_assignment.id + legal_hold_policy_assignment_from_api: LegalHoldPolicyAssignment = client.legal_hold_policy_assignments.get_legal_hold_policy_assignment_by_id(legal_hold_policy_assignment_id) + assert legal_hold_policy_assignment_from_api.id == legal_hold_policy_assignment_id + legal_policy_assignments: LegalHoldPolicyAssignments = client.legal_hold_policy_assignments.get_legal_hold_policy_assignments(legal_hold_policy_id) + assert len(legal_policy_assignments.entries) == 1 + files_on_hold: FilesOnHold = client.legal_hold_policy_assignments.get_legal_hold_policy_assignment_file_on_hold(legal_hold_policy_assignment_id) + assert len(files_on_hold.entries) == 1 + assert files_on_hold.entries[0].id == file_id + client.legal_hold_policy_assignments.delete_legal_hold_policy_assignment_by_id(legal_hold_policy_assignment_id) + with pytest.raises(Exception): + client.legal_hold_policy_assignments.delete_legal_hold_policy_assignment_by_id(legal_hold_policy_assignment_id) + client.files.delete_file_by_id(file_id) + try: + client.legal_hold_policies.delete_legal_hold_policy_by_id(legal_hold_policy_id) + except Exception: + print(''.join(['Could not delete Legal Policy with id: ', legal_hold_policy_id])) \ No newline at end of file diff --git a/test/test_gen/list_collaborations.py b/test/test_gen/list_collaborations.py new file mode 100644 index 000000000..3aa8c7769 --- /dev/null +++ b/test/test_gen/list_collaborations.py @@ -0,0 +1,59 @@ +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.group_full import GroupFull + +from box_sdk_gen.schemas.collaboration import Collaboration + +from box_sdk_gen.managers.user_collaborations import CreateCollaborationItem + +from box_sdk_gen.managers.user_collaborations import CreateCollaborationItemTypeField + +from box_sdk_gen.managers.user_collaborations import CreateCollaborationAccessibleBy + +from box_sdk_gen.managers.user_collaborations import CreateCollaborationAccessibleByTypeField + +from box_sdk_gen.managers.user_collaborations import CreateCollaborationRole + +from box_sdk_gen.schemas.collaborations import Collaborations + +from box_sdk_gen.schemas.collaborations_offset_paginated import CollaborationsOffsetPaginated + +from box_sdk_gen.managers.list_collaborations import GetCollaborationsStatus + +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 + +from test.commons import create_new_folder + +from test.commons import upload_new_file + +def testListCollaborations(): + client: BoxClient = get_default_client() + folder: FolderFull = create_new_folder() + file: FileFull = upload_new_file() + group: GroupFull = client.groups.create_group(get_uuid()) + group_collaboration: Collaboration = client.user_collaborations.create_collaboration(CreateCollaborationItem(type=CreateCollaborationItemTypeField.FOLDER, id=folder.id), CreateCollaborationAccessibleBy(type=CreateCollaborationAccessibleByTypeField.GROUP, id=group.id), CreateCollaborationRole.EDITOR) + file_collaboration: Collaboration = client.user_collaborations.create_collaboration(CreateCollaborationItem(type=CreateCollaborationItemTypeField.FILE, id=file.id), CreateCollaborationAccessibleBy(type=CreateCollaborationAccessibleByTypeField.USER, id=get_env_var('USER_ID')), CreateCollaborationRole.EDITOR) + assert to_string(group_collaboration.role) == 'editor' + assert to_string(group_collaboration.type) == 'collaboration' + file_collaborations: Collaborations = client.list_collaborations.get_file_collaborations(file.id) + assert len(file_collaborations.entries) > 0 + folder_collaborations: Collaborations = client.list_collaborations.get_folder_collaborations(folder.id) + assert len(folder_collaborations.entries) > 0 + pending_collaborations: CollaborationsOffsetPaginated = client.list_collaborations.get_collaborations(GetCollaborationsStatus.PENDING) + assert len(pending_collaborations.entries) >= 0 + group_collaborations: CollaborationsOffsetPaginated = client.list_collaborations.get_group_collaborations(group.id) + assert len(group_collaborations.entries) > 0 + client.user_collaborations.delete_collaboration_by_id(group_collaboration.id) + client.files.delete_file_by_id(file.id) + client.folders.delete_folder_by_id(folder.id) + client.groups.delete_group_by_id(group.id) \ No newline at end of file diff --git a/test/test_gen/memberships.py b/test/test_gen/memberships.py new file mode 100644 index 000000000..fd6db1ef3 --- /dev/null +++ b/test/test_gen/memberships.py @@ -0,0 +1,47 @@ +from box_sdk_gen.internal.utils import to_string + +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.user_full import UserFull + +from box_sdk_gen.schemas.group_memberships import GroupMemberships + +from box_sdk_gen.schemas.group_full import GroupFull + +from box_sdk_gen.schemas.group_membership import GroupMembership + +from box_sdk_gen.managers.memberships import CreateGroupMembershipUser + +from box_sdk_gen.managers.memberships import CreateGroupMembershipGroup + +from box_sdk_gen.managers.memberships import UpdateGroupMembershipByIdRole + +from box_sdk_gen.internal.utils import get_uuid + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def testMemberships(): + user: UserFull = client.users.create_user(get_uuid(), login=''.join([get_uuid(), '@boxdemo.com'])) + user_memberships: GroupMemberships = client.memberships.get_user_memberships(user.id) + assert user_memberships.total_count == 0 + group: GroupFull = client.groups.create_group(get_uuid()) + group_memberships: GroupMemberships = client.memberships.get_group_memberships(group.id) + assert group_memberships.total_count == 0 + group_membership: GroupMembership = client.memberships.create_group_membership(CreateGroupMembershipUser(id=user.id), CreateGroupMembershipGroup(id=group.id)) + assert group_membership.user.id == user.id + assert group_membership.group.id == group.id + assert to_string(group_membership.role) == 'member' + get_group_membership: GroupMembership = client.memberships.get_group_membership_by_id(group_membership.id) + assert get_group_membership.id == group_membership.id + updated_group_membership: GroupMembership = client.memberships.update_group_membership_by_id(group_membership.id, role=UpdateGroupMembershipByIdRole.ADMIN) + assert updated_group_membership.id == group_membership.id + assert to_string(updated_group_membership.role) == 'admin' + client.memberships.delete_group_membership_by_id(group_membership.id) + with pytest.raises(Exception): + client.memberships.get_group_membership_by_id(group_membership.id) + client.groups.delete_group_by_id(group.id) + client.users.delete_user_by_id(user.id) \ No newline at end of file diff --git a/test/test_gen/metadata_cascade_policies.py b/test/test_gen/metadata_cascade_policies.py new file mode 100644 index 000000000..7add68361 --- /dev/null +++ b/test/test_gen/metadata_cascade_policies.py @@ -0,0 +1,65 @@ +from box_sdk_gen.internal.utils import to_string + +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.managers.metadata_templates import CreateMetadataTemplateFields + +from box_sdk_gen.managers.metadata_templates import CreateMetadataTemplateFieldsTypeField + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.schemas.metadata_cascade_policy import MetadataCascadePolicy + +from box_sdk_gen.managers.metadata_cascade_policies import CreateMetadataCascadePolicyScope + +from box_sdk_gen.schemas.metadata_cascade_policies import MetadataCascadePolicies + +from box_sdk_gen.managers.metadata_cascade_policies import ApplyMetadataCascadePolicyConflictResolution + +from box_sdk_gen.managers.folder_metadata import CreateFolderMetadataByIdScope + +from box_sdk_gen.managers.metadata_templates import DeleteMetadataTemplateScope + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import get_env_var + +from box_sdk_gen.internal.utils import to_string + +from test.commons import get_default_client + +from test.commons import create_new_folder + +from test.commons import upload_new_file + +client: BoxClient = get_default_client() + +def testMetadataCascadePolicies(): + template_key: str = ''.join(['key', get_uuid()]) + client.metadata_templates.create_metadata_template('enterprise', template_key, template_key=template_key, fields=[CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.STRING, key='testName', display_name='testName')]) + folder: FolderFull = create_new_folder() + enterprise_id: str = get_env_var('ENTERPRISE_ID') + cascade_policy: MetadataCascadePolicy = client.metadata_cascade_policies.create_metadata_cascade_policy(folder.id, CreateMetadataCascadePolicyScope.ENTERPRISE, template_key) + assert to_string(cascade_policy.type) == 'metadata_cascade_policy' + assert to_string(cascade_policy.owner_enterprise.type) == 'enterprise' + assert to_string(cascade_policy.owner_enterprise.id) == enterprise_id + assert to_string(cascade_policy.parent.type) == 'folder' + assert cascade_policy.parent.id == folder.id + assert to_string(cascade_policy.scope) == ''.join(['enterprise_', enterprise_id]) + assert cascade_policy.template_key == template_key + cascade_policy_id: str = cascade_policy.id + policy_from_the_api: MetadataCascadePolicy = client.metadata_cascade_policies.get_metadata_cascade_policy_by_id(cascade_policy_id) + assert cascade_policy_id == policy_from_the_api.id + policies: MetadataCascadePolicies = client.metadata_cascade_policies.get_metadata_cascade_policies(folder.id) + assert len(policies.entries) == 1 + with pytest.raises(Exception): + client.metadata_cascade_policies.apply_metadata_cascade_policy(cascade_policy_id, ApplyMetadataCascadePolicyConflictResolution.OVERWRITE) + client.folder_metadata.create_folder_metadata_by_id(folder.id, CreateFolderMetadataByIdScope.ENTERPRISE, template_key, {'testName': 'xyz'}) + client.metadata_cascade_policies.apply_metadata_cascade_policy(cascade_policy_id, ApplyMetadataCascadePolicyConflictResolution.OVERWRITE) + client.metadata_cascade_policies.delete_metadata_cascade_policy_by_id(cascade_policy_id) + with pytest.raises(Exception): + client.metadata_cascade_policies.get_metadata_cascade_policy_by_id(cascade_policy_id) + client.metadata_templates.delete_metadata_template(DeleteMetadataTemplateScope.ENTERPRISE, template_key) + client.folders.delete_folder_by_id(folder.id) \ No newline at end of file diff --git a/test/test_gen/metadata_templates.py b/test/test_gen/metadata_templates.py new file mode 100644 index 000000000..30b4badb9 --- /dev/null +++ b/test/test_gen/metadata_templates.py @@ -0,0 +1,91 @@ +from box_sdk_gen.internal.utils import to_string + +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.metadata_template import MetadataTemplate + +from box_sdk_gen.managers.metadata_templates import CreateMetadataTemplateFields + +from box_sdk_gen.managers.metadata_templates import CreateMetadataTemplateFieldsTypeField + +from box_sdk_gen.managers.metadata_templates import CreateMetadataTemplateFieldsOptionsField + +from box_sdk_gen.managers.metadata_templates import UpdateMetadataTemplateScope + +from box_sdk_gen.managers.metadata_templates import UpdateMetadataTemplateRequestBody + +from box_sdk_gen.managers.metadata_templates import UpdateMetadataTemplateRequestBodyOpField + +from box_sdk_gen.managers.metadata_templates import GetMetadataTemplateScope + +from box_sdk_gen.schemas.metadata_templates import MetadataTemplates + +from box_sdk_gen.managers.metadata_templates import DeleteMetadataTemplateScope + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.metadata_full import MetadataFull + +from box_sdk_gen.managers.file_metadata import CreateFileMetadataByIdScope + +from box_sdk_gen.managers.file_metadata import DeleteFileMetadataByIdScope + +from box_sdk_gen.internal.utils import get_uuid + +from test.commons import get_default_client + +from test.commons import upload_new_file + +client: BoxClient = get_default_client() + +def testMetadataTemplates(): + template_key: str = ''.join(['key', get_uuid()]) + template: MetadataTemplate = client.metadata_templates.create_metadata_template('enterprise', template_key, template_key=template_key, fields=[CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.STRING, key='testName', display_name='testName'), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.FLOAT, key='age', display_name='age'), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.DATE, key='birthDate', display_name='birthDate'), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.ENUM, key='countryCode', display_name='countryCode', options=[CreateMetadataTemplateFieldsOptionsField(key='US'), CreateMetadataTemplateFieldsOptionsField(key='CA')]), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.MULTISELECT, key='sports', display_name='sports', options=[CreateMetadataTemplateFieldsOptionsField(key='basketball'), CreateMetadataTemplateFieldsOptionsField(key='football'), CreateMetadataTemplateFieldsOptionsField(key='tennis')])]) + assert template.template_key == template_key + assert template.display_name == template_key + assert len(template.fields) == 5 + assert template.fields[0].key == 'testName' + assert template.fields[0].display_name == 'testName' + assert to_string(template.fields[0].type) == 'string' + assert template.fields[1].key == 'age' + assert template.fields[1].display_name == 'age' + assert to_string(template.fields[1].type) == 'float' + assert template.fields[2].key == 'birthDate' + assert template.fields[2].display_name == 'birthDate' + assert to_string(template.fields[2].type) == 'date' + assert template.fields[3].key == 'countryCode' + assert template.fields[3].display_name == 'countryCode' + assert to_string(template.fields[3].type) == 'enum' + assert template.fields[4].key == 'sports' + assert template.fields[4].display_name == 'sports' + assert to_string(template.fields[4].type) == 'multiSelect' + updated_template: MetadataTemplate = client.metadata_templates.update_metadata_template(UpdateMetadataTemplateScope.ENTERPRISE, template_key, [UpdateMetadataTemplateRequestBody(op=UpdateMetadataTemplateRequestBodyOpField.ADDFIELD, field_key='newfieldname', data={'type': 'string', 'displayName': 'newFieldName'})]) + assert len(updated_template.fields) == 6 + assert updated_template.fields[5].key == 'newfieldname' + assert updated_template.fields[5].display_name == 'newFieldName' + get_metadata_template: MetadataTemplate = client.metadata_templates.get_metadata_template_by_id(template.id) + assert get_metadata_template.id == template.id + get_metadata_template_schema: MetadataTemplate = client.metadata_templates.get_metadata_template(GetMetadataTemplateScope.ENTERPRISE, template.template_key) + assert get_metadata_template_schema.id == template.id + enterprise_metadata_templates: MetadataTemplates = client.metadata_templates.get_enterprise_metadata_templates() + assert len(enterprise_metadata_templates.entries) > 0 + global_metadata_templates: MetadataTemplates = client.metadata_templates.get_global_metadata_templates() + assert len(global_metadata_templates.entries) > 0 + client.metadata_templates.delete_metadata_template(DeleteMetadataTemplateScope.ENTERPRISE, template.template_key) + with pytest.raises(Exception): + client.metadata_templates.delete_metadata_template(DeleteMetadataTemplateScope.ENTERPRISE, template.template_key) + +def testGetMetadataTemplateByInstance(): + file: FileFull = upload_new_file() + template_key: str = ''.join(['key', get_uuid()]) + template: MetadataTemplate = client.metadata_templates.create_metadata_template('enterprise', template_key, template_key=template_key, fields=[CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.STRING, key='testName', display_name='testName')]) + created_metadata_instance: MetadataFull = client.file_metadata.create_file_metadata_by_id(file.id, CreateFileMetadataByIdScope.ENTERPRISE, template_key, {'testName': 'xyz'}) + metadata_templates: MetadataTemplates = client.metadata_templates.get_metadata_templates_by_instance_id(created_metadata_instance.id) + assert len(metadata_templates.entries) == 1 + assert metadata_templates.entries[0].display_name == template_key + assert metadata_templates.entries[0].template_key == template_key + client.file_metadata.delete_file_metadata_by_id(file.id, DeleteFileMetadataByIdScope.ENTERPRISE, template_key) + client.metadata_templates.delete_metadata_template(DeleteMetadataTemplateScope.ENTERPRISE, template.template_key) + client.files.delete_file_by_id(file.id) \ No newline at end of file diff --git a/test/test_gen/recent_items.py b/test/test_gen/recent_items.py new file mode 100644 index 000000000..62d7bd079 --- /dev/null +++ b/test/test_gen/recent_items.py @@ -0,0 +1,16 @@ +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.recent_items import RecentItems + +from box_sdk_gen.internal.utils import decode_base_64 + +from box_sdk_gen.internal.utils import get_env_var + +from box_sdk_gen.internal.utils import get_uuid + +from test.commons import get_default_client_with_user_subject + +def testRecentItems(): + client: BoxClient = get_default_client_with_user_subject(get_env_var('USER_ID')) + recent_items: RecentItems = client.recent_items.get_recent_items() + assert len(recent_items.entries) >= 0 \ No newline at end of file diff --git a/test/test_gen/retention_policies.py b/test/test_gen/retention_policies.py new file mode 100644 index 000000000..de508d30c --- /dev/null +++ b/test/test_gen/retention_policies.py @@ -0,0 +1,32 @@ +from box_sdk_gen.schemas.retention_policy import RetentionPolicy + +from box_sdk_gen.managers.retention_policies import CreateRetentionPolicyPolicyType + +from box_sdk_gen.managers.retention_policies import CreateRetentionPolicyDispositionAction + +from box_sdk_gen.managers.retention_policies import CreateRetentionPolicyRetentionType + +from box_sdk_gen.schemas.retention_policies import RetentionPolicies + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.client import BoxClient + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def testCreateUpdateGetDeleteRetentionPolicy(): + retention_policy_name: str = get_uuid() + retention_description: str = 'test description' + retention_policy: RetentionPolicy = client.retention_policies.create_retention_policy(retention_policy_name, CreateRetentionPolicyPolicyType.FINITE, CreateRetentionPolicyDispositionAction.REMOVE_RETENTION, description=retention_description, retention_length='1', retention_type=CreateRetentionPolicyRetentionType.MODIFIABLE, can_owner_extend_retention=True, are_owners_notified=True) + assert retention_policy.policy_name == retention_policy_name + assert retention_policy.description == retention_description + retention_policy_by_id: RetentionPolicy = client.retention_policies.get_retention_policy_by_id(retention_policy.id) + assert retention_policy_by_id.id == retention_policy.id + retention_policies: RetentionPolicies = client.retention_policies.get_retention_policies() + assert len(retention_policies.entries) > 0 + updated_retention_policy_name: str = get_uuid() + updated_retention_policy: RetentionPolicy = client.retention_policies.update_retention_policy_by_id(retention_policy.id, policy_name=updated_retention_policy_name) + assert updated_retention_policy.policy_name == updated_retention_policy_name + client.retention_policies.delete_retention_policy_by_id(retention_policy.id) \ No newline at end of file diff --git a/test/test_gen/retention_policy_assignments.py b/test/test_gen/retention_policy_assignments.py new file mode 100644 index 000000000..ac22d5ba6 --- /dev/null +++ b/test/test_gen/retention_policy_assignments.py @@ -0,0 +1,69 @@ +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.retention_policy import RetentionPolicy + +from box_sdk_gen.managers.retention_policies import CreateRetentionPolicyPolicyType + +from box_sdk_gen.managers.retention_policies import CreateRetentionPolicyDispositionAction + +from box_sdk_gen.managers.retention_policies import CreateRetentionPolicyRetentionType + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.managers.folders import CreateFolderParent + +from box_sdk_gen.schemas.files import Files + +from box_sdk_gen.managers.uploads import UploadFileAttributes + +from box_sdk_gen.managers.uploads import UploadFileAttributesParentField + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.managers.uploads import UploadFileVersionAttributes + +from box_sdk_gen.schemas.retention_policy_assignment import RetentionPolicyAssignment + +from box_sdk_gen.managers.retention_policy_assignments import CreateRetentionPolicyAssignmentAssignTo + +from box_sdk_gen.managers.retention_policy_assignments import CreateRetentionPolicyAssignmentAssignToTypeField + +from box_sdk_gen.schemas.retention_policy_assignments import RetentionPolicyAssignments + +from box_sdk_gen.schemas.files_under_retention import FilesUnderRetention + +from box_sdk_gen.internal.utils import decode_base_64 + +from box_sdk_gen.internal.utils import get_env_var + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import generate_byte_stream + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def testCreateUpdateGetDeleteRetentionPolicyAssignment(): + retention_policy_name: str = get_uuid() + retention_description: str = 'test description' + retention_policy: RetentionPolicy = client.retention_policies.create_retention_policy(retention_policy_name, CreateRetentionPolicyPolicyType.FINITE, CreateRetentionPolicyDispositionAction.REMOVE_RETENTION, description=retention_description, retention_length='1', retention_type=CreateRetentionPolicyRetentionType.MODIFIABLE, can_owner_extend_retention=True, are_owners_notified=True) + folder: FolderFull = client.folders.create_folder(get_uuid(), CreateFolderParent(id='0')) + files: Files = client.uploads.upload_file(UploadFileAttributes(name=get_uuid(), parent=UploadFileAttributesParentField(id=folder.id)), generate_byte_stream(10)) + file: FileFull = files.entries[0] + new_versions: Files = client.uploads.upload_file_version(file.id, UploadFileVersionAttributes(name=get_uuid()), generate_byte_stream(20)) + new_version: FileFull = new_versions.entries[0] + retention_policy_assignment: RetentionPolicyAssignment = client.retention_policy_assignments.create_retention_policy_assignment(retention_policy.id, CreateRetentionPolicyAssignmentAssignTo(type=CreateRetentionPolicyAssignmentAssignToTypeField.FOLDER, id=folder.id)) + assert retention_policy_assignment.retention_policy.id == retention_policy.id + assert retention_policy_assignment.assigned_to.id == folder.id + retention_policy_assignment_by_id: RetentionPolicyAssignment = client.retention_policy_assignments.get_retention_policy_assignment_by_id(retention_policy_assignment.id) + assert retention_policy_assignment_by_id.id == retention_policy_assignment.id + retention_policy_assignments: RetentionPolicyAssignments = client.retention_policy_assignments.get_retention_policy_assignments(retention_policy.id) + assert len(retention_policy_assignments.entries) == 1 + files_under_retention: FilesUnderRetention = client.retention_policy_assignments.get_files_under_retention_policy_assignment(retention_policy_assignment.id) + assert len(files_under_retention.entries) == 1 + client.retention_policy_assignments.delete_retention_policy_assignment_by_id(retention_policy_assignment.id) + retention_policy_assignments_after_delete: RetentionPolicyAssignments = client.retention_policy_assignments.get_retention_policy_assignments(retention_policy.id) + assert len(retention_policy_assignments_after_delete.entries) == 0 + client.retention_policies.delete_retention_policy_by_id(retention_policy.id) + client.files.delete_file_by_id(file.id) \ No newline at end of file diff --git a/test/test_gen/search.py b/test/test_gen/search.py new file mode 100644 index 000000000..096ad9e8f --- /dev/null +++ b/test/test_gen/search.py @@ -0,0 +1,91 @@ +from typing import Union + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.metadata_template import MetadataTemplate + +from box_sdk_gen.managers.metadata_templates import CreateMetadataTemplateFields + +from box_sdk_gen.managers.metadata_templates import CreateMetadataTemplateFieldsTypeField + +from box_sdk_gen.managers.metadata_templates import CreateMetadataTemplateFieldsOptionsField + +from box_sdk_gen.schemas.files import Files + +from box_sdk_gen.managers.uploads import UploadFileAttributes + +from box_sdk_gen.managers.uploads import UploadFileAttributesParentField + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.metadata_full import MetadataFull + +from box_sdk_gen.managers.file_metadata import CreateFileMetadataByIdScope + +from box_sdk_gen.schemas.metadata_query_results import MetadataQueryResults + +from box_sdk_gen.managers.metadata_templates import DeleteMetadataTemplateScope + +from box_sdk_gen.schemas.search_results import SearchResults + +from box_sdk_gen.schemas.search_results_with_shared_links import SearchResultsWithSharedLinks + +from box_sdk_gen.schemas.metadata_filter import MetadataFilter + +from box_sdk_gen.schemas.metadata_filter import MetadataFilterScopeField + +from box_sdk_gen.managers.search import SearchForContentTrashContent + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import generate_byte_stream + +from box_sdk_gen.internal.utils import date_time_from_string + +from box_sdk_gen.internal.utils import delay_in_seconds + +from test.commons import get_default_client + +from box_sdk_gen.schemas.metadata_field_filter_date_range import MetadataFieldFilterDateRange + +from box_sdk_gen.schemas.metadata_field_filter_float_range import MetadataFieldFilterFloatRange + +client: BoxClient = get_default_client() + +def testCreateMetaDataQueryExecuteRead(): + template_key: str = ''.join(['key', get_uuid()]) + template: MetadataTemplate = client.metadata_templates.create_metadata_template('enterprise', template_key, template_key=template_key, fields=[CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.STRING, key='name', display_name='name'), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.FLOAT, key='age', display_name='age'), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.DATE, key='birthDate', display_name='birthDate'), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.ENUM, key='countryCode', display_name='countryCode', options=[CreateMetadataTemplateFieldsOptionsField(key='US'), CreateMetadataTemplateFieldsOptionsField(key='CA')]), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.MULTISELECT, key='sports', display_name='sports', options=[CreateMetadataTemplateFieldsOptionsField(key='basketball'), CreateMetadataTemplateFieldsOptionsField(key='football'), CreateMetadataTemplateFieldsOptionsField(key='tennis')])]) + assert template.template_key == template_key + files: Files = client.uploads.upload_file(UploadFileAttributes(name=get_uuid(), parent=UploadFileAttributesParentField(id='0')), generate_byte_stream(10)) + file: FileFull = files.entries[0] + metadata: MetadataFull = client.file_metadata.create_file_metadata_by_id(file.id, CreateFileMetadataByIdScope.ENTERPRISE, template_key, {'name': 'John', 'age': 23, 'birthDate': '2001-01-03T02:20:50.520Z', 'countryCode': 'US', 'sports': ['basketball', 'tennis']}) + assert metadata.template == template_key + assert metadata.scope == template.scope + delay_in_seconds(5) + search_from: str = ''.join([template.scope, '.', template.template_key]) + query: MetadataQueryResults = client.search.search_by_metadata_query(search_from, '0', query='name = :name AND age < :age AND birthDate >= :birthDate AND countryCode = :countryCode AND sports = :sports', query_params={'name': 'John', 'age': 50, 'birthDate': '2001-01-01T02:20:10.120Z', 'countryCode': 'US', 'sports': ['basketball', 'tennis']}) + assert len(query.entries) >= 0 + client.metadata_templates.delete_metadata_template(DeleteMetadataTemplateScope.ENTERPRISE, template.template_key) + client.files.delete_file_by_id(file.id) + +def testMetadataFilters(): + template_key: str = ''.join(['key', get_uuid()]) + template: MetadataTemplate = client.metadata_templates.create_metadata_template('enterprise', template_key, template_key=template_key, fields=[CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.FLOAT, key='floatField', display_name='floatField'), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.STRING, key='stringField', display_name='stringField'), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.DATE, key='dateField', display_name='dateField'), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.ENUM, key='enumField', display_name='enumField', options=[CreateMetadataTemplateFieldsOptionsField(key='enumValue1'), CreateMetadataTemplateFieldsOptionsField(key='enumValue2')]), CreateMetadataTemplateFields(type=CreateMetadataTemplateFieldsTypeField.MULTISELECT, key='multiSelectField', display_name='multiSelectField', options=[CreateMetadataTemplateFieldsOptionsField(key='multiSelectValue1'), CreateMetadataTemplateFieldsOptionsField(key='multiSelectValue2')])]) + files: Files = client.uploads.upload_file(UploadFileAttributes(name=get_uuid(), parent=UploadFileAttributesParentField(id='0')), generate_byte_stream(10)) + file: FileFull = files.entries[0] + metadata: MetadataFull = client.file_metadata.create_file_metadata_by_id(file.id, CreateFileMetadataByIdScope.ENTERPRISE, template_key, {'floatField': 10, 'stringField': 'stringValue', 'dateField': '2035-01-02T00:00:00Z', 'enumField': 'enumValue2', 'multiSelectField': ['multiSelectValue1', 'multiSelectValue2']}) + query: Union[SearchResults, SearchResultsWithSharedLinks] = client.search.search_for_content(ancestor_folder_ids=['0'], mdfilters=[MetadataFilter(filters={'stringField': 'stringValue', 'dateField': MetadataFieldFilterDateRange(lt=date_time_from_string('2035-01-01T00:00:00Z'), gt=date_time_from_string('2035-01-03T00:00:00Z')), 'floatField': MetadataFieldFilterFloatRange(lt=9.5, gt=10.5), 'enumField': 'enumValue2', 'multiSelectField': ['multiSelectValue1', 'multiSelectValue2']}, scope=MetadataFilterScopeField.ENTERPRISE, template_key=template_key)]) + assert len(query.entries) >= 0 + client.metadata_templates.delete_metadata_template(DeleteMetadataTemplateScope.ENTERPRISE, template.template_key) + client.files.delete_file_by_id(file.id) + +def testGetSearch(): + keyword: str = 'test' + search: Union[SearchResults, SearchResultsWithSharedLinks] = client.search.search_for_content(query=keyword, ancestor_folder_ids=['0'], trash_content=SearchForContentTrashContent.NON_TRASHED_ONLY) + assert len(search.entries) >= 0 + assert to_string(search.type) == 'search_results_items' + search_with_shared_link: Union[SearchResults, SearchResultsWithSharedLinks] = client.search.search_for_content(query=keyword, ancestor_folder_ids=['0'], trash_content=SearchForContentTrashContent.NON_TRASHED_ONLY, include_recent_shared_links=True) + assert len(search_with_shared_link.entries) >= 0 + assert to_string(search_with_shared_link.type) == 'search_results_with_shared_links' \ No newline at end of file diff --git a/test/test_gen/session_termination.py b/test/test_gen/session_termination.py new file mode 100644 index 000000000..3489412e8 --- /dev/null +++ b/test/test_gen/session_termination.py @@ -0,0 +1,30 @@ +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.user_full import UserFull + +from box_sdk_gen.schemas.session_termination_message import SessionTerminationMessage + +from box_sdk_gen.schemas.group_full import GroupFull + +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 + +from test.commons import get_default_client_with_user_subject + +client: BoxClient = get_default_client() + +def testSessionTerminationUser(): + admin_client: BoxClient = get_default_client_with_user_subject(get_env_var('USER_ID')) + user: UserFull = admin_client.users.get_user_me() + result: SessionTerminationMessage = client.session_termination.terminate_users_sessions([get_env_var('USER_ID')], [user.login]) + assert result.message == 'Request is successful, please check the admin events for the status of the job' + +def testSessionTerminationGroup(): + group_name: str = get_uuid() + group: GroupFull = client.groups.create_group(group_name) + result: SessionTerminationMessage = client.session_termination.terminate_groups_sessions([group.id]) + assert result.message == 'Request is successful, please check the admin events for the status of the job' + client.groups.delete_group_by_id(group.id) \ No newline at end of file diff --git a/test/test_gen/shared_links_app_items.py b/test/test_gen/shared_links_app_items.py new file mode 100644 index 000000000..8a23af475 --- /dev/null +++ b/test/test_gen/shared_links_app_items.py @@ -0,0 +1,17 @@ +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.app_item import AppItem + +from box_sdk_gen.internal.utils import get_env_var + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def testSharedLinksAppItems(): + app_item_shared_link: str = get_env_var('APP_ITEM_SHARED_LINK') + app_item: AppItem = client.shared_links_app_items.find_app_item_for_shared_link(''.join(['shared_link=', app_item_shared_link])) + assert to_string(app_item.type) == 'app_item' + assert app_item.application_type == 'hubs' \ No newline at end of file diff --git a/test/test_gen/shared_links_files.py b/test/test_gen/shared_links_files.py new file mode 100644 index 000000000..ef0cf056d --- /dev/null +++ b/test/test_gen/shared_links_files.py @@ -0,0 +1,54 @@ +from box_sdk_gen.internal.utils import to_string + +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.files import Files + +from box_sdk_gen.managers.uploads import UploadFileAttributes + +from box_sdk_gen.managers.uploads import UploadFileAttributesParentField + +from box_sdk_gen.managers.shared_links_files import AddShareLinkToFileSharedLink + +from box_sdk_gen.managers.shared_links_files import AddShareLinkToFileSharedLinkAccessField + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.managers.shared_links_files import UpdateSharedLinkOnFileSharedLink + +from box_sdk_gen.managers.shared_links_files import UpdateSharedLinkOnFileSharedLinkAccessField + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import generate_byte_stream + +from box_sdk_gen.internal.utils import get_env_var + +from test.commons import get_default_client + +from test.commons import get_default_client_with_user_subject + +from box_sdk_gen.internal.utils import create_null + +client: BoxClient = get_default_client() + +def testSharedLinksFiles(): + uploaded_files: Files = client.uploads.upload_file(UploadFileAttributes(name=get_uuid(), parent=UploadFileAttributesParentField(id='0')), generate_byte_stream(10)) + file_id: str = uploaded_files.entries[0].id + client.shared_links_files.add_share_link_to_file(file_id, 'shared_link', shared_link=AddShareLinkToFileSharedLink(access=AddShareLinkToFileSharedLinkAccessField.OPEN, password='Secret123@')) + file_from_api: FileFull = client.shared_links_files.get_shared_link_for_file(file_id, 'shared_link') + assert to_string(file_from_api.shared_link.access) == 'open' + user_id: str = get_env_var('USER_ID') + user_client: BoxClient = get_default_client_with_user_subject(user_id) + file_from_shared_link_password: FileFull = user_client.shared_links_files.find_file_for_shared_link(''.join(['shared_link=', file_from_api.shared_link.url, '&shared_link_password=Secret123@'])) + assert file_id == file_from_shared_link_password.id + with pytest.raises(Exception): + user_client.shared_links_files.find_file_for_shared_link(''.join(['shared_link=', file_from_api.shared_link.url, '&shared_link_password=incorrectPassword'])) + updated_file: FileFull = client.shared_links_files.update_shared_link_on_file(file_id, 'shared_link', shared_link=UpdateSharedLinkOnFileSharedLink(access=UpdateSharedLinkOnFileSharedLinkAccessField.COLLABORATORS)) + assert to_string(updated_file.shared_link.access) == 'collaborators' + client.shared_links_files.remove_shared_link_from_file(file_id, 'shared_link', shared_link=create_null()) + file_from_api_after_remove: FileFull = client.shared_links_files.get_shared_link_for_file(file_id, 'shared_link') + assert file_from_api_after_remove.shared_link == None + client.files.delete_file_by_id(file_id) \ No newline at end of file diff --git a/test/test_gen/shared_links_folders.py b/test/test_gen/shared_links_folders.py new file mode 100644 index 000000000..9d23ce8a0 --- /dev/null +++ b/test/test_gen/shared_links_folders.py @@ -0,0 +1,49 @@ +from box_sdk_gen.internal.utils import to_string + +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.managers.folders import CreateFolderParent + +from box_sdk_gen.managers.shared_links_folders import AddShareLinkToFolderSharedLink + +from box_sdk_gen.managers.shared_links_folders import AddShareLinkToFolderSharedLinkAccessField + +from box_sdk_gen.managers.shared_links_folders import UpdateSharedLinkOnFolderSharedLink + +from box_sdk_gen.managers.shared_links_folders import UpdateSharedLinkOnFolderSharedLinkAccessField + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import generate_byte_stream + +from box_sdk_gen.internal.utils import get_env_var + +from test.commons import get_default_client + +from test.commons import get_default_client_with_user_subject + +from box_sdk_gen.internal.utils import create_null + +client: BoxClient = get_default_client() + +def testSharedLinksFolders(): + folder: FolderFull = client.folders.create_folder(get_uuid(), CreateFolderParent(id='0')) + client.shared_links_folders.add_share_link_to_folder(folder.id, 'shared_link', shared_link=AddShareLinkToFolderSharedLink(access=AddShareLinkToFolderSharedLinkAccessField.OPEN, password='Secret123@')) + folder_from_api: FolderFull = client.shared_links_folders.get_shared_link_for_folder(folder.id, 'shared_link') + assert to_string(folder_from_api.shared_link.access) == 'open' + user_id: str = get_env_var('USER_ID') + user_client: BoxClient = get_default_client_with_user_subject(user_id) + folder_from_shared_link_password: FolderFull = user_client.shared_links_folders.find_folder_for_shared_link(''.join(['shared_link=', folder_from_api.shared_link.url, '&shared_link_password=Secret123@'])) + assert folder.id == folder_from_shared_link_password.id + with pytest.raises(Exception): + user_client.shared_links_folders.find_folder_for_shared_link(''.join(['shared_link=', folder_from_api.shared_link.url, '&shared_link_password=incorrectPassword'])) + updated_folder: FolderFull = client.shared_links_folders.update_shared_link_on_folder(folder.id, 'shared_link', shared_link=UpdateSharedLinkOnFolderSharedLink(access=UpdateSharedLinkOnFolderSharedLinkAccessField.COLLABORATORS)) + assert to_string(updated_folder.shared_link.access) == 'collaborators' + client.shared_links_folders.remove_shared_link_from_folder(folder.id, 'shared_link', shared_link=create_null()) + folder_from_api_after_remove: FolderFull = client.shared_links_folders.get_shared_link_for_folder(folder.id, 'shared_link') + assert folder_from_api_after_remove.shared_link == None + client.folders.delete_folder_by_id(folder.id) \ No newline at end of file diff --git a/test/test_gen/shared_links_web_links.py b/test/test_gen/shared_links_web_links.py new file mode 100644 index 000000000..b75c83aaf --- /dev/null +++ b/test/test_gen/shared_links_web_links.py @@ -0,0 +1,53 @@ +from box_sdk_gen.internal.utils import to_string + +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.schemas.web_link import WebLink + +from box_sdk_gen.managers.web_links import CreateWebLinkParent + +from box_sdk_gen.managers.shared_links_web_links import AddShareLinkToWebLinkSharedLink + +from box_sdk_gen.managers.shared_links_web_links import AddShareLinkToWebLinkSharedLinkAccessField + +from box_sdk_gen.managers.shared_links_web_links import UpdateSharedLinkOnWebLinkSharedLink + +from box_sdk_gen.managers.shared_links_web_links import UpdateSharedLinkOnWebLinkSharedLinkAccessField + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import generate_byte_stream + +from box_sdk_gen.internal.utils import get_env_var + +from test.commons import get_default_client + +from test.commons import get_default_client_with_user_subject + +from box_sdk_gen.internal.utils import create_null + +client: BoxClient = get_default_client() + +def testSharedLinksWebLinks(): + parent: FolderFull = client.folders.get_folder_by_id('0') + web_link: WebLink = client.web_links.create_web_link('https://www.box.com', CreateWebLinkParent(id=parent.id), name=get_uuid(), description='Weblink description') + web_link_id: str = web_link.id + client.shared_links_web_links.add_share_link_to_web_link(web_link_id, 'shared_link', shared_link=AddShareLinkToWebLinkSharedLink(access=AddShareLinkToWebLinkSharedLinkAccessField.OPEN, password='Secret123@')) + web_link_from_api: WebLink = client.shared_links_web_links.get_shared_link_for_web_link(web_link_id, 'shared_link') + assert to_string(web_link_from_api.shared_link.access) == 'open' + user_id: str = get_env_var('USER_ID') + user_client: BoxClient = get_default_client_with_user_subject(user_id) + web_link_from_shared_link_password: WebLink = user_client.shared_links_web_links.find_web_link_for_shared_link(''.join(['shared_link=', web_link_from_api.shared_link.url, '&shared_link_password=Secret123@'])) + assert web_link_id == web_link_from_shared_link_password.id + with pytest.raises(Exception): + user_client.shared_links_web_links.find_web_link_for_shared_link(''.join(['shared_link=', web_link_from_api.shared_link.url, '&shared_link_password=incorrectPassword'])) + updated_web_link: WebLink = client.shared_links_web_links.update_shared_link_on_web_link(web_link_id, 'shared_link', shared_link=UpdateSharedLinkOnWebLinkSharedLink(access=UpdateSharedLinkOnWebLinkSharedLinkAccessField.COLLABORATORS)) + assert to_string(updated_web_link.shared_link.access) == 'collaborators' + client.shared_links_web_links.remove_shared_link_from_web_link(web_link_id, 'shared_link', shared_link=create_null()) + web_link_from_api_after_remove: WebLink = client.shared_links_web_links.get_shared_link_for_web_link(web_link_id, 'shared_link') + assert web_link_from_api_after_remove.shared_link == None + client.web_links.delete_web_link_by_id(web_link_id) \ No newline at end of file diff --git a/test/test_gen/shield_information_barrier_reports.py b/test/test_gen/shield_information_barrier_reports.py new file mode 100644 index 000000000..7fb9025b7 --- /dev/null +++ b/test/test_gen/shield_information_barrier_reports.py @@ -0,0 +1,38 @@ +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.schemas.shield_information_barrier import ShieldInformationBarrier + +from box_sdk_gen.schemas.shield_information_barrier_reports import ShieldInformationBarrierReports + +from box_sdk_gen.schemas.shield_information_barrier_report import ShieldInformationBarrierReport + +from box_sdk_gen.schemas.shield_information_barrier_base import ShieldInformationBarrierBase + +from box_sdk_gen.schemas.shield_information_barrier_base import ShieldInformationBarrierBaseTypeField + +from box_sdk_gen.internal.utils import get_env_var + +from test.commons import get_default_client_with_user_subject + +from test.commons import get_or_create_shield_information_barrier + +from box_sdk_gen.client import BoxClient + +def testShieldInformationBarrierReports(): + client: BoxClient = get_default_client_with_user_subject(get_env_var('USER_ID')) + enterprise_id: str = get_env_var('ENTERPRISE_ID') + barrier: ShieldInformationBarrier = get_or_create_shield_information_barrier(client, enterprise_id) + assert to_string(barrier.status) == 'draft' + assert to_string(barrier.type) == 'shield_information_barrier' + assert barrier.enterprise.id == enterprise_id + assert to_string(barrier.enterprise.type) == 'enterprise' + barrier_id: str = barrier.id + existing_reports: ShieldInformationBarrierReports = client.shield_information_barrier_reports.get_shield_information_barrier_reports(barrier_id) + if len(existing_reports.entries) > 0: + return None + created_report: ShieldInformationBarrierReport = client.shield_information_barrier_reports.create_shield_information_barrier_report(shield_information_barrier=ShieldInformationBarrierBase(id=barrier_id, type=ShieldInformationBarrierBaseTypeField.SHIELD_INFORMATION_BARRIER)) + assert created_report.shield_information_barrier.shield_information_barrier.id == barrier_id + retrieved_report: ShieldInformationBarrierReport = client.shield_information_barrier_reports.get_shield_information_barrier_report_by_id(created_report.id) + assert retrieved_report.id == created_report.id + retrieved_reports: ShieldInformationBarrierReports = client.shield_information_barrier_reports.get_shield_information_barrier_reports(barrier_id) + assert len(retrieved_reports.entries) > 0 \ No newline at end of file diff --git a/test/test_gen/shield_information_barrier_segment_members.py b/test/test_gen/shield_information_barrier_segment_members.py new file mode 100644 index 000000000..8e23c02e4 --- /dev/null +++ b/test/test_gen/shield_information_barrier_segment_members.py @@ -0,0 +1,49 @@ +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.shield_information_barrier import ShieldInformationBarrier + +from box_sdk_gen.schemas.shield_information_barrier_segment import ShieldInformationBarrierSegment + +from box_sdk_gen.schemas.shield_information_barrier_base import ShieldInformationBarrierBase + +from box_sdk_gen.schemas.shield_information_barrier_base import ShieldInformationBarrierBaseTypeField + +from box_sdk_gen.schemas.shield_information_barrier_segment_member import ShieldInformationBarrierSegmentMember + +from box_sdk_gen.managers.shield_information_barrier_segment_members import CreateShieldInformationBarrierSegmentMemberShieldInformationBarrierSegment + +from box_sdk_gen.managers.shield_information_barrier_segment_members import CreateShieldInformationBarrierSegmentMemberShieldInformationBarrierSegmentTypeField + +from box_sdk_gen.schemas.user_base import UserBase + +from box_sdk_gen.schemas.shield_information_barrier_segment_members import ShieldInformationBarrierSegmentMembers + +from box_sdk_gen.internal.utils import get_env_var + +from box_sdk_gen.internal.utils import get_uuid + +from test.commons import get_default_client_with_user_subject + +from test.commons import get_or_create_shield_information_barrier + +def testShieldInformationBarrierSegmentMembers(): + client: BoxClient = get_default_client_with_user_subject(get_env_var('USER_ID')) + enterprise_id: str = get_env_var('ENTERPRISE_ID') + barrier: ShieldInformationBarrier = get_or_create_shield_information_barrier(client, enterprise_id) + barrier_id: str = barrier.id + segment_name: str = get_uuid() + segment: ShieldInformationBarrierSegment = client.shield_information_barrier_segments.create_shield_information_barrier_segment(ShieldInformationBarrierBase(id=barrier_id, type=ShieldInformationBarrierBaseTypeField.SHIELD_INFORMATION_BARRIER), segment_name) + assert segment.name == segment_name + segment_member: ShieldInformationBarrierSegmentMember = client.shield_information_barrier_segment_members.create_shield_information_barrier_segment_member(CreateShieldInformationBarrierSegmentMemberShieldInformationBarrierSegment(id=segment.id, type=CreateShieldInformationBarrierSegmentMemberShieldInformationBarrierSegmentTypeField.SHIELD_INFORMATION_BARRIER_SEGMENT), UserBase(id=get_env_var('USER_ID'))) + assert segment_member.user.id == get_env_var('USER_ID') + assert segment_member.shield_information_barrier_segment.id == segment.id + segment_members: ShieldInformationBarrierSegmentMembers = client.shield_information_barrier_segment_members.get_shield_information_barrier_segment_members(segment.id) + assert len(segment_members.entries) > 0 + segment_member_get: ShieldInformationBarrierSegmentMember = client.shield_information_barrier_segment_members.get_shield_information_barrier_segment_member_by_id(segment_member.id) + assert segment_member_get.id == segment_member.id + client.shield_information_barrier_segment_members.delete_shield_information_barrier_segment_member_by_id(segment_member.id) + with pytest.raises(Exception): + client.shield_information_barrier_segment_members.get_shield_information_barrier_segment_member_by_id(segment_member.id) + client.shield_information_barrier_segments.delete_shield_information_barrier_segment_by_id(segment.id) \ No newline at end of file diff --git a/test/test_gen/shield_information_barrier_segment_restrictions.py b/test/test_gen/shield_information_barrier_segment_restrictions.py new file mode 100644 index 000000000..d9f17a8e4 --- /dev/null +++ b/test/test_gen/shield_information_barrier_segment_restrictions.py @@ -0,0 +1,58 @@ +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.shield_information_barrier import ShieldInformationBarrier + +from box_sdk_gen.schemas.shield_information_barrier_segment import ShieldInformationBarrierSegment + +from box_sdk_gen.schemas.shield_information_barrier_base import ShieldInformationBarrierBase + +from box_sdk_gen.schemas.shield_information_barrier_base import ShieldInformationBarrierBaseTypeField + +from box_sdk_gen.schemas.shield_information_barrier_segment_restriction import ShieldInformationBarrierSegmentRestriction + +from box_sdk_gen.managers.shield_information_barrier_segment_restrictions import CreateShieldInformationBarrierSegmentRestrictionType + +from box_sdk_gen.managers.shield_information_barrier_segment_restrictions import CreateShieldInformationBarrierSegmentRestrictionShieldInformationBarrierSegment + +from box_sdk_gen.managers.shield_information_barrier_segment_restrictions import CreateShieldInformationBarrierSegmentRestrictionShieldInformationBarrierSegmentTypeField + +from box_sdk_gen.managers.shield_information_barrier_segment_restrictions import CreateShieldInformationBarrierSegmentRestrictionRestrictedSegment + +from box_sdk_gen.managers.shield_information_barrier_segment_restrictions import CreateShieldInformationBarrierSegmentRestrictionRestrictedSegmentTypeField + +from box_sdk_gen.schemas.shield_information_barrier_segment_restrictions import ShieldInformationBarrierSegmentRestrictions + +from box_sdk_gen.internal.utils import get_env_var + +from box_sdk_gen.internal.utils import get_uuid + +from test.commons import get_default_client_with_user_subject + +from test.commons import get_or_create_shield_information_barrier + +def testShieldInformationBarrierSegmentRestrictions(): + client: BoxClient = get_default_client_with_user_subject(get_env_var('USER_ID')) + enterprise_id: str = get_env_var('ENTERPRISE_ID') + barrier: ShieldInformationBarrier = get_or_create_shield_information_barrier(client, enterprise_id) + barrier_id: str = barrier.id + segment: ShieldInformationBarrierSegment = client.shield_information_barrier_segments.create_shield_information_barrier_segment(ShieldInformationBarrierBase(id=barrier_id, type=ShieldInformationBarrierBaseTypeField.SHIELD_INFORMATION_BARRIER), get_uuid(), description='barrier segment description') + segment_id: str = segment.id + segment_to_restrict: ShieldInformationBarrierSegment = client.shield_information_barrier_segments.create_shield_information_barrier_segment(ShieldInformationBarrierBase(id=barrier_id, type=ShieldInformationBarrierBaseTypeField.SHIELD_INFORMATION_BARRIER), get_uuid(), description='barrier segment description') + segment_to_restrict_id: str = segment_to_restrict.id + segment_restriction: ShieldInformationBarrierSegmentRestriction = client.shield_information_barrier_segment_restrictions.create_shield_information_barrier_segment_restriction(CreateShieldInformationBarrierSegmentRestrictionShieldInformationBarrierSegment(id=segment_id, type=CreateShieldInformationBarrierSegmentRestrictionShieldInformationBarrierSegmentTypeField.SHIELD_INFORMATION_BARRIER_SEGMENT), CreateShieldInformationBarrierSegmentRestrictionRestrictedSegment(id=segment_to_restrict_id, type=CreateShieldInformationBarrierSegmentRestrictionRestrictedSegmentTypeField.SHIELD_INFORMATION_BARRIER_SEGMENT), type=CreateShieldInformationBarrierSegmentRestrictionType.SHIELD_INFORMATION_BARRIER_SEGMENT_RESTRICTION) + segment_restriction_id: str = segment_restriction.id + assert segment_restriction.shield_information_barrier_segment.id == segment_id + segment_restrictions: ShieldInformationBarrierSegmentRestrictions = client.shield_information_barrier_segment_restrictions.get_shield_information_barrier_segment_restrictions(segment_id) + assert len(segment_restrictions.entries) > 0 + segment_restriction_from_api: ShieldInformationBarrierSegmentRestriction = client.shield_information_barrier_segment_restrictions.get_shield_information_barrier_segment_restriction_by_id(segment_restriction_id) + assert segment_restriction_from_api.id == segment_restriction_id + assert segment_restriction_from_api.shield_information_barrier_segment.id == segment_id + assert segment_restriction_from_api.restricted_segment.id == segment_to_restrict_id + assert segment_restriction_from_api.shield_information_barrier.id == barrier_id + client.shield_information_barrier_segment_restrictions.delete_shield_information_barrier_segment_restriction_by_id(segment_restriction_id) + with pytest.raises(Exception): + client.shield_information_barrier_segment_restrictions.get_shield_information_barrier_segment_restriction_by_id(segment_restriction_id) + client.shield_information_barrier_segments.delete_shield_information_barrier_segment_by_id(segment_id) + client.shield_information_barrier_segments.delete_shield_information_barrier_segment_by_id(segment_to_restrict_id) \ No newline at end of file diff --git a/test/test_gen/shield_information_barrier_segments.py b/test/test_gen/shield_information_barrier_segments.py new file mode 100644 index 000000000..2c9fe5769 --- /dev/null +++ b/test/test_gen/shield_information_barrier_segments.py @@ -0,0 +1,48 @@ +from box_sdk_gen.internal.utils import to_string + +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.shield_information_barrier import ShieldInformationBarrier + +from box_sdk_gen.schemas.shield_information_barrier_segment import ShieldInformationBarrierSegment + +from box_sdk_gen.schemas.shield_information_barrier_base import ShieldInformationBarrierBase + +from box_sdk_gen.schemas.shield_information_barrier_base import ShieldInformationBarrierBaseTypeField + +from box_sdk_gen.schemas.shield_information_barrier_segments import ShieldInformationBarrierSegments + +from box_sdk_gen.internal.utils import get_env_var + +from box_sdk_gen.internal.utils import get_uuid + +from test.commons import get_default_client_with_user_subject + +from test.commons import get_or_create_shield_information_barrier + +def testShieldInformationBarrierSegments(): + client: BoxClient = get_default_client_with_user_subject(get_env_var('USER_ID')) + enterprise_id: str = get_env_var('ENTERPRISE_ID') + barrier: ShieldInformationBarrier = get_or_create_shield_information_barrier(client, enterprise_id) + barrier_id: str = barrier.id + segment_name: str = get_uuid() + segment_description: str = 'barrier segment description' + segment: ShieldInformationBarrierSegment = client.shield_information_barrier_segments.create_shield_information_barrier_segment(ShieldInformationBarrierBase(id=barrier_id, type=ShieldInformationBarrierBaseTypeField.SHIELD_INFORMATION_BARRIER), segment_name, description=segment_description) + assert segment.name == segment_name + segments: ShieldInformationBarrierSegments = client.shield_information_barrier_segments.get_shield_information_barrier_segments(barrier_id) + assert len(segments.entries) > 0 + segment_id: str = segment.id + segment_from_api: ShieldInformationBarrierSegment = client.shield_information_barrier_segments.get_shield_information_barrier_segment_by_id(segment_id) + assert to_string(segment_from_api.type) == 'shield_information_barrier_segment' + assert segment_from_api.id == segment_id + assert segment_from_api.name == segment_name + assert segment_from_api.description == segment_description + assert segment_from_api.shield_information_barrier.id == barrier_id + updated_segment_description: str = 'updated barrier segment description' + updated_segment: ShieldInformationBarrierSegment = client.shield_information_barrier_segments.update_shield_information_barrier_segment_by_id(segment_id, description=updated_segment_description) + assert updated_segment.description == updated_segment_description + client.shield_information_barrier_segments.delete_shield_information_barrier_segment_by_id(segment_id) + with pytest.raises(Exception): + client.shield_information_barrier_segments.get_shield_information_barrier_segment_by_id(segment_id) \ No newline at end of file diff --git a/test/test_gen/shield_information_barriers.py b/test/test_gen/shield_information_barriers.py new file mode 100644 index 000000000..5f30b53ed --- /dev/null +++ b/test/test_gen/shield_information_barriers.py @@ -0,0 +1,33 @@ +from box_sdk_gen.internal.utils import to_string + +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.shield_information_barrier import ShieldInformationBarrier + +from box_sdk_gen.schemas.shield_information_barriers import ShieldInformationBarriers + +from box_sdk_gen.managers.shield_information_barriers import UpdateShieldInformationBarrierStatusStatus + +from box_sdk_gen.internal.utils import get_env_var + +from test.commons import get_default_client_with_user_subject + +from test.commons import get_or_create_shield_information_barrier + +def testShieldInformationBarriers(): + client: BoxClient = get_default_client_with_user_subject(get_env_var('USER_ID')) + enterprise_id: str = get_env_var('ENTERPRISE_ID') + barrier: ShieldInformationBarrier = get_or_create_shield_information_barrier(client, enterprise_id) + assert to_string(barrier.status) == 'draft' + assert to_string(barrier.type) == 'shield_information_barrier' + assert barrier.enterprise.id == enterprise_id + assert to_string(barrier.enterprise.type) == 'enterprise' + barrier_id: str = barrier.id + barrier_from_api: ShieldInformationBarrier = client.shield_information_barriers.get_shield_information_barrier_by_id(barrier_id) + assert barrier_from_api.id == barrier_id + barriers: ShieldInformationBarriers = client.shield_information_barriers.get_shield_information_barriers() + assert len(barriers.entries) == 1 + with pytest.raises(Exception): + client.shield_information_barriers.update_shield_information_barrier_status(barrier_id, UpdateShieldInformationBarrierStatusStatus.DISABLED) \ No newline at end of file diff --git a/test/test_gen/sign_requests.py b/test/test_gen/sign_requests.py new file mode 100644 index 000000000..59e12b2b5 --- /dev/null +++ b/test/test_gen/sign_requests.py @@ -0,0 +1,84 @@ +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.schemas.sign_request import SignRequest + +from box_sdk_gen.schemas.file_base import FileBase + +from box_sdk_gen.schemas.sign_request_create_signer import SignRequestCreateSigner + +from box_sdk_gen.schemas.sign_request_create_signer import SignRequestCreateSignerRoleField + +from box_sdk_gen.schemas.folder_mini import FolderMini + +from box_sdk_gen.schemas.sign_request_prefill_tag import SignRequestPrefillTag + +from box_sdk_gen.schemas.sign_requests import SignRequests + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import date_from_string + +from box_sdk_gen.internal.utils import date_to_string + +from test.commons import upload_new_file + +from test.commons import create_new_folder + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def testCreateGetCancelAndListSignRequest(): + signer_email: str = ''.join([get_uuid(), '@box.com']) + file_to_sign: FileFull = upload_new_file() + destination_folder: FolderFull = create_new_folder() + created_sign_request: SignRequest = client.sign_requests.create_sign_request([SignRequestCreateSigner(email=signer_email, suppress_notifications=True, declined_redirect_url='https://www.box.com', embed_url_external_user_id='123', is_in_person=False, login_required=False, password='password', role=SignRequestCreateSignerRoleField.SIGNER)], source_files=[FileBase(id=file_to_sign.id)], parent_folder=FolderMini(id=destination_folder.id), is_document_preparation_needed=False, redirect_url='https://www.box.com', declined_redirect_url='https://www.box.com', are_text_signatures_enabled=True, email_subject='Sign this document', email_message='Please sign this document', are_reminders_enabled=True, name='Sign Request', prefill_tags=[SignRequestPrefillTag(date_value=date_from_string('2035-01-01'), document_tag_id='0')], days_valid=30, external_id='123', external_system_name='BoxSignIntegration') + assert created_sign_request.are_reminders_enabled == True + assert created_sign_request.are_text_signatures_enabled == True + assert created_sign_request.days_valid == 30 + assert created_sign_request.declined_redirect_url == 'https://www.box.com' + assert created_sign_request.email_message == 'Please sign this document' + assert created_sign_request.email_subject == 'Sign this document' + assert created_sign_request.external_id == '123' + assert created_sign_request.external_system_name == 'BoxSignIntegration' + assert created_sign_request.is_document_preparation_needed == False + assert created_sign_request.name == 'Sign Request.pdf' + assert created_sign_request.redirect_url == 'https://www.box.com' + assert created_sign_request.sign_files.files[0].name == created_sign_request.name + assert created_sign_request.signers[1].email == signer_email + assert created_sign_request.signers[1].suppress_notifications == True + assert created_sign_request.signers[1].declined_redirect_url == 'https://www.box.com' + assert created_sign_request.signers[1].embed_url_external_user_id == '123' + assert created_sign_request.signers[1].is_in_person == False + assert created_sign_request.signers[1].login_required == False + assert to_string(created_sign_request.signers[1].role) == 'signer' + assert created_sign_request.parent_folder.id == destination_folder.id + assert date_to_string(created_sign_request.prefill_tags[0].date_value) == '2035-01-01' + new_sign_request: SignRequest = client.sign_requests.get_sign_request_by_id(created_sign_request.id) + assert new_sign_request.sign_files.files[0].name == created_sign_request.name + assert new_sign_request.signers[1].email == signer_email + assert new_sign_request.parent_folder.id == destination_folder.id + cancelled_sign_request: SignRequest = client.sign_requests.cancel_sign_request(created_sign_request.id) + assert to_string(cancelled_sign_request.status) == 'cancelled' + sign_requests: SignRequests = client.sign_requests.get_sign_requests() + assert to_string(sign_requests.entries[0].type) == 'sign-request' + client.folders.delete_folder_by_id(destination_folder.id, recursive=True) + client.files.delete_file_by_id(file_to_sign.id) + +def testCreateSignRequestWithSignerGroupId(): + signer_1_email: str = ''.join([get_uuid(), '@box.com']) + signer_2_email: str = ''.join([get_uuid(), '@box.com']) + file_to_sign: FileFull = upload_new_file() + destination_folder: FolderFull = create_new_folder() + created_sign_request: SignRequest = client.sign_requests.create_sign_request([SignRequestCreateSigner(email=signer_1_email, signer_group_id='user'), SignRequestCreateSigner(email=signer_2_email, signer_group_id='user')], source_files=[FileBase(id=file_to_sign.id)], parent_folder=FolderMini(id=destination_folder.id)) + assert len(created_sign_request.signers) == 3 + assert not created_sign_request.signers[1].signer_group_id == None + assert created_sign_request.signers[1].signer_group_id == created_sign_request.signers[2].signer_group_id + client.folders.delete_folder_by_id(destination_folder.id, recursive=True) + client.files.delete_file_by_id(file_to_sign.id) \ No newline at end of file diff --git a/test/test_gen/sign_templates.py b/test/test_gen/sign_templates.py new file mode 100644 index 000000000..a86cadf14 --- /dev/null +++ b/test/test_gen/sign_templates.py @@ -0,0 +1,27 @@ +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.sign_templates import SignTemplates + +from box_sdk_gen.schemas.sign_template import SignTemplate + +from box_sdk_gen.internal.utils import decode_base_64 + +from box_sdk_gen.internal.utils import get_env_var + +from test.commons import get_default_client_with_user_subject + +def testGetSignTemplates(): + client: BoxClient = get_default_client_with_user_subject(get_env_var('USER_ID')) + sign_templates: SignTemplates = client.sign_templates.get_sign_templates(limit=2) + assert len(sign_templates.entries) >= 0 + +def testGetSignTemplate(): + client: BoxClient = get_default_client_with_user_subject(get_env_var('USER_ID')) + sign_templates: SignTemplates = client.sign_templates.get_sign_templates(limit=2) + assert len(sign_templates.entries) >= 0 + if len(sign_templates.entries) > 0: + sign_template: SignTemplate = client.sign_templates.get_sign_template_by_id(sign_templates.entries[0].id) + assert sign_template.id == sign_templates.entries[0].id + assert len(sign_template.source_files) > 0 + assert not sign_template.name == '' + assert not sign_template.parent_folder.id == '' \ No newline at end of file diff --git a/test/test_gen/skills.py b/test/test_gen/skills.py new file mode 100644 index 000000000..8a02126a2 --- /dev/null +++ b/test/test_gen/skills.py @@ -0,0 +1,53 @@ +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.skill_cards_metadata import SkillCardsMetadata + +from box_sdk_gen.schemas.keyword_skill_card import KeywordSkillCardTypeField + +from box_sdk_gen.schemas.keyword_skill_card import KeywordSkillCardSkillCardTypeField + +from box_sdk_gen.schemas.keyword_skill_card import KeywordSkillCardSkillCardTitleField + +from box_sdk_gen.schemas.keyword_skill_card import KeywordSkillCardSkillField + +from box_sdk_gen.schemas.keyword_skill_card import KeywordSkillCardSkillTypeField + +from box_sdk_gen.schemas.keyword_skill_card import KeywordSkillCardInvocationField + +from box_sdk_gen.schemas.keyword_skill_card import KeywordSkillCardInvocationTypeField + +from box_sdk_gen.schemas.keyword_skill_card import KeywordSkillCardEntriesField + +from box_sdk_gen.managers.skills import UpdateBoxSkillCardsOnFileRequestBody + +from box_sdk_gen.managers.skills import UpdateBoxSkillCardsOnFileRequestBodyOpField + +from box_sdk_gen.internal.utils import get_uuid + +from test.commons import get_default_client + +from test.commons import upload_new_file + +from box_sdk_gen.schemas.keyword_skill_card import KeywordSkillCard + +client: BoxClient = get_default_client() + +def test_skills_cards_CRUD(): + file: FileFull = upload_new_file() + skill_id: str = get_uuid() + invocation_id: str = get_uuid() + title_message: str = 'License Plates' + skill_cards_metadata: SkillCardsMetadata = client.skills.create_box_skill_cards_on_file(file.id, [KeywordSkillCard(type=KeywordSkillCardTypeField.SKILL_CARD, skill_card_type=KeywordSkillCardSkillCardTypeField.KEYWORD, skill_card_title=KeywordSkillCardSkillCardTitleField(code='license-plates', message=title_message), skill=KeywordSkillCardSkillField(id=skill_id, type=KeywordSkillCardSkillTypeField.SERVICE), invocation=KeywordSkillCardInvocationField(id=invocation_id, type=KeywordSkillCardInvocationTypeField.SKILL_INVOCATION), entries=[KeywordSkillCardEntriesField(text='DN86 BOX')])]) + assert len(skill_cards_metadata.cards) == 1 + assert skill_cards_metadata.cards[0].skill.id == skill_id + assert skill_cards_metadata.cards[0].skill_card_title.message == title_message + updated_title_message: str = 'Updated License Plates' + updated_skill_cards_metadata: SkillCardsMetadata = client.skills.update_box_skill_cards_on_file(file.id, [UpdateBoxSkillCardsOnFileRequestBody(op=UpdateBoxSkillCardsOnFileRequestBodyOpField.REPLACE, path='/cards/0', value=KeywordSkillCard(type=KeywordSkillCardTypeField.SKILL_CARD, skill_card_type=KeywordSkillCardSkillCardTypeField.KEYWORD, skill_card_title=KeywordSkillCardSkillCardTitleField(code='license-plates', message=updated_title_message), skill=KeywordSkillCardSkillField(id=skill_id, type=KeywordSkillCardSkillTypeField.SERVICE), invocation=KeywordSkillCardInvocationField(id=invocation_id, type=KeywordSkillCardInvocationTypeField.SKILL_INVOCATION), entries=[KeywordSkillCardEntriesField(text='DN86 BOX')]))]) + assert updated_skill_cards_metadata.cards[0].skill.id == skill_id + assert updated_skill_cards_metadata.cards[0].skill_card_title.message == updated_title_message + received_skill_cards_metadata: SkillCardsMetadata = client.skills.get_box_skill_cards_on_file(file.id) + assert updated_skill_cards_metadata.cards[0].skill.id == skill_id + client.skills.delete_box_skill_cards_from_file(file.id) + client.files.delete_file_by_id(file.id) \ No newline at end of file diff --git a/test/test_gen/storage_policicy_assignments.py b/test/test_gen/storage_policicy_assignments.py new file mode 100644 index 000000000..6ab305a6d --- /dev/null +++ b/test/test_gen/storage_policicy_assignments.py @@ -0,0 +1,57 @@ +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.schemas.storage_policy_assignment import StoragePolicyAssignment + +from box_sdk_gen.schemas.storage_policy_assignments import StoragePolicyAssignments + +from box_sdk_gen.managers.storage_policy_assignments import GetStoragePolicyAssignmentsResolvedForType + +from box_sdk_gen.managers.storage_policy_assignments import CreateStoragePolicyAssignmentStoragePolicy + +from box_sdk_gen.managers.storage_policy_assignments import CreateStoragePolicyAssignmentAssignedTo + +from box_sdk_gen.managers.storage_policy_assignments import CreateStoragePolicyAssignmentAssignedToTypeField + +from box_sdk_gen.schemas.user_full import UserFull + +from box_sdk_gen.schemas.storage_policies import StoragePolicies + +from box_sdk_gen.schemas.storage_policy import StoragePolicy + +from box_sdk_gen.managers.storage_policy_assignments import UpdateStoragePolicyAssignmentByIdStoragePolicy + +from box_sdk_gen.internal.utils import get_env_var + +from test.commons import get_default_client_with_user_subject + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.internal.utils import get_uuid + +admin_user_id: str = get_env_var('USER_ID') + +def get_or_create_storage_policy_assignment(client: BoxClient, policy_id: str, user_id: str) -> StoragePolicyAssignment: + storage_policy_assignments: StoragePolicyAssignments = client.storage_policy_assignments.get_storage_policy_assignments(GetStoragePolicyAssignmentsResolvedForType.USER, user_id) + if len(storage_policy_assignments.entries) > 0: + if to_string(storage_policy_assignments.entries[0].assigned_to.type) == 'user': + return storage_policy_assignments.entries[0] + storage_policy_assignment: StoragePolicyAssignment = client.storage_policy_assignments.create_storage_policy_assignment(CreateStoragePolicyAssignmentStoragePolicy(id=policy_id), CreateStoragePolicyAssignmentAssignedTo(id=user_id, type=CreateStoragePolicyAssignmentAssignedToTypeField.USER)) + return storage_policy_assignment + +def testGetStoragePolicyAssignments(): + client: BoxClient = get_default_client_with_user_subject(admin_user_id) + user_name: str = get_uuid() + new_user: UserFull = client.users.create_user(user_name, is_platform_access_only=True) + storage_policies: StoragePolicies = client.storage_policies.get_storage_policies() + storage_policy_1: StoragePolicy = storage_policies.entries[0] + storage_policy_2: StoragePolicy = storage_policies.entries[1] + storage_policy_assignment: StoragePolicyAssignment = get_or_create_storage_policy_assignment(client, storage_policy_1.id, new_user.id) + assert to_string(storage_policy_assignment.type) == 'storage_policy_assignment' + assert to_string(storage_policy_assignment.assigned_to.type) == 'user' + assert storage_policy_assignment.assigned_to.id == new_user.id + get_storage_policy_assignment: StoragePolicyAssignment = client.storage_policy_assignments.get_storage_policy_assignment_by_id(storage_policy_assignment.id) + assert get_storage_policy_assignment.id == storage_policy_assignment.id + updated_storage_policy_assignment: StoragePolicyAssignment = client.storage_policy_assignments.update_storage_policy_assignment_by_id(storage_policy_assignment.id, UpdateStoragePolicyAssignmentByIdStoragePolicy(id=storage_policy_2.id)) + assert updated_storage_policy_assignment.storage_policy.id == storage_policy_2.id + client.storage_policy_assignments.delete_storage_policy_assignment_by_id(storage_policy_assignment.id) + client.users.delete_user_by_id(new_user.id) \ No newline at end of file diff --git a/test/test_gen/storage_policies.py b/test/test_gen/storage_policies.py new file mode 100644 index 000000000..864c7a19c --- /dev/null +++ b/test/test_gen/storage_policies.py @@ -0,0 +1,21 @@ +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.storage_policies import StoragePolicies + +from box_sdk_gen.schemas.storage_policy import StoragePolicy + +from box_sdk_gen.internal.utils import get_env_var + +from test.commons import get_default_client_with_user_subject + +user_id: str = get_env_var('USER_ID') + +def testGetStoragePolicies(): + client: BoxClient = get_default_client_with_user_subject(user_id) + storage_policies: StoragePolicies = client.storage_policies.get_storage_policies() + storage_policy: StoragePolicy = storage_policies.entries[0] + assert to_string(storage_policy.type) == 'storage_policy' + get_storage_policy: StoragePolicy = client.storage_policies.get_storage_policy_by_id(storage_policy.id) + assert get_storage_policy.id == storage_policy.id \ No newline at end of file diff --git a/test/test_gen/task_assignments.py b/test/test_gen/task_assignments.py new file mode 100644 index 000000000..92d67c0b2 --- /dev/null +++ b/test/test_gen/task_assignments.py @@ -0,0 +1,62 @@ +from box_sdk_gen.internal.utils import to_string + +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.internal.utils import DateTime + +from box_sdk_gen.schemas.task import Task + +from box_sdk_gen.managers.tasks import CreateTaskItem + +from box_sdk_gen.managers.tasks import CreateTaskItemTypeField + +from box_sdk_gen.managers.tasks import CreateTaskAction + +from box_sdk_gen.managers.tasks import CreateTaskCompletionRule + +from box_sdk_gen.schemas.user_full import UserFull + +from box_sdk_gen.schemas.task_assignment import TaskAssignment + +from box_sdk_gen.managers.task_assignments import CreateTaskAssignmentTask + +from box_sdk_gen.managers.task_assignments import CreateTaskAssignmentTaskTypeField + +from box_sdk_gen.managers.task_assignments import CreateTaskAssignmentAssignTo + +from box_sdk_gen.schemas.task_assignments import TaskAssignments + +from box_sdk_gen.managers.task_assignments import UpdateTaskAssignmentByIdResolutionState + +from test.commons import upload_new_file + +from test.commons import get_default_client + +from box_sdk_gen.internal.utils import date_time_from_string + +client: BoxClient = get_default_client() + +def testCreateUpdateGetDeleteTaskAssignment(): + file: FileFull = upload_new_file() + date: DateTime = date_time_from_string('2035-01-01T00:00:00Z') + task: Task = client.tasks.create_task(CreateTaskItem(type=CreateTaskItemTypeField.FILE, id=file.id), action=CreateTaskAction.REVIEW, message='test message', due_at=date, completion_rule=CreateTaskCompletionRule.ALL_ASSIGNEES) + assert task.message == 'test message' + assert task.item.id == file.id + current_user: UserFull = client.users.get_user_me() + task_assignment: TaskAssignment = client.task_assignments.create_task_assignment(CreateTaskAssignmentTask(type=CreateTaskAssignmentTaskTypeField.TASK, id=task.id), CreateTaskAssignmentAssignTo(id=current_user.id)) + assert task_assignment.item.id == file.id + assert task_assignment.assigned_to.id == current_user.id + task_assignment_by_id: TaskAssignment = client.task_assignments.get_task_assignment_by_id(task_assignment.id) + assert task_assignment_by_id.id == task_assignment.id + task_assignments_on_task: TaskAssignments = client.task_assignments.get_task_assignments(task.id) + assert task_assignments_on_task.total_count == 1 + updated_task_assignment: TaskAssignment = client.task_assignments.update_task_assignment_by_id(task_assignment.id, message='updated message', resolution_state=UpdateTaskAssignmentByIdResolutionState.APPROVED) + assert updated_task_assignment.message == 'updated message' + assert to_string(updated_task_assignment.resolution_state) == 'approved' + with pytest.raises(Exception): + client.task_assignments.delete_task_assignment_by_id(task_assignment.id) + client.files.delete_file_by_id(file.id) \ No newline at end of file diff --git a/test/test_gen/tasks.py b/test/test_gen/tasks.py new file mode 100644 index 000000000..cf7598040 --- /dev/null +++ b/test/test_gen/tasks.py @@ -0,0 +1,52 @@ +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.files import Files + +from box_sdk_gen.managers.uploads import UploadFileAttributes + +from box_sdk_gen.managers.uploads import UploadFileAttributesParentField + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.internal.utils import DateTime + +from box_sdk_gen.schemas.task import Task + +from box_sdk_gen.managers.tasks import CreateTaskItem + +from box_sdk_gen.managers.tasks import CreateTaskItemTypeField + +from box_sdk_gen.managers.tasks import CreateTaskAction + +from box_sdk_gen.managers.tasks import CreateTaskCompletionRule + +from box_sdk_gen.schemas.tasks import Tasks + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import generate_byte_stream + +from box_sdk_gen.internal.utils import date_time_from_string + +from box_sdk_gen.internal.utils import date_time_to_string + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def testCreateUpdateGetDeleteTask(): + files: Files = client.uploads.upload_file(UploadFileAttributes(name=get_uuid(), parent=UploadFileAttributesParentField(id='0')), generate_byte_stream(10)) + file: FileFull = files.entries[0] + date_time: DateTime = date_time_from_string('2035-01-01T00:00:00Z') + task: Task = client.tasks.create_task(CreateTaskItem(type=CreateTaskItemTypeField.FILE, id=file.id), action=CreateTaskAction.REVIEW, message='test message', due_at=date_time, completion_rule=CreateTaskCompletionRule.ALL_ASSIGNEES) + assert task.message == 'test message' + assert task.item.id == file.id + assert date_time_to_string(task.due_at) == date_time_to_string(date_time) + task_by_id: Task = client.tasks.get_task_by_id(task.id) + assert task_by_id.id == task.id + task_on_file: Tasks = client.tasks.get_file_tasks(file.id) + assert task_on_file.total_count == 1 + updated_task: Task = client.tasks.update_task_by_id(task.id, message='updated message') + assert updated_task.message == 'updated message' + client.tasks.delete_task_by_id(task.id) + client.files.delete_file_by_id(file.id) \ No newline at end of file diff --git a/test/test_gen/terms_of_service_user_statuses.py b/test/test_gen/terms_of_service_user_statuses.py new file mode 100644 index 000000000..c1a928f72 --- /dev/null +++ b/test/test_gen/terms_of_service_user_statuses.py @@ -0,0 +1,41 @@ +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.terms_of_service import TermsOfService + +from box_sdk_gen.schemas.user_full import UserFull + +from box_sdk_gen.schemas.terms_of_service_user_status import TermsOfServiceUserStatus + +from box_sdk_gen.managers.terms_of_service_user_statuses import CreateTermsOfServiceStatusForUserTos + +from box_sdk_gen.managers.terms_of_service_user_statuses import CreateTermsOfServiceStatusForUserUser + +from box_sdk_gen.schemas.terms_of_service_user_statuses import TermsOfServiceUserStatuses + +from test.commons import get_default_client_with_user_subject + +from test.commons import get_or_create_terms_of_services + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import get_env_var + +def testGetTermsOfServiceUserStatuses(): + admin_user_id: str = get_env_var('USER_ID') + client: BoxClient = get_default_client_with_user_subject(admin_user_id) + tos: TermsOfService = get_or_create_terms_of_services() + user: UserFull = client.users.create_user(get_uuid(), login=''.join([get_uuid(), '@boxdemo.com']), is_platform_access_only=True) + created_tos_user_status: TermsOfServiceUserStatus = client.terms_of_service_user_statuses.create_terms_of_service_status_for_user(CreateTermsOfServiceStatusForUserTos(id=tos.id), CreateTermsOfServiceStatusForUserUser(id=user.id), False) + assert created_tos_user_status.is_accepted == False + assert to_string(created_tos_user_status.type) == 'terms_of_service_user_status' + assert to_string(created_tos_user_status.tos.type) == 'terms_of_service' + assert to_string(created_tos_user_status.user.type) == 'user' + assert created_tos_user_status.tos.id == tos.id + assert created_tos_user_status.user.id == user.id + updated_tos_user_status: TermsOfServiceUserStatus = client.terms_of_service_user_statuses.update_terms_of_service_status_for_user_by_id(created_tos_user_status.id, True) + assert updated_tos_user_status.is_accepted == True + list_tos_user_statuses: TermsOfServiceUserStatuses = client.terms_of_service_user_statuses.get_terms_of_service_user_statuses(tos.id, user_id=user.id) + assert list_tos_user_statuses.total_count > 0 + client.users.delete_user_by_id(user.id) \ No newline at end of file diff --git a/test/test_gen/terms_of_services.py b/test/test_gen/terms_of_services.py new file mode 100644 index 000000000..78ea14ac8 --- /dev/null +++ b/test/test_gen/terms_of_services.py @@ -0,0 +1,26 @@ +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.terms_of_service import TermsOfService + +from box_sdk_gen.managers.terms_of_services import UpdateTermsOfServiceByIdStatus + +from box_sdk_gen.schemas.terms_of_services import TermsOfServices + +from test.commons import get_default_client + +from test.commons import get_or_create_terms_of_services + +client: BoxClient = get_default_client() + +def testGetTermsOfServices(): + tos: TermsOfService = get_or_create_terms_of_services() + updated_tos_1: TermsOfService = client.terms_of_services.update_terms_of_service_by_id(tos.id, UpdateTermsOfServiceByIdStatus.DISABLED, 'TOS') + assert to_string(updated_tos_1.status) == 'disabled' + assert updated_tos_1.text == 'TOS' + updated_tos_2: TermsOfService = client.terms_of_services.update_terms_of_service_by_id(tos.id, UpdateTermsOfServiceByIdStatus.DISABLED, 'Updated TOS') + assert to_string(updated_tos_2.status) == 'disabled' + assert updated_tos_2.text == 'Updated TOS' + list_tos: TermsOfServices = client.terms_of_services.get_terms_of_service() + assert list_tos.total_count > 0 \ No newline at end of file diff --git a/test/test_gen/transfer.py b/test/test_gen/transfer.py new file mode 100644 index 000000000..5a2313c7c --- /dev/null +++ b/test/test_gen/transfer.py @@ -0,0 +1,22 @@ +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.user_full import UserFull + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.managers.transfer import TransferOwnedFolderOwnedBy + +from box_sdk_gen.internal.utils import get_uuid + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def testTransferUserContent(): + new_user_name: str = get_uuid() + new_user: UserFull = client.users.create_user(new_user_name, is_platform_access_only=True) + current_user: UserFull = client.users.get_user_me() + transfered_folder: FolderFull = client.transfer.transfer_owned_folder(new_user.id, TransferOwnedFolderOwnedBy(id=current_user.id), notify=False) + assert transfered_folder.owned_by.id == current_user.id + client.folders.delete_folder_by_id(transfered_folder.id, recursive=True) + client.users.delete_user_by_id(new_user.id, notify=False, force=True) \ No newline at end of file diff --git a/test/test_gen/trashed_files.py b/test/test_gen/trashed_files.py new file mode 100644 index 000000000..3fe8a52f7 --- /dev/null +++ b/test/test_gen/trashed_files.py @@ -0,0 +1,49 @@ +from box_sdk_gen.internal.utils import to_string + +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.internal.utils import ByteStream + +from box_sdk_gen.schemas.files import Files + +from box_sdk_gen.managers.uploads import UploadFileAttributes + +from box_sdk_gen.managers.uploads import UploadFileAttributesParentField + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.trash_file import TrashFile + +from box_sdk_gen.schemas.trash_file_restored import TrashFileRestored + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import generate_byte_stream + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def testTrashedFiles(): + file_size: int = 1024 * 1024 + file_name: str = get_uuid() + file_byte_stream: ByteStream = generate_byte_stream(file_size) + files: Files = client.uploads.upload_file(UploadFileAttributes(name=file_name, parent=UploadFileAttributesParentField(id='0')), file_byte_stream) + file: FileFull = files.entries[0] + client.files.delete_file_by_id(file.id) + from_trash: TrashFile = client.trashed_files.get_trashed_file_by_id(file.id) + assert from_trash.id == file.id + assert from_trash.name == file.name + from_api_after_trashed: FileFull = client.files.get_file_by_id(file.id) + assert to_string(from_api_after_trashed.item_status) == 'trashed' + restored_file: TrashFileRestored = client.trashed_files.restore_file_from_trash(file.id) + from_api_after_restore: FileFull = client.files.get_file_by_id(file.id) + assert restored_file.id == from_api_after_restore.id + assert restored_file.name == from_api_after_restore.name + assert to_string(from_api_after_restore.item_status) == 'active' + client.files.delete_file_by_id(file.id) + client.trashed_files.delete_trashed_file_by_id(file.id) + with pytest.raises(Exception): + client.trashed_files.get_trashed_file_by_id(file.id) \ No newline at end of file diff --git a/test/test_gen/trashed_folders.py b/test/test_gen/trashed_folders.py new file mode 100644 index 000000000..3582dbfb9 --- /dev/null +++ b/test/test_gen/trashed_folders.py @@ -0,0 +1,34 @@ +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.managers.folders import CreateFolderParent + +from box_sdk_gen.schemas.trash_folder import TrashFolder + +from box_sdk_gen.schemas.trash_folder_restored import TrashFolderRestored + +from box_sdk_gen.internal.utils import get_uuid + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def testTrashedFolders(): + folder: FolderFull = client.folders.create_folder(get_uuid(), CreateFolderParent(id='0')) + client.folders.delete_folder_by_id(folder.id) + from_trash: TrashFolder = client.trashed_folders.get_trashed_folder_by_id(folder.id) + assert from_trash.id == folder.id + assert from_trash.name == folder.name + with pytest.raises(Exception): + client.folders.get_folder_by_id(folder.id) + restored_folder: TrashFolderRestored = client.trashed_folders.restore_folder_from_trash(folder.id) + from_api: FolderFull = client.folders.get_folder_by_id(folder.id) + assert restored_folder.id == from_api.id + assert restored_folder.name == from_api.name + client.folders.delete_folder_by_id(folder.id) + client.trashed_folders.delete_trashed_folder_by_id(folder.id) + with pytest.raises(Exception): + client.trashed_folders.get_trashed_folder_by_id(folder.id) \ No newline at end of file diff --git a/test/test_gen/trashed_items.py b/test/test_gen/trashed_items.py new file mode 100644 index 000000000..3b3b470f5 --- /dev/null +++ b/test/test_gen/trashed_items.py @@ -0,0 +1,17 @@ +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.items import Items + +from test.commons import get_default_client + +from test.commons import upload_new_file + +client: BoxClient = get_default_client() + +def testListTrashedItems(): + file: FileFull = upload_new_file() + client.files.delete_file_by_id(file.id) + trashed_items: Items = client.trashed_items.get_trashed_items() + assert len(trashed_items.entries) > 0 \ No newline at end of file diff --git a/test/test_gen/trashed_web_links.py b/test/test_gen/trashed_web_links.py new file mode 100644 index 000000000..9467d88fb --- /dev/null +++ b/test/test_gen/trashed_web_links.py @@ -0,0 +1,42 @@ +from box_sdk_gen.internal.utils import to_string + +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.schemas.web_link import WebLink + +from box_sdk_gen.managers.web_links import CreateWebLinkParent + +from box_sdk_gen.schemas.trash_web_link import TrashWebLink + +from box_sdk_gen.schemas.trash_web_link_restored import TrashWebLinkRestored + +from box_sdk_gen.internal.utils import get_uuid + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def testTrashedWebLinks(): + url: str = 'https://www.box.com' + parent: FolderFull = client.folders.get_folder_by_id('0') + name: str = get_uuid() + description: str = 'Weblink description' + weblink: WebLink = client.web_links.create_web_link(url, CreateWebLinkParent(id=parent.id), name=name, description=description) + client.web_links.delete_web_link_by_id(weblink.id) + from_trash: TrashWebLink = client.trashed_web_links.get_trashed_web_link_by_id(weblink.id) + assert from_trash.id == weblink.id + assert from_trash.name == weblink.name + from_api_after_trashed: WebLink = client.web_links.get_web_link_by_id(weblink.id) + assert to_string(from_api_after_trashed.item_status) == 'trashed' + restored_weblink: TrashWebLinkRestored = client.trashed_web_links.restore_weblink_from_trash(weblink.id) + from_api: WebLink = client.web_links.get_web_link_by_id(weblink.id) + assert restored_weblink.id == from_api.id + assert restored_weblink.name == from_api.name + client.web_links.delete_web_link_by_id(weblink.id) + client.trashed_web_links.delete_trashed_web_link_by_id(weblink.id) + with pytest.raises(Exception): + client.trashed_web_links.get_trashed_web_link_by_id(weblink.id) \ No newline at end of file diff --git a/test/test_gen/uploads.py b/test/test_gen/uploads.py new file mode 100644 index 000000000..ea21b74d5 --- /dev/null +++ b/test/test_gen/uploads.py @@ -0,0 +1,62 @@ +import pytest + +from box_sdk_gen.internal.utils import ByteStream + +from box_sdk_gen.schemas.files import Files + +from box_sdk_gen.managers.uploads import UploadFileAttributes + +from box_sdk_gen.managers.uploads import UploadFileAttributesParentField + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.managers.uploads import UploadFileVersionAttributes + +from box_sdk_gen.managers.uploads import UploadWithPreflightCheckAttributes + +from box_sdk_gen.managers.uploads import UploadWithPreflightCheckAttributesParentField + +from box_sdk_gen.schemas.upload_url import UploadUrl + +from box_sdk_gen.managers.uploads import PreflightFileUploadCheckParent + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import generate_byte_stream + +from box_sdk_gen.client import BoxClient + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def testUploadFileAndFileVersion(): + new_file_name: str = get_uuid() + file_content_stream: ByteStream = generate_byte_stream(1024 * 1024) + uploaded_files: Files = client.uploads.upload_file(UploadFileAttributes(name=new_file_name, parent=UploadFileAttributesParentField(id='0')), file_content_stream) + uploaded_file: FileFull = uploaded_files.entries[0] + assert uploaded_file.name == new_file_name + new_file_version_name: str = get_uuid() + new_file_content_stream: ByteStream = generate_byte_stream(1024 * 1024) + uploaded_files_version: Files = client.uploads.upload_file_version(uploaded_file.id, UploadFileVersionAttributes(name=new_file_version_name), new_file_content_stream) + new_file_version: FileFull = uploaded_files_version.entries[0] + assert new_file_version.name == new_file_version_name + client.files.delete_file_by_id(new_file_version.id) + +def testUploadFileWithPreflightCheck(): + new_file_name: str = get_uuid() + file_content_stream: ByteStream = generate_byte_stream(1024 * 1024) + with pytest.raises(Exception): + client.uploads.upload_with_preflight_check(UploadWithPreflightCheckAttributes(name=new_file_name, size=-1, parent=UploadWithPreflightCheckAttributesParentField(id='0')), file_content_stream) + upload_files_with_preflight: Files = client.uploads.upload_with_preflight_check(UploadWithPreflightCheckAttributes(name=new_file_name, size=1024 * 1024, parent=UploadWithPreflightCheckAttributesParentField(id='0')), file_content_stream) + file: FileFull = upload_files_with_preflight.entries[0] + assert file.name == new_file_name + assert file.size == 1024 * 1024 + with pytest.raises(Exception): + client.uploads.upload_with_preflight_check(UploadWithPreflightCheckAttributes(name=new_file_name, size=1024 * 1024, parent=UploadWithPreflightCheckAttributesParentField(id='0')), file_content_stream) + client.files.delete_file_by_id(file.id) + +def testPreflightCheck(): + new_file_name: str = get_uuid() + preflight_check_result: UploadUrl = client.uploads.preflight_file_upload_check(name=new_file_name, size=1024 * 1024, parent=PreflightFileUploadCheckParent(id='0')) + assert not preflight_check_result.upload_url == '' \ No newline at end of file diff --git a/test/test_gen/user_collaborations.py b/test/test_gen/user_collaborations.py new file mode 100644 index 000000000..d234097ab --- /dev/null +++ b/test/test_gen/user_collaborations.py @@ -0,0 +1,92 @@ +from box_sdk_gen.internal.utils import to_string + +from typing import Optional + +import pytest + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.user_full import UserFull + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.schemas.collaboration import Collaboration + +from box_sdk_gen.managers.user_collaborations import CreateCollaborationItem + +from box_sdk_gen.managers.user_collaborations import CreateCollaborationItemTypeField + +from box_sdk_gen.managers.user_collaborations import CreateCollaborationAccessibleBy + +from box_sdk_gen.managers.user_collaborations import CreateCollaborationAccessibleByTypeField + +from box_sdk_gen.managers.user_collaborations import CreateCollaborationRole + +from box_sdk_gen.managers.user_collaborations import UpdateCollaborationByIdRole + +from box_sdk_gen.schemas.collaborations import Collaborations + +from box_sdk_gen.internal.utils import get_uuid + +from test.commons import get_default_client + +from test.commons import create_new_folder + +client: BoxClient = get_default_client() + +def testUserCollaborations(): + user_name: str = get_uuid() + user_login: str = ''.join([get_uuid(), '@gmail.com']) + user: UserFull = client.users.create_user(user_name, login=user_login, is_platform_access_only=True) + folder: FolderFull = create_new_folder() + collaboration: Collaboration = client.user_collaborations.create_collaboration(CreateCollaborationItem(type=CreateCollaborationItemTypeField.FOLDER, id=folder.id), CreateCollaborationAccessibleBy(type=CreateCollaborationAccessibleByTypeField.USER, id=user.id), CreateCollaborationRole.EDITOR) + assert to_string(collaboration.role) == 'editor' + collaboration_id: str = collaboration.id + collaboration_from_api: Collaboration = client.user_collaborations.get_collaboration_by_id(collaboration_id) + assert collaboration_id == collaboration_from_api.id + assert to_string(collaboration_from_api.status) == 'accepted' + assert to_string(collaboration_from_api.type) == 'collaboration' + assert collaboration_from_api.invite_email == None + updated_collaboration: Optional[Collaboration] = client.user_collaborations.update_collaboration_by_id(collaboration_id, UpdateCollaborationByIdRole.VIEWER) + assert to_string(updated_collaboration.role) == 'viewer' + client.user_collaborations.delete_collaboration_by_id(collaboration_id) + with pytest.raises(Exception): + client.user_collaborations.get_collaboration_by_id(collaboration_id) + client.folders.delete_folder_by_id(folder.id) + client.users.delete_user_by_id(user.id) + +def testConvertingUserCollaborationToOwnership(): + user_name: str = get_uuid() + user_login: str = ''.join([get_uuid(), '@gmail.com']) + user: UserFull = client.users.create_user(user_name, login=user_login, is_platform_access_only=True) + folder: FolderFull = create_new_folder() + collaboration: Collaboration = client.user_collaborations.create_collaboration(CreateCollaborationItem(type=CreateCollaborationItemTypeField.FOLDER, id=folder.id), CreateCollaborationAccessibleBy(type=CreateCollaborationAccessibleByTypeField.USER, id=user.id), CreateCollaborationRole.EDITOR) + assert to_string(collaboration.role) == 'editor' + owner_collaboration: Optional[Collaboration] = client.user_collaborations.update_collaboration_by_id(collaboration.id, UpdateCollaborationByIdRole.OWNER) + assert owner_collaboration == None + folder_collaborations: Collaborations = client.list_collaborations.get_folder_collaborations(folder.id) + folder_collaboration: Collaboration = folder_collaborations.entries[0] + client.user_collaborations.delete_collaboration_by_id(folder_collaboration.id) + user_client: BoxClient = client.with_as_user_header(user.id) + user_client.folders.delete_folder_by_id(folder.id) + user_client.trashed_folders.delete_trashed_folder_by_id(folder.id) + client.users.delete_user_by_id(user.id) + +def testExternalUserCollaborations(): + user_name: str = get_uuid() + user_login: str = ''.join([get_uuid(), '@boxdemo.com']) + folder: FolderFull = create_new_folder() + collaboration: Collaboration = client.user_collaborations.create_collaboration(CreateCollaborationItem(type=CreateCollaborationItemTypeField.FOLDER, id=folder.id), CreateCollaborationAccessibleBy(type=CreateCollaborationAccessibleByTypeField.USER, login=user_login), CreateCollaborationRole.EDITOR) + assert to_string(collaboration.role) == 'editor' + collaboration_id: str = collaboration.id + collaboration_from_api: Collaboration = client.user_collaborations.get_collaboration_by_id(collaboration_id) + assert collaboration_id == collaboration_from_api.id + assert to_string(collaboration_from_api.status) == 'pending' + assert to_string(collaboration_from_api.type) == 'collaboration' + assert collaboration_from_api.invite_email == user_login + updated_collaboration: Optional[Collaboration] = client.user_collaborations.update_collaboration_by_id(collaboration_id, UpdateCollaborationByIdRole.VIEWER) + assert to_string(updated_collaboration.role) == 'viewer' + client.user_collaborations.delete_collaboration_by_id(collaboration_id) + with pytest.raises(Exception): + client.user_collaborations.get_collaboration_by_id(collaboration_id) + client.folders.delete_folder_by_id(folder.id) \ No newline at end of file diff --git a/test/test_gen/users.py b/test/test_gen/users.py new file mode 100644 index 000000000..74f598b49 --- /dev/null +++ b/test/test_gen/users.py @@ -0,0 +1,35 @@ +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.users import Users + +from box_sdk_gen.schemas.user_full import UserFull + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import create_null + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def test_get_users(): + users: Users = client.users.get_users() + assert users.total_count >= 0 + +def test_get_user_me(): + current_user: UserFull = client.users.get_user_me() + assert to_string(current_user.type) == 'user' + +def test_create_update_get_delete_user(): + user_name: str = get_uuid() + user_login: str = ''.join([get_uuid(), '@gmail.com']) + user: UserFull = client.users.create_user(user_name, login=user_login, is_platform_access_only=True) + assert user.name == user_name + user_by_id: UserFull = client.users.get_user_by_id(user.id) + assert user_by_id.id == user.id + updated_user_name: str = get_uuid() + updated_user: UserFull = client.users.update_user_by_id(user.id, name=updated_user_name) + assert updated_user.name == updated_user_name + client.users.delete_user_by_id(user.id) \ No newline at end of file diff --git a/test/test_gen/webhooks.py b/test/test_gen/webhooks.py new file mode 100644 index 000000000..4974fc2df --- /dev/null +++ b/test/test_gen/webhooks.py @@ -0,0 +1,98 @@ +from box_sdk_gen.internal.utils import to_string + +import pytest + +from typing import Dict + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.managers.folders import CreateFolderParent + +from box_sdk_gen.schemas.webhook import Webhook + +from box_sdk_gen.managers.webhooks import CreateWebhookTarget + +from box_sdk_gen.managers.webhooks import CreateWebhookTargetTypeField + +from box_sdk_gen.managers.webhooks import CreateWebhookTriggers + +from box_sdk_gen.schemas.webhooks import Webhooks + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import date_time_to_string + +from box_sdk_gen.internal.utils import epoch_seconds_to_date_time + +from box_sdk_gen.internal.utils import get_epoch_time_in_seconds + +from box_sdk_gen.internal.utils import compute_webhook_signature + +from box_sdk_gen.managers.webhooks import WebhooksManager + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def testWebhooksCRUD(): + folder: FolderFull = client.folders.create_folder(get_uuid(), CreateFolderParent(id='0')) + webhook: Webhook = client.webhooks.create_webhook(CreateWebhookTarget(id=folder.id, type=CreateWebhookTargetTypeField.FOLDER), 'https://example.com/new-webhook', [CreateWebhookTriggers.FILE_UPLOADED]) + assert webhook.target.id == folder.id + assert to_string(webhook.target.type) == 'folder' + assert len(webhook.triggers) == len(['FILE.UPLOADED']) + assert webhook.address == 'https://example.com/new-webhook' + webhooks: Webhooks = client.webhooks.get_webhooks() + assert len(webhooks.entries) > 0 + webhook_from_api: Webhook = client.webhooks.get_webhook_by_id(webhook.id) + assert webhook.id == webhook_from_api.id + assert webhook.target.id == webhook_from_api.target.id + assert webhook.address == webhook_from_api.address + updated_webhook: Webhook = client.webhooks.update_webhook_by_id(webhook.id, address='https://example.com/updated-webhook') + assert updated_webhook.id == webhook.id + assert updated_webhook.address == 'https://example.com/updated-webhook' + client.webhooks.delete_webhook_by_id(webhook.id) + with pytest.raises(Exception): + client.webhooks.delete_webhook_by_id(webhook.id) + client.folders.delete_folder_by_id(folder.id) + +def testWebhookValidation(): + primary_key: str = 'SamplePrimaryKey' + secondary_key: str = 'SampleSecondaryKey' + incorrect_key: str = 'IncorrectKey' + body: str = '{"type":"webhook_event","webhook":{"id":"1234567890"},"trigger":"FILE.UPLOADED","source":{"id":"1234567890","type":"file","name":"Test.txt"}}' + body_with_japanese: str = '{"webhook":{"id":"1234567890"},"trigger":"FILE.UPLOADED","source":{"id":"1234567890","type":"file","name":"スクリーンショット 2020-08-05.txt"}}' + body_with_emoji: str = '{"webhook":{"id":"1234567890"},"trigger":"FILE.UPLOADED","source":{"id":"1234567890","type":"file","name":"😀 2020-08-05.txt"}}' + body_with_carriage_return: str = '{"webhook":{"id":"1234567890"},"trigger":"FILE.UPLOADED","source":{"id":"1234567890","type":"file","name":"test \r"}}' + headers: Dict[str, str] = {'box-delivery-id': 'f96bb54b-ee16-4fc5-aa65-8c2d9e5b546f', 'box-delivery-timestamp': '2020-01-01T00:00:00-07:00', 'box-signature-algorithm': 'HmacSHA256', 'box-signature-primary': '6TfeAW3A1PASkgboxxA5yqHNKOwFyMWuEXny/FPD5hI=', 'box-signature-secondary': 'v+1CD1Jdo3muIcbpv5lxxgPglOqMfsNHPV899xWYydo=', 'box-signature-version': '1'} + headers_with_japanese: Dict = {**headers, 'box-signature-primary': 'LV2uCu+5NJtIHrCXDYgZ0v/PP5THGRuegw3RtdnEyuE='} + headers_with_emoji: Dict = {**headers, 'box-signature-primary': 'xF/SDZosX4le+v4A0Qn59sZhuD1RqY5KRUKzVMSbh0E='} + headers_with_carriage_return: Dict = {**headers, 'box-signature-primary': 'SVkbKgy3dEEf2PbbzpNu2lDZS7zZ/aboU7HOZgBGrJk='} + current_datetime: str = date_time_to_string(epoch_seconds_to_date_time(get_epoch_time_in_seconds())) + future_datetime: str = date_time_to_string(epoch_seconds_to_date_time(get_epoch_time_in_seconds() + 1200)) + past_datetime: str = date_time_to_string(epoch_seconds_to_date_time(get_epoch_time_in_seconds() - 1200)) + headers_with_correct_datetime: Dict = {**headers, 'box-delivery-timestamp': current_datetime, 'box-signature-primary': compute_webhook_signature(body, {**headers, 'box-delivery-timestamp': current_datetime}, primary_key), 'box-signature-secondary': compute_webhook_signature(body, {**headers, 'box-delivery-timestamp': current_datetime}, secondary_key)} + headers_with_japanese_with_correct_datetime: Dict = {**headers_with_japanese, 'box-delivery-timestamp': current_datetime, 'box-signature-primary': compute_webhook_signature(body_with_japanese, {**headers_with_japanese, 'box-delivery-timestamp': current_datetime}, primary_key), 'box-signature-secondary': compute_webhook_signature(body_with_japanese, {**headers_with_japanese, 'box-delivery-timestamp': current_datetime}, secondary_key)} + headers_with_future_datetime: Dict = {**headers, 'box-delivery-timestamp': future_datetime, 'box-signature-primary': compute_webhook_signature(body, {**headers, 'box-delivery-timestamp': future_datetime}, primary_key), 'box-signature-secondary': compute_webhook_signature(body, {**headers, 'box-delivery-timestamp': future_datetime}, secondary_key)} + headers_with_past_datetime: Dict = {**headers, 'box-delivery-timestamp': past_datetime, 'box-signature-primary': compute_webhook_signature(body, {**headers, 'box-delivery-timestamp': past_datetime}, primary_key), 'box-signature-secondary': compute_webhook_signature(body, {**headers, 'box-delivery-timestamp': past_datetime}, secondary_key)} + headers_with_wrong_signature_version: Dict = {**headers, 'box-signature-version': '2'} + headers_with_wrong_signature_algorithm: Dict = {**headers, 'box-signature-algorithm': 'HmacSHA1'} + assert compute_webhook_signature(body, headers, primary_key) == headers.get('box-signature-primary') + assert compute_webhook_signature(body, headers, secondary_key) == headers.get('box-signature-secondary') + assert not compute_webhook_signature(body, headers, incorrect_key) == headers.get('box-signature-primary') + assert compute_webhook_signature(body_with_japanese, headers_with_japanese, primary_key) == headers_with_japanese.get('box-signature-primary') + assert compute_webhook_signature(body_with_emoji, headers_with_emoji, primary_key) == headers_with_emoji.get('box-signature-primary') + assert compute_webhook_signature(body_with_carriage_return, headers_with_carriage_return, primary_key) == headers_with_carriage_return.get('box-signature-primary') + assert WebhooksManager.validate_message(body, headers_with_correct_datetime, primary_key, secondary_key=secondary_key) + assert WebhooksManager.validate_message(body, headers_with_correct_datetime, primary_key, secondary_key=incorrect_key) + assert WebhooksManager.validate_message(body, headers_with_correct_datetime, incorrect_key, secondary_key=secondary_key) + assert WebhooksManager.validate_message(body, headers_with_correct_datetime, incorrect_key, secondary_key=incorrect_key) == False + assert WebhooksManager.validate_message(body, headers_with_future_datetime, primary_key, secondary_key=secondary_key) == False + assert WebhooksManager.validate_message(body, headers_with_past_datetime, primary_key, secondary_key=secondary_key) == False + assert WebhooksManager.validate_message(body, headers_with_wrong_signature_version, primary_key, secondary_key=secondary_key) == False + assert WebhooksManager.validate_message(body, headers_with_wrong_signature_algorithm, primary_key, secondary_key=secondary_key) == False + assert WebhooksManager.validate_message(body_with_japanese, headers_with_japanese_with_correct_datetime, primary_key, secondary_key=secondary_key) + assert WebhooksManager.validate_message(body_with_japanese, headers_with_japanese_with_correct_datetime, primary_key, secondary_key=incorrect_key) + assert WebhooksManager.validate_message(body_with_japanese, headers_with_japanese_with_correct_datetime, incorrect_key, secondary_key=secondary_key) + assert WebhooksManager.validate_message(body_with_japanese, headers_with_japanese, primary_key, secondary_key=secondary_key) == False \ No newline at end of file diff --git a/test/test_gen/weblinks.py b/test/test_gen/weblinks.py new file mode 100644 index 000000000..e09b0216f --- /dev/null +++ b/test/test_gen/weblinks.py @@ -0,0 +1,41 @@ +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.schemas.web_link import WebLink + +from box_sdk_gen.managers.web_links import CreateWebLinkParent + +from box_sdk_gen.managers.web_links import UpdateWebLinkByIdSharedLink + +from box_sdk_gen.managers.web_links import UpdateWebLinkByIdSharedLinkAccessField + +from box_sdk_gen.internal.utils import get_uuid + +from test.commons import get_default_client + +client: BoxClient = get_default_client() + +def test_createGetDeleteWeblink(): + url: str = 'https://www.box.com' + parent: FolderFull = client.folders.get_folder_by_id('0') + name: str = get_uuid() + description: str = 'Weblink description' + password: str = 'super-secret-password' + weblink: WebLink = client.web_links.create_web_link(url, CreateWebLinkParent(id=parent.id), name=name, description=description) + assert weblink.url == url + assert weblink.parent.id == parent.id + assert weblink.name == name + assert weblink.description == description + weblink_by_id: WebLink = client.web_links.get_web_link_by_id(weblink.id) + assert weblink_by_id.id == weblink.id + assert weblink_by_id.url == url + updated_name: str = get_uuid() + updated_weblink: WebLink = client.web_links.update_web_link_by_id(weblink.id, name=updated_name, shared_link=UpdateWebLinkByIdSharedLink(access=UpdateWebLinkByIdSharedLinkAccessField.OPEN, password=password)) + assert updated_weblink.name == updated_name + assert to_string(updated_weblink.shared_link.access) == 'open' + client.web_links.delete_web_link_by_id(weblink.id) + deleted_weblink: WebLink = client.web_links.get_web_link_by_id(weblink.id) + assert to_string(deleted_weblink.item_status) == 'trashed' \ No newline at end of file diff --git a/test/test_gen/workflows.py b/test/test_gen/workflows.py new file mode 100644 index 000000000..973647739 --- /dev/null +++ b/test/test_gen/workflows.py @@ -0,0 +1,59 @@ +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.files import Files + +from box_sdk_gen.managers.uploads import UploadFileAttributes + +from box_sdk_gen.managers.uploads import UploadFileAttributesParentField + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.workflows import Workflows + +from box_sdk_gen.schemas.workflow import Workflow + +from box_sdk_gen.managers.workflows import StartWorkflowType + +from box_sdk_gen.managers.workflows import StartWorkflowFlow + +from box_sdk_gen.managers.workflows import StartWorkflowFiles + +from box_sdk_gen.managers.workflows import StartWorkflowFilesTypeField + +from box_sdk_gen.managers.workflows import StartWorkflowFolder + +from box_sdk_gen.managers.workflows import StartWorkflowFolderTypeField + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import get_env_var + +from box_sdk_gen.internal.utils import generate_byte_stream + +from test.commons import get_default_client + +from test.commons import upload_new_file + +from test.commons import get_default_client_with_user_subject + +client: BoxClient = get_default_client() + +def testWorkflows(): + admin_client: BoxClient = get_default_client_with_user_subject(get_env_var('USER_ID')) + workflow_folder_id: str = get_env_var('WORKFLOW_FOLDER_ID') + uploaded_files: Files = admin_client.uploads.upload_file(UploadFileAttributes(name=get_uuid(), parent=UploadFileAttributesParentField(id=workflow_folder_id)), generate_byte_stream(1024 * 1024)) + file: FileFull = uploaded_files.entries[0] + workflow_file_id: str = file.id + workflows: Workflows = admin_client.workflows.get_workflows(workflow_folder_id) + assert len(workflows.entries) == 1 + workflow_to_run: Workflow = workflows.entries[0] + assert to_string(workflow_to_run.type) == 'workflow' + assert workflow_to_run.is_enabled == True + assert to_string(workflow_to_run.flows[0].type) == 'flow' + assert to_string(workflow_to_run.flows[0].trigger.type) == 'trigger' + assert to_string(workflow_to_run.flows[0].trigger.trigger_type) == 'WORKFLOW_MANUAL_START' + assert to_string(workflow_to_run.flows[0].outcomes[0].action_type) == 'delete_file' + assert to_string(workflow_to_run.flows[0].outcomes[0].type) == 'outcome' + admin_client.workflows.start_workflow(workflow_to_run.id, StartWorkflowFlow(type='flow', id=workflow_to_run.flows[0].id), [StartWorkflowFiles(type=StartWorkflowFilesTypeField.FILE, id=workflow_file_id)], StartWorkflowFolder(type=StartWorkflowFolderTypeField.FOLDER, id=workflow_folder_id), type=StartWorkflowType.WORKFLOW_PARAMETERS) \ No newline at end of file diff --git a/test/test_gen/zip_downloads.py b/test/test_gen/zip_downloads.py new file mode 100644 index 000000000..5deeb0766 --- /dev/null +++ b/test/test_gen/zip_downloads.py @@ -0,0 +1,65 @@ +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.client import BoxClient + +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 ByteStream + +from box_sdk_gen.managers.zip_downloads import DownloadZipItems + +from box_sdk_gen.managers.zip_downloads import DownloadZipItemsTypeField + +from box_sdk_gen.schemas.zip_download import ZipDownload + +from box_sdk_gen.managers.zip_downloads import CreateZipDownloadItems + +from box_sdk_gen.schemas.zip_download_status import ZipDownloadStatus + +from test.commons import get_default_client + +from test.commons import upload_new_file + +from test.commons import create_new_folder + +from box_sdk_gen.internal.utils import buffer_equals + +from box_sdk_gen.internal.utils import read_byte_stream + +from box_sdk_gen.internal.utils import generate_byte_buffer + +from box_sdk_gen.internal.utils import date_time_to_string + +client: BoxClient = get_default_client() + +def testZipDownload(): + file_1: FileFull = upload_new_file() + file_2: FileFull = upload_new_file() + folder_1: FolderFull = create_new_folder() + zip_stream: ByteStream = client.zip_downloads.download_zip([DownloadZipItems(id=file_1.id, type=DownloadZipItemsTypeField.FILE), DownloadZipItems(id=file_2.id, type=DownloadZipItemsTypeField.FILE), DownloadZipItems(id=folder_1.id, type=DownloadZipItemsTypeField.FOLDER)], download_file_name='zip') + assert buffer_equals(read_byte_stream(zip_stream), generate_byte_buffer(10)) == False + client.files.delete_file_by_id(file_1.id) + client.files.delete_file_by_id(file_2.id) + client.folders.delete_folder_by_id(folder_1.id) + +def testManualZipDownloadAndCheckStatus(): + file_1: FileFull = upload_new_file() + file_2: FileFull = upload_new_file() + folder_1: FolderFull = create_new_folder() + zip_download: ZipDownload = client.zip_downloads.create_zip_download([CreateZipDownloadItems(id=file_1.id, type=DownloadZipItemsTypeField.FILE), CreateZipDownloadItems(id=file_2.id, type=DownloadZipItemsTypeField.FILE), CreateZipDownloadItems(id=folder_1.id, type=DownloadZipItemsTypeField.FOLDER)], download_file_name='zip') + assert not zip_download.download_url == '' + assert not zip_download.status_url == '' + assert not date_time_to_string(zip_download.expires_at) == '' + zip_stream: ByteStream = client.zip_downloads.get_zip_download_content(zip_download.download_url) + assert buffer_equals(read_byte_stream(zip_stream), generate_byte_buffer(10)) == False + zip_download_status: ZipDownloadStatus = client.zip_downloads.get_zip_download_status(zip_download.status_url) + assert zip_download_status.total_file_count == 2 + assert zip_download_status.downloaded_file_count == 2 + assert zip_download_status.skipped_file_count == 0 + assert zip_download_status.skipped_folder_count == 0 + assert not to_string(zip_download_status.state) == 'failed' + client.files.delete_file_by_id(file_1.id) + client.files.delete_file_by_id(file_2.id) + client.folders.delete_folder_by_id(folder_1.id) \ No newline at end of file diff --git a/tox.ini b/tox.ini index 182803998..51c71ae4a 100644 --- a/tox.ini +++ b/tox.ini @@ -14,7 +14,8 @@ envlist = py310, py311, coverage, - integration-tests + integration-tests, + integration-tests-gen [gh-actions] python = @@ -81,8 +82,15 @@ deps = twine [testenv:integration-tests] -passenv = JWT_CONFIG_BASE_64 ADMIN_USER_ID +passenv = JWT_CONFIG_BASE_64,ADMIN_USER_ID commands = pytest {toxinidir}/test/integration_new {posargs} --disable-pytest-warnings deps = -rrequirements-test.txt + +[testenv:integration-tests-gen] +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,APP_ITEM_SHARED_LINK,SLACK_AUTOMATION_USER_ID,SLACK_ORG_ID,SLACK_PARTNER_ITEM_ID +commands = + pytest {toxinidir}/test/test_gen {posargs} --disable-pytest-warnings --reruns 2 +deps = -rrequirements-test.txt +allowlist_externals = pytest