diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d396980..fa41c1f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,7 +3,7 @@ name: ci on: [push] jobs: compile: - runs-on: ubuntu-24.04 + runs-on: ubuntu-20.04 steps: - name: Checkout repo uses: actions/checkout@v3 @@ -19,7 +19,7 @@ jobs: - name: Compile run: poetry run mypy . test: - runs-on: ubuntu-24.04 + runs-on: ubuntu-20.04 steps: - name: Checkout repo uses: actions/checkout@v3 @@ -33,15 +33,13 @@ jobs: - name: Install dependencies run: poetry install - - name: Install Fern - run: npm install -g fern-api - name: Test - run: fern test --command "poetry run pytest -rP ./tests/custom/" + run: poetry run pytest -rP . publish: needs: [compile, test] if: github.event_name == 'push' && contains(github.ref, 'refs/tags/') - runs-on: ubuntu-24.04 + runs-on: ubuntu-20.04 steps: - name: Checkout repo uses: actions/checkout@v3 diff --git a/.mock/definition/__package__.yml b/.mock/definition/__package__.yml deleted file mode 100644 index db84636..0000000 --- a/.mock/definition/__package__.yml +++ /dev/null @@ -1,2894 +0,0 @@ -errors: - UnauthorizedError: - status-code: 401 - type: Error - docs: >- - Provided access token is invalid or does not have access to requested - resource - examples: - - value: - code: not_authorized - message: Request not authorized - ForbiddenError: - status-code: 403 - type: unknown - docs: Provided access token is valid, but is missing the required scopes. - examples: - - value: - code: missing_scopes - message: >- - OAuthForbidden: You are missing the following scopes - - components:write - - value: - key: value - - value: - code: forbidden - message: User is not authorized to perform this action - BadRequestError: - status-code: 400 - type: unknown - docs: Request body was incorrectly formatted. - examples: - - value: - code: bad_request - message: 'Bad Request: Request is malformed' - - value: - key: value - - value: - code: validation_error - message: 'Validation Error: Provided ID is invalid' - NotFoundError: - status-code: 404 - type: Error - docs: Requested resource not found - examples: - - value: - code: resource_not_found - message: 'Requested resource not found: The site cannot be found' - TooManyRequestsError: - status-code: 429 - type: Error - docs: >- - The rate limit of the provided access_token has been reached. Please have - your application respect the X-RateLimit-Remaining header we include on - API responses. - examples: - - value: - code: too_many_requests - message: Too many requests - InternalServerError: - status-code: 500 - type: Error - docs: We had a problem with our server. Try again later. - examples: - - value: - code: internal_error - message: An Internal Error occurred - ConflictError: - status-code: 409 - type: unknown - docs: Site is published to multiple domains at different times - examples: - - value: - message: '''Site is published to multiple domains at different times' - - value: - code: custom_code_max_registered_scripts - message: The maximum number of registered scripts has been reached. - - value: - code: forms_require_republish - message: To access this feature, the site needs to be republished. - - value: - key: value - - value: - code: ecommerce_not_enabled - message: Ecommerce is not yet initialized -types: - ForbiddenErrorBody: - discriminated: false - union: - - InvalidScopes - - UsersNotEnabled - source: - openapi: ../../../openapi/referenced-specs/v2.yml - BadRequestErrorBody: - discriminated: false - union: - - InvalidDomain - - NoDomains - source: - openapi: ../../../openapi/referenced-specs/v2.yml - ConflictErrorBody: - discriminated: false - union: - - DuplicateUserEmail - - UserLimitReached - source: - openapi: ../../../openapi/referenced-specs/v2.yml - AuthorizedUser: - properties: - id: - type: optional - docs: The unique ID of the user - email: - type: optional - docs: The user's email address - validation: - format: email - firstName: - type: optional - docs: The user's first name - lastName: - type: optional - docs: The user's last name - source: - openapi: ../../../openapi/referenced-specs/v2.yml - ErrorCode: - enum: - - bad_request - - collection_not_found - - conflict - - duplicate_collection - - duplicate_user_email - - ecommerce_not_enabled - - forbidden - - forms_require_republish - - incompatible_webhook_filter - - internal_error - - invalid_auth_version - - invalid_credentials - - invalid_domain - - invalid_user_email - - item_not_found - - missing_scopes - - no_domains - - not_authorized - - not_enterprise_plan_site - - not_enterprise_plan_workspace - - order_not_found - - resource_not_found - - too_many_requests - - unsupported_version - - unsupported_webhook_trigger_type - - user_limit_reached - - user_not_found - - users_not_enabled - - validation_error - docs: Error code - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - Error: - properties: - code: - type: optional - docs: Error code - message: - type: optional - docs: Error message - externalReference: - type: optional - docs: Link to more information - details: - type: optional> - docs: Array of errors - source: - openapi: ../../../openapi/referenced-specs/v2.yml - Application: unknown - AuthorizationAuthorizationAuthorizedTo: - properties: - siteIds: - type: optional> - docs: Array of Sites this app is authorized to - workspaceIds: - type: optional> - docs: Array of Workspaces this app is authorized to - userIds: - type: optional> - docs: Array of Users this app is authorized to - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - AuthorizationAuthorization: - docs: The Authorization object - properties: - id: - type: optional - docs: The unique ID of the Authorization instance - createdOn: - type: optional - docs: The date the Authorization was created - lastUsed: - type: optional - docs: The date the Authorization was last used - grantType: - type: optional - docs: The grant type of the Authorization - rateLimit: - type: optional - docs: The default rate limit for the Authorization (requests/min) - scope: - type: optional - docs: Comma separted list of OAuth scopes corresponding to the Authorization - authorizedTo: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - Authorization: - properties: - authorization: - type: optional - docs: The Authorization object - application: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - Domain: - properties: - id: - type: string - docs: Unique identifier for the Domain - url: - type: optional - docs: The registered Domain name - lastPublished: - type: optional - docs: The date the custom domain was last published to - source: - openapi: ../../../openapi/referenced-specs/v2.yml - Locale: - properties: - id: - type: optional - docs: The unique identifier for the locale. - cmsLocaleId: - type: optional - docs: A CMS-specific identifier for the locale. - enabled: - type: optional - docs: Indicates if the locale is enabled. - displayName: - type: optional - docs: The display name of the locale, typically in English. - displayImageId: - type: optional - docs: An optional ID for an image associated with the locale, nullable. - redirect: - type: optional - docs: Determines if requests should redirect to the locale's subdirectory. - subdirectory: - type: optional - docs: The subdirectory path for the locale, used in URLs. - tag: - type: optional - docs: >- - A tag or code representing the locale, often following a standard - format like 'en-US'. - source: - openapi: ../../../openapi/referenced-specs/v2.yml - Locales: - properties: - primary: - type: optional - docs: The primary locale for the site or application. - secondary: - type: optional> - docs: A list of secondary locales available for the site or application. - source: - openapi: ../../../openapi/referenced-specs/v2.yml - SiteDataCollectionType: - enum: - - always - - optOut - - disabled - docs: The type of data collection enabled for the site. - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - Site: - properties: - id: - type: string - docs: Unique identifier for the Site - workspaceId: - type: optional - docs: Unique identifier for the Workspace - createdOn: - type: optional - docs: Date the Site was created - displayName: - type: optional - docs: Name given to Site - shortName: - type: optional - docs: Slugified version of name - lastPublished: - type: optional - docs: Date the Site was last published - lastUpdated: - type: optional - docs: Date the Site was last updated - previewUrl: - type: optional - docs: URL of a generated image for the given Site - validation: - format: uri - timeZone: - type: optional - docs: Site timezone set under Site Settings - parentFolderId: - type: optional - docs: The ID of the parent folder the Site exists in - customDomains: optional> - locales: optional - dataCollectionEnabled: - type: optional - docs: Indicates if data collection is enabled for the site. - dataCollectionType: - type: optional - docs: The type of data collection enabled for the site. - source: - openapi: ../../../openapi/referenced-specs/v2.yml - InvalidScopes: unknown - NotEnterprisePlanWorkspace: unknown - Sites: - properties: - sites: optional> - source: - openapi: ../../../openapi/referenced-specs/v2.yml - NotEnterprisePlanSite: unknown - Domains: - properties: - customDomains: optional> - source: - openapi: ../../../openapi/referenced-specs/v2.yml - InvalidDomain: unknown - NoDomains: unknown - Redirect: - docs: A single redirection rule, specifying a source URL and a destination URL. - properties: - id: - type: optional - docs: The ID of the specific redirect rule - fromUrl: - type: optional - docs: The source URL path that will be redirected. - toUrl: - type: optional - docs: The target URL path where the user or client will be redirected. - source: - openapi: ../../../openapi/referenced-specs/v2.yml - Pagination: - docs: Pagination object - properties: - limit: - type: optional - docs: The limit used for pagination - offset: - type: optional - docs: The offset used for pagination - total: - type: optional - docs: The total number of records - source: - openapi: ../../../openapi/referenced-specs/v2.yml - Redirects: - docs: Site redirects response - properties: - redirects: - type: optional> - docs: List of redirects for a given site - pagination: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - SitePlanId: - enum: - - value: hosting-basic-v3 - name: HostingBasicV3 - - value: hosting-cms-v3 - name: HostingCmsV3 - - value: hosting-business-v3 - name: HostingBusinessV3 - - value: hosting-ecommerce-standard-v2 - name: HostingEcommerceStandardV2 - - value: hosting-ecommerce-plus-v2 - name: HostingEcommercePlusV2 - - value: hosting-ecommerce-advanced-v2 - name: HostingEcommerceAdvancedV2 - - value: hosting-basic-v4 - name: HostingBasicV4 - - value: hosting-cms-v4 - name: HostingCmsV4 - - value: hosting-business-v4 - name: HostingBusinessV4 - - value: hosting-ecommerce-standard-v3 - name: HostingEcommerceStandardV3 - - value: hosting-ecommerce-plus-v3 - name: HostingEcommercePlusV3 - - value: hosting-ecommerce-advanced-v3 - name: HostingEcommerceAdvancedV3 - docs: ID of the hosting plan. - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - SitePlanName: - enum: - - value: Basic Hosting - name: BasicHosting - - value: CMS Hosting - name: CmsHosting - - value: Business Hosting - name: BusinessHosting - - value: ECommerce Standard Hosting - name: ECommerceStandardHosting - - value: ECommerce Plus Hosting - name: ECommercePlusHosting - - value: ECommerce Advanced Hosting - name: ECommerceAdvancedHosting - docs: Name of the hosting plan. - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - SitePlan: - properties: - id: - type: optional - docs: ID of the hosting plan. - name: - type: optional - docs: Name of the hosting plan. - pricingInfo: - type: optional - docs: URL for more information about Webflow hosting plan pricing. - source: - openapi: ../../../openapi/referenced-specs/v2.yml - SiteActivityLogItemEvent: - enum: - - styles_modified - - site_published - - ix2_modified_on_page - - page_dom_modified - - cms_item - - backup_created - - page_custom_code_modified - - symbols_modified - - variable_modified - - variables_modified - - cms_collection - - page_settings_modified - - page_settings_custom_code_modified - - ix2_modified_on_component - - ix2_modified_on_class - - site_custom_code_modified - - page_duplicated - - secondary_locale_page_content_modified - - page_renamed - - page_created - - page_deleted - - site_unpublished - - backup_restored - - locale_added - - branch_created - - locale_display_name_updated - - locale_subdirectory_updated - - branch_merged - - locale_tag_updated - - branch_deleted - - locale_enabled - - locale_removed - - locale_disabled - - library_shared - - library_unshared - - library_installed - - library_uninstalled - - library_update_shared - - library_update_accepted - - branch_review_created - - branch_review_approved - - branch_review_canceled - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - SiteActivityLogItemResourceOperation: - enum: - - CREATED - - MODIFIED - - PUBLISHED - - UNPUBLISHED - - DELETED - - GROUP_REORDERED - - GROUP_CREATED - - GROUP_DELETED - - REORDERED - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - SiteActivityLogItemUser: - properties: - id: optional - displayName: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - SiteActivityLogItem: - properties: - id: optional - createdOn: optional - lastUpdated: optional - event: optional - resourceOperation: optional - user: optional - resourceId: optional - resourceName: optional - newValue: optional - previousValue: optional - payload: optional> - source: - openapi: ../../../openapi/referenced-specs/v2.yml - SiteActivityLogResponse: - properties: - items: optional> - pagination: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - CollectionListArrayItem: - docs: A collection object - properties: - id: - type: string - docs: Unique identifier for a Collection - displayName: - type: optional - docs: Name given to the Collection - singularName: - type: optional - docs: >- - The name of one Item in Collection (e.g. ”Blog Post” if the Collection - is called “Blog Posts”) - slug: - type: optional - docs: Slug of Collection in Site URL structure - createdOn: - type: optional - docs: The date the collection was created - lastUpdated: - type: optional - docs: The date the collection was last updated - source: - openapi: ../../../openapi/referenced-specs/v2.yml - CollectionList: - properties: - collections: - type: optional> - docs: An array of Collections - source: - openapi: ../../../openapi/referenced-specs/v2.yml - FieldType: - enum: - - Color - - DateTime - - Email - - ExtFileRef - - Image - - Link - - MultiImage - - Number - - Phone - - PlainText - - RichText - - Switch - - Video - docs: Choose these appropriate field type for your collection data - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - Field: - docs: The details of a field in a collection - properties: - id: - type: string - docs: Unique identifier for a Field - isRequired: - type: boolean - docs: define whether a field is required in a collection - isEditable: - type: optional - docs: Define whether the field is editable - type: - type: FieldType - docs: Choose these appropriate field type for your collection data - slug: - type: optional - docs: >- - Slug of Field in Site URL structure. Slugs should be all lowercase - with no spaces. Any spaces will be converted to "-." - displayName: - type: string - docs: The name of a field - helpText: - type: optional - docs: Additional text to help anyone filling out this field - source: - openapi: ../../../openapi/referenced-specs/v2.yml - Collection: - docs: A collection object - properties: - id: - type: string - docs: Unique identifier for a Collection - displayName: - type: optional - docs: Name given to the Collection - singularName: - type: optional - docs: >- - The name of one Item in Collection (e.g. ”Blog Post” if the Collection - is called “Blog Posts”) - slug: - type: optional - docs: Slug of Collection in Site URL structure - createdOn: - type: optional - docs: The date the collection was created - lastUpdated: - type: optional - docs: The date the collection was last updated - fields: - docs: The list of fields in the Collection - type: list - source: - openapi: ../../../openapi/referenced-specs/v2.yml - CollectionItemFieldData: - properties: - name: - type: string - docs: Name of the Item - slug: - type: string - docs: >- - URL structure of the Item in your site. Note: Updates to an item slug - will break all links referencing the old slug. - extra-properties: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - CollectionItem: - docs: > - A Collection Item represents a single entry in your collection. Each item - includes: - - - - **System metadata** - Automatically managed fields like IDs and - timestamp
- - - **Status flags** - Controls for managing content state: `isDraft`, - `isArchived `
- - - **Content fields** - Stored in `fieldData`. Each item needs a `name` and - `slug`, and may include additional fields matching your collection's - schema definition. - properties: - id: - type: optional - docs: Unique identifier for the Item - cmsLocaleId: - type: optional - docs: Identifier for the locale of the CMS item - lastPublished: - type: optional - docs: The date the item was last published - lastUpdated: - type: optional - docs: The date the item was last updated - createdOn: - type: optional - docs: The date the item was created - isArchived: - type: optional - docs: Boolean determining if the Item is set to archived - default: false - isDraft: - type: optional - docs: Boolean determining if the Item is set to draft - default: false - fieldData: CollectionItemFieldData - source: - openapi: ../../../openapi/referenced-specs/v2.yml - CollectionItemListPagination: - properties: - limit: - type: optional - docs: The limit specified in the request - default: 100 - offset: - type: optional - docs: The offset specified for pagination - default: 0 - total: - type: optional - docs: Total number of items in the collection - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - CollectionItemList: - docs: Results from collection items list - properties: - items: - type: optional> - docs: List of Items within the collection - pagination: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - CollectionItemPostSingleFieldData: - properties: - name: - type: string - docs: Name of the Item - slug: - type: string - docs: >- - URL structure of the Item in your site. Note: Updates to an item slug - will break all links referencing the old slug. - extra-properties: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - CollectionItemPostSingle: - docs: > - A Collection Item represents a single entry in your collection. Each item - includes: - - - - **System metadata** - Automatically managed fields like IDs and - timestamp
- - - **Status flags** - Controls for managing content state: `isDraft`, - `isArchived `
- - - **Content fields** - Stored in `fieldData`. Each item needs a `name` and - `slug`, and may include additional fields matching your collection's - schema definition. - properties: - id: - type: optional - docs: Unique identifier for the Item - cmsLocaleId: - type: optional - docs: Identifier for the locale of the CMS item - lastPublished: - type: optional - docs: The date the item was last published - lastUpdated: - type: optional - docs: The date the item was last updated - createdOn: - type: optional - docs: The date the item was created - isArchived: - type: optional - docs: Boolean determining if the Item is in an archived state. - default: false - isDraft: - type: optional - docs: Boolean determining if the Item is in a draft state. - default: false - fieldData: CollectionItemPostSingleFieldData - source: - openapi: ../../../openapi/referenced-specs/v2.yml - CollectionItemWithIdInputFieldData: - properties: - name: - type: optional - docs: Name of the Item - slug: - type: optional - docs: >- - URL structure of the Item in your site. Note: Updates to an item slug - will break all links referencing the old slug. - extra-properties: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - CollectionItemWithIdInput: - docs: > - The fields that define the schema for a given Item are based on the - Collection that Item belongs to. Beyond the user defined fields, there are - a handful of additional fields that are automatically created for all - items - properties: - id: - type: string - docs: Unique identifier for the Item - cmsLocaleId: - type: optional - docs: Identifier for the locale of the CMS item - lastPublished: - type: optional - docs: The date the item was last published - lastUpdated: - type: optional - docs: The date the item was last updated - createdOn: - type: optional - docs: The date the item was created - isArchived: - type: optional - docs: Boolean determining if the Item is set to archived - isDraft: - type: optional - docs: Boolean determining if the Item is set to draft - fieldData: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - CollectionItemListNoPagination: - docs: Results from collection items list - properties: - items: - type: optional> - docs: List of Items within the collection - source: - openapi: ../../../openapi/referenced-specs/v2.yml - BulkCollectionItemFieldData: - properties: - name: - type: optional - docs: Name of the Item - slug: - type: optional - docs: >- - URL structure of the Item in your site. Note: Updates to an item slug - will break all links referencing the old slug. - extra-properties: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - BulkCollectionItem: - docs: > - The fields that define the schema for a given Item are based on the - Collection that Item belongs to. Beyond the user defined fields, there are - a handful of additional fields that are automatically created for all - items - properties: - id: - type: string - docs: Unique identifier for the Item - cmsLocaleIds: - type: optional> - docs: Array of identifiers for the locales where the item will be created - lastPublished: - type: optional - docs: The date the item was last published - lastUpdated: - type: optional - docs: The date the item was last updated - createdOn: - type: optional - docs: The date the item was created - isArchived: - type: optional - docs: Boolean determining if the Item is set to archived - default: false - isDraft: - type: optional - docs: Boolean determining if the Item is set to draft - default: false - fieldData: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - CollectionItemPatchSingleFieldData: - properties: - name: - type: optional - docs: Name of the Item - slug: - type: optional - docs: >- - URL structure of the Item in your site. Note: Updates to an item slug - will break all links referencing the old slug. - extra-properties: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - CollectionItemPatchSingle: - docs: > - The fields that define the schema for a given Item are based on the - Collection that Item belongs to. Beyond the user defined fields, there are - a handful of additional fields that are automatically created for all - items - properties: - id: - type: optional - docs: Unique identifier for the Item - cmsLocaleId: - type: optional - docs: Identifier for the locale of the CMS item - lastPublished: - type: optional - docs: The date the item was last published - lastUpdated: - type: optional - docs: The date the item was last updated - createdOn: - type: optional - docs: The date the item was created - isArchived: - type: optional - docs: Boolean determining if the Item is set to archived - isDraft: - type: optional - docs: Boolean determining if the Item is set to draft - fieldData: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - PageSeo: - docs: SEO-related fields for the Page - properties: - title: - type: optional - docs: The Page title shown in search engine results - description: - type: optional - docs: The Page description shown in search engine results - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - PageOpenGraph: - docs: Open Graph fields for the Page - properties: - title: - type: optional - docs: The title supplied to Open Graph annotations - titleCopied: - type: optional - docs: Indicates the Open Graph title was copied from the SEO title - default: true - description: - type: optional - docs: The description supplied to Open Graph annotations - descriptionCopied: - type: optional - docs: >- - Indicates the Open Graph description was copied from the SEO - description - default: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - Page: - docs: The Page object - properties: - id: - type: string - docs: Unique identifier for the Page - siteId: - type: optional - docs: Unique identifier for the Site - title: - type: optional - docs: Title of the Page - slug: - type: optional - docs: slug of the Page (derived from title) - parentId: - type: optional - docs: Identifier of the parent folder - collectionId: - type: optional - docs: >- - Unique identifier for a linked Collection, value will be null if the - Page is not part of a Collection. - createdOn: - type: optional - docs: The date the Page was created - lastUpdated: - type: optional - docs: The date the Page was most recently updated - archived: - type: optional - docs: Whether the Page has been archived - default: false - draft: - type: optional - docs: Whether the Page is a draft - default: false - canBranch: - type: optional - docs: >- - Indicates whether the Page supports [Page - Branching](https://university.webflow.com/lesson/page-branching) - default: false - isBranch: - type: optional - docs: >- - Indicates whether the Page is a Branch of another Page [Page - Branching](https://university.webflow.com/lesson/page-branching) - default: false - isMembersOnly: - type: optional - docs: >- - Indicates whether the Page is restricted by [Memberships - Controls](https://university.webflow.com/lesson/webflow-memberships-overview#how-to-manage-page-restrictions) - default: false - seo: - type: optional - docs: SEO-related fields for the Page - openGraph: - type: optional - docs: Open Graph fields for the Page - localeId: - type: optional - docs: Unique ID of the page locale - publishedPath: - type: optional - docs: Relative path of the published page URL - source: - openapi: ../../../openapi/referenced-specs/v2.yml - PageList: - docs: The Page object - properties: - pages: optional> - pagination: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - TextNodeText: - properties: - html: - type: optional - docs: The HTML content of the text node. - text: - type: optional - docs: The raw text content of the text node. - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - TextNode: - docs: > - Represents text content within the DOM. It contains both the raw text and - its HTML representation. Additional attributes can be associated with the - text for styling or other purposes. - properties: - id: - type: optional - docs: Node UUID - text: optional - attributes: - type: optional> - docs: The custom attributes of the node - source: - openapi: ../../../openapi/referenced-specs/v2.yml - ImageNodeImage: - properties: - alt: optional - assetId: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - ImageNode: - docs: > - Represents an image within the DOM. It contains details about the image, - such as its alternative text (alt) for accessibility and an asset - identifier for fetching the actual image resource. Additional attributes - can be associated with the image for styling or other purposes. - properties: - id: - type: optional - docs: Node UUID - image: optional - attributes: - type: optional> - docs: The custom attributes of the node - source: - openapi: ../../../openapi/referenced-specs/v2.yml - Text: - properties: - html: - type: optional - docs: The HTML content of the text node. - text: - type: optional - docs: The raw text content of the text node. - source: - openapi: ../../../openapi/referenced-specs/v2.yml - ComponentPropertyType: - enum: - - value: Plain Text - name: PlainText - - value: Rich Text - name: RichText - - value: Alt Text - name: AltText - docs: The type of the property. - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - ComponentProperty: - docs: > - Represents a property of a component instance in the DOM. A property - contains a list of both the raw text and the HTML representation, allowing - for flexibility in rendering and processing. Additional attributes can be - associated with the text for styling or other purposes. - properties: - propertyId: - type: optional - docs: The ID of the property. - type: - type: optional - docs: The type of the property. - label: - type: optional - docs: The label of the property in the UI. - text: - type: optional - docs: >- - Represents text content within the DOM. It contains both the raw text - and its HTML representation. - source: - openapi: ../../../openapi/referenced-specs/v2.yml - ComponentNode: - docs: > - Represents a component instance within the DOM. It contains details about - the component instance, such as its type and properties. - properties: - id: - type: optional - docs: Node UUID - componentId: - type: optional - docs: Component ID - propertyOverrides: - type: optional> - docs: List of component properties with overrides for a component instance. - source: - openapi: ../../../openapi/referenced-specs/v2.yml - Node: - discriminant: type - base-properties: {} - docs: > - A generic representation of a content element within the Document Object - Model (DOM). Each node has a unique identifier and a specific type that - determines its content structure and attributes. - union: - text: TextNode - image: ImageNode - component-instance: ComponentNode - source: - openapi: ../../../openapi/referenced-specs/v2.yml - Dom: - docs: > - The DOM (Document Object Model) schema represents the content structure of - a web page or component. It captures various content nodes along with - their associated attributes. Each node has a unique identifier and can be - of different types like text, image or component-instance. The schema also - provides pagination details for scenarios where the content nodes are too - many to be fetched in a single request. - properties: - pageId: - type: optional - docs: Page ID - nodes: optional> - pagination: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - TextNodeWrite: - docs: Update a text node - properties: - nodeId: - type: string - docs: Node UUID - text: - type: string - docs: >- - HTML content of the node, including the HTML tag. The HTML tags must - be the same as what's returned from the Get Content endpoint. - source: - openapi: ../../../openapi/referenced-specs/v2.yml - ComponentInstanceNodePropertyOverridesWritePropertyOverridesItem: - properties: - propertyId: - type: string - docs: The ID of the property. - text: - type: string - docs: > - The new string or HTML value used to override the component instance - property value. - - The provided value must be compatible with the type of the component - instance property. - - For example, attempting to override a single-line plain-text property - with a multi-line - - value will result in an error. - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - ComponentInstanceNodePropertyOverridesWrite: - docs: Update text property overrides of a component instance - properties: - nodeId: - type: string - docs: Node UUID - propertyOverrides: - docs: >- - A list of component instance properties to override within the - specified secondary locale. - type: list - source: - openapi: ../../../openapi/referenced-specs/v2.yml - Component: - docs: The Component object - properties: - id: - type: string - docs: Unique identifier for the Component - name: - type: optional - docs: Component Name - group: - type: optional - docs: The group that the component belongs to - description: - type: optional - docs: Component Description - readonly: - type: optional - docs: >- - Indicates whether the component is read-only. Components that cannot - be updated within this Site are set to readonly. Workspace Libraries - are a good example. - source: - openapi: ../../../openapi/referenced-specs/v2.yml - ComponentList: - docs: List of Components on a site. - properties: - components: optional> - pagination: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - ComponentDom: - docs: > - The Component DOM schema represents the content structure of a component. - Similar to Page DOM, it captures various content nodes and their - associated attributes, but specifically for a component's structure. Each - node has a unique identifier and can contain text, images, or nested - component instances. - properties: - componentId: - type: optional - docs: Component ID - nodes: optional> - pagination: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - ComponentProperties: - docs: > - The Component Properties schema represents a list of properties that store - text content. Each property has a unique identifier and can be of - different types like plain text or rich text. The schema also provides - pagination details for scenarios where there more properties than the - limit. - properties: - componentId: - type: optional - docs: Component ID - properties: optional> - pagination: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - ScriptApplyLocation: - enum: - - header - - footer - docs: >- - Location of the script, either in the header or footer of the published - site - default: header - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - ScriptApply: - properties: - id: - type: string - docs: ID of the registered custom code script - location: - type: ScriptApplyLocation - docs: >- - Location of the script, either in the header or footer of the - published site - default: header - version: - type: string - docs: Semantic Version String for the registered script *e.g. 0.0.1* - attributes: - type: optional> - docs: >- - Developer-specified key/value pairs to be applied as attributes to the - script - source: - openapi: ../../../openapi/referenced-specs/v2.yml - ScriptApplyList: - properties: - scripts: - type: optional> - docs: A list of scripts applied to a Site or a Page - lastUpdated: - type: optional - docs: Date when the Site's scripts were last updated - createdOn: - type: optional - docs: Date when the Site's scripts were created - source: - openapi: ../../../openapi/referenced-specs/v2.yml - CustomCodeHostedResponse: - docs: Registered custom code for application - properties: - id: - type: optional - docs: Human readable id, derived from the user-specified display name - canCopy: - type: optional - docs: >- - Define whether the script can be copied on site duplication and - transfer - default: false - displayName: - type: optional - docs: >- - User-facing name for the script. Must be between 1 and 50 alphanumeric - characters - hostedLocation: - type: optional - docs: URI for an externally hosted script location - integrityHash: - type: optional - docs: >- - Sub-Resource Integrity Hash. Only required for externally hosted - scripts (passed via hostedLocation) - createdOn: - type: optional - docs: Timestamp when the script version was created - lastUpdated: - type: optional - docs: Timestamp when the script version was last updated - version: - type: optional - docs: A Semantic Version (SemVer) string, denoting the version of the script - source: - openapi: ../../../openapi/referenced-specs/v2.yml - RegisteredScriptList: - docs: A list of scripts registered to the site - properties: - registeredScripts: optional> - source: - openapi: ../../../openapi/referenced-specs/v2.yml - CustomCodeInlineResponse: - docs: Registered custom code for application - properties: - id: - type: optional - docs: Human readable id, derived from the user-specified display name - canCopy: - type: optional - docs: >- - Define whether the script can be copied on site duplication and - transfer - default: false - displayName: - type: optional - docs: >- - User-facing name for the script. Must be between 1 and 50 alphanumeric - characters - hostedLocation: - type: optional - docs: URI for an externally hosted script location - integrityHash: - type: optional - docs: >- - Sub-Resource Integrity Hash. Only required for externally hosted - scripts (passed via hostedLocation) - createdOn: - type: optional - docs: Timestamp when the script version was created - lastUpdated: - type: optional - docs: Timestamp when the script version was last updated - version: - type: optional - docs: A Semantic Version (SemVer) string, denoting the version of the script - source: - openapi: ../../../openapi/referenced-specs/v2.yml - Scripts: - docs: A list of scripts applied to a Site or a Page - type: list - CustomCodeBlockType: - enum: - - page - - site - docs: Whether the Custom Code script is applied at the Site-level or Page-level - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - CustomCodeBlock: - docs: A specific instance of Custom Code applied to a Site or Page - properties: - siteId: - type: optional - docs: The Site ID where the custom code was applied - pageId: - type: optional - docs: The Page ID (if applied at Page-level) - type: - type: optional - docs: >- - Whether the Custom Code script is applied at the Site-level or - Page-level - scripts: optional - createdOn: - type: optional - docs: The date the Block was created - lastUpdated: - type: optional - docs: The date the Block was most recently updated - source: - openapi: ../../../openapi/referenced-specs/v2.yml - ListCustomCodeBlocks: - docs: Custom Code Blocks corresponding to where scripts were applied - properties: - blocks: optional> - pagination: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - AssetVariant: - properties: - hostedUrl: - type: optional - docs: URL of where the asset variant is hosted - validation: - format: uri - originalFileName: - type: optional - docs: Original file name of the variant - displayName: - type: optional - docs: Display name of the variant - format: - type: optional - docs: format of the variant - width: - type: optional - docs: Width in pixels - height: - type: optional - docs: Height in pixels - quality: - type: optional - docs: Value between 0 and 100 representing the image quality - error: - type: optional - docs: Any associated validation errors - source: - openapi: ../../../openapi/referenced-specs/v2.yml - Asset: - properties: - id: - type: optional - docs: Unique identifier for this asset - contentType: - type: optional - docs: File format type - size: - type: optional - docs: size in bytes - siteId: - type: optional - docs: Unique identifier for the site that hosts this asset - hostedUrl: - type: optional - docs: Link to the asset - validation: - format: uri - originalFileName: - type: optional - docs: Original file name at the time of upload - displayName: - type: optional - docs: Display name of the asset - lastUpdated: - type: optional - docs: Date the asset metadata was last updated - createdOn: - type: optional - docs: Date the asset metadata was created - variants: optional> - altText: - type: optional - docs: The visual description of the asset - source: - openapi: ../../../openapi/referenced-specs/v2.yml - Assets: - docs: A list of assets - properties: - assets: optional> - source: - openapi: ../../../openapi/referenced-specs/v2.yml - AssetUploadUploadDetails: - docs: Metadata for uploading the asset binary - properties: - acl: optional - bucket: optional - X-Amz-Algorithm: optional - X-Amz-Credential: optional - X-Amz-Date: optional - key: optional - Policy: optional - X-Amz-Signature: optional - success_action_status: optional - content-type: optional - Cache-Control: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - AssetUpload: - properties: - uploadDetails: - type: optional - docs: Metadata for uploading the asset binary - contentType: optional - id: optional - parentFolder: - type: optional - docs: Parent folder for the asset - uploadUrl: - type: optional - validation: - format: uri - assetUrl: - type: optional - docs: S3 link to the asset - validation: - format: uri - hostedUrl: - type: optional - docs: Represents the link to the asset - validation: - format: uri - originalFileName: - type: optional - docs: >- - Original file name when uploaded. If not specified at time of upload, - it may be extracted from the raw file name - createdOn: - type: optional - docs: Date the asset metadata was created - lastUpdated: - type: optional - docs: Date the asset metadata was last updated - source: - openapi: ../../../openapi/referenced-specs/v2.yml - AssetFolder: - docs: Asset Folder details - properties: - id: - type: optional - docs: Unique identifier for the Asset Folder - displayName: - type: optional - docs: User visible name for the Asset Folder - parentFolder: - type: optional - docs: Pointer to parent Asset Folder (or null if root) - assets: - type: optional> - docs: Array of Asset instances in the folder - siteId: - type: optional - docs: The unique ID of the site the Asset Folder belongs to - createdOn: - type: optional - docs: Date that the Asset Folder was created on - lastUpdated: - type: optional - docs: Date that the Asset Folder was last updated on - source: - openapi: ../../../openapi/referenced-specs/v2.yml - AssetFolderList: - docs: The Asset Folders object - properties: - assetFolders: - type: optional> - docs: A list of Asset folders - pagination: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - TriggerType: - enum: - - form_submission - - site_publish - - page_created - - page_metadata_updated - - page_deleted - - ecomm_new_order - - ecomm_order_changed - - ecomm_inventory_changed - - user_account_added - - user_account_updated - - user_account_deleted - - collection_item_created - - collection_item_changed - - collection_item_deleted - - collection_item_unpublished - docs: > - * `form_submission` - Sends the [form_submission](#form_submission) event - - * `site_publish` - Sends a [site_publish](#site_publish) event - - * `page_created` - Send the [page_created](#page_created) event - - * `page_metadata_updated` - Sends the - [page_metadata_updated](#page_metadata_updated) event - - * `page_deleted` - Sends the [page_deleted](#page_deleted) event - - * `ecomm_new_order` - Sends the new [ecomm_new_order](#ecomm_new_order) - event - - * `ecomm_order_changed` - Sends the - [ecomm_order_changed](#ecomm_order_changed) event - - * `ecomm_inventory_changed` - Sends the - [ecomm_inventory_changed](#ecomm_inventory_changed) event - - * `user_account_added` - Sends the - [user_account_added](#user_account_added) event - - * `user_account_updated` - Sends the - [user_account_updated](#user_account_updated) event - - * `user_account_deleted` - Sends the - [user_account_deleted](#user_account_deleted) event - - * `collection_item_created` - Sends the - [collection_item_created](#collection_item_created) event - - * `collection_item_changed` - Sends the - [collection_item_changed](#collection_item_changed) event - - * `collection_item_deleted` - Sends the - [collection_item_deleted](#collection_item_deleted) event - - * `collection_item_unpublished` - Sends the - [collection_item_unpublished](#collection_item_unpublished) event - source: - openapi: ../../../openapi/referenced-specs/v2.yml - WebhookFilter: - docs: >- - Only supported for the `form_submission` trigger type. Filter for the form - you want Webhooks to be sent for. - properties: - name: - type: optional - docs: The name of the form you'd like to recieve notifications for. - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - Webhook: - properties: - id: - type: optional - docs: Unique identifier for the Webhook registration - triggerType: optional - url: - type: optional - docs: URL to send the Webhook payload to - workspaceId: - type: optional - docs: Unique identifier for the Workspace the Webhook is registered in - siteId: - type: optional - docs: Unique identifier for the Site the Webhook is registered in - filter: - type: optional - docs: >- - Only supported for the `form_submission` trigger type. Filter for the - form you want Webhooks to be sent for. - lastTriggered: - type: optional - docs: Date the Webhook instance was last triggered - createdOn: - type: optional - docs: Date the Webhook registration was created - source: - openapi: ../../../openapi/referenced-specs/v2.yml - WebhookList: - properties: - pagination: optional - webhooks: optional> - source: - openapi: ../../../openapi/referenced-specs/v2.yml - FormFieldValueType: - enum: - - Plain - - Email - - Password - - Phone - - Number - docs: The field type - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - FormFieldValue: - docs: An object containing field info for a specific fieldID. - properties: - displayName: - type: optional - docs: The field name displayed on the site - type: - type: optional - docs: The field type - placeholder: - type: optional - docs: The placeholder text for the field - userVisible: - type: optional - docs: Whether the field is visible to the user - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - FormField: - type: map - docs: A collection of form fields with additional properties. - FormResponseSettings: - docs: Settings for form responses - properties: - redirectUrl: - type: optional - docs: The url or path to redirect the user to after form submission - redirectMethod: - type: optional - docs: The HTTP request method to use for the redirectUrl (eg. POST or GET) - redirectAction: - type: optional - docs: The action to take after form submission - sendEmailConfirmation: - type: optional - docs: Whether to send an email confirmation to the user - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - Form: - docs: A Webflow form - properties: - displayName: - type: optional - docs: The Form name displayed on the site - createdOn: - type: optional - docs: Date that the Form was created on - lastUpdated: - type: optional - docs: Date that the Form was last updated on - fields: - type: optional - docs: A collection of form field objects - responseSettings: - type: optional - docs: Settings for form responses - id: - type: optional - docs: The unique ID for the Form - siteId: - type: optional - docs: The unique ID of the Site the Form belongs to - siteDomainId: - type: optional - docs: The unique ID corresponding to the site's Domain name - pageId: - type: optional - docs: The unique ID for the Page on which the Form is placed - pageName: - type: optional - docs: The user-visible name of the Page where the Form is placed - formElementId: - type: optional - docs: The unique ID of the Form element - workspaceId: - type: optional - docs: The unique ID of the Workspace the Site belongs to - source: - openapi: ../../../openapi/referenced-specs/v2.yml - FormList: - properties: - forms: optional> - pagination: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - FormSubmission: - properties: - id: - type: optional - docs: The unique ID of the Form submission - displayName: - type: optional - docs: The Form name displayed on the site - siteId: - type: optional - docs: The unique ID of the Site the Form belongs to - workspaceId: - type: optional - docs: The unique ID of the Workspace the Site belongs to - dateSubmitted: - type: optional - docs: Date that the Form was submitted on - formResponse: - type: optional> - docs: The data submitted in the Form - source: - openapi: ../../../openapi/referenced-specs/v2.yml - FormSubmissionList: - properties: - formSubmissions: optional> - pagination: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - UserDataData: - properties: - name: - type: optional - docs: | - The name of the user - email: - type: optional - docs: | - The email address of the user - accept-privacy: - type: optional - docs: | - Boolean indicating if the user has accepted the privacy policy - accept-communications: - type: optional - docs: | - Boolean indicating if the user has accepted to receive communications - additionalProperties: - type: optional - docs: Custom user attributes - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - UserData: - docs: An object containing the User's basic info and custom fields - properties: - data: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - UserStatus: - enum: - - invited - - verified - - unverified - docs: The status of the user - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - UserAccessGroupsItemType: - enum: - - admin - - ecommerce - docs: | - The type of access group based on how it was assigned to the user. - * `admin` - Assigned to the user via API or in the designer - * `ecommerce` - Assigned to the user via an ecommerce purchase - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - UserAccessGroupsItem: - docs: Access group slugs and types - properties: - slug: - type: optional - docs: Access group identifier for APIs - type: - type: optional - docs: | - The type of access group based on how it was assigned to the user. - * `admin` - Assigned to the user via API or in the designer - * `ecommerce` - Assigned to the user via an ecommerce purchase - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - User: - docs: > - The fields that define the schema for a given Item are based on the - Collection that Item belongs to. Beyond the user defined fields, there are - a handful of additional fields that are automatically created for all - items - properties: - id: - type: optional - docs: Unique identifier for the User - isEmailVerified: - type: optional - docs: Shows whether the user has verified their email address - lastUpdated: - type: optional - docs: The timestamp the user was updated - invitedOn: - type: optional - docs: The timestamp the user was invited - createdOn: - type: optional - docs: The timestamp the user was created - lastLogin: - type: optional - docs: The timestamp the user was logged in - status: - type: optional - docs: The status of the user - accessGroups: - type: optional> - docs: Access groups the user belongs to - data: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - UserList: - docs: The list users results - properties: - count: - type: optional - docs: Number of users returned - limit: - type: optional - docs: The limit specified in the request - default: 10 - offset: - type: optional - docs: The offset specified for pagination - default: 0 - total: - type: optional - docs: Total number of users in the collection - users: - type: optional> - docs: List of Users for a Site - source: - openapi: ../../../openapi/referenced-specs/v2.yml - UsersNotEnabled: unknown - DuplicateUserEmail: unknown - UserLimitReached: unknown - AccessGroup: - properties: - id: - type: optional - docs: Unique identifier for the Access Group - name: - type: optional - docs: Name of the the Access Group - shortId: - type: optional - docs: >- - Shortened unique identifier based on name, optimized for its use in - the user’s JWT - slug: - type: optional - docs: >- - Shortened unique identifier based on name, optimized for human - readability and public API use - createdOn: - type: optional - docs: The date the Access Group was created - source: - openapi: ../../../openapi/referenced-specs/v2.yml - AccessGroupList: - docs: The list access groups results - properties: - count: - type: optional - docs: Number of access groups returned - limit: - type: optional - docs: The limit specified in the request - default: 10 - offset: - type: optional - docs: The offset specified for pagination - default: 0 - total: - type: optional - docs: Total number of access groups in the collection - accessGroups: - type: optional> - docs: List of Site Access Groups - source: - openapi: ../../../openapi/referenced-specs/v2.yml - SkuPropertyListEnumItem: - docs: Enumerated Product variants/Options for the SKU - properties: - id: - type: string - docs: Unique identifier for a Product variant/Option - name: - type: string - docs: Name of the Product variant/Option - slug: - type: string - docs: Slug for the Product variant/Option in the Site URL structure - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - SkuPropertyList: - docs: A variant/option type for a SKU - properties: - id: - type: string - docs: Unique identifier for a collection of Product Variants - name: - type: string - docs: Name of the collection of Product Variants - enum: - docs: >- - The individual Product variants that are contained within the - collection - type: list - source: - openapi: ../../../openapi/referenced-specs/v2.yml - ProductFieldDataTaxCategory: - enum: - - value: standard-taxable - name: StandardTaxable - - value: standard-exempt - name: StandardExempt - - value: books-religious - name: BooksReligious - - value: books-textbook - name: BooksTextbook - - clothing - - value: clothing-swimwear - name: ClothingSwimwear - - value: digital-goods - name: DigitalGoods - - value: digital-service - name: DigitalService - - value: drugs-non-prescription - name: DrugsNonPrescription - - value: drugs-prescription - name: DrugsPrescription - - value: food-bottled-water - name: FoodBottledWater - - value: food-candy - name: FoodCandy - - value: food-groceries - name: FoodGroceries - - value: food-prepared - name: FoodPrepared - - value: food-soda - name: FoodSoda - - value: food-supplements - name: FoodSupplements - - value: magazine-individual - name: MagazineIndividual - - value: magazine-subscription - name: MagazineSubscription - - value: service-admission - name: ServiceAdmission - - value: service-advertising - name: ServiceAdvertising - - value: service-dry-cleaning - name: ServiceDryCleaning - - value: service-hairdressing - name: ServiceHairdressing - - value: service-installation - name: ServiceInstallation - - value: service-miscellaneous - name: ServiceMiscellaneous - - value: service-parking - name: ServiceParking - - value: service-printing - name: ServicePrinting - - value: service-professional - name: ServiceProfessional - - value: service-repair - name: ServiceRepair - - value: service-training - name: ServiceTraining - docs: Product tax class - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - ProductFieldDataEcProductType: - enum: - - ff42fee0113744f693a764e3431a9cc2 - - f22027db68002190aef89a4a2b7ac8a1 - - c599e43b1a1c34d5a323aedf75d3adf6 - - b6ccc1830db4b1babeb06a9ac5f6dd76 - docs: >- - Product - types. Enums reflect the following values in order: Physical, Digital, - Service, Advanced" - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - ProductFieldData: - docs: >- - Contains content-specific details for a product, covering both standard - (e.g., title, description) and custom fields tailored to the product - setup. - properties: - name: - type: optional - docs: Name of the Product - slug: - type: optional - docs: URL structure of the Product in your site. - description: - type: optional - docs: A description of your product - shippable: - type: optional - docs: Boolean determining if the Product is shippable - sku-properties: - type: optional> - docs: Variant types to include in SKUs - categories: - type: optional> - docs: The categories your product belongs to. - tax-category: - type: optional - docs: Product tax class - default-sku: - type: optional - docs: The default SKU associated with this product. - ec-product-type: - type: optional - docs: >- - Product - types. Enums reflect the following values in order: Physical, - Digital, Service, Advanced" - source: - openapi: ../../../openapi/referenced-specs/v2.yml - Product: - docs: The Product object - properties: - id: - type: optional - docs: Unique identifier for the Product - cmsLocaleId: - type: optional - docs: Identifier for the locale of the CMS item - lastPublished: - type: optional - docs: The date the Product was last published - lastUpdated: - type: optional - docs: The date the Product was last updated - createdOn: - type: optional - docs: The date the Product was created - isArchived: - type: optional - docs: Boolean determining if the Product is set to archived - default: false - isDraft: - type: optional - docs: Boolean determining if the Product is set to draft - default: false - fieldData: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - SkuValueList: - type: map - docs: > - A dictionary that maps a SKU property to a SKU value. The key of the - dictionary is the SKU property ID, and the value is the SKU value ID. - SkuFieldDataPrice: - docs: price of SKU - properties: - value: - type: optional - docs: Price of SKU - unit: - type: optional - docs: Currency of Item - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - SkuFieldDataCompareAtPrice: - docs: comparison price of SKU - properties: - value: - type: optional - docs: Price of SKU - unit: - type: optional - docs: Currency of Item - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - SkuFieldDataEcSkuBillingMethod: - enum: - - value: one-time - name: OneTime - - subscription - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - SkuFieldDataEcSkuSubscriptionPlanInterval: - enum: - - day - - week - - month - - year - docs: Interval of subscription renewal - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - SkuFieldDataEcSkuSubscriptionPlanPlansItemStatus: - enum: - - active - - inactive - - canceled - docs: The status of the plan - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - SkuFieldDataEcSkuSubscriptionPlanPlansItem: - properties: - platform: - type: optional> - docs: The platform of the subscription plan - id: - type: optional - docs: The unique identifier of the plan - status: - type: optional - docs: The status of the plan - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - SkuFieldDataEcSkuSubscriptionPlan: - properties: - interval: - type: optional - docs: Interval of subscription renewal - frequency: - type: optional - docs: Frequncy of billing within interval - trial: - type: optional - docs: Number of days of a trial - plans: optional> - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - SkuFieldData: - docs: Standard and Custom fields for a SKU - properties: - sku-values: optional - name: - type: string - docs: Name of the Product - slug: - type: string - docs: URL structure of the Product in your site. - price: - type: SkuFieldDataPrice - docs: price of SKU - compare-at-price: - type: optional - docs: comparison price of SKU - ec-sku-billing-method: optional - ec-sku-subscription-plan: optional - track-inventory: - type: optional - docs: >- - A boolean indicating whether inventory for this product should be - tracked. - default: false - quantity: - type: optional - docs: Quantity of SKU that will be tracked as items are ordered. - source: - openapi: ../../../openapi/referenced-specs/v2.yml - Sku: - docs: The SKU object - properties: - id: - type: optional - docs: Unique identifier for the Product - cmsLocaleId: - type: optional - docs: Identifier for the locale of the CMS item - lastPublished: - type: optional - docs: The date the Product was last published - lastUpdated: - type: optional - docs: The date the Product was last updated - createdOn: - type: optional - docs: The date the Product was created - fieldData: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - ProductAndSkUs: - docs: A product and its SKUs. - properties: - product: optional - skus: - type: optional> - docs: A list of SKU Objects - source: - openapi: ../../../openapi/referenced-specs/v2.yml - ProductAndSkUsList: - docs: Results from product list - properties: - items: - type: optional> - docs: >- - List of Item objects within the Collection. Contains product and skus - keys for each Item - pagination: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - PublishStatus: - enum: - - staging - - live - docs: Indicate whether your Product should be set as "staging" or "live" - default: staging - source: - openapi: ../../../openapi/referenced-specs/v2.yml - OrderPrice: - properties: - unit: - type: optional - docs: The three-letter ISO currency code - value: - type: optional - docs: The numeric value in the base unit of the currency - string: - type: optional - docs: The user-facing string representation of the amount - source: - openapi: ../../../openapi/referenced-specs/v2.yml - OrderAddressType: - enum: - - shipping - - billing - docs: The type of the order address (billing or shipping) - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - OrderAddressJapanType: - enum: - - kana - - kanji - docs: >- - Represents a Japan-only address format. This field will only appear on - orders placed from Japan. - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - OrderAddress: - docs: A customer address - properties: - type: - type: optional - docs: The type of the order address (billing or shipping) - japanType: - type: optional - docs: >- - Represents a Japan-only address format. This field will only appear on - orders placed from Japan. - addressee: - type: optional - docs: Display name on the address - line1: - type: optional - docs: The first line of the address - line2: - type: optional - docs: The second line of the address - city: - type: optional - docs: The city of the address. - state: - type: optional - docs: The state or province of the address - country: - type: optional - docs: The country of the address - postalCode: - type: optional - docs: The postal code of the address - source: - openapi: ../../../openapi/referenced-specs/v2.yml - OrderPurchasedItemVariantImageFileVariantsItem: - properties: - url: - type: optional - docs: The hosted location for the Variant's image - validation: - format: uri - originalFileName: optional - size: - type: optional - docs: The image size in bytes - width: - type: optional - docs: The image width in pixels - height: - type: optional - docs: The image height in pixels - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - OrderPurchasedItemVariantImageFile: - properties: - size: - type: optional - docs: The image size in bytes - originalFileName: - type: optional - docs: the original name of the image - createdOn: - type: optional - docs: The creation timestamp of the image - contentType: - type: optional - docs: The MIME type of the image - width: - type: optional - docs: The image width in pixels - height: - type: optional - docs: The image height in pixels - variants: - type: optional> - docs: Variants of the supplied image - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - OrderPurchasedItemVariantImage: - properties: - url: - type: optional - docs: The hosted location for the Variant's image - validation: - format: uri - file: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - OrderPurchasedItem: - docs: An Item that was purchased - properties: - count: - type: optional - docs: Number of Item purchased. - rowTotal: - type: optional - docs: The total for the row - productId: - type: optional - docs: The unique identifier for the Product - productName: - type: optional - docs: User-facing name of the Product - productSlug: - type: optional - docs: Slug for the Product - variantId: - type: optional - docs: Identifier for the Product Variant (SKU) - variantName: - type: optional - docs: User-facing name of the Product Variant (SKU) - variantSlug: - type: optional - docs: Slug for the Product Variant (SKU) - variantSKU: - type: optional - docs: The user-defined custom SKU of the Product Variant (SKU) - variantImage: optional - variantPrice: - type: optional - docs: The price corresponding to the variant - weight: - type: optional - docs: The physical weight of the variant if provided, or null - width: - type: optional - docs: The physical width of the variant if provided, or null - height: - type: optional - docs: The physical height of the variant if provided, or null - length: - type: optional - docs: The physical length of the variant if provided, or null - source: - openapi: ../../../openapi/referenced-specs/v2.yml - StripeDetails: - docs: >- - An object with various Stripe IDs, useful for linking into the stripe - dashboard. - properties: - subscriptionId: - type: optional - docs: Stripe-generated identifier for the Subscription - paymentMethod: - type: optional - docs: Stripe-generated identifier for the PaymentMethod used - paymentIntentId: - type: optional - docs: Stripe-generated identifier for the PaymentIntent, or null - customerId: - type: optional - docs: Stripe-generated customer identifier, or null - chargeId: - type: optional - docs: Stripe-generated charge identifier, or null - disputeId: - type: optional - docs: Stripe-generated dispute identifier, or null - refundId: - type: optional - docs: Stripe-generated refund identifier, or null - refundReason: - type: optional - docs: Stripe-generated refund reason, or null - source: - openapi: ../../../openapi/referenced-specs/v2.yml - StripeCardBrand: - enum: - - Visa - - value: American Express - name: AmericanExpress - - MasterCard - - Discover - - JCB - - value: Diners Club - name: DinersClub - - Unknown - docs: The card's brand (ie. credit card network) - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - StripeCardExpires: - docs: The card's expiration date. - properties: - year: - type: optional - docs: Year that the card expires - month: - type: optional - docs: Month that the card expires - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - StripeCard: - docs: > - Details on the card used to fulfill this order, if this order was - finalized with Stripe. - properties: - last4: - type: optional - docs: The last 4 digits on the card as a string - brand: - type: optional - docs: The card's brand (ie. credit card network) - ownerName: - type: optional - docs: The name on the card. - expires: - type: optional - docs: The card's expiration date. - source: - openapi: ../../../openapi/referenced-specs/v2.yml - PaypalDetails: - properties: - orderId: - type: optional - docs: PayPal order identifier - payerId: - type: optional - docs: PayPal payer identifier - captureId: - type: optional - docs: PayPal capture identifier - refundId: - type: optional - docs: PayPal refund identifier - refundReason: - type: optional - docs: PayPal-issued reason for the refund - disputeId: - type: optional - docs: PayPal dispute identifier - source: - openapi: ../../../openapi/referenced-specs/v2.yml - OrderStatus: - enum: - - pending - - unfulfilled - - fulfilled - - disputed - - value: dispute-lost - name: DisputeLost - - refunded - docs: | - The status of the Order - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - OrderDisputeLastStatus: - enum: - - warning_needs_response - - warning_under_review - - warning_closed - - needs_response - - under_review - - charge_refunded - - won - - lost - docs: > - If an order was disputed by the customer, then this key will be set with - the [dispute's status](https://stripe.com/docs/api#dispute_object-status). - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - OrderCustomerInfo: - docs: An object with the keys `fullName` and `email`. - properties: - fullName: - type: optional - docs: The full name of the Customer - email: - type: optional - docs: The Customer's email address - validation: - format: email - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - OrderMetadata: - properties: - isBuyNow: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - OrderTotalsExtrasItemType: - enum: - - discount - - value: discount-shipping - name: DiscountShipping - - shipping - - tax - docs: The type of extra item this is. - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - OrderTotalsExtrasItem: - docs: Extra order items, includes discounts, shipping, and taxes. - properties: - type: - type: optional - docs: The type of extra item this is. - name: - type: optional - docs: A human-readable (but English) name for this extra charge. - description: - type: optional - docs: A human-readable (but English) description of this extra charge. - price: - type: optional - docs: The price for the item - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - OrderTotals: - docs: An object describing various pricing totals - properties: - subtotal: - type: optional - docs: The subtotal price - extras: - type: optional> - docs: An array of extra items, includes discounts, shipping, and taxes. - total: - type: optional - docs: The total price - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - OrderDownloadFilesItem: - properties: - id: - type: optional - docs: The unique identifier for the downloadable file - name: - type: optional - docs: The user-facing name for the downloadable file - url: - type: optional - docs: The hosted location for the downloadable file - validation: - format: uri - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - Order: - properties: - orderId: - type: optional - docs: | - The order ID. Will usually be 6 hex characters, but can also be 9 - hex characters if the site has a very large number of Orders. - Randomly assigned. - status: - type: optional - docs: | - The status of the Order - comment: - type: optional - docs: >- - A comment string for this Order, which is editable by API user (not - used by Webflow). - orderComment: - type: optional - docs: A comment that the customer left when making their Order - acceptedOn: - type: optional - docs: The ISO8601 timestamp that an Order was placed. - fulfilledOn: - type: optional - docs: > - When an Order is marked as 'fulfilled', this field represents the - timestamp of the fulfillment in ISO8601 format. Otherwise, it is null. - refundedOn: - type: optional - docs: >- - When an Order is marked as 'refunded', this field represents the - timestamp of the fulfillment in ISO8601 format. Otherwise, it is null. - disputedOn: - type: optional - docs: > - When an Order is marked as 'disputed', this field represents the - timestamp of the fulfillment in ISO8601 format. Otherwise, it is null. - disputeUpdatedOn: - type: optional - docs: > - If an Order has been disputed by the customer, this key will be set to - the ISO8601 timestamp of the last update received. If the Order is not - disputed, the key will be null. - disputeLastStatus: - type: optional - docs: > - If an order was disputed by the customer, then this key will be set - with the [dispute's - status](https://stripe.com/docs/api#dispute_object-status). - customerPaid: - type: optional - docs: The total paid by the customer - netAmount: - type: optional - docs: The net amount after application fees - applicationFee: - type: optional - docs: The application fee assessed by the platform - allAddresses: - type: optional> - docs: All addresses provided by the customer during the ordering flow. - shippingAddress: - type: optional - docs: The shipping address - billingAddress: - type: optional - docs: The billing address - shippingProvider: - type: optional - docs: > - A string editable by the API user to note the shipping provider used - (not used by Webflow). - shippingTracking: - type: optional - docs: > - A string editable by the API user to note the shipping tracking number - for the order (not used by Webflow). - shippingTrackingURL: - type: optional - validation: - format: uri - customerInfo: - type: optional - docs: An object with the keys `fullName` and `email`. - purchasedItems: - type: optional> - docs: An array of all things that the Customer purchased. - purchasedItemsCount: - type: optional - docs: The sum of all 'count' fields in 'purchasedItems'. - stripeDetails: optional - stripeCard: optional - paypalDetails: optional - customData: - type: optional>> - docs: > - An array of additional inputs for custom order data gathering. Each - object in the array represents an input with a name, and a textInput, - textArea, or checkbox value. - metadata: optional - isCustomerDeleted: - type: optional - docs: > - A boolean indicating whether the customer has been deleted from the - site. - isShippingRequired: - type: optional - docs: > - A boolean indicating whether the order contains one or more purchased - items that require shipping. - hasDownloads: - type: optional - docs: > - A boolean indicating whether the order contains one or more purchased - items that are downloadable. - paymentProcessor: - type: optional - docs: | - A string indicating the payment processor used for this order. - totals: - type: optional - docs: An object describing various pricing totals - downloadFiles: - type: optional> - docs: An array of downloadable file objects. - source: - openapi: ../../../openapi/referenced-specs/v2.yml - OrderList: - docs: Results from order list - properties: - orders: - type: optional> - docs: List of orders - pagination: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - InventoryItemInventoryType: - enum: - - infinite - - finite - docs: infinite or finite - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - InventoryItem: - docs: The availabile inventory for an item - properties: - id: - type: optional - docs: Unique identifier for a SKU item - quantity: - type: optional - docs: >- - Total quantity of items remaining in inventory (if inventoryType is - finite) - inventoryType: - type: optional - docs: infinite or finite - source: - openapi: ../../../openapi/referenced-specs/v2.yml - EcommerceSettings: - docs: Ecommerce settings for a Webflow Site - properties: - siteId: - type: optional - docs: The identifier of the Site - createdOn: - type: optional - docs: Date that the Site was created on - defaultCurrency: - type: optional - docs: The three-letter ISO currency code for the Site - source: - openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/accessGroups.yml b/.mock/definition/accessGroups.yml deleted file mode 100644 index d8828f8..0000000 --- a/.mock/definition/accessGroups.yml +++ /dev/null @@ -1,80 +0,0 @@ -types: - AccessGroupsListRequestSort: - enum: - - value: CreatedOn - name: CreatedOnAscending - docs: Sorts users in ascending order based on their created date - - value: '-CreatedOn' - name: CreatedOnDescending - docs: Sorts users in descending order based on their created date - source: - openapi: ../../../openapi/referenced-specs/v2.yml -imports: - root: __package__.yml -service: - auth: false - base-path: '' - endpoints: - list: - path: /sites/{site_id}/accessgroups - method: GET - auth: true - docs: | - Get a list of access groups for a site - - Required scope | `users:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: List Access Groups - request: - name: AccessGroupsListRequest - query-parameters: - offset: - type: optional - docs: >- - Offset used for pagination if the results have more than limit - records - limit: - type: optional - docs: 'Maximum number of records to be returned (max limit: 100)' - sort: - type: optional - docs: | - Sort string to use when ordering access groups - Can be prefixed with a `-` to reverse the sort (ex. `-CreatedOn`) - response: - docs: Request was successful - type: root.AccessGroupList - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - response: - body: - count: 1 - limit: 10 - offset: 0 - total: 1 - accessGroups: - - id: 62be58d404be8a6cc900c081 - name: Research Team - shortId: rt - slug: hitchhikers-guide-research-team - createdOn: '2022-08-01T19:41:48Z' - - id: 65a96161991e77bbb4a6c573 - name: Admin - shortId: ad - slug: admin - createdOn: '2022-08-01T19:41:48Z' - source: - openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/api.yml b/.mock/definition/api.yml deleted file mode 100644 index aee9acd..0000000 --- a/.mock/definition/api.yml +++ /dev/null @@ -1,13 +0,0 @@ -name: api -error-discrimination: - strategy: status-code -display-name: Data API -environments: - Default: https://api.webflow.com/v2 -default-environment: Default -auth-schemes: - BearerToken: - scheme: bearer - token: - name: accessToken -auth: BearerToken diff --git a/.mock/definition/assets.yml b/.mock/definition/assets.yml deleted file mode 100644 index 35392ec..0000000 --- a/.mock/definition/assets.yml +++ /dev/null @@ -1,415 +0,0 @@ -imports: - root: __package__.yml -service: - auth: false - base-path: '' - endpoints: - list: - path: /sites/{site_id}/assets - method: GET - auth: true - docs: | - List assets for a given site - - Required scope | `assets:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: List Assets - response: - docs: Request was successful - type: root.Assets - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - response: - body: - assets: - - id: 63e5889e7fe4eafa7384cea4 - contentType: image/png - size: 2212772 - siteId: 63938b302ea6b0aa6f3d8745 - hostedUrl: >- - https://s3.amazonaws.com/webflow-prod-assets/63938b302ea6b0aa6f3d8745/63e5889e7fe4eafa7384cea4_Vectors-Wrapper.svg - originalFileName: Candy-Wrapper.svg - displayName: 63e5889e7fe4eafa7384cea4_Candy-Wrapper.png - lastUpdated: '2023-03-01T23:42:57Z' - createdOn: '2023-02-09T23:58:22Z' - variants: - - hostedUrl: >- - https://s3.amazonaws.com/webflow-prod-assets/6258612d1ee792848f805dcf/660d83ce30f3a599ddb0bdb3_Screenshot%202024-03-20%20at%209.03.24%E2%80%AFPM-p-500.png - originalFileName: >- - Screenshot%202024-03-20%20at%209.03.24%E2%80%AFPM-p-500.png - displayName: >- - 660d83ce30f3a599ddb0bdb3_Screenshot%202024-03-20%20at%209.03.24%E2%80%AFPM-p-500.png - format: png - width: 500 - height: 900 - quality: 100 - altText: A red chair - create: - path: /sites/{site_id}/assets - method: POST - auth: true - docs: > - Create a new asset entry. - - - - This endpoint generates a response with the following information: - `uploadUrl` and `uploadDetails`. - - You can use these two properties to [upload the file to Amazon s3 by - making a - POST](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html) - - request to the `uploadUrl` with the `uploadDetails` object as your - header information in the request. - - - Required scope | `assets:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: Create Asset Metadata - request: - name: AssetsCreateRequest - body: - properties: - fileName: - type: string - docs: >- - File name including file extension. File names must be less than - 100 characters. - fileHash: - type: string - docs: MD5 hash of the file - parentFolder: - type: optional - docs: ID of the Asset folder (optional) - content-type: application/json - response: - docs: Request was successful - type: root.AssetUpload - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - request: - fileName: file.png - fileHash: 3c7d87c9575702bc3b1e991f4d3c638e - response: - body: - uploadDetails: - acl: public-read - bucket: webflow-bucket-name - X-Amz-Algorithm: AWS4-HMAC-SHA256 - X-Amz-Credential: ///s3/aws4_request - X-Amz-Date: - key: /_ - Policy: - X-Amz-Signature: - success_action_status: '201' - content-type: image/png - Cache-Control: max-age=31536000, must-revalidate - contentType: image/png - id: 64358b9544249dc43d37d2b7 - parentFolder: 6436b1ce5281cace05b65aea - uploadUrl: >- - https://s3.amazonaws.com/webflow-dev-assets/643021114e290e0d3a0602b2/64358b9544249dc43d37d2b7_Screenshot%202023-04-11%20at%209.50.42%20AM.png - assetUrl: >- - https://s3.amazonaws.com/webflow-prod-assets/6258612d1ee792848f805dcf/660d907ab9e91e3e9f56385e_paranoidAndroid-2024.png - hostedUrl: >- - https://d1otoma47x30pg.cloudfront.net/643021114e290e0d3a0602b2/64358b9544249dc43d37d2b7_Screenshot%202023-04-11%20at%209.50.42%20AM.png - originalFileName: file.png - createdOn: '2023-04-11T16:32:21Z' - lastUpdated: '2023-04-12T20:31:03Z' - get: - path: /assets/{asset_id} - method: GET - auth: true - docs: | - Get an Asset - - Required scope | `assets:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - asset_id: - type: string - docs: Unique identifier for an Asset on a site - display-name: Get Asset - response: - docs: Request was successful - type: root.Asset - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - asset_id: 580e63fc8c9a982ac9b8b745 - response: - body: - id: 55131cd036c09f7d07883dfc - contentType: image/png - size: 1500 - siteId: 62749158efef318abc8d5a0f - hostedUrl: example.com/hostedimage.png - originalFileName: image.png - displayName: example-image-123.png - lastUpdated: '2016-09-06T21:12:22Z' - createdOn: '2016-09-02T23:26:22Z' - variants: - - hostedUrl: example.com/hostedimage.png - originalFileName: image.png - displayName: A brown dog - format: format - width: 1500 - height: 900 - quality: 1 - error: error - altText: A red chair - delete: - path: /assets/{asset_id} - method: DELETE - auth: true - docs: | - Delete an Asset - - Required Scope: `assets: write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - asset_id: - type: string - docs: Unique identifier for an Asset on a site - display-name: Delete Asset - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - asset_id: 580e63fc8c9a982ac9b8b745 - update: - path: /assets/{asset_id} - method: PATCH - auth: true - docs: | - Update an Asset - - Required scope | `assets:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - asset_id: - type: string - docs: Unique identifier for an Asset on a site - display-name: Update Asset - request: - name: AssetsUpdateRequest - body: - properties: - localeId: - type: optional - docs: >- - Unique identifier for a specific locale. Applicable, when using - localization. - displayName: - type: optional - docs: A human readable name for the asset - content-type: application/json - response: - docs: Request was successful - type: root.Asset - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - asset_id: 580e63fc8c9a982ac9b8b745 - request: {} - response: - body: - id: 55131cd036c09f7d07883dfc - contentType: image/png - size: 1500 - siteId: 62749158efef318abc8d5a0f - hostedUrl: example.com/hostedimage.png - originalFileName: image.png - displayName: example-image-123.png - lastUpdated: '2016-09-06T21:12:22Z' - createdOn: '2016-09-02T23:26:22Z' - variants: - - hostedUrl: example.com/hostedimage.png - originalFileName: image.png - displayName: A brown dog - format: format - width: 1500 - height: 900 - quality: 1 - error: error - altText: A red chair - list-folders: - path: /sites/{site_id}/asset_folders - method: GET - auth: true - docs: | - List Asset Folders within a given site - - Required scope | `assets:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: List Asset Folders - response: - docs: Request was successful - type: root.AssetFolderList - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - response: - body: - assetFolders: - - id: 6390c49774a71f0e3c1a08ee - displayName: emoji icons - parentFolder: 6390c49774a71f99f21a08eb - assets: - - 63e5889e7fe4eafa7384cea4 - - 659595234426a9fcbad57043 - siteId: 6390c49674a71f84b51a08d8 - createdOn: '2018-10-14T21:55:49Z' - lastUpdated: '2022-12-07T16:51:37Z' - pagination: - limit: 1 - offset: 0 - total: 1 - create-folder: - path: /sites/{site_id}/asset_folders - method: POST - auth: true - docs: | - Create an Asset Folder within a given site - - Required scope | `assets:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: Create Asset Folder - request: - name: AssetsCreateFolderRequest - body: - properties: - displayName: - type: string - docs: A human readable name for the Asset Folder - parentFolder: - type: optional - docs: >- - An (optional) pointer to a parent Asset Folder (or null for - root) - content-type: application/json - response: - docs: Request was successful - type: root.AssetFolder - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - request: - displayName: my asset folder - response: - body: - id: 6390c49774a71f0e3c1a08ee - displayName: emoji icons - parentFolder: 6390c49774a71f99f21a08eb - assets: - - 63e5889e7fe4eafa7384cea4 - - 659595234426a9fcbad57043 - siteId: 6390c49674a71f84b51a08d8 - createdOn: '2018-10-14T21:55:49Z' - lastUpdated: '2022-12-07T16:51:37Z' - get-folder: - path: /asset_folders/{asset_folder_id} - method: GET - auth: true - docs: | - Get details about a specific Asset Folder - - Required scope | `assets:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - asset_folder_id: - type: string - docs: Unique identifier for an Asset Folder - display-name: Get Asset Folder - response: - docs: Request was successful - type: root.AssetFolder - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - asset_folder_id: 6390c49774a71f0e3c1a08ee - response: - body: - id: 6390c49774a71f0e3c1a08ee - displayName: emoji icons - parentFolder: 6390c49774a71f99f21a08eb - assets: - - 63e5889e7fe4eafa7384cea4 - - 659595234426a9fcbad57043 - siteId: 6390c49674a71f84b51a08d8 - createdOn: '2018-10-14T21:55:49Z' - lastUpdated: '2022-12-07T16:51:37Z' - source: - openapi: ../../../openapi/referenced-specs/v2.yml - display-name: Assets -docs: Assets are files that are uploaded to your Webflow account. diff --git a/.mock/definition/collections.yml b/.mock/definition/collections.yml deleted file mode 100644 index 661b54b..0000000 --- a/.mock/definition/collections.yml +++ /dev/null @@ -1,186 +0,0 @@ -imports: - root: __package__.yml -service: - auth: false - base-path: '' - endpoints: - list: - path: /sites/{site_id}/collections - method: GET - auth: true - docs: | - List of all Collections within a Site. - - Required scope | `cms:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: List Collections - response: - docs: Request was successful - type: root.CollectionList - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - response: - body: - collections: - - id: 63692ab61fb2852f582ba8f5 - displayName: Products - singularName: Product - slug: product - createdOn: '2019-06-12T13:35:14Z' - lastUpdated: '2022-11-17T15:08:50Z' - - id: 63692ab61fb2856e6a2ba8f6 - displayName: Categories - singularName: Category - slug: category - createdOn: '2019-06-12T13:35:14Z' - lastUpdated: '2022-11-17T15:08:50Z' - - id: 63692ab61fb285a8562ba8f4 - displayName: SKUs - singularName: SKU - slug: sku - createdOn: '2019-06-12T13:35:14Z' - lastUpdated: '2022-11-17T15:08:50Z' - create: - path: /sites/{site_id}/collections - method: POST - auth: true - docs: | - Create a Collection for a site. - - Required scope | `cms:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: Create Collection - request: - name: CollectionsCreateRequest - body: - properties: - displayName: - type: string - docs: Name of the collection. Each collection name must be distinct. - singularName: - type: string - docs: Singular name of each item. - slug: - type: optional - docs: Part of a URL that identifier - content-type: application/json - response: - docs: Request was successful - type: root.Collection - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - request: - displayName: Blog Posts - singularName: Blog Post - slug: posts - response: - body: - id: 580e63fc8c9a982ac9b8b745 - displayName: Blog Posts - singularName: Blog Post - slug: post - createdOn: '2016-10-24T19:41:48Z' - lastUpdated: '2016-10-24T19:42:38Z' - fields: - - id: 23cc2d952d4e4631ffd4345d2743db4e - isRequired: true - isEditable: true - type: PlainText - slug: name - displayName: Name - helpText: helpText - get: - path: /collections/{collection_id} - method: GET - auth: true - docs: | - Get the full details of a collection from its ID. - - Required scope | `cms:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - collection_id: - type: string - docs: Unique identifier for a Collection - display-name: Get Collection Details - response: - docs: Request was successful - type: root.Collection - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - response: - body: - id: 580e63fc8c9a982ac9b8b745 - displayName: Blog Posts - singularName: Blog Post - slug: post - createdOn: '2016-10-24T19:41:48Z' - lastUpdated: '2016-10-24T19:42:38Z' - fields: - - id: 23cc2d952d4e4631ffd4345d2743db4e - isRequired: true - isEditable: true - type: PlainText - slug: name - displayName: Name - helpText: helpText - delete: - path: /collections/{collection_id} - method: DELETE - auth: true - docs: | - Delete a collection using its ID. - - Required scope | `cms:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - collection_id: - type: string - docs: Unique identifier for a Collection - display-name: Delete Collection - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - source: - openapi: ../../../openapi/referenced-specs/v2.yml - display-name: Collections -docs: Collections are CMS collections of items. diff --git a/.mock/definition/collections/fields.yml b/.mock/definition/collections/fields.yml deleted file mode 100644 index 08dc554..0000000 --- a/.mock/definition/collections/fields.yml +++ /dev/null @@ -1,189 +0,0 @@ -types: - FieldCreateType: - enum: - - Color - - DateTime - - Email - - ExtFileRef - - File - - Image - - Link - - MultiImage - - Number - - Phone - - PlainText - - RichText - - Switch - - Video - docs: Choose these appropriate field type for your collection data - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml -imports: - root: ../__package__.yml -service: - auth: false - base-path: '' - endpoints: - create: - path: /collections/{collection_id}/fields - method: POST - auth: true - docs: > - Create a custom field in a collection. - - - Slugs must be all lowercase letters without spaces. - - If you pass a string with uppercase letters and/or spaces to the "Slug" - property, Webflow will - - convert the slug to lowercase and replace spaces with "-." - - - Only some field types can be created through the API. - - This endpoint does not currently support bulk creation. - - - Required scope | `cms:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - collection_id: - type: string - docs: Unique identifier for a Collection - display-name: Create Collection Field - request: - name: FieldCreate - body: - properties: - isRequired: - type: optional - docs: define whether a field is required in a collection - type: - type: FieldCreateType - docs: Choose these appropriate field type for your collection data - displayName: - type: string - docs: The name of a field - helpText: - type: optional - docs: Additional text to help anyone filling out this field - content-type: application/json - response: - docs: Request was successful - type: root.Field - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - request: - isRequired: false - type: RichText - displayName: Post Body - helpText: Add the body of your post here - response: - body: - id: 75821f618da60c18383330bcc0ca488b - isRequired: false - isEditable: true - type: RichText - slug: post-body - displayName: Post Body - helpText: Add the body of your post here - delete: - path: /collections/{collection_id}/fields/{field_id} - method: DELETE - auth: true - docs: > - Delete a custom field in a collection. This endpoint does not currently - support bulk deletion. - - - Required scope | `cms:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - collection_id: - type: string - docs: Unique identifier for a Collection - field_id: - type: string - docs: Unique identifier for a Field in a collection - display-name: Delete Collection Field - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - field_id: 580e63fc8c9a982ac9b8b745 - update: - path: /collections/{collection_id}/fields/{field_id} - method: PATCH - auth: true - docs: | - Update a custom field in a collection. - - Required scope | `cms:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - collection_id: - type: string - docs: Unique identifier for a Collection - field_id: - type: string - docs: Unique identifier for a Field in a collection - display-name: Update Collection Field - request: - name: FieldUpdate - body: - properties: - isRequired: - type: optional - docs: Define whether a field is required in a collection - displayName: - type: optional - docs: The name of a field - helpText: - type: optional - docs: Additional text to help anyone filling out this field - content-type: application/json - response: - docs: Request was successful - type: root.Field - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - field_id: 580e63fc8c9a982ac9b8b745 - request: - isRequired: false - displayName: Post Body - helpText: Add the body of your post here - response: - body: - id: 75821f618da60c18383330bcc0ca488b - isRequired: false - isEditable: true - type: RichText - slug: post-body - displayName: Post Body - helpText: Add the body of your post here - source: - openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/collections/items.yml b/.mock/definition/collections/items.yml deleted file mode 100644 index f765817..0000000 --- a/.mock/definition/collections/items.yml +++ /dev/null @@ -1,1628 +0,0 @@ -types: - ItemsListItemsRequestSortBy: - enum: - - lastPublished - - name - - slug - source: - openapi: ../../../openapi/referenced-specs/v2.yml - ItemsListItemsRequestSortOrder: - enum: - - asc - - desc - source: - openapi: ../../../openapi/referenced-specs/v2.yml - Multiple Items: - properties: - items: - type: optional> - docs: An array of items to create - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - ItemsCreateItemRequest: - discriminated: false - union: - - root.CollectionItemPostSingle - - Multiple Items - source: - openapi: ../../../openapi/referenced-specs/v2.yml - ItemsDeleteItemsRequestItemsItem: - properties: - id: - type: string - docs: Unique identifier for the Item - cmsLocaleIds: - type: optional> - docs: Array of identifiers for the locales where the item will be created - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - ItemsListItemsLiveRequestSortBy: - enum: - - lastPublished - - name - - slug - source: - openapi: ../../../openapi/referenced-specs/v2.yml - ItemsListItemsLiveRequestSortOrder: - enum: - - asc - - desc - source: - openapi: ../../../openapi/referenced-specs/v2.yml - Multiple Live Items: - properties: - items: - type: optional> - docs: List of collection items to create - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - ItemsCreateItemLiveRequest: - discriminated: false - union: - - root.CollectionItem - - Multiple Live Items - source: - openapi: ../../../openapi/referenced-specs/v2.yml - ItemsDeleteItemsLiveRequestItemsItem: - properties: - itemId: - type: string - docs: Unique identifier for the Item - cmsLocaleIds: - type: optional> - docs: Array of identifiers for the locales where the item will be created - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - Single CMS Item: - properties: - name: - type: string - docs: The name of the item. - slug: - type: string - docs: >- - URL slug for the item in your site. - - Note: Updating the item slug will break all links referencing the old - slug. - extra-properties: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - CreateBulkCollectionItemRequestBodyFieldDataItem: - docs: A single CMS item to create - properties: - name: - type: string - docs: The name of the item. - slug: - type: string - docs: >- - URL slug for the item in your site. - - Note: Updating the item slug will break all links referencing the old - slug. - extra-properties: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - CreateBulkCollectionItemRequestBodyFieldData: - discriminated: false - union: - - Single CMS Item - - docs: A list of CMS items to create - type: list - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - ItemsPublishItemResponse: - properties: - publishedItemIds: optional> - errors: optional> - source: - openapi: ../../../openapi/referenced-specs/v2.yml -imports: - root: ../__package__.yml -service: - auth: false - base-path: '' - endpoints: - list-items: - path: /collections/{collection_id}/items - method: GET - auth: true - docs: | - List of all Items within a Collection. - - Required scope | `CMS:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - collection_id: - type: string - docs: Unique identifier for a Collection - display-name: List Collection Items - request: - name: ItemsListItemsRequest - query-parameters: - cmsLocaleId: - type: optional - docs: >- - Unique identifier for a CMS Locale. This UID is different from the - Site locale identifier and is listed as `cmsLocaleId` in the Sites - response. To query multiple locales, input a comma separated - string. - offset: - type: optional - docs: >- - Offset used for pagination if the results have more than limit - records - limit: - type: optional - docs: 'Maximum number of records to be returned (max limit: 100)' - name: - type: optional - docs: The name of the item(s) - slug: - type: optional - docs: The slug of the item - sortBy: - type: optional - docs: Sort results by the provided value - sortOrder: - type: optional - docs: Sorts the results by asc or desc - response: - docs: Request was successful - type: root.CollectionItemList - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - response: - body: - items: - - id: 62b720ef280c7a7a3be8cabe - cmsLocaleId: 66f6e966c9e1dc700a857ca3 - lastPublished: '2022-06-30T13:35:20.878Z' - lastUpdated: '2022-06-25T14:51:27.809Z' - createdOn: '2022-06-25T14:51:27.809Z' - isArchived: false - isDraft: false - fieldData: - name: Senior Data Analyst - slug: senior-data-analyst - url: https://boards.greenhouse.io/webflow/jobs/26567701 - department: Data - - id: 62c880ef281c7b7b4cf9dabc - cmsLocaleId: 66f6e966c9e1dc700a857ca3 - lastPublished: '2023-04-15T10:25:18.123Z' - lastUpdated: '2023-04-10T11:45:30.567Z' - createdOn: '2023-04-10T11:45:30.567Z' - isArchived: false - isDraft: false - fieldData: - name: Product Manager - slug: product-manager - url: https://boards.greenhouse.io/webflow/jobs/31234567 - department: Product - pagination: - limit: 25 - offset: 0 - total: 2 - create-item: - path: /collections/{collection_id}/items - method: POST - auth: true - docs: > - Create Item(s) in a Collection. - - - - To create items across multiple locales, please use [this - endpoint.](/v2.0.0/data/reference/cms/collection-items/staged-items/create-items) - - - Required scope | `CMS:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - collection_id: - type: string - docs: Unique identifier for a Collection - display-name: Create Collection Item(s) - request: - body: ItemsCreateItemRequest - content-type: application/json - response: - docs: Request was successful - type: root.CollectionItem - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - name: SingleItem - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - request: - isArchived: false - isDraft: false - fieldData: - name: Pan Galactic Gargle Blaster Recipe - slug: pan-galactic-gargle-blaster - date: '2022-11-18T00:00:00.000Z' - featured: true - color: '#db4b68' - response: - body: - id: 42b720ef280c7a7a3be8cabe - cmsLocaleId: 653ad57de882f528b32e810e - lastPublished: '2022-11-29T16:22:43.159Z' - lastUpdated: '2022-11-17T17:19:43.282Z' - createdOn: '2022-11-17T17:11:57.148Z' - isArchived: false - isDraft: false - fieldData: - name: Pan Galactic Gargle Blaster Recipe - slug: pan-galactic-gargle-blaster - color: '#db4b68' - date: '2022-11-18T00:00:00.000Z' - featured: true - - name: MultipleItems - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - request: - items: - - isArchived: false - isDraft: false - fieldData: - name: Senior Data Analyst - slug: senior-data-analyst - url: https://boards.greenhouse.io/webflow/jobs/26567701 - department: Data - - isArchived: false - isDraft: false - fieldData: - name: Product Manager - slug: product-manager - url: https://boards.greenhouse.io/webflow/jobs/31234567 - department: Product - response: - body: - id: id - cmsLocaleId: 653ad57de882f528b32e810e - lastPublished: '2023-03-17T18:47:35.560Z' - lastUpdated: '2023-03-17T18:47:35.560Z' - createdOn: '2023-03-17T18:47:35.560Z' - isArchived: true - isDraft: true - fieldData: - name: My new item - slug: my-new-item - date: '2022-11-18T00:00:00.000Z' - featured: false - color: '#db4b68' - delete-items: - path: /collections/{collection_id}/items - method: DELETE - auth: true - docs: > - Delete Items from a Collection. - - - **Note:** If the `cmsLocaleId` parameter is undefined or empty and the - items are localized, items will be deleted only in the primary locale. - - - Required scope | `CMS:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - collection_id: - type: string - docs: Unique identifier for a Collection - display-name: Delete Collection Items - request: - name: ItemsDeleteItemsRequest - body: - properties: - items: optional> - content-type: application/json - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.ConflictError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - request: {} - update-items: - path: /collections/{collection_id}/items - method: PATCH - auth: true - docs: > - Update a single item or multiple items (up to 100) in a Collection. - - - **Note:** If the `cmsLocaleId` parameter is undefined or empty and the - items are localized, items will be updated only in the primary locale. - - - Required scope | `CMS:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - collection_id: - type: string - docs: Unique identifier for a Collection - display-name: Update Collection Items - request: - name: ItemsUpdateItemsRequest - body: - properties: - items: optional> - content-type: application/json - response: - docs: Request was successful - type: root.CollectionItem - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - name: LocalizedItems - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - request: - items: - - id: 66f6ed9576ddacf3149d5ea6 - cmsLocaleId: 66f6e966c9e1dc700a857ca5 - fieldData: - name: Ne Paniquez Pas - slug: ne-paniquez-pas - featured: false - - id: 66f6ed9576ddacf3149d5ea6 - cmsLocaleId: 66f6e966c9e1dc700a857ca4 - fieldData: - name: No Entrar en Pánico - slug: no-entrar-en-panico - featured: false - - id: 66f6ed9576ddacf3149d5eaa - cmsLocaleId: 66f6e966c9e1dc700a857ca5 - fieldData: - name: Au Revoir et Merci pour Tous les Poissons - slug: au-revoir-et-merci - featured: false - - id: 66f6ed9576ddacf3149d5eaa - cmsLocaleId: 66f6e966c9e1dc700a857ca4 - fieldData: - name: Hasta Luego y Gracias por Todo el Pescado - slug: hasta-luego-y-gracias - featured: false - response: - body: - id: id - cmsLocaleId: 653ad57de882f528b32e810e - lastPublished: '2023-03-17T18:47:35.560Z' - lastUpdated: '2023-03-17T18:47:35.560Z' - createdOn: '2023-03-17T18:47:35.560Z' - isArchived: true - isDraft: true - fieldData: - name: My new item - slug: my-new-item - date: '2022-11-18T00:00:00.000Z' - featured: false - color: '#db4b68' - - name: MultipleItems - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - request: - items: - - id: 580e64008c9a982ac9b8b754 - isArchived: false - isDraft: false - fieldData: - name: Senior Data Analyst - slug: senior-data-analyst - url: https://boards.greenhouse.io/webflow/jobs/26567701 - department: Data - - id: 580e64008c9a982ac9b8b754 - isArchived: false - isDraft: false - fieldData: - name: Product Manager - slug: product-manager - url: https://boards.greenhouse.io/webflow/jobs/31234567 - department: Product - response: - body: - id: id - cmsLocaleId: 653ad57de882f528b32e810e - lastPublished: '2023-03-17T18:47:35.560Z' - lastUpdated: '2023-03-17T18:47:35.560Z' - createdOn: '2023-03-17T18:47:35.560Z' - isArchived: true - isDraft: true - fieldData: - name: My new item - slug: my-new-item - date: '2022-11-18T00:00:00.000Z' - featured: false - color: '#db4b68' - - name: Multiple items updated across multiple locales - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - request: - items: - - id: 66f6ed9576ddacf3149d5ea6 - cmsLocaleId: 66f6e966c9e1dc700a857ca5 - fieldData: - name: Ne Paniquez Pas - slug: ne-paniquez-pas - featured: false - - id: 66f6ed9576ddacf3149d5ea6 - cmsLocaleId: 66f6e966c9e1dc700a857ca4 - fieldData: - name: No Entrar en Pánico - slug: no-entrar-en-panico - featured: false - - id: 66f6ed9576ddacf3149d5eaa - cmsLocaleId: 66f6e966c9e1dc700a857ca5 - fieldData: - name: Au Revoir et Merci pour Tous les Poissons - slug: au-revoir-et-merci - featured: false - - id: 66f6ed9576ddacf3149d5eaa - cmsLocaleId: 66f6e966c9e1dc700a857ca4 - fieldData: - name: Hasta Luego y Gracias por Todo el Pescado - slug: hasta-luego-y-gracias - featured: false - response: - body: - id: id - cmsLocaleId: 653ad57de882f528b32e810e - lastPublished: '2023-03-17T18:47:35.560Z' - lastUpdated: '2023-03-17T18:47:35.560Z' - createdOn: '2023-03-17T18:47:35.560Z' - isArchived: true - isDraft: true - fieldData: - name: My new item - slug: my-new-item - date: '2022-11-18T00:00:00.000Z' - featured: false - color: '#db4b68' - - name: Mulitple items updated in a single locale - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - request: - items: - - id: 66f6ed9576ddacf3149d5ea6 - cmsLocaleId: 66f6e966c9e1dc700a857ca5 - fieldData: - name: Ne Paniquez Pas - slug: ne-paniquez-pas - featured: false - - id: 66f6ed9576ddacf3149d5ea6 - cmsLocaleId: 66f6e966c9e1dc700a857ca4 - fieldData: - name: No Entrar en Pánico - slug: no-entrar-en-panico - featured: false - - id: 66f6ed9576ddacf3149d5eaa - cmsLocaleId: 66f6e966c9e1dc700a857ca5 - fieldData: - name: Au Revoir et Merci pour Tous les Poissons - slug: au-revoir-et-merci - featured: false - - id: 66f6ed9576ddacf3149d5eaa - cmsLocaleId: 66f6e966c9e1dc700a857ca4 - fieldData: - name: Hasta Luego y Gracias por Todo el Pescado - slug: hasta-luego-y-gracias - featured: false - response: - body: - id: id - cmsLocaleId: 653ad57de882f528b32e810e - lastPublished: '2023-03-17T18:47:35.560Z' - lastUpdated: '2023-03-17T18:47:35.560Z' - createdOn: '2023-03-17T18:47:35.560Z' - isArchived: true - isDraft: true - fieldData: - name: My new item - slug: my-new-item - date: '2022-11-18T00:00:00.000Z' - featured: false - color: '#db4b68' - list-items-live: - path: /collections/{collection_id}/items/live - method: GET - auth: true - docs: | - List of all live Items within a Collection. - - Required scope | `CMS:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - collection_id: - type: string - docs: Unique identifier for a Collection - display-name: List Live Collection Items - request: - name: ItemsListItemsLiveRequest - query-parameters: - cmsLocaleId: - type: optional - docs: >- - Unique identifier for a CMS Locale. This UID is different from the - Site locale identifier and is listed as `cmsLocaleId` in the Sites - response. To query multiple locales, input a comma separated - string. - offset: - type: optional - docs: >- - Offset used for pagination if the results have more than limit - records - limit: - type: optional - docs: 'Maximum number of records to be returned (max limit: 100)' - name: - type: optional - docs: The name of the item(s) - slug: - type: optional - docs: The slug of the item - sortBy: - type: optional - docs: Sort results by the provided value - sortOrder: - type: optional - docs: Sorts the results by asc or desc - response: - docs: Request was successful - type: root.CollectionItemList - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - response: - body: - items: - - id: 62b720ef280c7a7a3be8cabe - cmsLocaleId: 66f6e966c9e1dc700a857ca3 - lastPublished: '2022-06-30T13:35:20.878Z' - lastUpdated: '2022-06-25T14:51:27.809Z' - createdOn: '2022-06-25T14:51:27.809Z' - isArchived: false - isDraft: false - fieldData: - name: Senior Data Analyst - slug: senior-data-analyst - url: https://boards.greenhouse.io/webflow/jobs/26567701 - department: Data - - id: 62c880ef281c7b7b4cf9dabc - cmsLocaleId: 66f6e966c9e1dc700a857ca3 - lastPublished: '2023-04-15T10:25:18.123Z' - lastUpdated: '2023-04-10T11:45:30.567Z' - createdOn: '2023-04-10T11:45:30.567Z' - isArchived: false - isDraft: false - fieldData: - name: Product Manager - slug: product-manager - url: https://boards.greenhouse.io/webflow/jobs/31234567 - department: Product - pagination: - limit: 25 - offset: 0 - total: 2 - create-item-live: - path: /collections/{collection_id}/items/live - method: POST - auth: true - docs: > - Create live Item(s) in a Collection. The Item(s) will be published to - the live site. - - - - To create items across multiple locales, [please use this - endpoint.](/v2.0.0/data/reference/cms/collection-items/staged-items/create-items) - - - - Required scope | `CMS:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - collection_id: - type: string - docs: Unique identifier for a Collection - display-name: Create Live Collection Item(s) - request: - body: ItemsCreateItemLiveRequest - content-type: application/json - response: - docs: Request was successful - type: root.CollectionItem - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - name: SingleItem - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - request: - isArchived: false - isDraft: false - fieldData: - name: Pan Galactic Gargle Blaster Recipe - slug: pan-galactic-gargle-blaster - date: '2022-11-18T00:00:00.000Z' - featured: true - color: '#db4b68' - response: - body: - id: 42b720ef280c7a7a3be8cabe - cmsLocaleId: 653ad57de882f528b32e810e - lastPublished: '2022-11-29T16:22:43.159Z' - lastUpdated: '2022-11-17T17:19:43.282Z' - createdOn: '2022-11-17T17:11:57.148Z' - isArchived: false - isDraft: false - fieldData: - name: Pan Galactic Gargle Blaster Recipe - slug: pan-galactic-gargle-blaster - color: '#db4b68' - date: '2022-11-18T00:00:00.000Z' - featured: true - - name: MultipleItems - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - request: - items: - - isArchived: false - isDraft: false - fieldData: - name: Senior Data Analyst - slug: senior-data-analyst - url: https://boards.greenhouse.io/webflow/jobs/26567701 - department: Data - - isArchived: false - isDraft: false - fieldData: - name: Product Manager - slug: product-manager - url: https://boards.greenhouse.io/webflow/jobs/31234567 - department: Product - response: - body: - id: 42b720ef280c7a7a3be8cabe - cmsLocaleId: 653ad57de882f528b32e810e - lastPublished: '2022-11-29T16:22:43.159Z' - lastUpdated: '2022-11-17T17:19:43.282Z' - createdOn: '2022-11-17T17:11:57.148Z' - isArchived: false - isDraft: false - fieldData: - name: Pan Galactic Gargle Blaster Recipe - slug: pan-galactic-gargle-blaster - color: '#db4b68' - date: '2022-11-18T00:00:00.000Z' - featured: true - delete-items-live: - path: /collections/{collection_id}/items/live - method: DELETE - auth: true - docs: > - Remove an item or multiple items (up to 100 items) from the live site. - Deleting published items will unpublish the items from the live site and - set them to draft. - - - **Note:** If the `cmsLocaleId` parameter is undefined or empty and the - items are localized, items will be unpublished only in the primary - locale. - - - Required scope | `CMS:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - collection_id: - type: string - docs: Unique identifier for a Collection - display-name: Delete Live Collection Items - request: - name: ItemsDeleteItemsLiveRequest - body: - properties: - items: optional> - content-type: application/json - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - request: {} - update-items-live: - path: /collections/{collection_id}/items/live - method: PATCH - auth: true - docs: > - Update a single live item or multiple live items (up to 100) in a - Collection - - - **Note:** If the `cmsLocaleId` parameter is undefined or empty and the - items are localized, items will be updated only in the primary locale. - - - Required scope | `CMS:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - collection_id: - type: string - docs: Unique identifier for a Collection - display-name: Update Live Collection Items - request: - name: ItemsUpdateItemsLiveRequest - body: - properties: - items: optional> - content-type: application/json - response: - docs: Request was successful - type: root.CollectionItemListNoPagination - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - name: LocalizedItems - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - request: - items: - - id: 66f6ed9576ddacf3149d5ea6 - cmsLocaleId: 66f6e966c9e1dc700a857ca5 - fieldData: - name: Ne Paniquez Pas - slug: ne-paniquez-pas - featured: false - - id: 66f6ed9576ddacf3149d5ea6 - cmsLocaleId: 66f6e966c9e1dc700a857ca4 - fieldData: - name: No Entrar en Pánico - slug: no-entrar-en-panico - featured: false - - id: 66f6ed9576ddacf3149d5eaa - cmsLocaleId: 66f6e966c9e1dc700a857ca5 - fieldData: - name: Au Revoir et Merci pour Tous les Poissons - slug: au-revoir-et-merci - featured: false - - id: 66f6ed9576ddacf3149d5eaa - cmsLocaleId: 66f6e966c9e1dc700a857ca4 - fieldData: - name: Hasta Luego y Gracias por Todo el Pescado - slug: hasta-luego-y-gracias - featured: false - response: - body: - items: - - id: 66f6ed9576ddacf3149d5ea6 - cmsLocaleId: 66f6e966c9e1dc700a857ca5 - lastPublished: '2023-03-17T18:47:35.560Z' - lastUpdated: '2024-09-27T17:38:29.066Z' - createdOn: '2024-09-27T17:38:29.066Z' - isArchived: true - isDraft: true - fieldData: - name: Ne Paniquez Pas - slug: ne-paniquez-pas - featured: false - - id: 66f6ed9576ddacf3149d5ea6 - cmsLocaleId: 66f6e966c9e1dc700a857ca4 - lastPublished: '2023-03-17T18:47:35.560Z' - lastUpdated: '2024-09-27T17:38:29.066Z' - createdOn: '2024-09-27T17:38:29.066Z' - isArchived: true - isDraft: true - fieldData: - name: No Entrar en Pánico - slug: no-entrar-en-panico - featured: false - - id: 66f6ed9576ddacf3149d5eaa - cmsLocaleId: 66f6e966c9e1dc700a857ca5 - lastPublished: '2023-03-17T18:47:35.560Z' - lastUpdated: '2024-09-27T17:38:29.066Z' - createdOn: '2024-09-27T17:38:29.066Z' - isArchived: true - isDraft: true - fieldData: - name: Au Revoir et Merci pour Tous les Poissons - slug: au-revoir-et-merci - featured: false - - id: 66f6ed9576ddacf3149d5eaa - cmsLocaleId: 66f6e966c9e1dc700a857ca4 - lastPublished: '2023-03-17T18:47:35.560Z' - lastUpdated: '2024-09-27T17:38:29.066Z' - createdOn: '2024-09-27T17:38:29.066Z' - isArchived: true - isDraft: true - fieldData: - name: Hasta Luego y Gracias por Todo el Pescado - slug: hasta-luego-y-gracias - featured: false - - name: MultipleItems - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - request: - items: - - id: 580e64008c9a982ac9b8b754 - isArchived: false - isDraft: false - fieldData: - name: Senior Data Analyst - slug: senior-data-analyst - url: https://boards.greenhouse.io/webflow/jobs/26567701 - department: Data - - id: 580e64008c9a982ac9b8b754 - isArchived: false - isDraft: false - fieldData: - name: Product Manager - slug: product-manager - url: https://boards.greenhouse.io/webflow/jobs/31234567 - department: Product - response: - body: - items: - - id: 66f6ed9576ddacf3149d5ea6 - cmsLocaleId: 66f6e966c9e1dc700a857ca5 - lastPublished: '2023-03-17T18:47:35.560Z' - lastUpdated: '2024-09-27T17:38:29.066Z' - createdOn: '2024-09-27T17:38:29.066Z' - isArchived: true - isDraft: true - fieldData: - name: Ne Paniquez Pas - slug: ne-paniquez-pas - featured: false - - id: 66f6ed9576ddacf3149d5ea6 - cmsLocaleId: 66f6e966c9e1dc700a857ca4 - lastPublished: '2023-03-17T18:47:35.560Z' - lastUpdated: '2024-09-27T17:38:29.066Z' - createdOn: '2024-09-27T17:38:29.066Z' - isArchived: true - isDraft: true - fieldData: - name: No Entrar en Pánico - slug: no-entrar-en-panico - featured: false - - id: 66f6ed9576ddacf3149d5eaa - cmsLocaleId: 66f6e966c9e1dc700a857ca5 - lastPublished: '2023-03-17T18:47:35.560Z' - lastUpdated: '2024-09-27T17:38:29.066Z' - createdOn: '2024-09-27T17:38:29.066Z' - isArchived: true - isDraft: true - fieldData: - name: Au Revoir et Merci pour Tous les Poissons - slug: au-revoir-et-merci - featured: false - - id: 66f6ed9576ddacf3149d5eaa - cmsLocaleId: 66f6e966c9e1dc700a857ca4 - lastPublished: '2023-03-17T18:47:35.560Z' - lastUpdated: '2024-09-27T17:38:29.066Z' - createdOn: '2024-09-27T17:38:29.066Z' - isArchived: true - isDraft: true - fieldData: - name: Hasta Luego y Gracias por Todo el Pescado - slug: hasta-luego-y-gracias - featured: false - - name: Multiple items updated across multiple locales - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - request: - items: - - id: 66f6ed9576ddacf3149d5ea6 - cmsLocaleId: 66f6e966c9e1dc700a857ca5 - fieldData: - name: Ne Paniquez Pas - slug: ne-paniquez-pas - featured: false - - id: 66f6ed9576ddacf3149d5ea6 - cmsLocaleId: 66f6e966c9e1dc700a857ca4 - fieldData: - name: No Entrar en Pánico - slug: no-entrar-en-panico - featured: false - - id: 66f6ed9576ddacf3149d5eaa - cmsLocaleId: 66f6e966c9e1dc700a857ca5 - fieldData: - name: Au Revoir et Merci pour Tous les Poissons - slug: au-revoir-et-merci - featured: false - - id: 66f6ed9576ddacf3149d5eaa - cmsLocaleId: 66f6e966c9e1dc700a857ca4 - fieldData: - name: Hasta Luego y Gracias por Todo el Pescado - slug: hasta-luego-y-gracias - featured: false - response: - body: - items: - - id: 66f6ed9576ddacf3149d5ea6 - cmsLocaleId: 66f6e966c9e1dc700a857ca5 - lastPublished: '2023-03-17T18:47:35.560Z' - lastUpdated: '2024-09-27T17:38:29.066Z' - createdOn: '2024-09-27T17:38:29.066Z' - isArchived: true - isDraft: true - fieldData: - name: Ne Paniquez Pas - slug: ne-paniquez-pas - featured: false - - id: 66f6ed9576ddacf3149d5ea6 - cmsLocaleId: 66f6e966c9e1dc700a857ca4 - lastPublished: '2023-03-17T18:47:35.560Z' - lastUpdated: '2024-09-27T17:38:29.066Z' - createdOn: '2024-09-27T17:38:29.066Z' - isArchived: true - isDraft: true - fieldData: - name: No Entrar en Pánico - slug: no-entrar-en-panico - featured: false - - id: 66f6ed9576ddacf3149d5eaa - cmsLocaleId: 66f6e966c9e1dc700a857ca5 - lastPublished: '2023-03-17T18:47:35.560Z' - lastUpdated: '2024-09-27T17:38:29.066Z' - createdOn: '2024-09-27T17:38:29.066Z' - isArchived: true - isDraft: true - fieldData: - name: Au Revoir et Merci pour Tous les Poissons - slug: au-revoir-et-merci - featured: false - - id: 66f6ed9576ddacf3149d5eaa - cmsLocaleId: 66f6e966c9e1dc700a857ca4 - lastPublished: '2023-03-17T18:47:35.560Z' - lastUpdated: '2024-09-27T17:38:29.066Z' - createdOn: '2024-09-27T17:38:29.066Z' - isArchived: true - isDraft: true - fieldData: - name: Hasta Luego y Gracias por Todo el Pescado - slug: hasta-luego-y-gracias - featured: false - - name: Mulitple items updated in a single locale - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - request: - items: - - id: 66f6ed9576ddacf3149d5ea6 - cmsLocaleId: 66f6e966c9e1dc700a857ca5 - fieldData: - name: Ne Paniquez Pas - slug: ne-paniquez-pas - featured: false - - id: 66f6ed9576ddacf3149d5ea6 - cmsLocaleId: 66f6e966c9e1dc700a857ca4 - fieldData: - name: No Entrar en Pánico - slug: no-entrar-en-panico - featured: false - - id: 66f6ed9576ddacf3149d5eaa - cmsLocaleId: 66f6e966c9e1dc700a857ca5 - fieldData: - name: Au Revoir et Merci pour Tous les Poissons - slug: au-revoir-et-merci - featured: false - - id: 66f6ed9576ddacf3149d5eaa - cmsLocaleId: 66f6e966c9e1dc700a857ca4 - fieldData: - name: Hasta Luego y Gracias por Todo el Pescado - slug: hasta-luego-y-gracias - featured: false - response: - body: - items: - - id: 62b720ef280c7a7a3be8cabe - cmsLocaleId: 66f6e966c9e1dc700a857ca3 - lastPublished: '2022-06-30T13:35:20.878Z' - lastUpdated: '2022-06-25T14:51:27.809Z' - createdOn: '2022-06-25T14:51:27.809Z' - isArchived: false - isDraft: false - fieldData: - name: Senior Data Analyst - slug: senior-data-analyst - url: https://boards.greenhouse.io/webflow/jobs/26567701 - department: Data - - id: 62c880ef281c7b7b4cf9dabc - cmsLocaleId: 66f6e966c9e1dc700a857ca3 - lastPublished: '2023-04-15T10:25:18.123Z' - lastUpdated: '2023-04-10T11:45:30.567Z' - createdOn: '2023-04-10T11:45:30.567Z' - isArchived: false - isDraft: false - fieldData: - name: Product Manager - slug: product-manager - url: https://boards.greenhouse.io/webflow/jobs/31234567 - department: Product - create-items: - path: /collections/{collection_id}/items/bulk - method: POST - auth: true - docs: > - Create an item or multiple items in a CMS Collection across multiple - corresponding locales. - - - **Notes:** - - This endpoint can create up to 100 items in a request. - - If the `cmsLocaleIds` parameter is undefined or empty and localization is enabled, items will only be created in the primary locale. - - Required scope | `CMS:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - collection_id: - type: string - docs: Unique identifier for a Collection - display-name: Create Collection Items - request: - name: CreateBulkCollectionItemRequestBody - body: - properties: - cmsLocaleIds: - type: optional> - docs: >- - Array of identifiers for the locales where the item will be - created - isArchived: - type: optional - docs: Indicates whether the item is archived. - default: false - isDraft: - type: optional - docs: Indicates whether the item is in draft state. - default: false - fieldData: CreateBulkCollectionItemRequestBodyFieldData - content-type: application/json - response: - docs: Request was successful - type: root.BulkCollectionItem - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - name: Create a single item across multiple locales - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - request: - cmsLocaleIds: - - 66f6e966c9e1dc700a857ca3 - - 66f6e966c9e1dc700a857ca4 - - 66f6e966c9e1dc700a857ca5 - isArchived: false - isDraft: false - fieldData: - name: Don’t Panic - slug: dont-panic - response: - body: - id: 580e64008c9a982ac9b8b754 - cmsLocaleIds: - - 653ad57de882f528b32e810e - - 6514390aea353fc691d69827 - - 65143930ea353fc691d69cd8 - lastPublished: '2023-03-17T18:47:35.560Z' - lastUpdated: '2023-03-17T18:47:35.560Z' - createdOn: '2023-03-17T18:47:35.560Z' - isArchived: true - isDraft: true - fieldData: - name: My new item - slug: my-new-item - date: '2022-11-18T00:00:00.000Z' - featured: false - color: '#db4b68' - - name: Create multiple items across multipel locales - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - request: - cmsLocaleIds: - - 66f6e966c9e1dc700a857ca3 - - 66f6e966c9e1dc700a857ca4 - isArchived: false - isDraft: false - fieldData: - - name: Don’t Panic - slug: dont-panic - - name: So Long and Thanks for All the Fish - slug: so-long-and-thanks - response: - body: - id: 580e64008c9a982ac9b8b754 - cmsLocaleIds: - - 653ad57de882f528b32e810e - - 6514390aea353fc691d69827 - - 65143930ea353fc691d69cd8 - lastPublished: '2023-03-17T18:47:35.560Z' - lastUpdated: '2023-03-17T18:47:35.560Z' - createdOn: '2023-03-17T18:47:35.560Z' - isArchived: true - isDraft: true - fieldData: - name: My new item - slug: my-new-item - date: '2022-11-18T00:00:00.000Z' - featured: false - color: '#db4b68' - - name: Single item created across multiple locales - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - request: - cmsLocaleIds: - - 66f6e966c9e1dc700a857ca3 - - 66f6e966c9e1dc700a857ca4 - - 66f6e966c9e1dc700a857ca5 - isArchived: false - isDraft: false - fieldData: - name: Don’t Panic - slug: dont-panic - response: - body: - id: 580e64008c9a982ac9b8b754 - cmsLocaleIds: - - 653ad57de882f528b32e810e - - 6514390aea353fc691d69827 - - 65143930ea353fc691d69cd8 - lastPublished: '2023-03-17T18:47:35.560Z' - lastUpdated: '2023-03-17T18:47:35.560Z' - createdOn: '2023-03-17T18:47:35.560Z' - isArchived: true - isDraft: true - fieldData: - name: My new item - slug: my-new-item - date: '2022-11-18T00:00:00.000Z' - featured: false - color: '#db4b68' - - name: Multiple items created across multiple locales - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - request: - cmsLocaleIds: - - 66f6e966c9e1dc700a857ca3 - - 66f6e966c9e1dc700a857ca4 - - 66f6e966c9e1dc700a857ca5 - isArchived: false - isDraft: false - fieldData: - name: Don’t Panic - slug: dont-panic - response: - body: - id: 580e64008c9a982ac9b8b754 - cmsLocaleIds: - - 653ad57de882f528b32e810e - - 6514390aea353fc691d69827 - - 65143930ea353fc691d69cd8 - lastPublished: '2023-03-17T18:47:35.560Z' - lastUpdated: '2023-03-17T18:47:35.560Z' - createdOn: '2023-03-17T18:47:35.560Z' - isArchived: true - isDraft: true - fieldData: - name: My new item - slug: my-new-item - date: '2022-11-18T00:00:00.000Z' - featured: false - color: '#db4b68' - get-item: - path: /collections/{collection_id}/items/{item_id} - method: GET - auth: true - docs: | - Get details of a selected Collection Item. - - Required scope | `CMS:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - collection_id: - type: string - docs: Unique identifier for a Collection - item_id: - type: string - docs: Unique identifier for an Item - display-name: Get Collection Item - request: - name: ItemsGetItemRequest - query-parameters: - cmsLocaleId: - type: optional - docs: >- - Unique identifier for a CMS Locale. This UID is different from the - Site locale identifier and is listed as `cmsLocaleId` in the Sites - response. To query multiple locales, input a comma separated - string. - response: - docs: Request was successful - type: root.CollectionItem - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - item_id: 580e64008c9a982ac9b8b754 - response: - body: - id: 42b720ef280c7a7a3be8cabe - cmsLocaleId: 653ad57de882f528b32e810e - lastPublished: '2022-11-29T16:22:43.159Z' - lastUpdated: '2022-11-17T17:19:43.282Z' - createdOn: '2022-11-17T17:11:57.148Z' - isArchived: false - isDraft: false - fieldData: - name: Pan Galactic Gargle Blaster Recipe - slug: pan-galactic-gargle-blaster - color: '#db4b68' - date: '2022-11-18T00:00:00.000Z' - featured: true - delete-item: - path: /collections/{collection_id}/items/{item_id} - method: DELETE - auth: true - docs: > - Delete an Item from a Collection. This endpoint does not currently - support bulk deletion. - - - Required scope | `CMS:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - collection_id: - type: string - docs: Unique identifier for a Collection - item_id: - type: string - docs: Unique identifier for an Item - display-name: Delete Collection Item - request: - name: ItemsDeleteItemRequest - query-parameters: - cmsLocaleId: - type: optional - docs: >- - Unique identifier for a CMS Locale. This UID is different from the - Site locale identifier and is listed as `cmsLocaleId` in the Sites - response. To query multiple locales, input a comma separated - string. - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - item_id: 580e64008c9a982ac9b8b754 - update-item: - path: /collections/{collection_id}/items/{item_id} - method: PATCH - auth: true - docs: | - Update a selected Item in a Collection. - - Required scope | `CMS:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - collection_id: - type: string - docs: Unique identifier for a Collection - item_id: - type: string - docs: Unique identifier for an Item - display-name: Update Collection Item - request: - body: root.CollectionItemPatchSingle - content-type: application/json - response: - docs: Request was successful - type: root.CollectionItem - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - item_id: 580e64008c9a982ac9b8b754 - request: - isArchived: false - isDraft: false - fieldData: - name: Pan Galactic Gargle Blaster Recipe - slug: pan-galactic-gargle-blaster - date: '2022-11-18T00:00:00.000Z' - featured: true - color: '#db4b68' - response: - body: - id: 42b720ef280c7a7a3be8cabe - cmsLocaleId: 653ad57de882f528b32e810e - lastPublished: '2022-11-29T16:22:43.159Z' - lastUpdated: '2022-11-17T17:19:43.282Z' - createdOn: '2022-11-17T17:11:57.148Z' - isArchived: false - isDraft: false - fieldData: - name: Pan Galactic Gargle Blaster Recipe - slug: pan-galactic-gargle-blaster - color: '#db4b68' - date: '2022-11-18T00:00:00.000Z' - featured: true - get-item-live: - path: /collections/{collection_id}/items/{item_id}/live - method: GET - auth: true - docs: | - Get details of a selected Collection live Item. - - Required scope | `CMS:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - collection_id: - type: string - docs: Unique identifier for a Collection - item_id: - type: string - docs: Unique identifier for an Item - display-name: Get Live Collection Item - request: - name: ItemsGetItemLiveRequest - query-parameters: - cmsLocaleId: - type: optional - docs: >- - Unique identifier for a CMS Locale. This UID is different from the - Site locale identifier and is listed as `cmsLocaleId` in the Sites - response. To query multiple locales, input a comma separated - string. - response: - docs: Request was successful - type: root.CollectionItem - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - item_id: 580e64008c9a982ac9b8b754 - response: - body: - id: 42b720ef280c7a7a3be8cabe - cmsLocaleId: 653ad57de882f528b32e810e - lastPublished: '2022-11-29T16:22:43.159Z' - lastUpdated: '2022-11-17T17:19:43.282Z' - createdOn: '2022-11-17T17:11:57.148Z' - isArchived: false - isDraft: false - fieldData: - name: Pan Galactic Gargle Blaster Recipe - slug: pan-galactic-gargle-blaster - color: '#db4b68' - date: '2022-11-18T00:00:00.000Z' - featured: true - delete-item-live: - path: /collections/{collection_id}/items/{item_id}/live - method: DELETE - auth: true - docs: > - Remove a live item from the site. Removing a published item will - unpublish the item from the live site and set it to draft. - - - This endpoint does not currently support bulk deletion. - - - Required scope | `CMS:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - collection_id: - type: string - docs: Unique identifier for a Collection - item_id: - type: string - docs: Unique identifier for an Item - display-name: Delete Live Collection Item - request: - name: ItemsDeleteItemLiveRequest - query-parameters: - cmsLocaleId: - type: optional - docs: >- - Unique identifier for a CMS Locale. This UID is different from the - Site locale identifier and is listed as `cmsLocaleId` in the Sites - response. To query multiple locales, input a comma separated - string. - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - item_id: 580e64008c9a982ac9b8b754 - update-item-live: - path: /collections/{collection_id}/items/{item_id}/live - method: PATCH - auth: true - docs: > - Update a selected live Item in a Collection. The updates for this Item - will be published to the live site. - - - Required scope | `CMS:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - collection_id: - type: string - docs: Unique identifier for a Collection - item_id: - type: string - docs: Unique identifier for an Item - display-name: Update Live Collection Item - request: - body: root.CollectionItemPatchSingle - content-type: application/json - response: - docs: Request was successful - type: root.CollectionItem - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - item_id: 580e64008c9a982ac9b8b754 - request: - isArchived: false - isDraft: false - fieldData: - name: Pan Galactic Gargle Blaster Recipe - slug: pan-galactic-gargle-blaster - date: '2022-11-18T00:00:00.000Z' - featured: true - color: '#db4b68' - response: - body: - id: 42b720ef280c7a7a3be8cabe - cmsLocaleId: 653ad57de882f528b32e810e - lastPublished: '2022-11-29T16:22:43.159Z' - lastUpdated: '2022-11-17T17:19:43.282Z' - createdOn: '2022-11-17T17:11:57.148Z' - isArchived: false - isDraft: false - fieldData: - name: Pan Galactic Gargle Blaster Recipe - slug: pan-galactic-gargle-blaster - color: '#db4b68' - date: '2022-11-18T00:00:00.000Z' - featured: true - publish-item: - path: /collections/{collection_id}/items/publish - method: POST - auth: true - docs: | - Publish an item or multiple items. - - Required scope | `cms:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - collection_id: - type: string - docs: Unique identifier for a Collection - display-name: Publish Collection Item - request: - name: ItemsPublishItemRequest - body: - properties: - itemIds: list - content-type: application/json - response: - docs: Request was successful - type: ItemsPublishItemResponse - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.ConflictError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - request: - itemIds: - - itemIds - response: - body: - publishedItemIds: - - 643fd856d66b6528195ee2ca - - 643fd856d66b6528195ee2cb - errors: - - Staging item ID 643fd856d66b6528195ee2cf not found. - source: - openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/components.yml b/.mock/definition/components.yml deleted file mode 100644 index b9eb7d6..0000000 --- a/.mock/definition/components.yml +++ /dev/null @@ -1,486 +0,0 @@ -imports: - root: __package__.yml -service: - auth: false - base-path: '' - endpoints: - list: - path: /sites/{site_id}/components - method: GET - auth: true - docs: | - List of all components for a site. - - Required scope | `components:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: List Components - request: - name: ComponentsListRequest - query-parameters: - limit: - type: optional - docs: 'Maximum number of records to be returned (max limit: 100)' - offset: - type: optional - docs: >- - Offset used for pagination if the results have more than limit - records - response: - docs: Request was successful - type: root.ComponentList - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - response: - body: - components: - - id: 6596da6045e56dee495bcbba - name: Primary Button - group: Buttons - description: A default button component that can be used across the site - readonly: true - - id: 658205daa3e8206a523b5ad4 - name: Secondary Button - group: Buttons - description: >- - A secondary button component that can be used across the - site - readonly: true - - id: 6258612d1ee792848f805dcf - name: Card - group: Buttons - description: A button component that can be used across the site - readonly: true - - id: 68a2b1d1ee792848f805dcf - name: Nav - group: Buttons - description: A button component that can be used across the site - readonly: true - pagination: - limit: 20 - offset: 0 - total: 4 - get-content: - path: /sites/{site_id}/components/{component_id}/dom - method: GET - auth: true - docs: > - Get static content from a component definition. This includes text - nodes, image nodes and nested component instances. - - To retrieve dynamic content set by component properties, use the [get - component - properties](/data/reference/pages-and-components/components/get-properties) - endpoint. - - - If you do not provide a Locale ID in your request, the response - will return any content that can be localized from the Primary - locale. - - - Required scope | `components:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - component_id: - type: string - docs: Unique identifier for a Component - display-name: Get Component Content - request: - name: ComponentsGetContentRequest - query-parameters: - localeId: - type: optional - docs: >- - Unique identifier for a specific locale. Applicable, when using - localization. - limit: - type: optional - docs: 'Maximum number of records to be returned (max limit: 100)' - offset: - type: optional - docs: >- - Offset used for pagination if the results have more than limit - records - response: - docs: Request was successful - type: root.ComponentDom - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - name: ComponentDOM - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - component_id: 8505ba55-ef72-629e-f85c-33e4b703d48b - query-parameters: - localeId: 65427cf400e02b306eaa04a0 - response: - body: - componentId: 69118560-d0bc-15fc-bbf8-b8fe5f6535b5 - nodes: - - type: component-instance - id: a245c12d-995b-55ee-5ec7-aa36a6cad623 - componentId: nodes - propertyOverrides: - - propertyId: 7dd14c08-2e96-8d3d-2b19-b5c03642a0f0 - - type: component-instance - id: a245c12d-995b-55ee-5ec7-aa36a6cad627 - componentId: nodes - propertyOverrides: - - propertyId: 7dd14c08-2e96-8d3d-2b19-b5c03642a0f0 - - type: component-instance - id: a245c12d-995b-55ee-5ec7-aa36a6cad629 - componentId: nodes - propertyOverrides: - - propertyId: 7dd14c08-2e96-8d3d-2b19-b5c03642a0f0 - - type: component-instance - id: a245c12d-995b-55ee-5ec7-aa36a6cad631 - componentId: 6258612d1ee792848f805dcf - propertyOverrides: - - propertyId: a245c12d-995b-55ee-5ec7-aa36a6cad633 - type: Plain Text - text: - text: Don't Panic! - - propertyId: a245c12d-995b-55ee-5ec7-aa36a6cad635 - type: Rich Text - text: - html:

Always know where your towel is.

- pagination: - limit: 4 - offset: 0 - total: 4 - - name: LocalizedComponentDOM - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - component_id: 8505ba55-ef72-629e-f85c-33e4b703d48b - query-parameters: - localeId: 65427cf400e02b306eaa04a0 - response: - body: - componentId: 69118560-d0bc-15fc-bbf8-b8fe5f6535b5 - nodes: - - type: component-instance - id: 69118560-d0bc-15fc-bbf8-b8fe5f6535b8 - componentId: nodes - propertyOverrides: - - propertyId: 7dd14c08-2e96-8d3d-2b19-b5c03642a0f0 - - type: component-instance - id: 8ebfb409-7493-3bca-5d48-0e547befb960 - componentId: nodes - propertyOverrides: - - propertyId: 7dd14c08-2e96-8d3d-2b19-b5c03642a0f0 - - type: component-instance - id: 69118560-d0bc-15fc-bbf8-b8fe5f6535c2 - componentId: 69118560-d0bc-15fc-bbf8-b8fe5f6535b5 - propertyOverrides: - - propertyId: a245c12d-995b-55ee-5ec7-aa36a6cad623 - pagination: - limit: 100 - offset: 0 - total: 3 - update-content: - path: /sites/{site_id}/components/{component_id}/dom - method: POST - auth: true - docs: > - This endpoint updates content within a component defintion for - **secondary locales**. It supports updating up to 1000 nodes in a single - request. - - - Before making updates: - - 1. Use the [get component - content](/data/reference/pages-and-components/components/get-content) - endpoint to identify available content nodes and their types - - 2. If your component definition has a component instance nested within - it, retrieve the nested component instance's properties that you'll - override using the [get component - properties](/data/reference/pages-and-components/components/get-properties) - endpoint - - - - This endpoint is specifically for localizing component definitions. Ensure that the specified `localeId` is a valid **secondary locale** for the site otherwise the request will fail. - - - - Required scope | `components:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - component_id: - type: string - docs: Unique identifier for a Component - display-name: Update Component Content - request: - name: ComponentDomWrite - query-parameters: - localeId: - type: optional - docs: >- - Unique identifier for a specific locale. Applicable, when using - localization. - body: - properties: - nodes: - docs: >- - List of DOM Nodes with the new content that will be updated in - each node. - type: list - content-type: application/json - response: - docs: Request was successful - type: ComponentsUpdateContentResponse - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - component_id: 8505ba55-ef72-629e-f85c-33e4b703d48b - query-parameters: - localeId: 65427cf400e02b306eaa04a0 - request: - nodes: - - nodeId: a245c12d-995b-55ee-5ec7-aa36a6cad623 - text:

The Hitchhiker's Guide to the Galaxy

- - nodeId: a245c12d-995b-55ee-5ec7-aa36a6cad627 - text: >- -

Don't Panic!

Always know where your towel - is.

- - nodeId: a245c12d-995b-55ee-5ec7-aa36a6cad629 - propertyOverrides: - - propertyId: 7dd14c08-2e96-8d3d-2b19-b5c03642a0f0 - text:

Time is an illusion

- - propertyId: 7dd14c08-2e96-8d3d-2b19-b5c03642a0f1 - text: Life, the Universe and Everything - response: - body: - errors: - - errors - get-properties: - path: /sites/{site_id}/components/{component_id}/properties - method: GET - auth: true - docs: > - Get the property default values of a component definition. - - - If you do not provide a Locale ID in your request, the response - will return any properties that can be localized from the Primary - locale. - - - Required scope | `components:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - component_id: - type: string - docs: Unique identifier for a Component - display-name: Get Component Properties - request: - name: ComponentsGetPropertiesRequest - query-parameters: - localeId: - type: optional - docs: >- - Unique identifier for a specific locale. Applicable, when using - localization. - limit: - type: optional - docs: 'Maximum number of records to be returned (max limit: 100)' - offset: - type: optional - docs: >- - Offset used for pagination if the results have more than limit - records - response: - docs: Request was successful - type: root.ComponentProperties - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - component_id: 8505ba55-ef72-629e-f85c-33e4b703d48b - query-parameters: - localeId: 65427cf400e02b306eaa04a0 - response: - body: - componentId: 658205daa3e8206a523b5ad4 - properties: - - propertyId: a245c12d-995b-55ee-5ec7-aa36a6cad623 - type: Plain Text - label: Title - text: - text: The Hitchhiker's Guide to the Galaxy - - propertyId: a245c12d-995b-55ee-5ec7-aa36a6cad627 - type: Rich Text - label: Content - text: - html: >- -

Don't Panic!

Always know where your towel - is.

- pagination: - limit: 2 - offset: 0 - total: 2 - update-properties: - path: /sites/{site_id}/components/{component_id}/properties - method: POST - auth: true - docs: > - Update the property default values of a component definition in a - specificed locale. - - - Before making updates: - - 1. Use the [get component - properties](/data/reference/pages-and-components/components/get-properties) - endpoint to identify available properties - - - The request requires a secondary locale ID. If a locale is - missing, the request will not be processed and will result in an - error. - - - Required scope | `components:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - component_id: - type: string - docs: Unique identifier for a Component - display-name: Update Component Properties - request: - name: ComponentPropertiesWrite - query-parameters: - localeId: - type: optional - docs: >- - Unique identifier for a specific locale. Applicable, when using - localization. - body: - properties: - properties: - docs: >- - A list of component properties to update within the specified - secondary locale. - type: list - content-type: application/json - response: - docs: Request was successful - type: ComponentsUpdatePropertiesResponse - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - component_id: 8505ba55-ef72-629e-f85c-33e4b703d48b - query-parameters: - localeId: 65427cf400e02b306eaa04a0 - request: - properties: - - propertyId: a245c12d-995b-55ee-5ec7-aa36a6cad623 - text: The Hitchhiker’s Guide to the Galaxy - - propertyId: a245c12d-995b-55ee-5ec7-aa36a6cad627 - text: >- -

Dont Panic!

Always know where your towel - is.

- response: - body: - errors: - - errors - source: - openapi: ../../../openapi/referenced-specs/v2.yml -types: - ComponentDomWriteNodesItem: - discriminated: false - union: - - root.TextNodeWrite - - root.ComponentInstanceNodePropertyOverridesWrite - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - ComponentsUpdateContentResponse: - properties: - errors: - docs: A list of error messages, if any. - type: list - source: - openapi: ../../../openapi/referenced-specs/v2.yml - ComponentPropertiesWritePropertiesItem: - properties: - propertyId: - type: string - docs: The ID of the property. - text: - type: string - docs: > - The new string or HTML value used to update the component property in - the secondary locale. - - - The provided value must be compatible with the type of the component - property. - - - For example, attempting to update a single-line plain-text property - with a multi-line - - value will result in an error. - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - ComponentsUpdatePropertiesResponse: - properties: - errors: - docs: A list of error messages, if any. - type: list - source: - openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/ecommerce.yml b/.mock/definition/ecommerce.yml deleted file mode 100644 index 1a2ca95..0000000 --- a/.mock/definition/ecommerce.yml +++ /dev/null @@ -1,42 +0,0 @@ -imports: - root: __package__.yml -service: - auth: false - base-path: '' - endpoints: - get-settings: - path: /sites/{site_id}/ecommerce/settings - method: GET - auth: true - docs: | - Retrieve ecommerce settings for a site. - - Required scope | `ecommerce:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: Get Ecommerce Settings - response: - docs: Request was successful - type: root.EcommerceSettings - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.ConflictError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - response: - body: - siteId: 5eb0b5583bf24e2d3a488969 - createdOn: '2018-10-04T15:21:02Z' - defaultCurrency: USD - source: - openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/forms.yml b/.mock/definition/forms.yml deleted file mode 100644 index 9eac177..0000000 --- a/.mock/definition/forms.yml +++ /dev/null @@ -1,302 +0,0 @@ -imports: - root: __package__.yml -service: - auth: false - base-path: '' - endpoints: - list: - path: /sites/{site_id}/forms - method: GET - auth: true - docs: | - List forms for a given site. - - Required scope | `forms:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: List Forms - request: - name: FormsListRequest - query-parameters: - limit: - type: optional - docs: 'Maximum number of records to be returned (max limit: 100)' - offset: - type: optional - docs: >- - Offset used for pagination if the results have more than limit - records - response: - docs: Request was successful - type: root.FormList - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.ConflictError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - response: - body: - forms: - - displayName: Email Form - createdOn: '2016-10-24T19:41:29Z' - lastUpdated: '2016-10-24T19:43:17Z' - fields: - '0': - displayName: Email - userVisible: true - '1': - displayName: Email - userVisible: true - responseSettings: - redirectUrl: https://example.com - redirectMethod: GET - sendEmailConfirmation: true - id: 589a331aa51e760df7ccb89e - siteId: 580e63e98c9a982ac9b8b741 - siteDomainId: 6419db964a9c436a4baf6248 - pageId: 6419db964a9c43f6a3af6348 - pageName: Home - formElementId: 4e038d2c-6a1e-4953-7be9-a59a2b453177 - workspaceId: 580e63fc8c9a982ac9b8b744 - - displayName: Name Form - createdOn: '2016-10-24T19:41:29Z' - lastUpdated: '2016-10-24T19:43:17Z' - fields: - '0': - displayName: Email - userVisible: true - responseSettings: - redirectUrl: https://example.com - redirectMethod: GET - sendEmailConfirmation: false - id: 580ff8d7ba3e45ba9fe588e9 - siteId: 580e63e98c9a982ac9b8b741 - siteDomainId: 6419db964a9c436a4baf6248 - pageId: 6419db964a9c43f6a3af6348 - pageName: Home - formElementId: 4e038d2c-6a1e-4953-7be9-a59a2b453177 - workspaceId: 580e63fc8c9a982ac9b8b744 - pagination: - limit: 25 - offset: 0 - total: 2 - get: - path: /forms/{form_id} - method: GET - auth: true - docs: | - Get information about a given form. - - Required scope | `forms:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - form_id: - type: string - docs: Unique identifier for a Form - display-name: Get Form Schema - response: - docs: Request was successful - type: root.Form - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - form_id: 580e63e98c9a982ac9b8b741 - response: - body: - displayName: Email Form - createdOn: '2016-10-24T19:41:29Z' - lastUpdated: '2016-10-24T19:43:17Z' - fields: - 660d5bcc9c0772150459dfb1: - displayName: Name - type: Plain - placeholder: Enter your email - userVisible: true - 589a331aa51e760df7ccb89d: - displayName: Email - type: Email - placeholder: Enter your email - userVisible: true - responseSettings: - redirectUrl: https://example.com - redirectMethod: GET - redirectAction: POST https://example.com - sendEmailConfirmation: true - id: 589a331aa51e760df7ccb89e - siteId: 580e63e98c9a982ac9b8b741 - siteDomainId: 6419db964a9c436a4baf6248 - pageId: 6419db964a9c43f6a3af6348 - pageName: Home - formElementId: 4e038d2c-6a1e-4953-7be9-a59a2b453177 - workspaceId: 580e63fc8c9a982ac9b8b744 - list-submissions: - path: /forms/{form_id}/submissions - method: GET - auth: true - docs: | - List form submissions for a given form - - Required scope | `forms:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - form_id: - type: string - docs: Unique identifier for a Form - display-name: List Form Submissions - request: - name: FormsListSubmissionsRequest - query-parameters: - offset: - type: optional - docs: >- - Offset used for pagination if the results have more than limit - records - limit: - type: optional - docs: 'Maximum number of records to be returned (max limit: 100)' - response: - docs: Request was successful - type: root.FormSubmissionList - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - form_id: 580e63e98c9a982ac9b8b741 - response: - body: - formSubmissions: - - id: 6321ca84df3949bfc6752327 - displayName: Sample Form - siteId: 62749158efef318abc8d5a0f - workspaceId: 62749158efef318abc8d5a0f - dateSubmitted: '2022-09-14T12:35:16Z' - formResponse: - First Name: Arthur - Last Name: Dent - - id: 660d64fabf6e0a0d4edab981 - displayName: Sample Form - siteId: 62749158efef318abc8d5a0f - workspaceId: 62749158efef318abc8d5a0f - dateSubmitted: '2022-09-14T12:35:16Z' - formResponse: - First Name: Ford - Last Name: Prefect - pagination: - limit: 25 - offset: 0 - total: 2 - get-submission: - path: /form_submissions/{form_submission_id} - method: GET - auth: true - docs: | - Get information about a given form submissio. - - Required scope | `forms:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - form_submission_id: - type: string - docs: Unique identifier for a Form Submission - display-name: Get Form Submission - response: - docs: Request was successful - type: root.FormSubmission - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - form_submission_id: 580e63e98c9a982ac9b8b741 - response: - body: - id: 6321ca84df3949bfc6752327 - displayName: Sample Form - siteId: 62749158efef318abc8d5a0f - workspaceId: 62749158efef318abc8d5a0f - dateSubmitted: '2022-09-14T12:35:16Z' - formResponse: - First Name: Arthur - Last Name: Dent - update-submission: - path: /form_submissions/{form_submission_id} - method: PATCH - auth: true - docs: | - Update hidden fields on a form submission - - Required scope | `forms:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - form_submission_id: - type: string - docs: Unique identifier for a Form Submission - display-name: Modify Form Submission - request: - name: FormsUpdateSubmissionRequest - body: - properties: - formSubmissionData: - type: optional> - docs: >- - An existing **hidden field** defined on the form schema, and the - corresponding value to set - content-type: application/json - response: - docs: Request was successful - type: root.FormSubmission - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.ConflictError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - form_submission_id: 580e63e98c9a982ac9b8b741 - request: {} - response: - body: - id: 6321ca84df3949bfc6752327 - displayName: Sample Form - siteId: 62749158efef318abc8d5a0f - workspaceId: 62749158efef318abc8d5a0f - dateSubmitted: '2022-09-14T12:35:16Z' - formResponse: - First Name: Arthur - Last Name: Dent - source: - openapi: ../../../openapi/referenced-specs/v2.yml - display-name: Forms -docs: Forms are forms that are created on your Webflow site. diff --git a/.mock/definition/inventory.yml b/.mock/definition/inventory.yml deleted file mode 100644 index 5e69c29..0000000 --- a/.mock/definition/inventory.yml +++ /dev/null @@ -1,122 +0,0 @@ -imports: - root: __package__.yml -service: - auth: false - base-path: '' - endpoints: - list: - path: /collections/{collection_id}/items/{item_id}/inventory - method: GET - auth: true - docs: | - List the current inventory levels for a particular SKU item. - - Required scope | `ecommerce:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - collection_id: - type: string - docs: Unique identifier for a Collection - item_id: - type: string - docs: Unique identifier for an Item - display-name: List Inventory - response: - docs: Request was successful - type: root.InventoryItem - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.ConflictError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - item_id: 580e64008c9a982ac9b8b754 - response: - body: - id: 5bfedb42bab0ad90fa7dad39 - quantity: 100 - inventoryType: finite - update: - path: /collections/{collection_id}/items/{item_id}/inventory - method: PATCH - auth: true - docs: > - Updates the current inventory levels for a particular SKU item. - - - Updates may be given in one or two methods, absolutely or - incrementally. - - - Absolute updates are done by setting `quantity` directly. - - - Incremental updates are by specifying the inventory delta in - `updateQuantity` which is then added to the `quantity` stored on the - server. - - - Required scope | `ecommerce:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - collection_id: - type: string - docs: Unique identifier for a Collection - item_id: - type: string - docs: Unique identifier for an Item - display-name: Update Item Inventory - request: - name: InventoryUpdateRequest - body: - properties: - inventoryType: - type: InventoryUpdateRequestInventoryType - docs: infinite or finite - updateQuantity: - type: optional - docs: Adds this quantity to currently store quantity. Can be negative. - quantity: - type: optional - docs: Immediately sets quantity to this value. - content-type: application/json - response: - docs: Request was successful - type: root.InventoryItem - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.ConflictError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - item_id: 580e64008c9a982ac9b8b754 - request: - inventoryType: infinite - response: - body: - id: 5bfedb42bab0ad90fa7dad39 - quantity: 100 - inventoryType: finite - source: - openapi: ../../../openapi/referenced-specs/v2.yml - display-name: Inventory -docs: Inventory is the stock of e-commerce items in your Webflow site. -types: - InventoryUpdateRequestInventoryType: - enum: - - infinite - - finite - docs: infinite or finite - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/orders.yml b/.mock/definition/orders.yml deleted file mode 100644 index b2802cf..0000000 --- a/.mock/definition/orders.yml +++ /dev/null @@ -1,1571 +0,0 @@ -types: - OrdersListRequestStatus: - enum: - - pending - - refunded - - value: dispute-lost - name: DisputeLost - - fulfilled - - disputed - - unfulfilled - source: - openapi: ../../../openapi/referenced-specs/v2.yml - OrdersRefundRequestReason: - enum: - - duplicate - - fraudulent - - requested - docs: The reason for the refund - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml -imports: - root: __package__.yml -service: - auth: false - base-path: '' - endpoints: - list: - path: /sites/{site_id}/orders - method: GET - auth: true - docs: | - List all orders created for a given site. - - Required scope | `ecommerce:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: List Orders - request: - name: OrdersListRequest - query-parameters: - status: - type: optional - docs: Filter the orders by status - offset: - type: optional - docs: >- - Offset used for pagination if the results have more than limit - records - limit: - type: optional - docs: 'Maximum number of records to be returned (max limit: 100)' - response: - docs: Request was successful - type: root.OrderList - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.ConflictError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - response: - body: - orders: - - orderId: 7c1-9fd - status: unfulfilled - comment: >- - Customer requested gift wrapping and a personalized note - saying: Happy Birthday, Ford! 🎉 Please ensure the item is - packed with extra bubble wrap for safe transit. - orderComment: >- - Please gift wrap with a personal note saying "Happy - Birthday, Ford! 🎉 - acceptedOn: '2024-04-10T13:16:21Z' - fulfilledOn: '2018-12-03T22:06:15Z' - refundedOn: '2018-12-03T22:06:15Z' - disputedOn: '2018-12-03T22:06:15Z' - disputeUpdatedOn: '2018-12-03T22:06:15Z' - disputeLastStatus: warning_needs_response - customerPaid: - unit: USD - value: '5892' - string: ' 211.55 USD' - netAmount: - unit: USD - value: '5892' - string: ' 200.89 USD' - applicationFee: - unit: USD - value: '5892' - string: ' 4.23 USD' - allAddresses: - - type: billing - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - - type: shipping - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - shippingAddress: - type: shipping - japanType: kanji - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - billingAddress: - type: billing - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - shippingProvider: Shipping Company, Co. - shippingTracking: tr00000000002 - shippingTrackingURL: https://www.shippingcompany.com/tracking/tr00000000002 - customerInfo: - fullName: Arthur Dent - email: arthur.dent@example.com - purchasedItems: - - count: 2 - rowTotal: - unit: USD - value: '5892' - string: ' 111.22 USD' - productId: 66072fb61b89448912e26791 - productName: Luxurious Fresh Ball - productSlug: luxurious-fresh-ball - variantId: 66072fb71b89448912e2683f - variantName: 'Luxurious Fresh Ball Generic: Bronze, Practical: Plastic' - variantSlug: luxurious-fresh-ball-generic-bronze-practical-plastic - variantSKU: luxurious-fresh-ball-generic-bronze-practical-plastic - variantImage: - url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg - variantPrice: - unit: USD - value: '5892' - string: ' 55.61 USD' - weight: 11 - width: 82 - height: 70 - length: 9 - - count: 1 - rowTotal: - unit: USD - value: '5892' - string: ' 83.09 USD' - productId: 66072fb61b89448912e2678b - productName: Incredible Bronze Towels - productSlug: incredible-bronze-towels - variantId: 66072fb71b89448912e2681e - variantName: >- - Incredible Bronze Towels Sleek: Frozen, Incredible: - Metal - variantSlug: incredible-bronze-towels-sleek-frozen-incredible-metal - variantSKU: incredible-bronze-towels-sleek-frozen-incredible-metal - variantImage: - url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e26729_image16.jpeg - variantPrice: - unit: USD - value: '5892' - string: ' 83.09 USD' - width: 19 - height: 72 - length: 18 - purchasedItemsCount: 3 - stripeDetails: - paymentMethod: pm_1P410gJYFi4lcbXWbeKghqjK - paymentIntentId: pi_3P410iJYFi4lcbXW0EKKgcVg - customerId: cus_Ptod8KJBiiPgnH - chargeId: ch_3P410iJYFi4lcbXW0DxUkzCH - stripeCard: - last4: '4242' - brand: Visa - ownerName: Arthur Dent - expires: - year: 2025 - month: 4 - paypalDetails: - orderId: 1a2b3c4d5e6f7g8h9i0j - payerId: 9k8j7i6h5g4f3e2d1c0b - captureId: qwe123rty456uio789p - refundId: abcde12345fghij67890 - refundReason: Customer requested refund - disputeId: zxcvbnm987poiuytrewq - customData: - - key: value - metadata: - isBuyNow: false - isCustomerDeleted: false - isShippingRequired: false - hasDownloads: false - paymentProcessor: stripe - totals: - extras: - - type: tax - name: State Taxes - description: CA Taxes (6.25%) - price: - unit: USD - value: '5892' - string: '3.44' - downloadFiles: - - id: 5e9a5eba75e0ac242e1b6f64 - name: The modern web design process - Webflow Ebook.pdf - url: >- - https://webflow.com/dashboard/download-digital-product?payload=5d93ba5e38c6b0160ab711d3;e7634a;5eb1aac72912ec06f561278c;5e9a5eba75e0ac242e1b6f63:ka2nehxy:4a1ee0a632feaab94294350087215ed89533f2f530903e3b933b638940e921aa - - orderId: fc7-128 - status: refunded - comment: Example comment to myself - orderComment: '' - acceptedOn: '2024-03-29T21:29:21Z' - fulfilledOn: '2018-12-03T22:06:15Z' - refundedOn: '2024-04-08T18:25:04Z' - disputedOn: '2018-12-03T22:06:15Z' - disputeUpdatedOn: '2018-12-03T22:06:15Z' - disputeLastStatus: warning_needs_response - customerPaid: - unit: USD - value: '5892' - string: ' 118.73 USD' - netAmount: - unit: USD - value: '5892' - string: ' 112.62 USD' - applicationFee: - unit: USD - value: '5892' - string: ' 2.37 USD' - allAddresses: - - type: billing - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - - type: shipping - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - shippingAddress: - type: shipping - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - billingAddress: - type: billing - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - shippingProvider: Shipping Company, Co. - shippingTracking: tr00000000001 - shippingTrackingURL: https://www.shippingcompany.com/tracking/tr00000000001 - customerInfo: - fullName: Arthur Dent - email: arthur.dent@example.com - purchasedItems: - - count: 1 - rowTotal: - unit: USD - value: '5892' - string: ' 55.61 USD' - productId: 66072fb61b89448912e26791 - productName: Luxurious Fresh Ball - productSlug: luxurious-fresh-ball - variantId: 66072fb71b89448912e2683f - variantName: 'Luxurious Fresh Ball Generic: Bronze, Practical: Plastic' - variantSlug: luxurious-fresh-ball-generic-bronze-practical-plastic - variantSKU: luxurious-fresh-ball-generic-bronze-practical-plastic - variantImage: - url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg - variantPrice: - unit: USD - value: '5892' - string: ' 55.61 USD' - weight: 11 - width: 82 - height: 70 - length: 9 - - count: 1 - rowTotal: - unit: USD - value: '5892' - string: ' 53.44 USD' - productId: 66072fb61b89448912e26799 - productName: Recycled Steel Gloves - productSlug: recycled-steel-gloves - variantId: 66072fb91b89448912e26ab9 - variantName: >- - Recycled Steel Gloves Electronic: Granite, Handcrafted: - grey - variantSlug: >- - recycled-steel-gloves-electronic-granite-handcrafted-grey - variantSKU: >- - recycled-steel-gloves-electronic-granite-handcrafted-grey - variantImage: - url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2671e_image2.jpeg - variantPrice: - unit: USD - value: '5892' - string: ' 53.44 USD' - weight: 38 - width: 76 - height: 85 - length: 40 - purchasedItemsCount: 2 - stripeDetails: - paymentMethod: pm_1OzmzBJYFi4lcbXWHKNdXU7j - paymentIntentId: pi_3OzmzDJYFi4lcbXW1hTBW6ft - customerId: cus_PpRsNHwWdUoRKR - chargeId: ch_3OzmzDJYFi4lcbXW1ndkkrH2 - refundId: re_3OzmzDJYFi4lcbXW1kFAmlBk - refundReason: fraudulent - stripeCard: - last4: '4242' - brand: Visa - ownerName: Arthur Dent - expires: - year: 2024 - month: 4 - paypalDetails: - orderId: 1a2b3c4d5e6f7g8h9i0j - payerId: 9k8j7i6h5g4f3e2d1c0b - captureId: qwe123rty456uio789p - refundId: abcde12345fghij67890 - refundReason: Customer requested refund - disputeId: zxcvbnm987poiuytrewq - customData: - - key: value - metadata: - isBuyNow: false - isCustomerDeleted: false - isShippingRequired: true - hasDownloads: false - paymentProcessor: stripe - totals: - subtotal: - unit: USD - value: '5892' - string: ' 109.05 USD' - extras: - - type: tax - name: State Taxes - description: NY Taxes (4.00%) - price: - unit: USD - value: '5892' - string: ' 4.36 USD' - - type: tax - name: City Taxes - description: NEW YORK Taxes (4.88%) - price: - unit: USD - value: '5892' - string: ' 5.32 USD' - - type: shipping - name: Flat - description: '' - price: - unit: USD - value: '5892' - string: ' 0.00 USD' - total: - unit: USD - value: '5892' - string: ' 118.73 USD' - downloadFiles: - - id: 5e9a5eba75e0ac242e1b6f64 - name: New product guide - url: >- - https://webflow.com/dashboard/download-digital-product?payload=5d93ba5e38c6b0160ab711d3;e7634a;5eb1aac72912ec06f561278c;5e9a5eba75e0ac242e1b6f63:ka2nehxy:4a1ee0a632feaab94294350087215ed89533f2f530903e3b933b638940e921aa - pagination: - limit: 100 - offset: 0 - total: 2 - get: - path: /sites/{site_id}/orders/{order_id} - method: GET - auth: true - docs: | - Retrieve a single product by its ID. All of its SKUs will also be - retrieved. - - Required scope | `ecommerce:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - order_id: - type: string - docs: Unique identifier for an Order - display-name: Get Order - response: - docs: Request was successful - type: root.Order - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.ConflictError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - order_id: 5e8518516e147040726cc415 - response: - body: - orderId: fc7-128 - status: refunded - comment: >- - Customer requested gift wrapping and a personalized note saying: - Happy Birthday, Ford! 🎉 Please ensure the item is packed with - extra bubble wrap for safe transit. - orderComment: >- - Please gift wrap with a personal note saying "Happy Birthday, - Ford! 🎉 - acceptedOn: '2024-03-29T21:29:21Z' - fulfilledOn: '2024-03-29T21:29:21Z' - refundedOn: '2024-04-08T18:25:04Z' - disputedOn: '2024-03-29T21:29:21Z' - disputeUpdatedOn: '2024-03-29T21:29:21Z' - disputeLastStatus: charge_refunded - customerPaid: - unit: USD - value: '5892' - string: ' 118.73 USD' - netAmount: - unit: USD - value: '5892' - string: ' 112.62 USD' - applicationFee: - unit: USD - value: '5892' - string: ' 2.37 USD' - allAddresses: - - type: billing - japanType: kana - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - - type: shipping - japanType: kana - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - shippingAddress: - type: shipping - japanType: kanji - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - billingAddress: - type: billing - japanType: kana - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - shippingProvider: Shipping Company, Co. - shippingTracking: tr00000000001 - shippingTrackingURL: https://www.shippingcompany.com/tracking/tr00000000001 - customerInfo: - fullName: Arthur Dent - email: arthur.dent@example.com - purchasedItems: - - count: 1 - rowTotal: - unit: USD - value: '5892' - string: ' 55.61 USD' - productId: 66072fb61b89448912e26791 - productName: Luxurious Fresh Ball - productSlug: luxurious-fresh-ball - variantId: 66072fb71b89448912e2683f - variantName: 'Luxurious Fresh Ball Generic: Bronze, Practical: Plastic' - variantSlug: luxurious-fresh-ball-generic-bronze-practical-plastic - variantSKU: luxurious-fresh-ball-generic-bronze-practical-plastic - variantImage: - url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg - variantPrice: - unit: USD - value: '5892' - string: ' 55.61 USD' - weight: 11 - width: 82 - height: 70 - length: 9 - - count: 1 - rowTotal: - unit: USD - value: '5892' - string: ' 53.44 USD' - productId: 66072fb61b89448912e26799 - productName: Recycled Steel Gloves - productSlug: recycled-steel-gloves - variantId: 66072fb91b89448912e26ab9 - variantName: 'Recycled Steel Gloves Electronic: Granite, Handcrafted: grey' - variantSlug: recycled-steel-gloves-electronic-granite-handcrafted-grey - variantSKU: recycled-steel-gloves-electronic-granite-handcrafted-grey - variantImage: - url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2671e_image2.jpeg - variantPrice: - unit: USD - value: '5892' - string: ' 53.44 USD' - weight: 38 - width: 76 - height: 85 - length: 40 - purchasedItemsCount: 2 - stripeDetails: - subscriptionId: sub_1J6xwG2eZvKYlo2CXu9Zt0Tn - paymentMethod: pm_1OzmzBJYFi4lcbXWHKNdXU7j - paymentIntentId: pi_3OzmzDJYFi4lcbXW1hTBW6ft - customerId: cus_PpRsNHwWdUoRKR - chargeId: ch_3OzmzDJYFi4lcbXW1ndkkrH2 - disputeId: disputeId - refundId: re_3OzmzDJYFi4lcbXW1kFAmlBk - refundReason: fraudulent - stripeCard: - last4: '4242' - brand: Visa - ownerName: Arthur Dent - expires: - year: 2024 - month: 4 - paypalDetails: - orderId: 1a2b3c4d5e6f7g8h9i0j - payerId: 9k8j7i6h5g4f3e2d1c0b - captureId: qwe123rty456uio789p - refundId: abcde12345fghij67890 - refundReason: Customer requested refund - disputeId: zxcvbnm987poiuytrewq - customData: - - key: value - metadata: - isBuyNow: false - isCustomerDeleted: false - isShippingRequired: true - hasDownloads: false - paymentProcessor: stripe - totals: - subtotal: - unit: USD - value: '5892' - string: ' 109.05 USD' - extras: - - type: tax - name: State Taxes - description: NY Taxes (4.00%) - price: - unit: USD - value: '5892' - string: ' 4.36 USD' - - type: tax - name: City Taxes - description: NEW YORK Taxes (4.88%) - price: - unit: USD - value: '5892' - string: ' 5.32 USD' - - type: shipping - name: Flat - description: '' - price: - unit: USD - value: '5892' - string: ' 0.00 USD' - total: - unit: USD - value: '5892' - string: ' 118.73 USD' - downloadFiles: - - id: 5e9a5eba75e0ac242e1b6f64 - name: New product guide - url: >- - https://webflow.com/dashboard/download-digital-product?payload=5d93ba5e38c6b0160ab711d3;e7634a;5eb1aac72912ec06f561278c;5e9a5eba75e0ac242e1b6f63:ka2nehxy:4a1ee0a632feaab94294350087215ed89533f2f530903e3b933b638940e921aa - update: - path: /sites/{site_id}/orders/{order_id} - method: PATCH - auth: true - docs: | - This API lets you update the fields, `comment`, `shippingProvider`, - and/or `shippingTracking` for a given order. All three fields can be - updated simultaneously or independently. - - Required scope | `ecommerce:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - order_id: - type: string - docs: Unique identifier for an Order - display-name: Update Order - request: - name: OrdersUpdateRequest - body: - properties: - comment: - type: optional - docs: Arbitrary data for your records - shippingProvider: - type: optional - docs: Company or method used to ship order - shippingTracking: - type: optional - docs: Tracking number for order shipment - shippingTrackingURL: - type: optional - docs: URL to track order shipment - content-type: application/json - response: - docs: Request was successful - type: root.Order - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.ConflictError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - order_id: 5e8518516e147040726cc415 - request: {} - response: - body: - orderId: fc7-128 - status: refunded - comment: >- - Customer requested gift wrapping and a personalized note saying: - Happy Birthday, Ford! 🎉 Please ensure the item is packed with - extra bubble wrap for safe transit. - orderComment: >- - Please gift wrap with a personal note saying "Happy Birthday, - Ford! 🎉 - acceptedOn: '2024-03-29T21:29:21Z' - fulfilledOn: '2024-03-29T21:29:21Z' - refundedOn: '2024-04-08T18:25:04Z' - disputedOn: '2024-03-29T21:29:21Z' - disputeUpdatedOn: '2024-03-29T21:29:21Z' - disputeLastStatus: charge_refunded - customerPaid: - unit: USD - value: '5892' - string: ' 118.73 USD' - netAmount: - unit: USD - value: '5892' - string: ' 112.62 USD' - applicationFee: - unit: USD - value: '5892' - string: ' 2.37 USD' - allAddresses: - - type: billing - japanType: kana - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - - type: shipping - japanType: kana - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - shippingAddress: - type: shipping - japanType: kanji - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - billingAddress: - type: billing - japanType: kana - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - shippingProvider: Shipping Company, Co. - shippingTracking: tr00000000001 - shippingTrackingURL: https://www.shippingcompany.com/tracking/tr00000000001 - customerInfo: - fullName: Arthur Dent - email: arthur.dent@example.com - purchasedItems: - - count: 1 - rowTotal: - unit: USD - value: '5892' - string: ' 55.61 USD' - productId: 66072fb61b89448912e26791 - productName: Luxurious Fresh Ball - productSlug: luxurious-fresh-ball - variantId: 66072fb71b89448912e2683f - variantName: 'Luxurious Fresh Ball Generic: Bronze, Practical: Plastic' - variantSlug: luxurious-fresh-ball-generic-bronze-practical-plastic - variantSKU: luxurious-fresh-ball-generic-bronze-practical-plastic - variantImage: - url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg - variantPrice: - unit: USD - value: '5892' - string: ' 55.61 USD' - weight: 11 - width: 82 - height: 70 - length: 9 - - count: 1 - rowTotal: - unit: USD - value: '5892' - string: ' 53.44 USD' - productId: 66072fb61b89448912e26799 - productName: Recycled Steel Gloves - productSlug: recycled-steel-gloves - variantId: 66072fb91b89448912e26ab9 - variantName: 'Recycled Steel Gloves Electronic: Granite, Handcrafted: grey' - variantSlug: recycled-steel-gloves-electronic-granite-handcrafted-grey - variantSKU: recycled-steel-gloves-electronic-granite-handcrafted-grey - variantImage: - url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2671e_image2.jpeg - variantPrice: - unit: USD - value: '5892' - string: ' 53.44 USD' - weight: 38 - width: 76 - height: 85 - length: 40 - purchasedItemsCount: 2 - stripeDetails: - subscriptionId: sub_1J6xwG2eZvKYlo2CXu9Zt0Tn - paymentMethod: pm_1OzmzBJYFi4lcbXWHKNdXU7j - paymentIntentId: pi_3OzmzDJYFi4lcbXW1hTBW6ft - customerId: cus_PpRsNHwWdUoRKR - chargeId: ch_3OzmzDJYFi4lcbXW1ndkkrH2 - disputeId: disputeId - refundId: re_3OzmzDJYFi4lcbXW1kFAmlBk - refundReason: fraudulent - stripeCard: - last4: '4242' - brand: Visa - ownerName: Arthur Dent - expires: - year: 2024 - month: 4 - paypalDetails: - orderId: 1a2b3c4d5e6f7g8h9i0j - payerId: 9k8j7i6h5g4f3e2d1c0b - captureId: qwe123rty456uio789p - refundId: abcde12345fghij67890 - refundReason: Customer requested refund - disputeId: zxcvbnm987poiuytrewq - customData: - - key: value - metadata: - isBuyNow: false - isCustomerDeleted: false - isShippingRequired: true - hasDownloads: false - paymentProcessor: stripe - totals: - subtotal: - unit: USD - value: '5892' - string: ' 109.05 USD' - extras: - - type: tax - name: State Taxes - description: NY Taxes (4.00%) - price: - unit: USD - value: '5892' - string: ' 4.36 USD' - - type: tax - name: City Taxes - description: NEW YORK Taxes (4.88%) - price: - unit: USD - value: '5892' - string: ' 5.32 USD' - - type: shipping - name: Flat - description: '' - price: - unit: USD - value: '5892' - string: ' 0.00 USD' - total: - unit: USD - value: '5892' - string: ' 118.73 USD' - downloadFiles: - - id: 5e9a5eba75e0ac242e1b6f64 - name: New product guide - url: >- - https://webflow.com/dashboard/download-digital-product?payload=5d93ba5e38c6b0160ab711d3;e7634a;5eb1aac72912ec06f561278c;5e9a5eba75e0ac242e1b6f63:ka2nehxy:4a1ee0a632feaab94294350087215ed89533f2f530903e3b933b638940e921aa - update-fulfill: - path: /sites/{site_id}/orders/{order_id}/fulfill - method: POST - auth: true - docs: | - Updates an order's status to fulfilled - - Required scope | `ecommerce:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - order_id: - type: string - docs: Unique identifier for an Order - display-name: Fulfill Order - request: - name: OrdersUpdateFulfillRequest - body: - properties: - sendOrderFulfilledEmail: - type: optional - docs: Whether or not the Order Fulfilled email should be sent - default: false - content-type: application/json - response: - docs: Request was successful - type: root.Order - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.ConflictError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - order_id: 5e8518516e147040726cc415 - request: {} - response: - body: - orderId: fc7-128 - status: refunded - comment: >- - Customer requested gift wrapping and a personalized note saying: - Happy Birthday, Ford! 🎉 Please ensure the item is packed with - extra bubble wrap for safe transit. - orderComment: >- - Please gift wrap with a personal note saying "Happy Birthday, - Ford! 🎉 - acceptedOn: '2024-03-29T21:29:21Z' - fulfilledOn: '2024-03-29T21:29:21Z' - refundedOn: '2024-04-08T18:25:04Z' - disputedOn: '2024-03-29T21:29:21Z' - disputeUpdatedOn: '2024-03-29T21:29:21Z' - disputeLastStatus: charge_refunded - customerPaid: - unit: USD - value: '5892' - string: ' 118.73 USD' - netAmount: - unit: USD - value: '5892' - string: ' 112.62 USD' - applicationFee: - unit: USD - value: '5892' - string: ' 2.37 USD' - allAddresses: - - type: billing - japanType: kana - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - - type: shipping - japanType: kana - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - shippingAddress: - type: shipping - japanType: kanji - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - billingAddress: - type: billing - japanType: kana - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - shippingProvider: Shipping Company, Co. - shippingTracking: tr00000000001 - shippingTrackingURL: https://www.shippingcompany.com/tracking/tr00000000001 - customerInfo: - fullName: Arthur Dent - email: arthur.dent@example.com - purchasedItems: - - count: 1 - rowTotal: - unit: USD - value: '5892' - string: ' 55.61 USD' - productId: 66072fb61b89448912e26791 - productName: Luxurious Fresh Ball - productSlug: luxurious-fresh-ball - variantId: 66072fb71b89448912e2683f - variantName: 'Luxurious Fresh Ball Generic: Bronze, Practical: Plastic' - variantSlug: luxurious-fresh-ball-generic-bronze-practical-plastic - variantSKU: luxurious-fresh-ball-generic-bronze-practical-plastic - variantImage: - url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg - variantPrice: - unit: USD - value: '5892' - string: ' 55.61 USD' - weight: 11 - width: 82 - height: 70 - length: 9 - - count: 1 - rowTotal: - unit: USD - value: '5892' - string: ' 53.44 USD' - productId: 66072fb61b89448912e26799 - productName: Recycled Steel Gloves - productSlug: recycled-steel-gloves - variantId: 66072fb91b89448912e26ab9 - variantName: 'Recycled Steel Gloves Electronic: Granite, Handcrafted: grey' - variantSlug: recycled-steel-gloves-electronic-granite-handcrafted-grey - variantSKU: recycled-steel-gloves-electronic-granite-handcrafted-grey - variantImage: - url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2671e_image2.jpeg - variantPrice: - unit: USD - value: '5892' - string: ' 53.44 USD' - weight: 38 - width: 76 - height: 85 - length: 40 - purchasedItemsCount: 2 - stripeDetails: - subscriptionId: sub_1J6xwG2eZvKYlo2CXu9Zt0Tn - paymentMethod: pm_1OzmzBJYFi4lcbXWHKNdXU7j - paymentIntentId: pi_3OzmzDJYFi4lcbXW1hTBW6ft - customerId: cus_PpRsNHwWdUoRKR - chargeId: ch_3OzmzDJYFi4lcbXW1ndkkrH2 - disputeId: disputeId - refundId: re_3OzmzDJYFi4lcbXW1kFAmlBk - refundReason: fraudulent - stripeCard: - last4: '4242' - brand: Visa - ownerName: Arthur Dent - expires: - year: 2024 - month: 4 - paypalDetails: - orderId: 1a2b3c4d5e6f7g8h9i0j - payerId: 9k8j7i6h5g4f3e2d1c0b - captureId: qwe123rty456uio789p - refundId: abcde12345fghij67890 - refundReason: Customer requested refund - disputeId: zxcvbnm987poiuytrewq - customData: - - key: value - metadata: - isBuyNow: false - isCustomerDeleted: false - isShippingRequired: true - hasDownloads: false - paymentProcessor: stripe - totals: - subtotal: - unit: USD - value: '5892' - string: ' 109.05 USD' - extras: - - type: tax - name: State Taxes - description: NY Taxes (4.00%) - price: - unit: USD - value: '5892' - string: ' 4.36 USD' - - type: tax - name: City Taxes - description: NEW YORK Taxes (4.88%) - price: - unit: USD - value: '5892' - string: ' 5.32 USD' - - type: shipping - name: Flat - description: '' - price: - unit: USD - value: '5892' - string: ' 0.00 USD' - total: - unit: USD - value: '5892' - string: ' 118.73 USD' - downloadFiles: - - id: 5e9a5eba75e0ac242e1b6f64 - name: New product guide - url: >- - https://webflow.com/dashboard/download-digital-product?payload=5d93ba5e38c6b0160ab711d3;e7634a;5eb1aac72912ec06f561278c;5e9a5eba75e0ac242e1b6f63:ka2nehxy:4a1ee0a632feaab94294350087215ed89533f2f530903e3b933b638940e921aa - update-unfulfill: - path: /sites/{site_id}/orders/{order_id}/unfulfill - method: POST - auth: true - docs: | - Updates an order's status to unfulfilled - - Required scope | `ecommerce:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - order_id: - type: string - docs: Unique identifier for an Order - display-name: Unfulfill Order - response: - docs: Request was successful - type: root.Order - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.ConflictError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - order_id: 5e8518516e147040726cc415 - response: - body: - orderId: fc7-128 - status: refunded - comment: >- - Customer requested gift wrapping and a personalized note saying: - Happy Birthday, Ford! 🎉 Please ensure the item is packed with - extra bubble wrap for safe transit. - orderComment: >- - Please gift wrap with a personal note saying "Happy Birthday, - Ford! 🎉 - acceptedOn: '2024-03-29T21:29:21Z' - fulfilledOn: '2024-03-29T21:29:21Z' - refundedOn: '2024-04-08T18:25:04Z' - disputedOn: '2024-03-29T21:29:21Z' - disputeUpdatedOn: '2024-03-29T21:29:21Z' - disputeLastStatus: charge_refunded - customerPaid: - unit: USD - value: '5892' - string: ' 118.73 USD' - netAmount: - unit: USD - value: '5892' - string: ' 112.62 USD' - applicationFee: - unit: USD - value: '5892' - string: ' 2.37 USD' - allAddresses: - - type: billing - japanType: kana - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - - type: shipping - japanType: kana - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - shippingAddress: - type: shipping - japanType: kanji - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - billingAddress: - type: billing - japanType: kana - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - shippingProvider: Shipping Company, Co. - shippingTracking: tr00000000001 - shippingTrackingURL: https://www.shippingcompany.com/tracking/tr00000000001 - customerInfo: - fullName: Arthur Dent - email: arthur.dent@example.com - purchasedItems: - - count: 1 - rowTotal: - unit: USD - value: '5892' - string: ' 55.61 USD' - productId: 66072fb61b89448912e26791 - productName: Luxurious Fresh Ball - productSlug: luxurious-fresh-ball - variantId: 66072fb71b89448912e2683f - variantName: 'Luxurious Fresh Ball Generic: Bronze, Practical: Plastic' - variantSlug: luxurious-fresh-ball-generic-bronze-practical-plastic - variantSKU: luxurious-fresh-ball-generic-bronze-practical-plastic - variantImage: - url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg - variantPrice: - unit: USD - value: '5892' - string: ' 55.61 USD' - weight: 11 - width: 82 - height: 70 - length: 9 - - count: 1 - rowTotal: - unit: USD - value: '5892' - string: ' 53.44 USD' - productId: 66072fb61b89448912e26799 - productName: Recycled Steel Gloves - productSlug: recycled-steel-gloves - variantId: 66072fb91b89448912e26ab9 - variantName: 'Recycled Steel Gloves Electronic: Granite, Handcrafted: grey' - variantSlug: recycled-steel-gloves-electronic-granite-handcrafted-grey - variantSKU: recycled-steel-gloves-electronic-granite-handcrafted-grey - variantImage: - url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2671e_image2.jpeg - variantPrice: - unit: USD - value: '5892' - string: ' 53.44 USD' - weight: 38 - width: 76 - height: 85 - length: 40 - purchasedItemsCount: 2 - stripeDetails: - subscriptionId: sub_1J6xwG2eZvKYlo2CXu9Zt0Tn - paymentMethod: pm_1OzmzBJYFi4lcbXWHKNdXU7j - paymentIntentId: pi_3OzmzDJYFi4lcbXW1hTBW6ft - customerId: cus_PpRsNHwWdUoRKR - chargeId: ch_3OzmzDJYFi4lcbXW1ndkkrH2 - disputeId: disputeId - refundId: re_3OzmzDJYFi4lcbXW1kFAmlBk - refundReason: fraudulent - stripeCard: - last4: '4242' - brand: Visa - ownerName: Arthur Dent - expires: - year: 2024 - month: 4 - paypalDetails: - orderId: 1a2b3c4d5e6f7g8h9i0j - payerId: 9k8j7i6h5g4f3e2d1c0b - captureId: qwe123rty456uio789p - refundId: abcde12345fghij67890 - refundReason: Customer requested refund - disputeId: zxcvbnm987poiuytrewq - customData: - - key: value - metadata: - isBuyNow: false - isCustomerDeleted: false - isShippingRequired: true - hasDownloads: false - paymentProcessor: stripe - totals: - subtotal: - unit: USD - value: '5892' - string: ' 109.05 USD' - extras: - - type: tax - name: State Taxes - description: NY Taxes (4.00%) - price: - unit: USD - value: '5892' - string: ' 4.36 USD' - - type: tax - name: City Taxes - description: NEW YORK Taxes (4.88%) - price: - unit: USD - value: '5892' - string: ' 5.32 USD' - - type: shipping - name: Flat - description: '' - price: - unit: USD - value: '5892' - string: ' 0.00 USD' - total: - unit: USD - value: '5892' - string: ' 118.73 USD' - downloadFiles: - - id: 5e9a5eba75e0ac242e1b6f64 - name: New product guide - url: >- - https://webflow.com/dashboard/download-digital-product?payload=5d93ba5e38c6b0160ab711d3;e7634a;5eb1aac72912ec06f561278c;5e9a5eba75e0ac242e1b6f63:ka2nehxy:4a1ee0a632feaab94294350087215ed89533f2f530903e3b933b638940e921aa - refund: - path: /sites/{site_id}/orders/{order_id}/refund - method: POST - auth: true - docs: | - This API will reverse a Stripe charge and refund an order back to a - customer. It will also set the order's status to `refunded`. - - Required scope | `ecommerce:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - order_id: - type: string - docs: Unique identifier for an Order - display-name: Refund Order - request: - name: OrdersRefundRequest - body: - properties: - reason: - type: optional - docs: The reason for the refund - content-type: application/json - response: - docs: Request was successful - type: root.Order - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.ConflictError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - order_id: 5e8518516e147040726cc415 - request: {} - response: - body: - orderId: fc7-128 - status: refunded - comment: >- - Customer requested gift wrapping and a personalized note saying: - Happy Birthday, Ford! 🎉 Please ensure the item is packed with - extra bubble wrap for safe transit. - orderComment: >- - Please gift wrap with a personal note saying "Happy Birthday, - Ford! 🎉 - acceptedOn: '2024-03-29T21:29:21Z' - fulfilledOn: '2024-03-29T21:29:21Z' - refundedOn: '2024-04-08T18:25:04Z' - disputedOn: '2024-03-29T21:29:21Z' - disputeUpdatedOn: '2024-03-29T21:29:21Z' - disputeLastStatus: charge_refunded - customerPaid: - unit: USD - value: '5892' - string: ' 118.73 USD' - netAmount: - unit: USD - value: '5892' - string: ' 112.62 USD' - applicationFee: - unit: USD - value: '5892' - string: ' 2.37 USD' - allAddresses: - - type: billing - japanType: kana - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - - type: shipping - japanType: kana - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - shippingAddress: - type: shipping - japanType: kanji - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - billingAddress: - type: billing - japanType: kana - addressee: Arthur Dent - line1: 20 W 34th St - line2: Empire State Building - city: New York - state: New York - country: US - postalCode: '10118' - shippingProvider: Shipping Company, Co. - shippingTracking: tr00000000001 - shippingTrackingURL: https://www.shippingcompany.com/tracking/tr00000000001 - customerInfo: - fullName: Arthur Dent - email: arthur.dent@example.com - purchasedItems: - - count: 1 - rowTotal: - unit: USD - value: '5892' - string: ' 55.61 USD' - productId: 66072fb61b89448912e26791 - productName: Luxurious Fresh Ball - productSlug: luxurious-fresh-ball - variantId: 66072fb71b89448912e2683f - variantName: 'Luxurious Fresh Ball Generic: Bronze, Practical: Plastic' - variantSlug: luxurious-fresh-ball-generic-bronze-practical-plastic - variantSKU: luxurious-fresh-ball-generic-bronze-practical-plastic - variantImage: - url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg - variantPrice: - unit: USD - value: '5892' - string: ' 55.61 USD' - weight: 11 - width: 82 - height: 70 - length: 9 - - count: 1 - rowTotal: - unit: USD - value: '5892' - string: ' 53.44 USD' - productId: 66072fb61b89448912e26799 - productName: Recycled Steel Gloves - productSlug: recycled-steel-gloves - variantId: 66072fb91b89448912e26ab9 - variantName: 'Recycled Steel Gloves Electronic: Granite, Handcrafted: grey' - variantSlug: recycled-steel-gloves-electronic-granite-handcrafted-grey - variantSKU: recycled-steel-gloves-electronic-granite-handcrafted-grey - variantImage: - url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2671e_image2.jpeg - variantPrice: - unit: USD - value: '5892' - string: ' 53.44 USD' - weight: 38 - width: 76 - height: 85 - length: 40 - purchasedItemsCount: 2 - stripeDetails: - subscriptionId: sub_1J6xwG2eZvKYlo2CXu9Zt0Tn - paymentMethod: pm_1OzmzBJYFi4lcbXWHKNdXU7j - paymentIntentId: pi_3OzmzDJYFi4lcbXW1hTBW6ft - customerId: cus_PpRsNHwWdUoRKR - chargeId: ch_3OzmzDJYFi4lcbXW1ndkkrH2 - disputeId: disputeId - refundId: re_3OzmzDJYFi4lcbXW1kFAmlBk - refundReason: fraudulent - stripeCard: - last4: '4242' - brand: Visa - ownerName: Arthur Dent - expires: - year: 2024 - month: 4 - paypalDetails: - orderId: 1a2b3c4d5e6f7g8h9i0j - payerId: 9k8j7i6h5g4f3e2d1c0b - captureId: qwe123rty456uio789p - refundId: abcde12345fghij67890 - refundReason: Customer requested refund - disputeId: zxcvbnm987poiuytrewq - customData: - - key: value - metadata: - isBuyNow: false - isCustomerDeleted: false - isShippingRequired: true - hasDownloads: false - paymentProcessor: stripe - totals: - subtotal: - unit: USD - value: '5892' - string: ' 109.05 USD' - extras: - - type: tax - name: State Taxes - description: NY Taxes (4.00%) - price: - unit: USD - value: '5892' - string: ' 4.36 USD' - - type: tax - name: City Taxes - description: NEW YORK Taxes (4.88%) - price: - unit: USD - value: '5892' - string: ' 5.32 USD' - - type: shipping - name: Flat - description: '' - price: - unit: USD - value: '5892' - string: ' 0.00 USD' - total: - unit: USD - value: '5892' - string: ' 118.73 USD' - downloadFiles: - - id: 5e9a5eba75e0ac242e1b6f64 - name: New product guide - url: >- - https://webflow.com/dashboard/download-digital-product?payload=5d93ba5e38c6b0160ab711d3;e7634a;5eb1aac72912ec06f561278c;5e9a5eba75e0ac242e1b6f63:ka2nehxy:4a1ee0a632feaab94294350087215ed89533f2f530903e3b933b638940e921aa - source: - openapi: ../../../openapi/referenced-specs/v2.yml - display-name: Orders -docs: Orders are the orders for your Webflow site. diff --git a/.mock/definition/pages.yml b/.mock/definition/pages.yml deleted file mode 100644 index 62de7dc..0000000 --- a/.mock/definition/pages.yml +++ /dev/null @@ -1,470 +0,0 @@ -imports: - root: __package__.yml -service: - auth: false - base-path: '' - endpoints: - list: - path: /sites/{site_id}/pages - method: GET - auth: true - docs: | - List of all pages for a site. - - Required scope | `pages:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: List Pages - request: - name: PagesListRequest - query-parameters: - localeId: - type: optional - docs: >- - Unique identifier for a specific locale. Applicable, when using - localization. - limit: - type: optional - docs: 'Maximum number of records to be returned (max limit: 100)' - offset: - type: optional - docs: >- - Offset used for pagination if the results have more than limit - records - response: - docs: Request was successful - type: root.PageList - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - query-parameters: - localeId: 65427cf400e02b306eaa04a0 - response: - body: - pages: - - id: 6596da6045e56dee495bcbba - siteId: 6258612d1ee792848f805dcf - title: Guide to the Galaxy - slug: guide-to-the-galaxy - parentId: 6419db964a9c435aa3af6251 - collectionId: 6390c49774a71f12831a08e3 - createdOn: '2024-03-11T10:42:00Z' - lastUpdated: '2024-03-11T10:42:42Z' - archived: false - draft: false - canBranch: true - isBranch: false - isMembersOnly: false - seo: - title: The Ultimate Hitchhiker's Guide to the Galaxy - description: >- - Everything you need to know about the galaxy, from - avoiding Vogon poetry to the importance of towels. - openGraph: - title: Explore the Cosmos with The Ultimate Guide - titleCopied: false - description: >- - Dive deep into the mysteries of the universe with your - guide to everything galactic. - descriptionCopied: false - localeId: 653fd9af6a07fc9cfd7a5e57 - publishedPath: /en-us/guide-to-the-galaxy - - id: 6596da6045e56dee495bcbad - siteId: 6258612d1ee792848f805dcf - title: Towel Day Celebrations - slug: towel-day - parentId: 6419db964a9c435aa3af6251 - collectionId: 6390c49774a71f12831a08e3 - createdOn: '2024-05-25T09:00:00Z' - lastUpdated: '2024-05-25T09:42:00Z' - archived: false - draft: false - canBranch: true - isBranch: false - isMembersOnly: false - seo: - title: Celebrate Towel Day - The Hitchhiker's Guide to the Galaxy - description: >- - A guide to celebrating Towel Day, in honor of the most - massively useful thing an interstellar hitchhiker can - have. - openGraph: - title: Towel Day - Don't Panic - titleCopied: false - description: >- - Join the galaxy in celebrating Towel Day, the day - dedicated to carrying towels everywhere in memory of - Douglas Adams. - descriptionCopied: false - localeId: 653fd9af6a07fc9cfd7a5e57 - publishedPath: /en-us/towel-day - pagination: - limit: 20 - offset: 0 - total: 2 - get-metadata: - path: /pages/{page_id} - method: GET - auth: true - docs: | - Get metadata information for a single page. - - Required scope | `pages:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - page_id: - type: string - docs: Unique identifier for a Page - display-name: Get Page Metadata - request: - name: PagesGetMetadataRequest - query-parameters: - localeId: - type: optional - docs: >- - Unique identifier for a specific locale. Applicable, when using - localization. - response: - docs: Request was successful - type: root.Page - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - page_id: 63c720f9347c2139b248e552 - query-parameters: - localeId: 65427cf400e02b306eaa04a0 - response: - body: - id: 6596da6045e56dee495bcbba - siteId: 6258612d1ee792848f805dcf - title: Guide to the Galaxy - slug: guide-to-the-galaxy - parentId: 6419db964a9c435aa3af6251 - collectionId: 6390c49774a71f12831a08e3 - createdOn: '2024-03-11T10:42:00Z' - lastUpdated: '2024-03-11T10:42:42Z' - archived: false - draft: false - canBranch: true - isBranch: false - isMembersOnly: false - seo: - title: The Ultimate Hitchhiker's Guide to the Galaxy - description: >- - Everything you need to know about the galaxy, from avoiding - Vogon poetry to the importance of towels. - openGraph: - title: Explore the Cosmos with The Ultimate Guide - titleCopied: false - description: >- - Dive deep into the mysteries of the universe with your guide - to everything galactic. - descriptionCopied: false - localeId: 653fd9af6a07fc9cfd7a5e57 - publishedPath: /en-us/guide-to-the-galaxy - update-page-settings: - path: /pages/{page_id} - method: PUT - auth: true - docs: | - Update Page-level metadata, including SEO and Open Graph fields. - - Required scope | `pages:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - page_id: - type: string - docs: Unique identifier for a Page - display-name: Update Page Metadata - request: - body: root.Page - query-parameters: - localeId: - type: optional - docs: >- - Unique identifier for a specific locale. Applicable, when using - localization. - name: UpdatePageSettingsRequest - content-type: application/json - response: - docs: Request was successful - type: root.Page - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - page_id: 63c720f9347c2139b248e552 - query-parameters: - localeId: 65427cf400e02b306eaa04a0 - request: - id: 6596da6045e56dee495bcbba - siteId: 6258612d1ee792848f805dcf - title: Guide to the Galaxy - slug: guide-to-the-galaxy - createdOn: '2024-03-11T10:42:00Z' - lastUpdated: '2024-03-11T10:42:42Z' - archived: false - draft: false - canBranch: true - isBranch: false - seo: - title: The Ultimate Hitchhiker's Guide to the Galaxy - description: >- - Everything you need to know about the galaxy, from avoiding - Vogon poetry to the importance of towels. - openGraph: - title: Explore the Cosmos with The Ultimate Guide - titleCopied: false - description: >- - Dive deep into the mysteries of the universe with your guide to - everything galactic. - descriptionCopied: false - localeId: 653fd9af6a07fc9cfd7a5e57 - publishedPath: /en-us/guide-to-the-galaxy - response: - body: - id: 6596da6045e56dee495bcbba - siteId: 6258612d1ee792848f805dcf - title: Guide to the Galaxy - slug: guide-to-the-galaxy - parentId: 6419db964a9c435aa3af6251 - collectionId: 6390c49774a71f12831a08e3 - createdOn: '2024-03-11T10:42:00Z' - lastUpdated: '2024-03-11T10:42:42Z' - archived: false - draft: false - canBranch: true - isBranch: false - isMembersOnly: false - seo: - title: The Ultimate Hitchhiker's Guide to the Galaxy - description: >- - Everything you need to know about the galaxy, from avoiding - Vogon poetry to the importance of towels. - openGraph: - title: Explore the Cosmos with The Ultimate Guide - titleCopied: false - description: >- - Dive deep into the mysteries of the universe with your guide - to everything galactic. - descriptionCopied: false - localeId: 653fd9af6a07fc9cfd7a5e57 - publishedPath: /en-us/guide-to-the-galaxy - get-content: - path: /pages/{page_id}/dom - method: GET - auth: true - docs: > - Get static content from a static page. This includes text nodes, image - nodes and component instances. - - To retrieve the contents of components in the page use the [get - component - content](/data/reference/pages-and-components/components/get-content) - endpoint. - - - If you do not provide a Locale ID in your request, the response - will return any content that can be localized from the Primary - locale. - - - Required scope | `pages:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - page_id: - type: string - docs: Unique identifier for a Page - display-name: Get Page Content - request: - name: PagesGetContentRequest - query-parameters: - localeId: - type: optional - docs: >- - Unique identifier for a specific locale. Applicable, when using - localization. - limit: - type: optional - docs: 'Maximum number of records to be returned (max limit: 100)' - offset: - type: optional - docs: >- - Offset used for pagination if the results have more than limit - records - response: - docs: Request was successful - type: root.Dom - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - name: PageDOM - path-parameters: - page_id: 63c720f9347c2139b248e552 - query-parameters: - localeId: 65427cf400e02b306eaa04a0 - response: - body: - pageId: 658205daa3e8206a523b5ad4 - nodes: - - type: component-instance - id: a245c12d-995b-55ee-5ec7-aa36a6cad623 - componentId: nodes - propertyOverrides: - - propertyId: 7dd14c08-2e96-8d3d-2b19-b5c03642a0f0 - - type: component-instance - id: a245c12d-995b-55ee-5ec7-aa36a6cad627 - componentId: nodes - propertyOverrides: - - propertyId: 7dd14c08-2e96-8d3d-2b19-b5c03642a0f0 - - type: component-instance - id: a245c12d-995b-55ee-5ec7-aa36a6cad629 - componentId: nodes - propertyOverrides: - - propertyId: 7dd14c08-2e96-8d3d-2b19-b5c03642a0f0 - - type: component-instance - id: a245c12d-995b-55ee-5ec7-aa36a6cad631 - componentId: 6258612d1ee792848f805dcf - propertyOverrides: - - propertyId: a245c12d-995b-55ee-5ec7-aa36a6cad633 - type: Plain Text - label: Catchphrase - text: - text: Don't Panic! - - propertyId: a245c12d-995b-55ee-5ec7-aa36a6cad635 - type: Rich Text - label: Tagline - text: - html:

Always know where your towel is.

- pagination: - limit: 4 - offset: 0 - total: 4 - update-static-content: - path: /pages/{page_id}/dom - method: POST - auth: true - docs: > - This endpoint updates content on a static page in **secondary locales**. - It supports updating up to 1000 nodes in a single request. - - - Before making updates: - - 1. Use the [get page - content](/data/reference/pages-and-components/pages/get-content) - endpoint to identify available content nodes and their types - - 2. If the page has component instances, retrieve the component's - properties that you'll override using the [get component - properties](/data/reference/pages-and-components/components/get-properties) - endpoint - - - - This endpoint is specifically for localized pages. Ensure that the specified `localeId` is a valid **secondary locale** for the site otherwise the request will fail. - - - - Required scope | `pages:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - page_id: - type: string - docs: Unique identifier for a Page - display-name: Update Page Content - request: - name: PageDomWrite - query-parameters: - localeId: - type: string - docs: The locale identifier. - body: - properties: - nodes: - docs: >- - List of DOM Nodes with the new content that will be updated in - each node. - type: list - content-type: application/json - response: - docs: Request was successful - type: UpdateStaticContentResponse - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - page_id: 63c720f9347c2139b248e552 - query-parameters: - localeId: localeId - request: - nodes: - - nodeId: a245c12d-995b-55ee-5ec7-aa36a6cad623 - text:

The Hitchhiker's Guide to the Galaxy

- - nodeId: a245c12d-995b-55ee-5ec7-aa36a6cad627 - text: >- -

Don't Panic!

Always know where your towel - is.

- - nodeId: a245c12d-995b-55ee-5ec7-aa36a6cad629 - propertyOverrides: - - propertyId: 7dd14c08-2e96-8d3d-2b19-b5c03642a0f0 - text:

Time is an illusion

- - propertyId: 7dd14c08-2e96-8d3d-2b19-b5c03642a0f1 - text: Life, the Universe and Everything - response: - body: - errors: - - errors - source: - openapi: ../../../openapi/referenced-specs/v2.yml - display-name: Pages -docs: Pages are the pages in your Webflow site. -types: - PageDomWriteNodesItem: - discriminated: false - union: - - root.TextNodeWrite - - root.ComponentInstanceNodePropertyOverridesWrite - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - UpdateStaticContentResponse: - properties: - errors: - docs: A list of error messages, if any. - type: list - source: - openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/pages/scripts.yml b/.mock/definition/pages/scripts.yml deleted file mode 100644 index f8ee328..0000000 --- a/.mock/definition/pages/scripts.yml +++ /dev/null @@ -1,170 +0,0 @@ -imports: - root: ../__package__.yml -service: - auth: false - base-path: '' - endpoints: - get-custom-code: - path: /pages/{page_id}/custom_code - method: GET - auth: true - docs: > - Get all registered scripts that have been applied to a specific Page. - - - In order to use the Custom Code APIs for Sites and Pages, Custom Code - Scripts must first be registered - - to a Site via the `registered_scripts` endpoints, and then applied to a - Site or Page using the appropriate - - `custom_code` endpoints. - - - Access to this endpoint requires a bearer token from a [Data - Client App](/data/docs/getting-started-data-clients). - - - Required scope | `custom_code:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - page_id: - type: string - docs: Unique identifier for a Page - display-name: Get Custom Code - response: - docs: Request was successful - type: root.ScriptApplyList - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - page_id: 63c720f9347c2139b248e552 - response: - body: - scripts: - - id: id - location: header - version: version - attributes: - key: value - lastUpdated: lastUpdated - createdOn: createdOn - upsert-custom-code: - path: /pages/{page_id}/custom_code - method: PUT - auth: true - docs: > - Add a registered script to a Page. - - - In order to use the Custom Code APIs for Sites and Pages, Custom Code - Scripts must first be registered - - to a Site via the `registered_scripts` endpoints, and then applied to a - Site or Page using the appropriate - - `custom_code` endpoints. - - - A site can have a maximum of 800 registered scripts. - - - Access to this endpoint requires a bearer token from a [Data - Client App](/data/docs/getting-started-data-clients). - - - Required scope | `custom_code:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - page_id: - type: string - docs: Unique identifier for a Page - display-name: Add/Update Custom Code - request: - body: root.ScriptApplyList - content-type: application/json - response: - docs: Request was successful - type: root.ScriptApplyList - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.ConflictError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - page_id: 63c720f9347c2139b248e552 - request: - scripts: - - id: cms_slider - location: header - version: 1.0.0 - attributes: - my-attribute: some-value - - id: alert - location: header - version: 0.0.1 - response: - body: - scripts: - - id: cms_slider - location: header - version: 1.0.0 - attributes: - my-attribute: some-value - - id: alert - location: header - version: 0.0.1 - attributes: - key: value - lastUpdated: '2022-10-26T00:28:54.191Z' - createdOn: '2022-10-26T00:28:54.191Z' - delete-custom-code: - path: /pages/{page_id}/custom_code - method: DELETE - auth: true - docs: > - Delete the custom code block that an app has created for a page - - - In order to use the Custom Code APIs for Sites and Pages, Custom Code - Scripts must first be registered - - to a Site via the `registered_scripts` endpoints, and then applied to a - Site or Page using the appropriate - - `custom_code` endpoints. - - - Access to this endpoint requires a bearer token from a [Data - Client App](/data/docs/getting-started-data-clients). - - - Required scope | `custom_code:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - page_id: - type: string - docs: Unique identifier for a Page - display-name: Delete Custom Code - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - page_id: 63c720f9347c2139b248e552 - source: - openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/products.yml b/.mock/definition/products.yml deleted file mode 100644 index 4c6fcd1..0000000 --- a/.mock/definition/products.yml +++ /dev/null @@ -1,500 +0,0 @@ -imports: - root: __package__.yml -service: - auth: false - base-path: '' - endpoints: - list: - path: /sites/{site_id}/products - method: GET - auth: true - docs: > - Retrieve all products for a site. - - - Use `limit` and `offset` to page through all products with subsequent - requests. All SKUs for each product - - will also be fetched and returned. The `limit`, `offset` and `total` - values represent Products only and do not include any SKUs. - - - Required scope | `ecommerce:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: List Products & SKUs - request: - name: ProductsListRequest - query-parameters: - offset: - type: optional - docs: >- - Offset used for pagination if the results have more than limit - records - limit: - type: optional - docs: 'Maximum number of records to be returned (max limit: 100)' - response: - docs: Request was successful - type: root.ProductAndSkUsList - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.ConflictError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - response: - body: - items: - - product: - id: 660eb7a486d1d6e0412292d7 - cmsLocaleId: 653ad57de882f528b32e810e - lastPublished: '2024-04-04T14:24:19Z' - lastUpdated: '2024-04-04T14:30:19Z' - createdOn: '2024-04-04T14:22:28Z' - isArchived: false - isDraft: false - fieldData: - name: T-Shirt - slug: t-shirt - description: A plain cotton t-shirt. - shippable: true - sku-properties: - - id: Color - name: Color - enum: - - id: id - name: Royal Blue - slug: royal-blue - skus: - - id: 580e63fc8c9a982ac9b8b745 - cmsLocaleId: 653ad57de882f528b32e810e - lastPublished: '2023-03-17T18:47:35Z' - lastUpdated: '2023-03-17T18:47:35Z' - createdOn: '2023-03-17T18:47:35Z' - fieldData: - sku-values: - ff42fee0113744f693a764e3431a9cc2: 64a74715c456e36762fc39a1 - name: Blue T-shirt - slug: t-shirt-blue - price: - value: 100 - unit: USD - quantity: 10 - pagination: - limit: 100 - offset: 0 - total: 100 - create: - path: /sites/{site_id}/products - method: POST - auth: true - docs: > - Create a new product and SKU. - - - When you create a product, you will always create a SKU, since a Product - Item must have, at minimum, a single SKU. - - - To create a Product with multiple SKUs - for example a T-shirt in sizes - small, medium and large: - - Create parameters in `sku-properties`, also known as [product options and variants.](https://help.webflow.com/hc/en-us/articles/33961334531347-Create-product-options-and-variants). - - A single `sku-property` would be `color`. Within the `color` property, list the various colors of T-shirts as an array of `enum` values: `royal-blue`, `crimson-red`, and `forrest-green`. - - Once, you've created a Product and its `sku-properties` with `enum` values, Webflow will create a **default SKU**, which will automatically be a combination of the first `sku-properties` you've created. - - In our example, the default SKU will be a Royal Blue T-Shirt, because our first `enum` of our Color `sku-property` is Royal Blue. - - After you've created your product, you can create additional SKUs using the [Create SKU endpoint.](/data/reference/ecommerce/products/create-sku) - - Upon creation, the default product type will be `Advanced`, which - ensures all Product and SKU fields will be shown to users in the - Designer. - - - Required scope | `ecommerce:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: Create Product & SKU - request: - name: ProductSkuCreate - body: - properties: - publishStatus: optional - product: optional - sku: optional - content-type: application/json - response: - docs: Request was successful - type: root.ProductAndSkUs - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.ConflictError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - request: {} - response: - body: - product: - id: 660eb7a486d1d6e0412292d7 - cmsLocaleId: 653ad57de882f528b32e810e - lastPublished: '2024-04-04T14:24:19Z' - lastUpdated: '2024-04-04T14:30:19Z' - createdOn: '2024-04-04T14:22:28Z' - isArchived: false - isDraft: false - fieldData: - name: T-Shirt - slug: t-shirt - description: A plain cotton t-shirt. - shippable: true - sku-properties: - - id: Color - name: Color - enum: - - id: id - name: Royal Blue - slug: royal-blue - categories: - - categories - tax-category: standard-taxable - default-sku: default-sku - ec-product-type: ff42fee0113744f693a764e3431a9cc2 - skus: - - id: 580e63fc8c9a982ac9b8b745 - cmsLocaleId: 653ad57de882f528b32e810e - lastPublished: '2023-03-17T18:47:35Z' - lastUpdated: '2023-03-17T18:47:35Z' - createdOn: '2023-03-17T18:47:35Z' - fieldData: - sku-values: - ff42fee0113744f693a764e3431a9cc2: 64a74715c456e36762fc39a1 - name: Blue T-shirt - slug: t-shirt-blue - price: - value: 100 - unit: USD - quantity: 10 - get: - path: /sites/{site_id}/products/{product_id} - method: GET - auth: true - docs: | - Retrieve a single product by its ID. All of its SKUs will also be - retrieved. - - Required scope | `ecommerce:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - product_id: - type: string - docs: Unique identifier for a Product - display-name: Get Product and SKUs - response: - docs: Request was successful - type: root.ProductAndSkUs - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.ConflictError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - product_id: 580e63fc8c9a982ac9b8b745 - response: - body: - product: - id: 660eb7a486d1d6e0412292d7 - cmsLocaleId: 653ad57de882f528b32e810e - lastPublished: '2024-04-04T14:24:19Z' - lastUpdated: '2024-04-04T14:30:19Z' - createdOn: '2024-04-04T14:22:28Z' - isArchived: false - isDraft: false - fieldData: - name: T-Shirt - slug: t-shirt - description: A plain cotton t-shirt. - shippable: true - sku-properties: - - id: Color - name: Color - enum: - - id: id - name: Royal Blue - slug: royal-blue - categories: - - categories - tax-category: standard-taxable - default-sku: default-sku - ec-product-type: ff42fee0113744f693a764e3431a9cc2 - skus: - - id: 580e63fc8c9a982ac9b8b745 - cmsLocaleId: 653ad57de882f528b32e810e - lastPublished: '2023-03-17T18:47:35Z' - lastUpdated: '2023-03-17T18:47:35Z' - createdOn: '2023-03-17T18:47:35Z' - fieldData: - sku-values: - ff42fee0113744f693a764e3431a9cc2: 64a74715c456e36762fc39a1 - name: Blue T-shirt - slug: t-shirt-blue - price: - value: 100 - unit: USD - quantity: 10 - update: - path: /sites/{site_id}/products/{product_id} - method: PATCH - auth: true - docs: > - Update an existing Product. - - - Updating an existing Product will set the product type to `Advanced`, - which ensures all Product and SKU fields will be shown to users in the - Designer. - - - Required scope | `ecommerce:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - product_id: - type: string - docs: Unique identifier for a Product - display-name: Update Product - request: - name: ProductSkuUpdate - body: - properties: - publishStatus: optional - product: optional - sku: optional - content-type: application/json - response: - docs: Request was successful - type: root.Product - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.ConflictError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - product_id: 580e63fc8c9a982ac9b8b745 - request: {} - response: - body: - id: 660eb7a486d1d6e0412292d7 - cmsLocaleId: 653ad57de882f528b32e810e - lastPublished: '2024-04-04T14:24:19Z' - lastUpdated: '2024-04-04T14:30:19Z' - createdOn: '2024-04-04T14:22:28Z' - isArchived: false - isDraft: false - fieldData: - name: T-Shirt - slug: t-shirt - description: A plain cotton t-shirt. - shippable: true - sku-properties: - - id: Color - name: Color - enum: - - id: id - name: Royal Blue - slug: royal-blue - categories: - - categories - tax-category: standard-taxable - default-sku: default-sku - ec-product-type: ff42fee0113744f693a764e3431a9cc2 - create-sku: - path: /sites/{site_id}/products/{product_id}/skus - method: POST - auth: true - docs: > - Create additional SKUs to manage every [option and variant of your - Product.](https://help.webflow.com/hc/en-us/articles/33961334531347-Create-product-options-and-variants) - - - Creating SKUs through the API will set the product type to `Advanced`, - which ensures all Product and SKU fields will be shown to users in the - Designer. - - - Required scope | `ecommerce:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - product_id: - type: string - docs: Unique identifier for a Product - display-name: Create SKU - request: - name: ProductsCreateSkuRequest - body: - properties: - publishStatus: optional - skus: - docs: An array of the SKU data your are adding - type: list - content-type: application/json - response: - docs: Request was successful - type: ProductsCreateSkuResponse - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.ConflictError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - product_id: 580e63fc8c9a982ac9b8b745 - request: - skus: - - {} - response: - body: - skus: - - id: 580e63fc8c9a982ac9b8b745 - cmsLocaleId: 653ad57de882f528b32e810e - lastPublished: '2023-03-17T18:47:35Z' - lastUpdated: '2023-03-17T18:47:35Z' - createdOn: '2023-03-17T18:47:35Z' - fieldData: - sku-values: - ff42fee0113744f693a764e3431a9cc2: 64a74715c456e36762fc39a1 - name: Blue T-shirt - slug: t-shirt-blue - price: - value: 100 - unit: USD - quantity: 10 - update-sku: - path: /sites/{site_id}/products/{product_id}/skus/{sku_id} - method: PATCH - auth: true - docs: > - Update a specified SKU. - - - Updating an existing SKU will set the Product type to `Advanced`, which - ensures all Product and SKU fields will be shown to users in the - Designer. - - - Required scope | `ecommerce:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - product_id: - type: string - docs: Unique identifier for a Product - sku_id: - type: string - docs: Unique identifier for a SKU - display-name: Update SKU - request: - name: ProductsUpdateSkuRequest - body: - properties: - publishStatus: optional - sku: root.Sku - content-type: application/json - response: - docs: Request was successful - type: root.Sku - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.ConflictError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - product_id: 580e63fc8c9a982ac9b8b745 - sku_id: 5e8518516e147040726cc415 - request: - sku: {} - response: - body: - id: 580e63fc8c9a982ac9b8b745 - cmsLocaleId: 653ad57de882f528b32e810e - lastPublished: '2023-03-17T18:47:35Z' - lastUpdated: '2023-03-17T18:47:35Z' - createdOn: '2023-03-17T18:47:35Z' - fieldData: - sku-values: - ff42fee0113744f693a764e3431a9cc2: 64a74715c456e36762fc39a1 - name: Blue T-shirt - slug: t-shirt-blue - price: - value: 100 - unit: USD - compare-at-price: - value: 100 - unit: USD - ec-sku-billing-method: one-time - ec-sku-subscription-plan: - interval: day - frequency: 1 - trial: 7 - plans: - - {} - track-inventory: true - quantity: 10 - source: - openapi: ../../../openapi/referenced-specs/v2.yml -types: - ProductsCreateSkuResponse: - properties: - skus: optional> - source: - openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/scripts.yml b/.mock/definition/scripts.yml deleted file mode 100644 index 8236ed2..0000000 --- a/.mock/definition/scripts.yml +++ /dev/null @@ -1,253 +0,0 @@ -imports: - root: __package__.yml -service: - auth: false - base-path: '' - endpoints: - list: - path: /sites/{site_id}/registered_scripts - method: GET - auth: true - docs: > - List of scripts registered to a Site. - - - In order to use the Custom Code APIs for Sites and Pages, Custom Code - Scripts must first be registered - - to a Site via the `registered_scripts` endpoints, and then applied to a - Site or Page using the appropriate - - `custom_code` endpoints. - - Additionally, Scripts can be remotely hosted, or registered as inline - snippets. - - - Access to this endpoint requires a bearer token from a [Data - Client App](/data/docs/getting-started-data-clients). - - - Required scope | `custom_code:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: Get Registered Scripts - response: - docs: Request was successful - type: root.RegisteredScriptList - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - response: - body: - registeredScripts: - - id: alert - canCopy: false - displayName: Alert - hostedLocation: https://cdn.webflow.io/.../alert-0.0.1.js - integrityHash: integrityHash - createdOn: '2022-10-26T00:28:54.191Z' - lastUpdated: lastUpdated - version: 0.0.1 - - id: alert - canCopy: false - displayName: Alert - hostedLocation: https://cdn.webflow.io/.../alert-0.0.2.js - integrityHash: integrityHash - createdOn: '2022-10-26T00:28:54.191Z' - lastUpdated: lastUpdated - version: 0.0.2 - - id: cms_slider - canCopy: true - displayName: CMS Slider - hostedLocation: https://cdn.jsdelivr.net/.../cms_slider.js - integrityHash: >- - sha384-J+YlJ8v0gpaRoKH7SbFbEmxOZlAxLiwNjfSsBhDooGa5roXlPPpXbEevck4J7YZ+ - createdOn: '2022-10-26T00:28:54.191Z' - lastUpdated: lastUpdated - version: 1.0.0 - register-hosted: - path: /sites/{site_id}/registered_scripts/hosted - method: POST - auth: true - docs: > - Add a script to a Site's Custom Code registry. - - - In order to use the Custom Code APIs for Sites and Pages, Custom Code - Scripts must first be registered - - to a Site via the `registered_scripts` endpoints, and then applied to a - Site or Page using the appropriate - - `custom_code` endpoints. - - Additionally, Scripts can be remotely hosted, or registered as inline - snippets. - - - Access to this endpoint requires a bearer token from a [Data - Client App](/data/docs/getting-started-data-clients). - - - Required scope | `custom_code:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: Register Script - Hosted - request: - name: CustomCodeHostedRequest - body: - properties: - hostedLocation: - type: string - docs: URI for an externally hosted script location - integrityHash: - type: string - docs: Sub-Resource Integrity Hash - canCopy: - type: optional - docs: >- - Define whether the script can be copied on site duplication and - transfer - default: false - version: - type: string - docs: >- - A Semantic Version (SemVer) string, denoting the version of the - script - displayName: - type: string - docs: >- - User-facing name for the script. Must be between 1 and 50 - alphanumeric characters - content-type: application/json - response: - docs: Request was successful - type: root.CustomCodeHostedResponse - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - request: - hostedLocation: hostedLocation - integrityHash: integrityHash - version: version - displayName: displayName - response: - body: - id: cms_slider - canCopy: true - displayName: CMS Slider - hostedLocation: https://cdn.jsdelivr.net/.../cmsslider.js - integrityHash: >- - sha384-J+YlJ8v0gpaRoKH7SbFbEmxOZlAxLiwNjfSsBhDooGa5roXlPPpXbEevck4J7YZ+ - createdOn: '2022-10-26T00:28:54.191Z' - lastUpdated: lastUpdated - version: 1.0.0 - register-inline: - path: /sites/{site_id}/registered_scripts/inline - method: POST - auth: true - docs: > - Add a script to a Site's Custom Code registry. Inline scripts can be - between 1 and 2000 characters. - - - In order to use the Custom Code APIs for Sites and Pages, Custom Code - Scripts must first be registered - - to a Site via the `registered_scripts` endpoints, and then applied to a - Site or Page using the appropriate - - `custom_code` endpoints. - - - Access to this endpoint requires a bearer token from a [Data - Client App](/data/docs/getting-started-data-clients). - - - Required scope | `custom_code:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: Register Script - Inline - request: - name: CustomCodeInlineRequest - body: - properties: - sourceCode: - type: string - docs: The code to be added to the site (to be hosted by Webflow). - integrityHash: - type: optional - docs: >- - Sub-Resource Integrity Hash. Only required for externally hosted - scripts (passed via hostedLocation) - canCopy: - type: optional - docs: >- - Define whether the script can be copied on site duplication and - transfer - default: false - version: - type: string - docs: >- - A Semantic Version (SemVer) string, denoting the version of the - script - displayName: - type: string - docs: >- - User-facing name for the script. Must be between 1 and 50 - alphanumeric characters - content-type: application/json - response: - docs: Created - type: root.CustomCodeInlineResponse - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - request: - sourceCode: alert('hello world'); - version: 0.0.1 - displayName: Alert - response: - body: - id: alert - canCopy: false - displayName: Alert - hostedLocation: >- - https://uploads-ssl.webflow.com/6258612d1ee792848f805dcf%2F64b6c769ff52ba6c3d904a91%2F660d6e15b3d1696f2d2b1447%2Falert-0.0.1.js - integrityHash: integrityHash - createdOn: '2022-10-26T00:28:54.191Z' - lastUpdated: lastUpdated - version: 0.0.1 - source: - openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/sites.yml b/.mock/definition/sites.yml deleted file mode 100644 index cea8997..0000000 --- a/.mock/definition/sites.yml +++ /dev/null @@ -1,495 +0,0 @@ -imports: - root: __package__.yml -service: - auth: false - base-path: '' - endpoints: - create: - path: /workspaces/{workspace_id}/sites - method: POST - auth: true - docs: | - Create a site. This endpoint requires an Enterprise workspace. - - Required scope | `workspace:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - workspace_id: - type: string - docs: Unique identifier for a Workspace - display-name: Create Site - request: - name: SitesCreateRequest - body: - properties: - name: - type: string - docs: The name of the site - templateName: - type: optional - docs: The workspace or marketplace template to use - parentFolderId: - type: optional - docs: MegaDodo Publications - Potential Book Ideas - content-type: application/json - response: - docs: Request was successful - type: root.Site - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - name: NewlyCreatedSite - path-parameters: - workspace_id: 580e63e98c9a982ac9b8b741 - request: - name: The Hitchhiker's Guide to the Galaxy - response: - body: - id: 670ecf86817e3cc7a510eb6a - workspaceId: 625860a7a6c16d624927122f - createdOn: '2024-10-15T20:24:38Z' - displayName: The Hitchiker‘s Guide - shortName: hitchikers-guide - lastPublished: '2016-10-24T19:43:17Z' - lastUpdated: '2024-10-15T20:24:38Z' - previewUrl: >- - https://d1otoma47x30pg.cloudfront.net/580e63e98c9a982ac9b8b741/201610241243.png - timeZone: America/Los_Angeles - parentFolderId: 670ece123598db72d9648be1 - customDomains: - - id: 589a331aa51e760df7ccb89d - url: test-api-domain.com - lastPublished: '2022-12-07T16:51:37Z' - locales: - primary: - id: 653fd9af6a07fc9cfd7a5e57 - cmsLocaleId: 653ad57de882f528b32e810e - enabled: false - displayName: English (United States) - displayImageId: displayImageId - redirect: true - subdirectory: '' - tag: en-US - secondary: - - id: 653fd9af6a07fc9cfd7a5e57 - cmsLocaleId: 653ad57de882f528b32e810e - enabled: false - displayName: English (United States) - redirect: true - subdirectory: '' - tag: en-US - dataCollectionEnabled: false - dataCollectionType: always - list: - path: /sites - method: GET - auth: true - docs: | - List of all sites the provided access token is able to access. - - Required scope | `sites:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - display-name: List Sites - response: - docs: Request was successful - type: root.Sites - errors: - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - examples: - - response: - body: - sites: - - id: 42e63e98c9a982ac9b8b741 - workspaceId: 42e63fc8c9a982ac9b8b744 - createdOn: '1979-10-12T12:00:00Z' - displayName: Heart of Gold Spaceship - shortName: heart-of-gold - lastPublished: '2023-04-02T12:42:00Z' - lastUpdated: '2016-10-24T19:43:17Z' - previewUrl: >- - https://d1otoma47x30pg.cloudfront.net/42e63e98c9a982ac9b8b741/197910121200.png - timeZone: DeepSpace/InfiniteImprobability - parentFolderId: 1as2d3f4g5h6j7k8l9z0x1c2v3b4n5m6 - customDomains: - - id: 589a331aa51e760df7ccb89e - url: heartofgold.galaxy - lastPublished: '2022-12-07T16:51:37Z' - locales: - primary: - id: 653fd9af6a07fc9cfd7a5e57 - cmsLocaleId: 653ad57de882f528b32e810e - enabled: true - displayName: English - Heart of Gold Standard - redirect: false - subdirectory: /en - tag: The Ultimate Answer - secondary: - - id: 653fd9af6a07fc9cfd7a5e58 - cmsLocaleId: 653ad57de882f528b32e810g - enabled: true - displayName: Betelgeusian - Vogon Liaison - redirect: true - subdirectory: /bet - tag: Vogon - - id: 653fd9af6a07fc9cfd7a5e59 - cmsLocaleId: 653ad57de882f528b32e810h - enabled: false - displayName: Magrathean - Custom Planet Designs - redirect: true - subdirectory: /mg - tag: Magrathean - dataCollectionEnabled: true - dataCollectionType: always - - id: 42e63e98c9a982ac9b8b742 - workspaceId: 42e63fc8c9a982ac9b8b745 - createdOn: '1981-10-12T12:00:00Z' - displayName: Marvin's Personal Blog - shortName: paranoid-android - lastPublished: '2023-04-02T12:45:00Z' - lastUpdated: '2016-10-24T19:43:17Z' - previewUrl: >- - https://d1otoma47x30pg.cloudfront.net/42e63e98c9a982ac9b8b742/198110121200.png - timeZone: DeepSpace/Depression - parentFolderId: 1as2d3f4g5h6j7k8l9z0x1c2v3b4n5m6 - customDomains: - - id: 589a331aa51e760df7ccb89f - url: marvin.blog - lastPublished: '2022-12-07T16:51:37Z' - locales: - primary: - id: 653fd9af6a07fc9cfd7a5e57 - cmsLocaleId: 653ad57de882f528b32e810e - enabled: true - displayName: English - Marvin's Musings - redirect: false - subdirectory: /en - tag: English - secondary: - - id: 653fd9af6a07fc9cfd7a5e56 - cmsLocaleId: 653ad57de882f528b32e810f - enabled: true - displayName: Squornshellous - Mattress Speak - redirect: true - subdirectory: /sr - tag: Squornshellous - dataCollectionEnabled: true - dataCollectionType: always - - id: 42e63e98c9a982ac9b8b743 - workspaceId: 42e63fc8c9a982ac9b8b746 - createdOn: '1982-10-12T12:00:00Z' - displayName: Vogon Poetry Archive - shortName: vogon-poetry - lastPublished: '2023-04-02T12:50:00Z' - lastUpdated: '2016-10-24T19:43:17Z' - previewUrl: >- - https://d1otoma47x30pg.cloudfront.net/42e63e98c9a982ac9b8b743/198210121200.png - timeZone: Vogsphere/PoetryHall - parentFolderId: 1as2d3f4g5h6j7k8l9z0x1c2v3b4n5m6 - customDomains: - - id: 589a331aa51e760df7ccb8a0 - url: vogonpoetry.galaxy - lastPublished: '2022-12-07T16:51:37Z' - locales: - primary: - id: 653fd9af6a07fc9cfd7a5e55 - cmsLocaleId: 653ad57de882f528b32e810d - enabled: true - displayName: English - Vogon Verse - redirect: false - subdirectory: /en - tag: Third Worst Poetry - secondary: - - id: 653fd9af6a07fc9cfd7a5e54 - cmsLocaleId: 653ad57de882f528b32e810c - enabled: true - displayName: Galactic - Universal Language - redirect: true - subdirectory: /gl - tag: Pan-Galactic Gargle Blaster - dataCollectionEnabled: true - dataCollectionType: always - get: - path: /sites/{site_id} - method: GET - auth: true - docs: | - Get details of a site. - - Required scope | `sites:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: Get Site - response: - docs: Request was successful - type: root.Site - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - response: - body: - id: 42e98c9a982ac9b8b742 - workspaceId: 42e63e98c9a982ac9b8b742 - createdOn: '1979-10-12T12:00:00Z' - displayName: The Hitchhiker's Guide to the Galaxy - shortName: hitchhikers-guide - lastPublished: '2023-04-02T12:42:00Z' - lastUpdated: '2023-04-02T12:42:00Z' - previewUrl: >- - https://screenshots.webflow.com/sites/6258612d1ee792848f805dcf/20231219211811_d5990556c743f33b7071300a03bf67e6.png - timeZone: Magrathea/FactoryFloor - parentFolderId: 1as2d3f4g5h6j7k8l9z0x1c2v3b4n5m6 - customDomains: - - id: 589a331aa51e760df7ccb89d - url: hitchhikersguide.galaxy - lastPublished: '2022-12-07T16:51:37Z' - - id: 589a331aa51e760df7ccb89e - url: heartofgold.spaceship - lastPublished: '2022-12-07T16:51:37Z' - locales: - primary: - id: 653fd9af6a07fc9cfd7a5e57 - cmsLocaleId: 653ad57de882f528b32e810e - enabled: false - displayName: English (United States) - displayImageId: displayImageId - redirect: true - subdirectory: '' - tag: en-US - secondary: - - id: 653fd9af6a07fc9cfd7a5e57 - cmsLocaleId: 653ad57de882f528b32e810e - enabled: false - displayName: English (United States) - redirect: true - subdirectory: '' - tag: en-US - dataCollectionEnabled: true - dataCollectionType: always - delete: - path: /sites/{site_id} - method: DELETE - auth: true - docs: | - Delete a site. This endpoint requires an Enterprise workspace. - - Required scope | `sites:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: Delete Site - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - update: - path: /sites/{site_id} - method: PATCH - auth: true - docs: | - Update a site. This endpoint requires an Enterprise workspace. - - Required scope | `sites:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: Update Site - request: - name: SitesUpdateRequest - body: - properties: - name: - type: optional - docs: The name of the site - parentFolderId: - type: optional - docs: The parent folder ID of the site - content-type: application/json - response: - docs: Request was successful - type: root.Site - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - request: {} - response: - body: - id: 42e98c9a982ac9b8b742 - workspaceId: 42e63e98c9a982ac9b8b742 - createdOn: '1979-10-12T12:00:00Z' - displayName: The Hitchhiker's Guide to the Galaxy - shortName: hitchhikers-guide - lastPublished: '2023-04-02T12:42:00Z' - lastUpdated: '2023-04-02T12:42:00Z' - previewUrl: >- - https://screenshots.webflow.com/sites/6258612d1ee792848f805dcf/20231219211811_d5990556c743f33b7071300a03bf67e6.png - timeZone: Magrathea/FactoryFloor - parentFolderId: 1as2d3f4g5h6j7k8l9z0x1c2v3b4n5m6 - customDomains: - - id: 589a331aa51e760df7ccb89d - url: hitchhikersguide.galaxy - lastPublished: '2022-12-07T16:51:37Z' - - id: 589a331aa51e760df7ccb89e - url: heartofgold.spaceship - lastPublished: '2022-12-07T16:51:37Z' - locales: - primary: - id: 653fd9af6a07fc9cfd7a5e57 - cmsLocaleId: 653ad57de882f528b32e810e - enabled: false - displayName: English (United States) - displayImageId: displayImageId - redirect: true - subdirectory: '' - tag: en-US - secondary: - - id: 653fd9af6a07fc9cfd7a5e57 - cmsLocaleId: 653ad57de882f528b32e810e - enabled: false - displayName: English (United States) - redirect: true - subdirectory: '' - tag: en-US - dataCollectionEnabled: true - dataCollectionType: always - get-custom-domain: - path: /sites/{site_id}/custom_domains - method: GET - auth: true - docs: | - Get a list of all custom domains related to site. - - Required scope | `sites:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: Get Custom Domains - response: - docs: Request was successful - type: root.Domains - errors: - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - response: - body: - customDomains: - - id: 589a331aa51e760df7ccb89d - url: hitchhikersguide.galaxy - lastPublished: '2022-12-07T16:51:37Z' - - id: 589a331aa51e760df7ccb89e - url: heartofgold.spaceship - lastPublished: '2022-12-07T16:51:37Z' - publish: - path: /sites/{site_id}/publish - method: POST - auth: true - docs: > - Publishes a site to one or more more domains. - - - This endpoint has a limit of - one successful publish queue per minute. - - - Required scope | `sites:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: Publish Site - request: - name: SitesPublishRequest - body: - properties: - customDomains: - type: optional> - docs: Array of Custom Domain IDs to publish - publishToWebflowSubdomain: - type: optional - docs: Choice of whether to publish to the default Webflow Subdomain - default: false - content-type: application/json - response: - docs: Request accepted - type: SitesPublishResponse - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.TooManyRequestsError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - request: {} - response: - body: - customDomains: - - id: 589a331aa51e760df7ccb89d - url: test-api-domain.com - lastPublished: '2022-12-07T16:51:37Z' - publishToWebflowSubdomain: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - display-name: Sites -docs: Sites are the sites in your Webflow workspace. -types: - SitesPublishResponse: - properties: - customDomains: - type: optional> - docs: Array of domains objects - publishToWebflowSubdomain: - type: optional - docs: Flag for publishing to webflow.io subdomain - default: false - source: - openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/sites/activityLogs.yml b/.mock/definition/sites/activityLogs.yml deleted file mode 100644 index 1468f52..0000000 --- a/.mock/definition/sites/activityLogs.yml +++ /dev/null @@ -1,65 +0,0 @@ -imports: - root: ../__package__.yml -service: - auth: false - base-path: '' - endpoints: - list: - path: /sites/{site_id}/activity_logs - method: GET - auth: true - docs: >- - Retrieve Activity Logs for a specific Site. Requires Site to be on an - Enterprise plan.

Required scope | `site_activity:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: Get Site Activity Logs - request: - name: ActivityLogsListRequest - query-parameters: - limit: - type: optional - docs: 'Maximum number of records to be returned (max limit: 100)' - offset: - type: optional - docs: >- - Offset used for pagination if the results have more than limit - records - response: - docs: A list of site activity logs - type: root.SiteActivityLogResponse - errors: - - root.ForbiddenError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - response: - body: - items: - - id: 654c16c7b229e56bcf26872d - createdOn: '2023-11-08T23:16:23Z' - lastUpdated: '2023-11-08T23:16:23Z' - event: cms_collection - resourceOperation: CREATED - user: - id: 6509cd56e90eec668b009712 - displayName: John Doe - resourceId: 654c16c7b229e56bcf26870c - resourceName: foo-bar - newValue: newValue - previousValue: previousValue - payload: - key: value - pagination: - limit: 25 - offset: 0 - total: 1 - source: - openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/sites/plans.yml b/.mock/definition/sites/plans.yml deleted file mode 100644 index ae9de6d..0000000 --- a/.mock/definition/sites/plans.yml +++ /dev/null @@ -1,40 +0,0 @@ -imports: - root: ../__package__.yml -service: - auth: false - base-path: '' - endpoints: - get-site-plan: - path: /sites/{site_id}/plan - method: GET - auth: true - docs: | - Get site plan details for the specified Site. - - Required scope | `sites:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: Get Site Plan - response: - docs: Request was successful - type: root.SitePlan - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - response: - body: - id: hosting-business-v4 - name: Business Hosting - pricingInfo: https://webflow.com/pricing - source: - openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/sites/redirects.yml b/.mock/definition/sites/redirects.yml deleted file mode 100644 index b104d86..0000000 --- a/.mock/definition/sites/redirects.yml +++ /dev/null @@ -1,190 +0,0 @@ -imports: - root: ../__package__.yml -service: - auth: false - base-path: '' - endpoints: - list: - path: /sites/{site_id}/redirects - method: GET - auth: true - docs: > - Fetch a list of all URL redirect rules configured for a specific site. - - - Use this endpoint to review, audit, or manage the redirection rules that - control how traffic is rerouted on your site. - - - - Required scope: `sites:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: Get URL redirects - response: - docs: Request was successful - type: root.Redirects - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - response: - body: - redirects: - - id: 42e1a2b7aa1a13f768a0042a - fromUrl: /mostly-harmless - toUrl: /earth - - id: 6x9e7f8d9a4b1c2d3e4f5678 - fromUrl: /babel-fish - toUrl: /translate - pagination: - limit: 100 - offset: 0 - total: 2 - create: - path: /sites/{site_id}/redirects - method: POST - auth: true - docs: > - Add a new URL redirection rule to a site. - - - This endpoint allows you to define a source path (`fromUrl`) and its - corresponding destination path (`toUrl`), which will dictate how traffic - is rerouted on your site. This is useful for managing site changes, - restructuring URLs, or handling outdated links. - - - Required scope: `sites:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: Create a URL redirect - request: - body: root.Redirect - content-type: application/json - response: - docs: Request was successful - type: root.Redirect - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - request: - id: 42e1a2b7aa1a13f768a0042a - fromUrl: /mostly-harmless - toUrl: /earth - response: - body: - id: 42e1a2b7aa1a13f768a0042a - fromUrl: /mostly-harmless - toUrl: /earth - delete: - path: /sites/{site_id}/redirects/{redirect_id} - method: DELETE - auth: true - docs: > - Remove a URL redirection rule from a site. - - This is useful for cleaning up outdated or unnecessary redirects, - ensuring that your site's routing behavior remains efficient and - up-to-date. - - Required scope: `sites:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - redirect_id: - type: string - docs: Unique identifier site rediect - display-name: Delete URL redirects - response: - docs: Request was successful - type: root.Redirects - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - redirect_id: 66c4cb9a20cac35ed19500e6 - response: - body: - redirects: - - id: 42e1a2b7aa1a13f768a0042a - fromUrl: /mostly-harmless - toUrl: /earth - - id: 6x9e7f8d9a4b1c2d3e4f5678 - fromUrl: /babel-fish - toUrl: /translate - pagination: - limit: 100 - offset: 0 - total: 2 - update: - path: /sites/{site_id}/redirects/{redirect_id} - method: PATCH - auth: true - docs: | - Update a URL redirection rule from a site. - Required scope: `sites:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - redirect_id: - type: string - docs: Unique identifier site rediect - display-name: Update URL redirect - request: - body: root.Redirect - content-type: application/json - response: - docs: Request was successful - type: root.Redirect - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - redirect_id: 66c4cb9a20cac35ed19500e6 - request: - id: 42e1a2b7aa1a13f768a0042a - fromUrl: /mostly-harmless - toUrl: /earth - response: - body: - id: 42e1a2b7aa1a13f768a0042a - fromUrl: /mostly-harmless - toUrl: /earth - source: - openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/sites/scripts.yml b/.mock/definition/sites/scripts.yml deleted file mode 100644 index 92ad0e4..0000000 --- a/.mock/definition/sites/scripts.yml +++ /dev/null @@ -1,223 +0,0 @@ -imports: - root: ../__package__.yml -service: - auth: false - base-path: '' - endpoints: - get-custom-code: - path: /sites/{site_id}/custom_code - method: GET - auth: true - docs: > - Get all registered scripts that have been applied to a specific Site. - - - Access to this endpoint requires a bearer token from a [Data - Client App](/data/docs/getting-started-data-clients). - - - Required scope | `custom_code:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: Get Custom Code - response: - docs: Request was successful - type: root.ScriptApplyList - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - response: - body: - scripts: - - id: cms_slider - location: header - version: 1.0.0 - attributes: - my-attribute: some-value - - id: alert - location: header - version: 0.0.1 - attributes: - key: value - lastUpdated: '2022-10-26T00:28:54.191Z' - createdOn: '2022-10-26T00:28:54.191Z' - upsert-custom-code: - path: /sites/{site_id}/custom_code - method: PUT - auth: true - docs: > - Add a registered script to a Site. - - - In order to use the Custom Code APIs for Sites and Pages, Custom Code - Scripts must first be registered - - to a Site via the `registered_scripts` endpoints, and then applied to a - Site or Page using the appropriate - - `custom_code` endpoints. - - - Access to this endpoint requires a bearer token from a [Data - Client App](/data/docs/getting-started-data-clients). - - - Required scope | `custom_code:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: Add/Update Custom Code - request: - body: root.ScriptApplyList - content-type: application/json - response: - docs: Request was successful - type: root.ScriptApplyList - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - request: - scripts: - - id: cms_slider - location: header - version: 1.0.0 - attributes: - my-attribute: some-value - - id: alert - location: header - version: 0.0.1 - response: - body: - scripts: - - id: cms_slider - location: header - version: 1.0.0 - attributes: - my-attribute: some-value - - id: alert - location: header - version: 0.0.1 - attributes: - key: value - lastUpdated: lastUpdated - createdOn: createdOn - delete-custom-code: - path: /sites/{site_id}/custom_code - method: DELETE - auth: true - docs: > - Delete the custom code block that an app created for a Site - - - Access to this endpoint requires a bearer token from a [Data - Client App](/data/docs/getting-started-data-clients). - - - Required scope | `custom_code:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: Delete Custom Code - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - list-custom-code-blocks: - path: /sites/{site_id}/custom_code/blocks - method: GET - auth: true - docs: > - Get all instances of Custom Code applied to a Site or Pages. - - - Access to this endpoint requires a bearer token from a [Data - Client App](/data/docs/getting-started-data-clients). - - - Required scope | `custom_code:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: List Custom Code Blocks - request: - name: ScriptsListCustomCodeBlocksRequest - query-parameters: - offset: - type: optional - docs: >- - Offset used for pagination if the results have more than limit - records - limit: - type: optional - docs: 'Maximum number of records to be returned (max limit: 100)' - response: - docs: Request was successful - type: root.ListCustomCodeBlocks - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - response: - body: - blocks: - - siteId: 6258612d1ee792848f805dcf - pageId: pageId - type: site - scripts: - - id: chartjs - location: header - version: 4.4.2 - attributes: - key: value - createdOn: '2024-04-03T16:49:15Z' - lastUpdated: '2024-04-03T16:49:15Z' - - siteId: 6390c49674a71f84b51a08d8 - pageId: 6419db964a9c43f6a3af6348 - type: page - scripts: - - id: id - location: header - version: version - createdOn: '2022-10-26T00:28:54Z' - lastUpdated: '2022-10-26T00:28:54Z' - pagination: - limit: 10 - offset: 0 - total: 1 - source: - openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/token.yml b/.mock/definition/token.yml deleted file mode 100644 index 033c5c3..0000000 --- a/.mock/definition/token.yml +++ /dev/null @@ -1,72 +0,0 @@ -imports: - root: __package__.yml -service: - auth: false - base-path: '' - endpoints: - authorized-by: - path: /token/authorized_by - method: GET - auth: true - docs: | - Information about the Authorized User - - Required Scope | `authorized_user:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - display-name: Get Authorization User Info - response: - docs: Request was successful - type: root.AuthorizedUser - errors: - - root.UnauthorizedError - - root.ForbiddenError - examples: - - response: - body: - id: 545bbecb7bdd6769632504a7 - email: some@email.com - firstName: Some - lastName: One - introspect: - path: /token/introspect - method: GET - auth: true - docs: > - Information about the authorization token - - - Access to this endpoint requires a bearer token from a [Data - Client App](/data/docs/getting-started-data-clients). - source: - openapi: ../../../openapi/referenced-specs/v2.yml - display-name: Get Authorization Info - response: - docs: Request was successful - type: root.Authorization - errors: - - root.UnauthorizedError - examples: - - response: - body: - authorization: - id: 55818d58616600637b9a5786 - createdOn: '2016-10-03T23:12:00Z' - lastUsed: '2016-10-10T21:41:12Z' - grantType: authorization_code - rateLimit: 60 - scope: assets:read,assets:write - authorizedTo: - siteIds: - - 62f3b1f7eafac55d0c64ef91 - workspaceIds: - - 52f3b1f7eafac55d0c64ef91 - userIds: - - 545bbecb7bdd6769632504a7 - application: - id: 55131cd036c09f7d07883dfc - description: My Amazing App - homepage: https://webflow.com - displayName: My Amazing App - source: - openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/users.yml b/.mock/definition/users.yml deleted file mode 100644 index 19a17cc..0000000 --- a/.mock/definition/users.yml +++ /dev/null @@ -1,392 +0,0 @@ -types: - UsersListRequestSort: - enum: - - value: CreatedOn - name: CreatedOnAscending - docs: Sorts users in ascending order based on their created date - - value: '-CreatedOn' - name: CreatedOnDescending - docs: Sorts users in descending order based on their created date - - value: Email - name: EmailAscending - docs: Sorts users in ascending order based on their email - - value: '-Email' - name: EmailDescending - docs: Sorts users in descending order based on their email - - value: Status - name: StatusAscending - docs: Sorts users in ascending order based on their status - - value: '-Status' - name: StatusDescending - docs: Sorts users in descending order based on their status - - value: LastLogin - name: LastLoginAscending - docs: Sorts users in ascending order based on their last login date - - value: '-LastLogin' - name: LastLoginDescending - docs: Sorts users in descending order based on their last login date - - value: UpdatedOn - name: UpdatedOnAscending - docs: Sorts users in ascending order based on their update date - - value: '-UpdatedOn' - name: UpdatedOnDescending - docs: Sorts users in descending order based on their update date - source: - openapi: ../../../openapi/referenced-specs/v2.yml - UsersUpdateRequestData: - properties: - name: - type: optional - docs: | - The name of the user - accept-privacy: - type: optional - docs: | - Boolean indicating if the user has accepted the privacy policy - accept-communications: - type: optional - docs: | - Boolean indicating if the user has accepted to receive communications - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true -imports: - root: __package__.yml -service: - auth: false - base-path: '' - endpoints: - list: - path: /sites/{site_id}/users - method: GET - auth: true - docs: | - Get a list of users for a site - - Required scope | `users:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: List Users - request: - name: UsersListRequest - query-parameters: - offset: - type: optional - docs: >- - Offset used for pagination if the results have more than limit - records - limit: - type: optional - docs: 'Maximum number of records to be returned (max limit: 100)' - sort: - type: optional - docs: | - Sort string to use when ordering users - - Example(`CreatedOn`, `Email`, `Status`, `LastLogin`, `UpdatedOn`). - - Can be prefixed with a `-` to reverse the sort (ex. `-CreatedOn`) - response: - docs: Request was successful - type: root.UserList - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - response: - body: - count: 5 - limit: 5 - offset: 0 - total: 201 - users: - - id: 6287ec36a841b25637c663df - isEmailVerified: false - lastUpdated: '2022-05-20T13:46:12Z' - invitedOn: '2016-10-24T19:41:29Z' - createdOn: '2022-05-20T13:46:12Z' - lastLogin: '2016-10-24T19:41:29Z' - status: unverified - accessGroups: - - slug: vogon-construction-crew - type: admin - - id: 6287ec36a841b25637c663f0 - isEmailVerified: false - lastUpdated: '2022-05-19T05:32:04Z' - invitedOn: '2016-10-24T19:41:29Z' - createdOn: '2022-05-19T05:32:04Z' - lastLogin: '2016-10-24T19:41:29Z' - status: unverified - accessGroups: - - slug: improbability-drive-test-subjects - type: admin - - id: 6287ec36a841b25637c663d9 - isEmailVerified: true - lastUpdated: '2022-05-17T03:34:06Z' - invitedOn: '2016-10-24T19:41:29Z' - createdOn: '2022-05-17T03:34:06Z' - lastLogin: '2016-10-24T19:41:29Z' - status: verified - accessGroups: - - slug: heart-of-gold-crew - type: admin - - id: 6287ec37a841b25637c6641b - isEmailVerified: false - lastUpdated: '2022-05-15T03:46:09Z' - invitedOn: '2016-10-24T19:41:29Z' - createdOn: '2022-05-15T03:46:09Z' - lastLogin: '2016-10-24T19:41:29Z' - status: unverified - accessGroups: - - slug: hitchhikers-guide-research-team - type: admin - - id: 6287ec37a841b25637c66449 - isEmailVerified: true - lastUpdated: '2022-05-15T02:55:38Z' - invitedOn: '2016-10-24T19:41:29Z' - createdOn: '2022-05-15T02:55:38Z' - lastLogin: '2016-10-24T19:41:29Z' - status: verified - accessGroups: - - slug: milliways-reservationists - type: admin - get: - path: /sites/{site_id}/users/{user_id} - method: GET - auth: true - docs: | - Get a User by ID - - Required scope | `users:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - user_id: - type: string - docs: Unique identifier for a User - display-name: Get User - response: - docs: Request was successful - type: root.User - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - user_id: 580e63e98c9a982ac9b8b741 - response: - body: - id: 6287ec36a841b25637c663df - isEmailVerified: true - lastUpdated: '2022-05-20T13:46:12Z' - invitedOn: '2022-05-20T13:46:12Z' - createdOn: '2022-05-20T13:46:12Z' - lastLogin: '2022-05-20T13:46:12Z' - status: verified - accessGroups: - - slug: webflowers - type: admin - data: - data: - name: name - email: email - accept-privacy: true - accept-communications: true - additionalProperties: additionalProperties - delete: - path: /sites/{site_id}/users/{user_id} - method: DELETE - auth: true - docs: | - Delete a User by ID - - Required scope | `users:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - user_id: - type: string - docs: Unique identifier for a User - display-name: Delete User - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - user_id: 580e63e98c9a982ac9b8b741 - update: - path: /sites/{site_id}/users/{user_id} - method: PATCH - auth: true - docs: | - Update a User by ID - - Required scope | `users:write` - - The email and password - fields cannot be updated using this endpoint - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - user_id: - type: string - docs: Unique identifier for a User - display-name: Update User - request: - name: UsersUpdateRequest - body: - properties: - data: optional - accessGroups: - type: optional> - docs: > - An array of access group slugs. Access groups are assigned to - the user as type `admin` and the user remains in the group until - removed. - content-type: application/json - response: - docs: Request was successful - type: root.User - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - user_id: 580e63e98c9a982ac9b8b741 - request: - data: - name: Some One - accept-privacy: false - accept-communications: false - accessGroups: - - webflowers - - platinum - - free-tier - response: - body: - id: 6287ec36a841b25637c663df - isEmailVerified: true - lastUpdated: '2022-05-20T13:46:12Z' - invitedOn: '2022-05-20T13:46:12Z' - createdOn: '2022-05-20T13:46:12Z' - lastLogin: '2022-05-20T13:46:12Z' - status: verified - accessGroups: - - slug: webflowers - type: admin - data: - data: - name: name - email: email - accept-privacy: true - accept-communications: true - additionalProperties: additionalProperties - invite: - path: /sites/{site_id}/users/invite - method: POST - auth: true - docs: > - Create and invite a user with an email address. - - - The user will be sent and invite via email, which they will need to - accept in order to join paid any paid access group. - - - Required scope | `users:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: Create and Invite a User - request: - name: UsersInviteRequest - body: - properties: - email: - type: string - docs: Email address of user to send invite to - validation: - format: email - accessGroups: - type: optional> - docs: > - An array of access group slugs. Access groups are assigned to - the user as type `admin` and the user remains in the group until - removed. - content-type: application/json - response: - docs: Request was successful - type: root.User - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.ConflictError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - request: - email: some.one@home.com - accessGroups: - - webflowers - response: - body: - id: 6287ec36a841b25637c663df - isEmailVerified: true - lastUpdated: '2022-05-20T13:46:12Z' - invitedOn: '2022-05-20T13:46:12Z' - createdOn: '2022-05-20T13:46:12Z' - lastLogin: '2022-05-20T13:46:12Z' - status: verified - accessGroups: - - slug: webflowers - type: admin - data: - data: - name: name - email: email - accept-privacy: true - accept-communications: true - additionalProperties: additionalProperties - source: - openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/webhooks.yml b/.mock/definition/webhooks.yml deleted file mode 100644 index d40e3e4..0000000 --- a/.mock/definition/webhooks.yml +++ /dev/null @@ -1,189 +0,0 @@ -imports: - root: __package__.yml -service: - auth: false - base-path: '' - endpoints: - list: - path: /sites/{site_id}/webhooks - method: GET - auth: true - docs: | - List all App-created Webhooks registered for a given site - - Required scope | `sites:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: List Webhooks - response: - docs: Request was successful - type: root.WebhookList - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - response: - body: - pagination: - limit: 100 - offset: 0 - total: 100 - webhooks: - - id: 57ca0a9e418c504a6e1acbb6 - triggerType: form_submission - url: https://webhook.site/7f7f7f7f-7f7f-7f7f-7f7f-7f7f7f7f7f7f - workspaceId: 4f4e46fd476ea8c507000001 - siteId: 562ac0395358780a1f5e6fbd - filter: - name: Email Form - lastTriggered: '2023-02-08T23:59:28Z' - createdOn: '2016-09-02T23:26:22Z' - - id: 578d85cce0c47cd2865f4cf2 - triggerType: form_submission - url: https://webhook.site/7f7f7f7f-7f7f-7f7f-7f7f-7f7f7f7f7f7f - workspaceId: 4f4e46fd476ea8c507000001 - siteId: 562ac0395358780a1f5e6fbd - filter: - name: Email Form - lastTriggered: '2023-02-08T23:59:28Z' - createdOn: '2016-07-19T01:43:40Z' - - id: 578d85cce0c47cd2865f4cf3 - triggerType: form_submission - url: https://webhook.site/7f7f7f7f-7f7f-7f7f-7f7f-7f7f7f7f7f7f - workspaceId: 4f4e46fd476ea8c507000001 - siteId: 562ac0395358780a1f5e6fbd - filter: - name: Email Form - lastTriggered: '2023-02-08T23:59:28Z' - createdOn: '2016-07-19T01:43:40Z' - create: - path: /sites/{site_id}/webhooks - method: POST - auth: true - docs: > - Create a new Webhook. - - - Limit of 75 registrations per `triggerType`, per site. - - - Access to this endpoint requires a bearer token from a [Data - Client App](/data/docs/getting-started-data-clients). - - Required scope | `sites:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: Create Webhook - request: - body: root.Webhook - content-type: application/json - response: - docs: Request was successful - type: root.Webhook - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - request: - id: 582266e0cd48de0f0e3c6d8b - triggerType: form_submission - url: https://webhook.site/7f7f7f7f-7f7f-7f7f-7f7f-7f7f7f7f7f7f - workspaceId: 4f4e46fd476ea8c507000001 - siteId: 562ac0395358780a1f5e6fbd - lastTriggered: '2023-02-08T23:59:28Z' - createdOn: '2022-11-08T23:59:28Z' - response: - body: - id: 582266e0cd48de0f0e3c6d8b - triggerType: form_submission - url: https://webhook.site/7f7f7f7f-7f7f-7f7f-7f7f-7f7f7f7f7f7f - workspaceId: 4f4e46fd476ea8c507000001 - siteId: 562ac0395358780a1f5e6fbd - filter: - name: My Form - lastTriggered: '2023-02-08T23:59:28Z' - createdOn: '2022-11-08T23:59:28Z' - get: - path: /webhooks/{webhook_id} - method: GET - auth: true - docs: | - Get a specific Webhook instance - - Required scope: `sites:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - webhook_id: - type: string - docs: Unique identifier for a Webhook - display-name: Get Webhook - response: - docs: Request was successful - type: root.Webhook - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - webhook_id: 580e64008c9a982ac9b8b754 - response: - body: - id: 582266e0cd48de0f0e3c6d8b - triggerType: form_submission - url: https://webhook.site/7f7f7f7f-7f7f-7f7f-7f7f-7f7f7f7f7f7f - workspaceId: 4f4e46fd476ea8c507000001 - siteId: 562ac0395358780a1f5e6fbd - filter: - name: My Form - lastTriggered: '2023-02-08T23:59:28Z' - createdOn: '2022-11-08T23:59:28Z' - delete: - path: /webhooks/{webhook_id} - method: DELETE - auth: true - docs: | - Remove a Webhook - - Required scope: `sites:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - webhook_id: - type: string - docs: Unique identifier for a Webhook - display-name: Remove Webhook - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - webhook_id: 580e64008c9a982ac9b8b754 - source: - openapi: ../../../openapi/referenced-specs/v2.yml - display-name: Webhooks -docs: Webhooks are the webhooks in your Webflow site. diff --git a/.mock/fern.config.json b/.mock/fern.config.json deleted file mode 100644 index 8b3316e..0000000 --- a/.mock/fern.config.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "organization" : "webflow", - "version" : "0.46.19" -} \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index 658601b..f4d4428 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. [[package]] name = "annotated-types" @@ -38,13 +38,13 @@ trio = ["trio (>=0.26.1)"] [[package]] name = "certifi" -version = "2024.12.14" +version = "2025.11.12" description = "Python package for providing Mozilla's CA Bundle." optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, - {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, + {file = "certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b"}, + {file = "certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316"}, ] [[package]] @@ -60,15 +60,18 @@ files = [ [[package]] name = "exceptiongroup" -version = "1.2.2" +version = "1.3.1" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, - {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, + {file = "exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598"}, + {file = "exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219"}, ] +[package.dependencies] +typing-extensions = {version = ">=4.6.0", markers = "python_version < \"3.13\""} + [package.extras] test = ["pytest (>=6)"] @@ -130,13 +133,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "idna" -version = "3.10" +version = "3.11" description = "Internationalized Domain Names in Applications (IDNA)" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, - {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, + {file = "idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea"}, + {file = "idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902"}, ] [package.extras] @@ -144,13 +147,13 @@ all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2 [[package]] name = "iniconfig" -version = "2.0.0" +version = "2.1.0" description = "brain-dead simple config-ini parsing" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, + {file = "iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"}, + {file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"}, ] [[package]] @@ -201,24 +204,24 @@ reports = ["lxml"] [[package]] name = "mypy-extensions" -version = "1.0.0" +version = "1.1.0" description = "Type system extensions for programs checked with the mypy type checker." optional = false -python-versions = ">=3.5" +python-versions = ">=3.8" files = [ - {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, - {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, + {file = "mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505"}, + {file = "mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558"}, ] [[package]] name = "packaging" -version = "24.2" +version = "25.0" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, - {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, + {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, + {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, ] [[package]] @@ -238,13 +241,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pydantic" -version = "2.10.5" +version = "2.10.6" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.10.5-py3-none-any.whl", hash = "sha256:4dd4e322dbe55472cb7ca7e73f4b63574eecccf2835ffa2af9021ce113c83c53"}, - {file = "pydantic-2.10.5.tar.gz", hash = "sha256:278b38dbbaec562011d659ee05f63346951b3a248a6f3642e1bc68894ea2b4ff"}, + {file = "pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584"}, + {file = "pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236"}, ] [package.dependencies] @@ -473,43 +476,53 @@ files = [ [[package]] name = "tomli" -version = "2.2.1" +version = "2.3.0" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" files = [ - {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, - {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, - {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, - {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, - {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, - {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, - {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, - {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, - {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, - {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, - {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, - {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, - {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, - {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, + {file = "tomli-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:88bd15eb972f3664f5ed4b57c1634a97153b4bac4479dcb6a495f41921eb7f45"}, + {file = "tomli-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:883b1c0d6398a6a9d29b508c331fa56adbcdff647f6ace4dfca0f50e90dfd0ba"}, + {file = "tomli-2.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1381caf13ab9f300e30dd8feadb3de072aeb86f1d34a8569453ff32a7dea4bf"}, + {file = "tomli-2.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a0e285d2649b78c0d9027570d4da3425bdb49830a6156121360b3f8511ea3441"}, + {file = "tomli-2.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a154a9ae14bfcf5d8917a59b51ffd5a3ac1fd149b71b47a3a104ca4edcfa845"}, + {file = "tomli-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:74bf8464ff93e413514fefd2be591c3b0b23231a77f901db1eb30d6f712fc42c"}, + {file = "tomli-2.3.0-cp311-cp311-win32.whl", hash = "sha256:00b5f5d95bbfc7d12f91ad8c593a1659b6387b43f054104cda404be6bda62456"}, + {file = "tomli-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:4dc4ce8483a5d429ab602f111a93a6ab1ed425eae3122032db7e9acf449451be"}, + {file = "tomli-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7d86942e56ded512a594786a5ba0a5e521d02529b3826e7761a05138341a2ac"}, + {file = "tomli-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:73ee0b47d4dad1c5e996e3cd33b8a76a50167ae5f96a2607cbe8cc773506ab22"}, + {file = "tomli-2.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:792262b94d5d0a466afb5bc63c7daa9d75520110971ee269152083270998316f"}, + {file = "tomli-2.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f195fe57ecceac95a66a75ac24d9d5fbc98ef0962e09b2eddec5d39375aae52"}, + {file = "tomli-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e31d432427dcbf4d86958c184b9bfd1e96b5b71f8eb17e6d02531f434fd335b8"}, + {file = "tomli-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b0882799624980785240ab732537fcfc372601015c00f7fc367c55308c186f6"}, + {file = "tomli-2.3.0-cp312-cp312-win32.whl", hash = "sha256:ff72b71b5d10d22ecb084d345fc26f42b5143c5533db5e2eaba7d2d335358876"}, + {file = "tomli-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:1cb4ed918939151a03f33d4242ccd0aa5f11b3547d0cf30f7c74a408a5b99878"}, + {file = "tomli-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5192f562738228945d7b13d4930baffda67b69425a7f0da96d360b0a3888136b"}, + {file = "tomli-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:be71c93a63d738597996be9528f4abe628d1adf5e6eb11607bc8fe1a510b5dae"}, + {file = "tomli-2.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4665508bcbac83a31ff8ab08f424b665200c0e1e645d2bd9ab3d3e557b6185b"}, + {file = "tomli-2.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4021923f97266babc6ccab9f5068642a0095faa0a51a246a6a02fccbb3514eaf"}, + {file = "tomli-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4ea38c40145a357d513bffad0ed869f13c1773716cf71ccaa83b0fa0cc4e42f"}, + {file = "tomli-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad805ea85eda330dbad64c7ea7a4556259665bdf9d2672f5dccc740eb9d3ca05"}, + {file = "tomli-2.3.0-cp313-cp313-win32.whl", hash = "sha256:97d5eec30149fd3294270e889b4234023f2c69747e555a27bd708828353ab606"}, + {file = "tomli-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0c95ca56fbe89e065c6ead5b593ee64b84a26fca063b5d71a1122bf26e533999"}, + {file = "tomli-2.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:cebc6fe843e0733ee827a282aca4999b596241195f43b4cc371d64fc6639da9e"}, + {file = "tomli-2.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4c2ef0244c75aba9355561272009d934953817c49f47d768070c3c94355c2aa3"}, + {file = "tomli-2.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c22a8bf253bacc0cf11f35ad9808b6cb75ada2631c2d97c971122583b129afbc"}, + {file = "tomli-2.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0eea8cc5c5e9f89c9b90c4896a8deefc74f518db5927d0e0e8d4a80953d774d0"}, + {file = "tomli-2.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b74a0e59ec5d15127acdabd75ea17726ac4c5178ae51b85bfe39c4f8a278e879"}, + {file = "tomli-2.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5870b50c9db823c595983571d1296a6ff3e1b88f734a4c8f6fc6188397de005"}, + {file = "tomli-2.3.0-cp314-cp314-win32.whl", hash = "sha256:feb0dacc61170ed7ab602d3d972a58f14ee3ee60494292d384649a3dc38ef463"}, + {file = "tomli-2.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:b273fcbd7fc64dc3600c098e39136522650c49bca95df2d11cf3b626422392c8"}, + {file = "tomli-2.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:940d56ee0410fa17ee1f12b817b37a4d4e4dc4d27340863cc67236c74f582e77"}, + {file = "tomli-2.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f85209946d1fe94416debbb88d00eb92ce9cd5266775424ff81bc959e001acaf"}, + {file = "tomli-2.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a56212bdcce682e56b0aaf79e869ba5d15a6163f88d5451cbde388d48b13f530"}, + {file = "tomli-2.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5f3ffd1e098dfc032d4d3af5c0ac64f6d286d98bc148698356847b80fa4de1b"}, + {file = "tomli-2.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e01decd096b1530d97d5d85cb4dff4af2d8347bd35686654a004f8dea20fc67"}, + {file = "tomli-2.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8a35dd0e643bb2610f156cca8db95d213a90015c11fee76c946aa62b7ae7e02f"}, + {file = "tomli-2.3.0-cp314-cp314t-win32.whl", hash = "sha256:a1f7f282fe248311650081faafa5f4732bdbfef5d45fe3f2e702fbc6f2d496e0"}, + {file = "tomli-2.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:70a251f8d4ba2d9ac2542eecf008b3c8a9fc5c3f9f02c56a9d7952612be2fdba"}, + {file = "tomli-2.3.0-py3-none-any.whl", hash = "sha256:e95b1af3c5b07d9e643909b5abbec77cd9f1217e6d0bca72b0234736b9fb1f1b"}, + {file = "tomli-2.3.0.tar.gz", hash = "sha256:64be704a875d2a59753d80ee8a533c3fe183e3f06807ff7dc2232938ccb01549"}, ] [[package]] @@ -525,16 +538,16 @@ files = [ [[package]] name = "typing-extensions" -version = "4.12.2" +version = "4.13.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, + {file = "typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c"}, + {file = "typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef"}, ] [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "2974ad2d485417c468bff08c2d5526b20e5e4790deaffc5363b3c831bebca3b3" +content-hash = "6f6c191c1028d17a97fdfa84cedfd3cef94b5d63d98b8c1d333b3398eeea9055" diff --git a/pyproject.toml b/pyproject.toml index 58c9529..66a8846 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "webflow" -version = "2.0.0b2" +version = "1.2.1" description = "" readme = "README.md" authors = [] @@ -33,7 +33,6 @@ Repository = 'https://github.com/webflow/webflow-python' [tool.poetry.dependencies] python = "^3.8" httpx = ">=0.21.2" -httpcore = "1.0.9" pydantic = ">= 1.9.2" pydantic-core = "^2.18.2" typing_extensions = ">= 4.0.0" diff --git a/reference.md b/reference.md index 5001bba..7e3b964 100644 --- a/reference.md +++ b/reference.md @@ -137,7 +137,9 @@ client.token.introspect()
-Create a site. This endpoint requires an Enterprise workspace. +Create a site. + +This endpoint requires an Enterprise workspace. Required scope | `workspace:write`
@@ -368,7 +370,9 @@ client.sites.get(
-Delete a site. This endpoint requires an Enterprise workspace. +Delete a site. + +This endpoint requires an Enterprise workspace. Required scope | `sites:write`
@@ -440,7 +444,9 @@ client.sites.delete(
-Update a site. This endpoint requires an Enterprise workspace. +Update a site. + +This endpoint requires an Enterprise workspace. Required scope | `sites:write`
@@ -600,9 +606,11 @@ client.sites.get_custom_domain(
-Publishes a site to one or more more domains. +Publishes a site to one or more more domains. + +To publish to a specific custom domain, use the domain IDs from the [Get Custom Domains](/data/reference/sites/get-custom-domain) endpoint. -This endpoint has a limit of one successful publish queue per minute. +This endpoint has a specific rate limit of one successful publish queue per minute. Required scope | `sites:write`
@@ -626,6 +634,8 @@ client = Webflow( ) client.sites.publish( site_id="580e63e98c9a982ac9b8b741", + custom_domains=["660c6449dd97ebc7346ac629", "660c6449dd97ebc7346ac62f"], + publish_to_webflow_subdomain=False, ) ``` @@ -763,7 +773,9 @@ client.collections.list(
-Create a Collection for a site. +Create a Collection for a site with collection fields. + +Each collection includes the required _name_ and _slug_ fields, which are generated automatically. You can update the `displayName` of these fields, but the slug for them cannot be changed. Fields slugs are automatically converted to lowercase. Spaces in slugs are replaced with hyphens. Required scope | `cms:write`
@@ -780,7 +792,7 @@ Required scope | `cms:write`
```python -from webflow import Webflow +from webflow import ReferenceField, ReferenceFieldMetadata, StaticField, Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", @@ -790,6 +802,29 @@ client.collections.create( display_name="Blog Posts", singular_name="Blog Post", slug="posts", + fields=[ + StaticField( + is_required=True, + type="PlainText", + display_name="Title", + help_text="The title of the blog post", + ), + StaticField( + is_required=True, + type="RichText", + display_name="Content", + help_text="The content of the blog post", + ), + ReferenceField( + is_required=True, + type="Reference", + display_name="Author", + help_text="The author of the blog post", + metadata=ReferenceFieldMetadata( + collection_id="23cc2d952d4e4631ffd4345d2743db4e", + ), + ), + ], ) ``` @@ -838,6 +873,14 @@ client.collections.create(
+**fields:** `typing.Optional[typing.Sequence[FieldCreate]]` — An array of custom fields to add to the collection + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -1032,6 +1075,8 @@ client = Webflow( client.pages.list( site_id="580e63e98c9a982ac9b8b741", locale_id="65427cf400e02b306eaa04a0", + limit=1.1, + offset=1.1, ) ``` @@ -1056,7 +1101,11 @@ client.pages.list(
-**locale_id:** `typing.Optional[str]` — Unique identifier for a specific locale. Applicable, when using localization. +**locale_id:** `typing.Optional[str]` + +Unique identifier for a specific Locale. + +[Lear more about localization.](/data/v2.0.0/docs/working-with-localization)
@@ -1153,7 +1202,11 @@ client.pages.get_metadata(
-**locale_id:** `typing.Optional[str]` — Unique identifier for a specific locale. Applicable, when using localization. +**locale_id:** `typing.Optional[str]` + +Unique identifier for a specific Locale. + +[Lear more about localization.](/data/v2.0.0/docs/working-with-localization)
@@ -1202,9 +1255,11 @@ Required scope | `pages:write`
```python -import datetime - -from webflow import PageOpenGraph, PageSeo, Webflow +from webflow import Webflow +from webflow.resources.pages import ( + PageMetadataWriteOpenGraph, + PageMetadataWriteSeo, +) client = Webflow( access_token="YOUR_ACCESS_TOKEN", @@ -1212,32 +1267,18 @@ client = Webflow( client.pages.update_page_settings( page_id="63c720f9347c2139b248e552", locale_id="65427cf400e02b306eaa04a0", - id="6596da6045e56dee495bcbba", - site_id="6258612d1ee792848f805dcf", title="Guide to the Galaxy", slug="guide-to-the-galaxy", - created_on=datetime.datetime.fromisoformat( - "2024-03-11 10:42:00+00:00", - ), - last_updated=datetime.datetime.fromisoformat( - "2024-03-11 10:42:42+00:00", - ), - archived=False, - draft=False, - can_branch=True, - is_branch=False, - seo=PageSeo( + seo=PageMetadataWriteSeo( title="The Ultimate Hitchhiker's Guide to the Galaxy", description="Everything you need to know about the galaxy, from avoiding Vogon poetry to the importance of towels.", ), - open_graph=PageOpenGraph( + open_graph=PageMetadataWriteOpenGraph( title="Explore the Cosmos with The Ultimate Guide", title_copied=False, description="Dive deep into the mysteries of the universe with your guide to everything galactic.", description_copied=False, ), - page_locale_id="653fd9af6a07fc9cfd7a5e57", - published_path="/en-us/guide-to-the-galaxy", ) ``` @@ -1262,95 +1303,11 @@ client.pages.update_page_settings(
-**id:** `str` — Unique identifier for the Page - -
-
- -
-
- -**locale_id:** `typing.Optional[str]` — Unique identifier for a specific locale. Applicable, when using localization. - -
-
- -
-
- -**site_id:** `typing.Optional[str]` — Unique identifier for the Site - -
-
- -
-
- -**title:** `typing.Optional[str]` — Title of the Page - -
-
- -
-
- -**slug:** `typing.Optional[str]` — slug of the Page (derived from title) - -
-
- -
-
- -**parent_id:** `typing.Optional[str]` — Identifier of the parent folder - -
-
- -
-
- -**collection_id:** `typing.Optional[str]` — Unique identifier for a linked Collection, value will be null if the Page is not part of a Collection. - -
-
- -
-
- -**created_on:** `typing.Optional[dt.datetime]` — The date the Page was created - -
-
- -
-
- -**last_updated:** `typing.Optional[dt.datetime]` — The date the Page was most recently updated - -
-
- -
-
- -**archived:** `typing.Optional[bool]` — Whether the Page has been archived - -
-
- -
-
- -**draft:** `typing.Optional[bool]` — Whether the Page is a draft - -
-
+**locale_id:** `typing.Optional[str]` -
-
+Unique identifier for a specific Locale. -**can_branch:** `typing.Optional[bool]` — Indicates whether the Page supports [Page Branching](https://university.webflow.com/lesson/page-branching) +[Lear more about localization.](/data/v2.0.0/docs/working-with-localization)
@@ -1358,7 +1315,7 @@ client.pages.update_page_settings(
-**is_branch:** `typing.Optional[bool]` — Indicates whether the Page is a Branch of another Page [Page Branching](https://university.webflow.com/lesson/page-branching) +**title:** `typing.Optional[str]` — Title for the page
@@ -1366,23 +1323,12 @@ client.pages.update_page_settings(
-**is_members_only:** `typing.Optional[bool]` — Indicates whether the Page is restricted by [Memberships Controls](https://university.webflow.com/lesson/webflow-memberships-overview#how-to-manage-page-restrictions) - -
-
- -
-
+**slug:** `typing.Optional[str]` -**seo:** `typing.Optional[PageSeo]` — SEO-related fields for the Page - -
-
+Slug for the page. -
-
-**open_graph:** `typing.Optional[PageOpenGraph]` — Open Graph fields for the Page +**Note:** Updating slugs in secondary locales is only supported in Advanced and Enterprise localization add-on plans.
@@ -1390,7 +1336,7 @@ client.pages.update_page_settings(
-**page_locale_id:** `typing.Optional[str]` — Unique ID of the page locale +**seo:** `typing.Optional[PageMetadataWriteSeo]` — SEO-related fields for the Page
@@ -1398,7 +1344,7 @@ client.pages.update_page_settings(
-**published_path:** `typing.Optional[str]` — Relative path of the published page URL +**open_graph:** `typing.Optional[PageMetadataWriteOpenGraph]` — Open Graph fields for the Page
@@ -1430,10 +1376,9 @@ client.pages.update_page_settings(
-Get static content from a static page. This includes text nodes, image nodes and component instances. -To retrieve the contents of components in the page use the [get component content](/data/reference/pages-and-components/components/get-content) endpoint. +Get text and component instance content from a static page. -If you do not provide a Locale ID in your request, the response will return any content that can be localized from the Primary locale. +Localization Required scope | `pages:read`
@@ -1458,6 +1403,8 @@ client = Webflow( client.pages.get_content( page_id="63c720f9347c2139b248e552", locale_id="65427cf400e02b306eaa04a0", + limit=1.1, + offset=1.1, ) ``` @@ -1482,7 +1429,11 @@ client.pages.get_content(
-**locale_id:** `typing.Optional[str]` — Unique identifier for a specific locale. Applicable, when using localization. +**locale_id:** `typing.Optional[str]` + +Unique identifier for a specific Locale. + +[Lear more about localization.](/data/v2.0.0/docs/working-with-localization)
@@ -1533,8 +1484,9 @@ client.pages.get_content( This endpoint updates content on a static page in **secondary locales**. It supports updating up to 1000 nodes in a single request. Before making updates: -1. Use the [get page content](/data/reference/pages-and-components/pages/get-content) endpoint to identify available content nodes and their types -2. If the page has component instances, retrieve the component's properties that you'll override using the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint +1. Use the [get page content](/data/reference/pages-and-components/pages/get-content) endpoint to identify available content nodes and their types. +2. If the page has component instances, retrieve the component's properties that you'll override using the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint. +3. DOM elements may include a `data-w-id` attribute. This attribute is used by Webflow to maintain custom attributes and links across locales. Always include the original `data-w-id` value in your update requests to ensure consistent behavior across all locales. This endpoint is specifically for localized pages. Ensure that the specified `localeId` is a valid **secondary locale** for the site otherwise the request will fail. @@ -1558,6 +1510,10 @@ Required scope | `pages:write` from webflow import ( ComponentInstanceNodePropertyOverridesWrite, ComponentInstanceNodePropertyOverridesWritePropertyOverridesItem, + Select, + SelectNodeWriteChoicesItem, + SubmitButtonNodeWrite, + TextInputNodeWrite, TextNodeWrite, Webflow, ) @@ -1577,6 +1533,28 @@ client.pages.update_static_content( node_id="a245c12d-995b-55ee-5ec7-aa36a6cad627", text="

Don't Panic!

Always know where your towel is.

", ), + Select( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad635", + choices=[ + SelectNodeWriteChoicesItem( + value="choice-1", + text="First choice", + ), + SelectNodeWriteChoicesItem( + value="choice-2", + text="Second choice", + ), + ], + ), + TextInputNodeWrite( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad642", + placeholder="Enter something here...", + ), + SubmitButtonNodeWrite( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad671", + value="Submit", + waiting_text="Submitting...", + ), ComponentInstanceNodePropertyOverridesWrite( node_id="a245c12d-995b-55ee-5ec7-aa36a6cad629", property_overrides=[ @@ -1680,6 +1658,9 @@ client = Webflow( ) client.components.list( site_id="580e63e98c9a982ac9b8b741", + branch_id="68026fa68ef6dc744c75b833", + limit=1.1, + offset=1.1, ) ``` @@ -1704,6 +1685,14 @@ client.components.list(
+**branch_id:** `typing.Optional[str]` — Scope the operation to work on a specific branch. + +
+
+ +
+
+ **limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100)
@@ -1744,7 +1733,7 @@ client.components.list(
-Get static content from a component definition. This includes text nodes, image nodes and nested component instances. +Get static content from a component definition. This includes text nodes, image nodes, select nodes, text input nodes, submit button nodes, and nested component instances. To retrieve dynamic content set by component properties, use the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint. If you do not provide a Locale ID in your request, the response will return any content that can be localized from the Primary locale. @@ -1773,6 +1762,9 @@ client.components.get_content( site_id="580e63e98c9a982ac9b8b741", component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", locale_id="65427cf400e02b306eaa04a0", + branch_id="68026fa68ef6dc744c75b833", + limit=1.1, + offset=1.1, ) ``` @@ -1805,7 +1797,19 @@ client.components.get_content(
-**locale_id:** `typing.Optional[str]` — Unique identifier for a specific locale. Applicable, when using localization. +**locale_id:** `typing.Optional[str]` + +Unique identifier for a specific Locale. + +[Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + +
+
+ +
+
+ +**branch_id:** `typing.Optional[str]` — Scope the operation to work on a specific branch.
@@ -1856,8 +1860,9 @@ client.components.get_content( This endpoint updates content within a component defintion for **secondary locales**. It supports updating up to 1000 nodes in a single request. Before making updates: -1. Use the [get component content](/data/reference/pages-and-components/components/get-content) endpoint to identify available content nodes and their types -2. If your component definition has a component instance nested within it, retrieve the nested component instance's properties that you'll override using the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint +1. Use the [get component content](/data/reference/pages-and-components/components/get-content) endpoint to identify available content nodes and their types. +2. If your component definition has a component instance nested within it, retrieve the nested component instance's properties that you'll override using the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint. +3. DOM elements may include a `data-w-id` attribute. This attribute is used by Webflow to maintain custom attributes and links across locales. Always include the original `data-w-id` value in your update requests to ensure consistent behavior across all locales. This endpoint is specifically for localizing component definitions. Ensure that the specified `localeId` is a valid **secondary locale** for the site otherwise the request will fail. @@ -1881,6 +1886,10 @@ Required scope | `components:write` from webflow import ( ComponentInstanceNodePropertyOverridesWrite, ComponentInstanceNodePropertyOverridesWritePropertyOverridesItem, + Select, + SelectNodeWriteChoicesItem, + SubmitButtonNodeWrite, + TextInputNodeWrite, TextNodeWrite, Webflow, ) @@ -1892,6 +1901,7 @@ client.components.update_content( site_id="580e63e98c9a982ac9b8b741", component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", locale_id="65427cf400e02b306eaa04a0", + branch_id="68026fa68ef6dc744c75b833", nodes=[ TextNodeWrite( node_id="a245c12d-995b-55ee-5ec7-aa36a6cad623", @@ -1901,6 +1911,28 @@ client.components.update_content( node_id="a245c12d-995b-55ee-5ec7-aa36a6cad627", text="

Don't Panic!

Always know where your towel is.

", ), + Select( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad635", + choices=[ + SelectNodeWriteChoicesItem( + value="choice-1", + text="First choice", + ), + SelectNodeWriteChoicesItem( + value="choice-2", + text="Second choice", + ), + ], + ), + TextInputNodeWrite( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad642", + placeholder="Enter something here...", + ), + SubmitButtonNodeWrite( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad671", + value="Submit", + waiting_text="Submitting...", + ), ComponentInstanceNodePropertyOverridesWrite( node_id="a245c12d-995b-55ee-5ec7-aa36a6cad629", property_overrides=[ @@ -1955,7 +1987,19 @@ client.components.update_content(
-**locale_id:** `typing.Optional[str]` — Unique identifier for a specific locale. Applicable, when using localization. +**locale_id:** `typing.Optional[str]` + +Unique identifier for a specific Locale. + +[Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + +
+
+ +
+
+ +**branch_id:** `typing.Optional[str]` — Scope the operation to work on a specific branch.
@@ -1987,9 +2031,9 @@ client.components.update_content(
-Get the property default values of a component definition. +Get the default property values of a component definition. -If you do not provide a Locale ID in your request, the response will return any properties that can be localized from the Primary locale. +If you do not include a `localeId` in your request, the response will return any properties that can be localized from the Primary locale. Required scope | `components:read`
@@ -2015,6 +2059,9 @@ client.components.get_properties( site_id="580e63e98c9a982ac9b8b741", component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", locale_id="65427cf400e02b306eaa04a0", + branch_id="68026fa68ef6dc744c75b833", + limit=1.1, + offset=1.1, ) ``` @@ -2047,7 +2094,19 @@ client.components.get_properties(
-**locale_id:** `typing.Optional[str]` — Unique identifier for a specific locale. Applicable, when using localization. +**locale_id:** `typing.Optional[str]` + +Unique identifier for a specific Locale. + +[Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + +
+
+ +
+
+ +**branch_id:** `typing.Optional[str]` — Scope the operation to work on a specific branch.
@@ -2095,12 +2154,13 @@ client.components.get_properties(
-Update the property default values of a component definition in a specificed locale. +Update the default property values of a component definition in a specificed locale. Before making updates: -1. Use the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint to identify available properties +1. Use the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint to identify properties that can be updated in a secondary locale. +2. Rich Text properties may include a `data-w-id` attribute. This attribute is used by Webflow to maintain links across locales. Always include the original `data-w-id` value in your update requests to ensure consistent behavior across all locales. -The request requires a secondary locale ID. If a locale is missing, the request will not be processed and will result in an error. +The request requires a secondary locale ID. If a `localeId` is missing, the request will not be processed and will result in an error. Required scope | `components:write`
@@ -2127,6 +2187,7 @@ client.components.update_properties( site_id="580e63e98c9a982ac9b8b741", component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", locale_id="65427cf400e02b306eaa04a0", + branch_id="68026fa68ef6dc744c75b833", properties=[ ComponentPropertiesWritePropertiesItem( property_id="a245c12d-995b-55ee-5ec7-aa36a6cad623", @@ -2177,7 +2238,19 @@ client.components.update_properties(
-**locale_id:** `typing.Optional[str]` — Unique identifier for a specific locale. Applicable, when using localization. +**locale_id:** `typing.Optional[str]` + +Unique identifier for a specific Locale. + +[Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + +
+
+ +
+
+ +**branch_id:** `typing.Optional[str]` — Scope the operation to work on a specific branch.
@@ -2210,14 +2283,11 @@ client.components.update_properties(
-List of scripts registered to a Site. +Get a list of scripts that have been registered to a site. A site can have a maximum of 800 registered scripts. -In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered -to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate -`custom_code` endpoints. -Additionally, Scripts can be remotely hosted, or registered as inline snippets. - -Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:read`
@@ -2289,14 +2359,11 @@ client.scripts.list(
-Add a script to a Site's Custom Code registry. +Register a hosted script to a site. -In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered -to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate -`custom_code` endpoints. -Additionally, Scripts can be remotely hosted, or registered as inline snippets. - -Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:write`
@@ -2412,13 +2479,11 @@ client.scripts.register_hosted(
-Add a script to a Site's Custom Code registry. Inline scripts can be between 1 and 2000 characters. +Register an inline script to a site. Inline scripts are limited to 2000 characters. -In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered -to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate -`custom_code` endpoints. - -Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:write`
@@ -2534,7 +2599,7 @@ client.scripts.register_inline(
-List assets for a given site +List of assets uploaded to a site Required scope | `assets:read`
@@ -2558,6 +2623,8 @@ client = Webflow( ) client.assets.list( site_id="580e63e98c9a982ac9b8b741", + offset=1.1, + limit=1.1, ) ``` @@ -2582,6 +2649,22 @@ client.assets.list(
+**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records + +
+
+ +
+
+ +**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -2606,15 +2689,18 @@ client.assets.list(
-Create a new asset entry. +The first step in uploading an asset to a site. -This endpoint generates a response with the following information: `uploadUrl` and `uploadDetails`. -You can use these two properties to [upload the file to Amazon s3 by making a POST](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html) -request to the `uploadUrl` with the `uploadDetails` object as your header information in the request. +This endpoint generates a response with the following information: `uploadUrl` and `uploadDetails`. - -Required scope | `assets:write` + +Use these properties in the header of a [POST request to Amazson s3](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html) to complete the upload. + + +To learn more about how to upload assets to Webflow, see our [assets guide](/data/docs/working-with-assets). + + Required scope | `assets:write`
@@ -2710,7 +2796,7 @@ client.assets.create(
-Get an Asset +Get details about an asset Required scope | `assets:read`
@@ -2854,7 +2940,7 @@ client.assets.delete(
-Update an Asset +Update details of an Asset. Required scope | `assets:write`
@@ -3569,6 +3655,8 @@ client = Webflow( ) client.forms.list( site_id="580e63e98c9a982ac9b8b741", + limit=1.1, + offset=1.1, ) ``` @@ -3707,6 +3795,12 @@ client.forms.get( List form submissions for a given form + + When a form is used in a component definition, each instance of the form is considered a unique form. + + To get a combined list of submissions for a form that appears across multiple component instances, use the [List Form Submissions by Site](/data/reference/forms/form-submissions/list-submissions-by-site) endpoint. + + Required scope | `forms:read`
@@ -3729,6 +3823,8 @@ client = Webflow( ) client.forms.list_submissions( form_id="580e63e98c9a982ac9b8b741", + offset=1.1, + limit=1.1, ) ``` @@ -3853,7 +3949,7 @@ client.forms.get_submission(
-
client.forms.update_submission(...) +
client.forms.delete_submission(...)
@@ -3865,7 +3961,8 @@ client.forms.get_submission(
-Update hidden fields on a form submission +Delete a form submission + Required scope | `forms:write`
@@ -3887,7 +3984,7 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.forms.update_submission( +client.forms.delete_submission( form_submission_id="580e63e98c9a982ac9b8b741", ) @@ -3913,14 +4010,6 @@ client.forms.update_submission(
-**form_submission_data:** `typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]` — An existing **hidden field** defined on the form schema, and the corresponding value to set - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -3933,8 +4022,7 @@ client.forms.update_submission(
-## Users -
client.users.list(...) +
client.forms.update_submission(...)
@@ -3946,9 +4034,9 @@ client.forms.update_submission(
-Get a list of users for a site +Update hidden fields on a form submission -Required scope | `users:read` +Required scope | `forms:write`
@@ -3968,8 +4056,8 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.users.list( - site_id="580e63e98c9a982ac9b8b741", +client.forms.update_submission( + form_submission_id="580e63e98c9a982ac9b8b741", ) ``` @@ -3986,7 +4074,7 @@ client.users.list(
-**site_id:** `str` — Unique identifier for a Site +**form_submission_id:** `str` — Unique identifier for a Form Submission
@@ -3994,7 +4082,7 @@ client.users.list(
-**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records +**form_submission_data:** `typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]` — An existing **hidden field** defined on the form schema, and the corresponding value to set
@@ -4002,30 +4090,114 @@ client.users.list(
-**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+ +
-
-
- -**sort:** `typing.Optional[UsersListRequestSort]` - -Sort string to use when ordering users - -Example(`CreatedOn`, `Email`, `Status`, `LastLogin`, `UpdatedOn`). -Can be prefixed with a `-` to reverse the sort (ex. `-CreatedOn`) -
+
+## Users +
client.users.list(...)
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. - +#### 📝 Description + +
+
+ +
+
+ +Get a list of users for a site + +Required scope | `users:read` +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from webflow import Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.users.list( + site_id="580e63e98c9a982ac9b8b741", + offset=1.1, + limit=1.1, + sort="CreatedOn", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**site_id:** `str` — Unique identifier for a Site + +
+
+ +
+
+ +**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records + +
+
+ +
+
+ +**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) + +
+
+ +
+
+ +**sort:** `typing.Optional[UsersListRequestSort]` + +Sort string to use when ordering users + +Example(`CreatedOn`, `Email`, `Status`, `LastLogin`, `UpdatedOn`). + +Can be prefixed with a `-` to reverse the sort (ex. `-CreatedOn`) + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +
@@ -4230,8 +4402,9 @@ fields cannot be updated using this endpoint
```python -from webflow import Webflow -from webflow.resources.users import UsersUpdateRequestData +import datetime + +from webflow import UserAccessGroupsItem, Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", @@ -4239,12 +4412,27 @@ client = Webflow( client.users.update( site_id="580e63e98c9a982ac9b8b741", user_id="580e63e98c9a982ac9b8b741", - data=UsersUpdateRequestData( - name="Some One", - accept_privacy=False, - accept_communications=False, + id="6287ec36a841b25637c663df", + is_email_verified=True, + last_updated=datetime.datetime.fromisoformat( + "2022-05-20 13:46:12+00:00", + ), + invited_on=datetime.datetime.fromisoformat( + "2022-05-20 13:46:12+00:00", + ), + created_on=datetime.datetime.fromisoformat( + "2022-05-20 13:46:12+00:00", + ), + last_login=datetime.datetime.fromisoformat( + "2022-05-20 13:46:12+00:00", ), - access_groups=["webflowers", "platinum", "free-tier"], + status="verified", + access_groups=[ + UserAccessGroupsItem( + slug="webflowers", + type="admin", + ) + ], ) ``` @@ -4277,7 +4465,7 @@ client.users.update(
-**data:** `typing.Optional[UsersUpdateRequestData]` +**id:** `typing.Optional[str]` — Unique identifier for the User
@@ -4285,8 +4473,63 @@ client.users.update(
-**access_groups:** `typing.Optional[typing.Sequence[str]]` — An array of access group slugs. Access groups are assigned to the user as type `admin` and the user remains in the group until removed. +**is_email_verified:** `typing.Optional[bool]` — Shows whether the user has verified their email address + +
+
+ +
+
+ +**last_updated:** `typing.Optional[dt.datetime]` — The timestamp the user was updated + +
+
+ +
+
+ +**invited_on:** `typing.Optional[dt.datetime]` — The timestamp the user was invited + +
+
+ +
+
+ +**created_on:** `typing.Optional[dt.datetime]` — The timestamp the user was created + +
+
+ +
+
+ +**last_login:** `typing.Optional[dt.datetime]` — The timestamp the user was logged in + +
+
+ +
+
+ +**status:** `typing.Optional[UserStatus]` + +
+
+ +
+
+ +**access_groups:** `typing.Optional[typing.Sequence[UserAccessGroupsItem]]` — Access groups the user belongs to + +
+
+ +
+
+**data:** `typing.Optional[UserData]`
@@ -4345,7 +4588,7 @@ client = Webflow( client.users.invite( site_id="580e63e98c9a982ac9b8b741", email="some.one@home.com", - access_groups=["webflowers"], + access_groups=["accessGroups"], ) ``` @@ -4379,7 +4622,6 @@ client.users.invite(
**access_groups:** `typing.Optional[typing.Sequence[str]]` — An array of access group slugs. Access groups are assigned to the user as type `admin` and the user remains in the group until removed. -
@@ -4436,6 +4678,9 @@ client = Webflow( ) client.access_groups.list( site_id="580e63e98c9a982ac9b8b741", + offset=1.1, + limit=1.1, + sort="CreatedOn", ) ``` @@ -4539,6 +4784,8 @@ client = Webflow( ) client.products.list( site_id="580e63e98c9a982ac9b8b741", + offset=1.1, + limit=1.1, ) ``` @@ -4603,16 +4850,12 @@ client.products.list(
-Create a new product and SKU. - -When you create a product, you will always create a SKU, since a Product Item must have, at minimum, a single SKU. +Create a new ecommerce product and defaultSKU. A product, at minimum, must have a single SKU. -To create a Product with multiple SKUs - for example a T-shirt in sizes small, medium and large: - - Create parameters in `sku-properties`, also known as [product options and variants.](https://help.webflow.com/hc/en-us/articles/33961334531347-Create-product-options-and-variants). - - A single `sku-property` would be `color`. Within the `color` property, list the various colors of T-shirts as an array of `enum` values: `royal-blue`, `crimson-red`, and `forrest-green`. - - Once, you've created a Product and its `sku-properties` with `enum` values, Webflow will create a **default SKU**, which will automatically be a combination of the first `sku-properties` you've created. - - In our example, the default SKU will be a Royal Blue T-Shirt, because our first `enum` of our Color `sku-property` is Royal Blue. - - After you've created your product, you can create additional SKUs using the [Create SKU endpoint.](/data/reference/ecommerce/products/create-sku) +To create a product with multiple SKUs: + - First, create a list of `sku-properties`, also known as [product options](https://help.webflow.com/hc/en-us/articles/33961334531347-Create-product-options-and-variants). For example, a T-shirt product may have a "color" `sku-property`, with a list of enum values: red, yellow, and blue, another `sku-property` may be "size", with a list of enum values: small, medium, and large. + - Once, a product is created with a list of `sku-properties`, Webflow will create a **default SKU**, which is always a combination of the first `enum` values of each `sku-property`. (e.g. Small - Red - T-Shirt) + - After creation, you can create additional SKUs for the product, using the [Create SKUs endpoint.](/data/reference/ecommerce/products/create-sku) Upon creation, the default product type will be `Advanced`, which ensures all Product and SKU fields will be shown to users in the Designer. @@ -4631,13 +4874,88 @@ Required scope | `ecommerce:write`
```python -from webflow import Webflow +from webflow import ( + ProductFieldData, + SkuFieldData, + SkuFieldDataPrice, + SkuPropertyList, + SkuPropertyListEnumItem, + Webflow, +) +from webflow.resources.products import ( + ProductSkuCreateProduct, + ProductSkuCreateSku, +) client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.products.create( site_id="580e63e98c9a982ac9b8b741", + publish_status="staging", + product=ProductSkuCreateProduct( + field_data=ProductFieldData( + name="Colorful T-shirt", + slug="colorful-t-shirt", + description="Our best-selling t-shirt available in multiple colors and sizes", + sku_properties=[ + SkuPropertyList( + id="color", + name="Color", + enum=[ + SkuPropertyListEnumItem( + id="red", + name="Red", + slug="red", + ), + SkuPropertyListEnumItem( + id="yellow", + name="Yellow", + slug="yellow", + ), + SkuPropertyListEnumItem( + id="blue", + name="Blue", + slug="blue", + ), + ], + ), + SkuPropertyList( + id="size", + name="Size", + enum=[ + SkuPropertyListEnumItem( + id="small", + name="Small", + slug="small", + ), + SkuPropertyListEnumItem( + id="medium", + name="Medium", + slug="medium", + ), + SkuPropertyListEnumItem( + id="large", + name="Large", + slug="large", + ), + ], + ), + ], + ), + ), + sku=ProductSkuCreateSku( + field_data=SkuFieldData( + name="Colorful T-shirt - Red Small", + slug="colorful-t-shirt-red-small", + price=SkuFieldDataPrice( + value=2499.0, + unit="USD", + currency="USD", + ), + main_image="https://rocketamp-sample-store.myshopify.com/cdn/shop/products/Gildan_2000_Antique_Cherry_Red_Front_1024x1024.jpg?v=1527232987", + ), + ), ) ``` @@ -4662,7 +4980,7 @@ client.products.create(
-**publish_status:** `typing.Optional[PublishStatus]` +**product:** `ProductSkuCreateProduct`
@@ -4670,7 +4988,7 @@ client.products.create(
-**product:** `typing.Optional[Product]` +**sku:** `ProductSkuCreateSku`
@@ -4678,7 +4996,7 @@ client.products.create(
-**sku:** `typing.Optional[Sku]` +**publish_status:** `typing.Optional[PublishStatus]`
@@ -4918,7 +5236,9 @@ Required scope | `ecommerce:write`
```python -from webflow import Sku, Webflow +import datetime + +from webflow import Sku, SkuFieldData, SkuFieldDataPrice, Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", @@ -4926,7 +5246,30 @@ client = Webflow( client.products.create_sku( site_id="580e63e98c9a982ac9b8b741", product_id="580e63fc8c9a982ac9b8b745", - skus=[Sku()], + skus=[ + Sku( + id="66072fb71b89448912e2681c", + cms_locale_id="653ad57de882f528b32e810e", + last_published=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + last_updated=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + created_on=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + field_data=SkuFieldData( + name="Colorful T-shirt - Default", + slug="colorful-t-shirt-default", + price=SkuFieldDataPrice( + value=2499.0, + unit="USD", + currency="USD", + ), + ), + ) + ], ) ``` @@ -5018,7 +5361,9 @@ Required scope | `ecommerce:write`
```python -from webflow import Sku, Webflow +import datetime + +from webflow import Sku, SkuFieldData, SkuFieldDataPrice, Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", @@ -5027,7 +5372,28 @@ client.products.update_sku( site_id="580e63e98c9a982ac9b8b741", product_id="580e63fc8c9a982ac9b8b745", sku_id="5e8518516e147040726cc415", - sku=Sku(), + sku=Sku( + id="66072fb71b89448912e2681c", + cms_locale_id="653ad57de882f528b32e810e", + last_published=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + last_updated=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + created_on=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + field_data=SkuFieldData( + name="Colorful T-shirt - Default", + slug="colorful-t-shirt-default", + price=SkuFieldDataPrice( + value=2499.0, + unit="USD", + currency="USD", + ), + ), + ), ) ``` @@ -5133,6 +5499,9 @@ client = Webflow( ) client.orders.list( site_id="580e63e98c9a982ac9b8b741", + status="pending", + offset=1.1, + limit=1.1, ) ``` @@ -5686,8 +6055,8 @@ client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.inventory.list( - collection_id="580e63fc8c9a982ac9b8b745", - item_id="580e64008c9a982ac9b8b754", + sku_collection_id="6377a7c4b7a79608c34a46f7", + sku_id="5e8518516e147040726cc415", ) ``` @@ -5704,7 +6073,7 @@ client.inventory.list(
-**collection_id:** `str` — Unique identifier for a Collection +**sku_collection_id:** `str` — Unique identifier for a SKU collection. Use the List Collections API to find this ID.
@@ -5712,7 +6081,7 @@ client.inventory.list(
-**item_id:** `str` — Unique identifier for an Item +**sku_id:** `str` — Unique identifier for a SKU
@@ -5771,8 +6140,8 @@ client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.inventory.update( - collection_id="580e63fc8c9a982ac9b8b745", - item_id="580e64008c9a982ac9b8b754", + sku_collection_id="6377a7c4b7a79608c34a46f7", + sku_id="5e8518516e147040726cc415", inventory_type="infinite", ) @@ -5790,7 +6159,7 @@ client.inventory.update(
-**collection_id:** `str` — Unique identifier for a Collection +**sku_collection_id:** `str` — Unique identifier for a SKU collection. Use the List Collections API to find this ID.
@@ -5798,7 +6167,7 @@ client.inventory.update(
-**item_id:** `str` — Unique identifier for an Item +**sku_id:** `str` — Unique identifier for a SKU
@@ -5928,14 +6297,11 @@ client.ecommerce.get_settings(
-Create a custom field in a collection. +Create a custom field in a collection. -Slugs must be all lowercase letters without spaces. -If you pass a string with uppercase letters and/or spaces to the "Slug" property, Webflow will -convert the slug to lowercase and replace spaces with "-." +Field validation is currently not available through the API. -Only some field types can be created through the API. -This endpoint does not currently support bulk creation. +Bulk creation of fields is not supported with this endpoint. To add multiple fields at once, include them when you [create the collection.](/data/v2.0.0/reference/cms/collections/create) Required scope | `cms:write`
@@ -5952,17 +6318,24 @@ Required scope | `cms:write`
```python -from webflow import Webflow +from webflow import ReferenceField, ReferenceFieldMetadata, Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.collections.fields.create( collection_id="580e63fc8c9a982ac9b8b745", - is_required=False, - type="RichText", - display_name="Post Body", - help_text="Add the body of your post here", + request=ReferenceField( + id="562ac0395358780a1f5e6fbd", + is_editable=True, + is_required=False, + type="Reference", + display_name="Author", + help_text="Add the post author here", + metadata=ReferenceFieldMetadata( + collection_id="63692ab61fb2852f582ba8f5", + ), + ), ) ``` @@ -5987,31 +6360,7 @@ client.collections.fields.create(
-**type:** `FieldCreateType` — Choose these appropriate field type for your collection data - -
-
- -
-
- -**display_name:** `str` — The name of a field - -
-
- -
-
- -**is_required:** `typing.Optional[bool]` — define whether a field is required in a collection - -
-
- -
-
- -**help_text:** `typing.Optional[str]` — Additional text to help anyone filling out this field +**request:** `FieldCreate`
@@ -6257,6 +6606,13 @@ client = Webflow( ) client.collections.items.list_items( collection_id="580e63fc8c9a982ac9b8b745", + cms_locale_id="cmsLocaleId", + offset=1.1, + limit=1.1, + name="name", + slug="slug", + sort_by="lastPublished", + sort_order="asc", ) ``` @@ -6305,7 +6661,15 @@ client.collections.items.list_items(
-**name:** `typing.Optional[str]` — The name of the item(s) +**name:** `typing.Optional[str]` — Filter by the exact name of the item(s) + +
+
+ +
+
+ +**slug:** `typing.Optional[str]` — Filter by the exact slug of the item
@@ -6313,7 +6677,7 @@ client.collections.items.list_items(
-**slug:** `typing.Optional[str]` — The slug of the item +**last_published:** `typing.Optional[ItemsListItemsRequestLastPublished]` — Filter by the last published date of the item(s)
@@ -6364,7 +6728,7 @@ client.collections.items.list_items( Create Item(s) in a Collection. -To create items across multiple locales, please use [this endpoint.](/v2.0.0/data/reference/cms/collection-items/staged-items/create-items) +To create items across multiple locales, please use [this endpoint.](/data/reference/cms/collection-items/staged-items/create-items) Required scope | `CMS:write`
@@ -6393,6 +6757,7 @@ client = Webflow( ) client.collections.items.create_item( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, request=MultipleItems( items=[ CollectionItemPostSingle( @@ -6437,7 +6802,15 @@ client.collections.items.create_item(
-**request:** `ItemsCreateItemRequest` +**request:** `ItemsCreateItemRequestBody` + +
+
+ +
+
+ +**skip_invalid_files:** `typing.Optional[bool]` — When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid.
@@ -6471,7 +6844,7 @@ client.collections.items.create_item( Delete Items from a Collection. -**Note:** If the `cmsLocaleId` parameter is undefined or empty and the items are localized, items will be deleted only in the primary locale. +Items will only be deleted in the primary locale unless a `cmsLocaleId` is included in the request. Required scope | `CMS:write`
@@ -6489,12 +6862,20 @@ Required scope | `CMS:write` ```python from webflow import Webflow +from webflow.resources.collections.resources.items import ( + ItemsDeleteItemsRequestItemsItem, +) client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.collections.items.delete_items( collection_id="580e63fc8c9a982ac9b8b745", + items=[ + ItemsDeleteItemsRequestItemsItem( + id="580e64008c9a982ac9b8b754", + ) + ], ) ``` @@ -6519,7 +6900,7 @@ client.collections.items.delete_items(
-**items:** `typing.Optional[typing.Sequence[ItemsDeleteItemsRequestItemsItem]]` +**items:** `typing.Sequence[ItemsDeleteItemsRequestItemsItem]`
@@ -6551,9 +6932,11 @@ client.collections.items.delete_items(
-Update a single item or multiple items (up to 100) in a Collection. +Update a single item or multiple items in a Collection. -**Note:** If the `cmsLocaleId` parameter is undefined or empty and the items are localized, items will be updated only in the primary locale. +The limit for this endpoint is 100 items. + +Items will only be updated in the primary locale, unless a `cmsLocaleId` is included in the request. Required scope | `CMS:write`
@@ -6581,37 +6964,24 @@ client = Webflow( ) client.collections.items.update_items( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, items=[ CollectionItemWithIdInput( - id="66f6ed9576ddacf3149d5ea6", - cms_locale_id="66f6e966c9e1dc700a857ca5", - field_data=CollectionItemWithIdInputFieldData( - name="Ne Paniquez Pas", - slug="ne-paniquez-pas", - ), - ), - CollectionItemWithIdInput( - id="66f6ed9576ddacf3149d5ea6", - cms_locale_id="66f6e966c9e1dc700a857ca4", + id="580e64008c9a982ac9b8b754", + is_archived=False, + is_draft=False, field_data=CollectionItemWithIdInputFieldData( - name="No Entrar en Pánico", - slug="no-entrar-en-panico", + name="Senior Data Analyst", + slug="senior-data-analyst", ), ), CollectionItemWithIdInput( - id="66f6ed9576ddacf3149d5eaa", - cms_locale_id="66f6e966c9e1dc700a857ca5", + id="580e64008c9a982ac9b8b754", + is_archived=False, + is_draft=False, field_data=CollectionItemWithIdInputFieldData( - name="Au Revoir et Merci pour Tous les Poissons", - slug="au-revoir-et-merci", - ), - ), - CollectionItemWithIdInput( - id="66f6ed9576ddacf3149d5eaa", - cms_locale_id="66f6e966c9e1dc700a857ca4", - field_data=CollectionItemWithIdInputFieldData( - name="Hasta Luego y Gracias por Todo el Pescado", - slug="hasta-luego-y-gracias", + name="Product Manager", + slug="product-manager", ), ), ], @@ -6639,6 +7009,14 @@ client.collections.items.update_items(
+**skip_invalid_files:** `typing.Optional[bool]` — When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + +
+
+ +
+
+ **items:** `typing.Optional[typing.Sequence[CollectionItemWithIdInput]]`
@@ -6671,7 +7049,11 @@ client.collections.items.update_items(
-List of all live Items within a Collection. +List all published items in a collection. + + + Serving data to applications in real-time? Use the Content Delivery API at `api-cdn.webflow.com` for better performance. The CDN-backed endpoint is optimized for high-volume reads, while the Data API is designed for writes and management operations. + Required scope | `CMS:read`
@@ -6695,6 +7077,13 @@ client = Webflow( ) client.collections.items.list_items_live( collection_id="580e63fc8c9a982ac9b8b745", + cms_locale_id="cmsLocaleId", + offset=1.1, + limit=1.1, + name="name", + slug="slug", + sort_by="lastPublished", + sort_order="asc", ) ``` @@ -6743,7 +7132,15 @@ client.collections.items.list_items_live(
-**name:** `typing.Optional[str]` — The name of the item(s) +**name:** `typing.Optional[str]` — Filter by the exact name of the item(s) + +
+
+ +
+
+ +**slug:** `typing.Optional[str]` — Filter by the exact slug of the item
@@ -6751,7 +7148,7 @@ client.collections.items.list_items_live(
-**slug:** `typing.Optional[str]` — The slug of the item +**last_published:** `typing.Optional[ItemsListItemsLiveRequestLastPublished]` — Filter by the last published date of the item(s)
@@ -6799,10 +7196,10 @@ client.collections.items.list_items_live(
-Create live Item(s) in a Collection. The Item(s) will be published to the live site. +Create item(s) in a collection that will be immediately published to the live site. -To create items across multiple locales, [please use this endpoint.](/v2.0.0/data/reference/cms/collection-items/staged-items/create-items) +To create items across multiple locales, [please use this endpoint.](/data/reference/cms/collection-items/staged-items/create-items) Required scope | `CMS:write` @@ -6828,6 +7225,7 @@ client = Webflow( ) client.collections.items.create_item_live( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, request=MultipleLiveItems( items=[ CollectionItem( @@ -6872,7 +7270,15 @@ client.collections.items.create_item_live(
-**request:** `ItemsCreateItemLiveRequest` +**request:** `ItemsCreateItemLiveRequestBody` + +
+
+ +
+
+ +**skip_invalid_files:** `typing.Optional[bool]` — When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid.
@@ -6904,9 +7310,9 @@ client.collections.items.create_item_live(
-Remove an item or multiple items (up to 100 items) from the live site. Deleting published items will unpublish the items from the live site and set them to draft. +Unpublish up to 100 items from the live site and set the `isDraft` property to `true`. -**Note:** If the `cmsLocaleId` parameter is undefined or empty and the items are localized, items will be unpublished only in the primary locale. +Items will only be unpublished in the primary locale unless a `cmsLocaleId` is included in the request. Required scope | `CMS:write`
@@ -6924,12 +7330,20 @@ Required scope | `CMS:write` ```python from webflow import Webflow +from webflow.resources.collections.resources.items import ( + ItemsDeleteItemsLiveRequestItemsItem, +) client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.collections.items.delete_items_live( collection_id="580e63fc8c9a982ac9b8b745", + items=[ + ItemsDeleteItemsLiveRequestItemsItem( + id="580e64008c9a982ac9b8b754", + ) + ], ) ``` @@ -6954,7 +7368,7 @@ client.collections.items.delete_items_live(
-**items:** `typing.Optional[typing.Sequence[ItemsDeleteItemsLiveRequestItemsItem]]` +**items:** `typing.Sequence[ItemsDeleteItemsLiveRequestItemsItem]`
@@ -6986,9 +7400,9 @@ client.collections.items.delete_items_live(
-Update a single live item or multiple live items (up to 100) in a Collection +Update a single published item or multiple published items (up to 100) in a Collection -**Note:** If the `cmsLocaleId` parameter is undefined or empty and the items are localized, items will be updated only in the primary locale. +Items will only be updated in the primary locale, unless a `cmsLocaleId` is included in the request. Required scope | `CMS:write`
@@ -7016,6 +7430,7 @@ client = Webflow( ) client.collections.items.update_items_live( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, items=[ CollectionItemWithIdInput( id="66f6ed9576ddacf3149d5ea6", @@ -7074,6 +7489,14 @@ client.collections.items.update_items_live(
+**skip_invalid_files:** `typing.Optional[bool]` — When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + +
+
+ +
+
+ **items:** `typing.Optional[typing.Sequence[CollectionItemWithIdInput]]`
@@ -7108,9 +7531,10 @@ client.collections.items.update_items_live( Create an item or multiple items in a CMS Collection across multiple corresponding locales. -**Notes:** + - This endpoint can create up to 100 items in a request. - - If the `cmsLocaleIds` parameter is undefined or empty and localization is enabled, items will only be created in the primary locale. + - If the `cmsLocaleIds` parameter is not included in the request, an item will only be created in the primary locale. + Required scope | `CMS:write`
@@ -7135,6 +7559,7 @@ client = Webflow( ) client.collections.items.create_items( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, cms_locale_ids=[ "66f6e966c9e1dc700a857ca3", "66f6e966c9e1dc700a857ca4", @@ -7178,6 +7603,14 @@ client.collections.items.create_items(
+**skip_invalid_files:** `typing.Optional[bool]` — When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + +
+
+ +
+
+ **cms_locale_ids:** `typing.Optional[typing.Sequence[str]]` — Array of identifiers for the locales where the item will be created
@@ -7251,6 +7684,7 @@ client = Webflow( client.collections.items.get_item( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + cms_locale_id="cmsLocaleId", ) ``` @@ -7315,7 +7749,7 @@ client.collections.items.get_item(
-Delete an Item from a Collection. This endpoint does not currently support bulk deletion. +Delete an item from a collection. Required scope | `CMS:write`
@@ -7340,6 +7774,7 @@ client = Webflow( client.collections.items.delete_item( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + cms_locale_id="cmsLocaleId", ) ``` @@ -7429,11 +7864,12 @@ client = Webflow( client.collections.items.update_item( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + skip_invalid_files=True, is_archived=False, is_draft=False, field_data=CollectionItemPatchSingleFieldData( - name="Pan Galactic Gargle Blaster Recipe", - slug="pan-galactic-gargle-blaster", + name="The Hitchhiker's Guide to the Galaxy", + slug="hitchhikers-guide-to-the-galaxy", ), ) @@ -7467,6 +7903,14 @@ client.collections.items.update_item(
+**skip_invalid_files:** `typing.Optional[bool]` — When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + +
+
+ +
+
+ **id:** `typing.Optional[str]` — Unique identifier for the Item
@@ -7557,6 +8001,10 @@ client.collections.items.update_item( Get details of a selected Collection live Item. + + Serving data to applications in real-time? Use the Content Delivery API at `api-cdn.webflow.com` for better performance. The CDN-backed endpoint is optimized for high-volume reads, while the Data API is designed for writes and management operations. + + Required scope | `CMS:read`
@@ -7580,6 +8028,7 @@ client = Webflow( client.collections.items.get_item_live( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + cms_locale_id="cmsLocaleId", ) ``` @@ -7644,9 +8093,9 @@ client.collections.items.get_item_live(
-Remove a live item from the site. Removing a published item will unpublish the item from the live site and set it to draft. +Unpublish a live item from the site and set the `isDraft` property to `true`. -This endpoint does not currently support bulk deletion. +For bulk unpublishing, please use [this endpoint.](/data/v2.0.0/reference/cms/collection-items/live-items/delete-items-live) Required scope | `CMS:write`
@@ -7671,6 +8120,7 @@ client = Webflow( client.collections.items.delete_item_live( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + cms_locale_id="cmsLocaleId", ) ``` @@ -7760,11 +8210,12 @@ client = Webflow( client.collections.items.update_item_live( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + skip_invalid_files=True, is_archived=False, is_draft=False, field_data=CollectionItemPatchSingleFieldData( - name="Pan Galactic Gargle Blaster Recipe", - slug="pan-galactic-gargle-blaster", + name="The Hitchhiker's Guide to the Galaxy", + slug="hitchhikers-guide-to-the-galaxy", ), ) @@ -7798,6 +8249,14 @@ client.collections.items.update_item_live(
+**skip_invalid_files:** `typing.Optional[bool]` — When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + +
+
+ +
+
+ **id:** `typing.Optional[str]` — Unique identifier for the Item
@@ -7904,13 +8363,28 @@ Required scope | `cms:write` ```python from webflow import Webflow +from webflow.resources.collections.resources.items import ( + ItemIDsWithLocales, + ItemsPublishItemRequestItemsItemsItem, +) client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.collections.items.publish_item( collection_id="580e63fc8c9a982ac9b8b745", - item_ids=["itemIds"], + request=ItemIDsWithLocales( + items=[ + ItemsPublishItemRequestItemsItemsItem( + id="643fd856d66b6528195ee2ca", + cms_locale_ids=[ + "653ad57de882f528b32e810e", + "6514390aea353fc691d69827", + "65143930ea353fc691d69cd8", + ], + ) + ], + ), ) ``` @@ -7935,7 +8409,7 @@ client.collections.items.publish_item(
-**item_ids:** `typing.Sequence[str]` +**request:** `ItemsPublishItemRequest`
@@ -7968,13 +8442,7 @@ client.collections.items.publish_item(
-Get all registered scripts that have been applied to a specific Page. - -In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered -to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate -`custom_code` endpoints. - -Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). +Get all scripts applied to a page. Required scope | `custom_code:read`
@@ -8046,15 +8514,11 @@ client.pages.scripts.get_custom_code(
-Add a registered script to a Page. - -In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered -to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate -`custom_code` endpoints. - -A site can have a maximum of 800 registered scripts. +Apply registered scripts to a page. If you have multiple scripts your App needs to apply or maintain on a page, ensure they are always included in the request body for this endpoint. To remove individual scripts, simply call this endpoint without the script in the request body. -Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a page, the script must first be registered to a Site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:write`
@@ -8163,13 +8627,11 @@ client.pages.scripts.upsert_custom_code(
-Delete the custom code block that an app has created for a page +Remove all scripts from a page applied by the App. This endpoint will not remove scripts from the site's registered scripts. -In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered -to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate -`custom_code` endpoints. +To remove individual scripts applied by the App, use the [Add/Update Custom Code](/data/reference/custom-code/custom-code-pages/upsert-custom-code) endpoint. -Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). +Access to this endpoint requires a bearer token obtained from an [OAuth Code Grant Flow](/data/reference/oauth-app). Required scope | `custom_code:write`
@@ -8242,10 +8704,11 @@ client.pages.scripts.delete_custom_code(
-Fetch a list of all URL redirect rules configured for a specific site. +Fetch a list of all 301 redirect rules configured for a specific site. Use this endpoint to review, audit, or manage the redirection rules that control how traffic is rerouted on your site. +This endpoint requires an Enterprise workspace. Required scope: `sites:read`
@@ -8317,10 +8780,12 @@ client.sites.redirects.list(
-Add a new URL redirection rule to a site. +Add a new 301 redirection rule to a site. This endpoint allows you to define a source path (`fromUrl`) and its corresponding destination path (`toUrl`), which will dictate how traffic is rerouted on your site. This is useful for managing site changes, restructuring URLs, or handling outdated links. +This endpoint requires an Enterprise workspace. + Required scope: `sites:write`
@@ -8418,8 +8883,12 @@ client.sites.redirects.create(
-Remove a URL redirection rule from a site. +Remove a 301 redirection rule from a site. + This is useful for cleaning up outdated or unnecessary redirects, ensuring that your site's routing behavior remains efficient and up-to-date. + +This endpoint requires an Enterprise workspace. + Required scope: `sites:write`
@@ -8499,7 +8968,10 @@ client.sites.redirects.delete(
-Update a URL redirection rule from a site. +Update a 301 redirection rule from a site. + +This endpoint requires an Enterprise workspace. + Required scope: `sites:write`
@@ -8609,6 +9081,8 @@ client.sites.redirects.update( Get site plan details for the specified Site. +This endpoint requires an Enterprise workspace. + Required scope | `sites:read`
@@ -8667,8 +9141,8 @@ client.sites.plans.get_site_plan(
-## Sites ActivityLogs -
client.sites.activity_logs.list(...) +## Sites RobotsTxt +
client.sites.robots_txt.get(...)
@@ -8680,7 +9154,11 @@ client.sites.plans.get_site_plan(
-Retrieve Activity Logs for a specific Site. Requires Site to be on an Enterprise plan.

Required scope | `site_activity:read` +Retrieve the robots.txt configuration for various user agents. + +This endpoint requires an Enterprise workspace. + +Required scope: `site_config:read`
@@ -8700,7 +9178,7 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.sites.activity_logs.list( +client.sites.robots_txt.get( site_id="580e63e98c9a982ac9b8b741", ) @@ -8726,15 +9204,97 @@ client.sites.activity_logs.list(
-**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+ +
+ + + +
+ + +
client.sites.robots_txt.put(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Replace the `robots.txt` configuration for various user agents. + +This endpoint requires an Enterprise workspace. + +Required scope | `site_config:write` +
+
+
+
+ +#### 🔌 Usage
-**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records +
+
+ +```python +from webflow import RobotsRulesItem, Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.sites.robots_txt.put( + site_id="580e63e98c9a982ac9b8b741", + rules=[ + RobotsRulesItem( + user_agent="googlebot", + allows=["/public"], + disallows=["/vogon-poetry", "/total-perspective-vortex"], + ) + ], + sitemap="https://heartofgold.ship/sitemap.xml", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**site_id:** `str` — Unique identifier for a Site + +
+
+ +
+
+ +**rules:** `typing.Optional[typing.Sequence[RobotsRulesItem]]` — List of rules for user agents. + +
+
+ +
+
+ +**sitemap:** `typing.Optional[str]` — URL to the sitemap.
@@ -8754,8 +9314,7 @@ client.sites.activity_logs.list(
-## Sites Scripts -
client.sites.scripts.get_custom_code(...) +
client.sites.robots_txt.delete(...)
@@ -8767,11 +9326,13 @@ client.sites.activity_logs.list(
-Get all registered scripts that have been applied to a specific Site. +Remove specific rules for a user-agent in your `robots.txt` file. To delete all rules for a user-agent, provide an empty rule set. This will remove the user-agent's entry entirely, leaving it subject to your site's default crawling behavior. -Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). +**Note:** Deleting a user-agent with no rules will make the user-agent's access unrestricted unless other directives apply. -Required scope | `custom_code:read` +This endpoint requires an Enterprise workspace. + +Required scope: `site_config:write`
@@ -8786,13 +9347,20 @@ Required scope | `custom_code:read`
```python -from webflow import Webflow +from webflow import RobotsRulesItem, Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.sites.scripts.get_custom_code( +client.sites.robots_txt.delete( site_id="580e63e98c9a982ac9b8b741", + rules=[ + RobotsRulesItem( + user_agent="*", + allows=["/public"], + disallows=["/bubbles"], + ) + ], ) ``` @@ -8817,6 +9385,22 @@ client.sites.scripts.get_custom_code(
+**rules:** `typing.Optional[typing.Sequence[RobotsRulesItem]]` — List of rules for user agents. + +
+
+ +
+
+ +**sitemap:** `typing.Optional[str]` — URL to the sitemap. + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -8829,7 +9413,7 @@ client.sites.scripts.get_custom_code(
-
client.sites.scripts.upsert_custom_code(...) +
client.sites.robots_txt.patch(...)
@@ -8841,15 +9425,11 @@ client.sites.scripts.get_custom_code(
-Add a registered script to a Site. +Update the `robots.txt` configuration for various user agents. -In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered -to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate -`custom_code` endpoints. +This endpoint requires an Enterprise workspace. -Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). - -Required scope | `custom_code:write` +Required scope | `site_config:write`
@@ -8864,26 +9444,21 @@ Required scope | `custom_code:write`
```python -from webflow import ScriptApply, Webflow +from webflow import RobotsRulesItem, Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.sites.scripts.upsert_custom_code( +client.sites.robots_txt.patch( site_id="580e63e98c9a982ac9b8b741", - scripts=[ - ScriptApply( - id="cms_slider", - location="header", - version="1.0.0", - attributes={"my-attribute": "some-value"}, - ), - ScriptApply( - id="alert", - location="header", - version="0.0.1", - ), + rules=[ + RobotsRulesItem( + user_agent="googlebot", + allows=["/public"], + disallows=["/vogon-poetry", "/total-perspective-vortex"], + ) ], + sitemap="https://heartofgold.ship/sitemap.xml", ) ``` @@ -8908,15 +9483,7 @@ client.sites.scripts.upsert_custom_code(
-**scripts:** `typing.Optional[typing.Sequence[ScriptApply]]` — A list of scripts applied to a Site or a Page - -
-
- -
-
- -**last_updated:** `typing.Optional[str]` — Date when the Site's scripts were last updated +**rules:** `typing.Optional[typing.Sequence[RobotsRulesItem]]` — List of rules for user agents.
@@ -8924,7 +9491,7 @@ client.sites.scripts.upsert_custom_code(
-**created_on:** `typing.Optional[str]` — Date when the Site's scripts were created +**sitemap:** `typing.Optional[str]` — URL to the sitemap.
@@ -8944,7 +9511,8 @@ client.sites.scripts.upsert_custom_code(
-
client.sites.scripts.delete_custom_code(...) +## Sites WellKnown +
client.sites.well_known.put(...)
@@ -8956,11 +9524,20 @@ client.sites.scripts.upsert_custom_code(
-Delete the custom code block that an app created for a Site +Upload a supported well-known file to a site. -Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). +The current restrictions on well-known files are as follows: + - Each file must be smaller than 100kb + - Less than 30 total files + - Have one of the following file extensions (or no extension): `.txt`, `.json`, `.noext` + + + `.noext` is a special file extension that removes other extensions. For example, `apple-app-site-association.noext.txt` will be uploaded as `apple-app-site-association`. Use this extension for tools that have trouble uploading extensionless files. + -Required scope | `custom_code:write` +This endpoint requires an Enterprise workspace. + +Required scope: `site_config:write`
@@ -8980,8 +9557,11 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.sites.scripts.delete_custom_code( +client.sites.well_known.put( site_id="580e63e98c9a982ac9b8b741", + file_name="apple-app-site-association.txt", + file_data='{\n "applinks": {\n "apps": [],\n "details": [\n {\n "appID": "ABCDE12345.com.example.app",\n "paths": [ "/*", "/some/path/*" ]\n }\n ]\n }\n}\n', + content_type="application/json", ) ``` @@ -9006,6 +9586,30 @@ client.sites.scripts.delete_custom_code(
+**file_name:** `str` — The name of the file + +
+
+ +
+
+ +**file_data:** `str` — The contents of the file + +
+
+ +
+
+ +**content_type:** `typing.Optional[WellKnownFileContentType]` — The content type of the file. Defaults to application/json + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -9018,7 +9622,7 @@ client.sites.scripts.delete_custom_code(
-
client.sites.scripts.list_custom_code_blocks(...) +
client.sites.well_known.delete(...)
@@ -9030,11 +9634,11 @@ client.sites.scripts.delete_custom_code(
-Get all instances of Custom Code applied to a Site or Pages. +Delete existing well-known files from a site. -Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). +This endpoint requires an Enterprise workspace. -Required scope | `custom_code:read` +Required scope: `site_config:write`
@@ -9054,7 +9658,7 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.sites.scripts.list_custom_code_blocks( +client.sites.well_known.delete( site_id="580e63e98c9a982ac9b8b741", ) @@ -9080,7 +9684,7 @@ client.sites.scripts.list_custom_code_blocks(
-**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records +**file_names:** `typing.Optional[typing.Sequence[str]]` — A list of file names to delete
@@ -9088,7 +9692,1443 @@ client.sites.scripts.list_custom_code_blocks(
-**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+ +
+ + + +
+ + +## Sites ActivityLogs +
client.sites.activity_logs.list(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieve Activity Logs for a specific Site. + +This endpoint requires an Enterprise workspace. + +Required scope: `site_activity:read` +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from webflow import Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.sites.activity_logs.list( + site_id="580e63e98c9a982ac9b8b741", + limit=1.1, + offset=1.1, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**site_id:** `str` — Unique identifier for a Site + +
+
+ +
+
+ +**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) + +
+
+ +
+
+ +**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Sites Comments +
client.sites.comments.list_comment_threads(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +List all comment threads for a site. + + + There may be a delay of up to 5 minutes before new comments appear in the system. + + +Required scope | `comments:read` +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from webflow import Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.sites.comments.list_comment_threads( + site_id="580e63e98c9a982ac9b8b741", + locale_id="65427cf400e02b306eaa04a0", + offset=1.1, + limit=1.1, + sort_by="createdOn", + sort_order="asc", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**site_id:** `str` — Unique identifier for a Site + +
+
+ +
+
+ +**locale_id:** `typing.Optional[str]` + +Unique identifier for a specific Locale. + +[Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + +
+
+ +
+
+ +**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records + +
+
+ +
+
+ +**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) + +
+
+ +
+
+ +**sort_by:** `typing.Optional[CommentsListCommentThreadsRequestSortBy]` — Sort results by the provided value. Only allowed when sortOrder is provided. + +
+
+ +
+
+ +**sort_order:** `typing.Optional[CommentsListCommentThreadsRequestSortOrder]` — Sorts the results by asc or desc + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.sites.comments.get_comment_thread(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Get details of a specific comment thread. + + + There may be a delay of up to 5 minutes before new comments appear in the system. + + +Required scope | `comments:read` +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from webflow import Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.sites.comments.get_comment_thread( + site_id="580e63e98c9a982ac9b8b741", + comment_thread_id="580e63e98c9a982ac9b8b741", + locale_id="65427cf400e02b306eaa04a0", + offset=1.1, + limit=1.1, + sort_by="createdOn", + sort_order="asc", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**site_id:** `str` — Unique identifier for a Site + +
+
+ +
+
+ +**comment_thread_id:** `str` — Unique identifier for a Comment Thread + +
+
+ +
+
+ +**locale_id:** `typing.Optional[str]` + +Unique identifier for a specific Locale. + +[Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + +
+
+ +
+
+ +**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records + +
+
+ +
+
+ +**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) + +
+
+ +
+
+ +**sort_by:** `typing.Optional[CommentsGetCommentThreadRequestSortBy]` — Sort results by the provided value. Only allowed when sortOrder is provided. + +
+
+ +
+
+ +**sort_order:** `typing.Optional[CommentsGetCommentThreadRequestSortOrder]` — Sorts the results by asc or desc + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.sites.comments.list_comment_replies(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +List all replies to a specific comment thread. + + + There may be a delay of up to 5 minutes before new comments appear in the system. + + +Required scope | `comments:read` +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from webflow import Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.sites.comments.list_comment_replies( + site_id="580e63e98c9a982ac9b8b741", + comment_thread_id="580e63e98c9a982ac9b8b741", + locale_id="65427cf400e02b306eaa04a0", + offset=1.1, + limit=1.1, + sort_by="createdOn", + sort_order="asc", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**site_id:** `str` — Unique identifier for a Site + +
+
+ +
+
+ +**comment_thread_id:** `str` — Unique identifier for a Comment Thread + +
+
+ +
+
+ +**locale_id:** `typing.Optional[str]` + +Unique identifier for a specific Locale. + +[Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + +
+
+ +
+
+ +**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records + +
+
+ +
+
+ +**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) + +
+
+ +
+
+ +**sort_by:** `typing.Optional[CommentsListCommentRepliesRequestSortBy]` — Sort results by the provided value. Only allowed when sortOrder is provided. + +
+
+ +
+
+ +**sort_order:** `typing.Optional[CommentsListCommentRepliesRequestSortOrder]` — Sorts the results by asc or desc + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Sites Scripts +
client.sites.scripts.get_custom_code(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Get all scripts applied to a site by the App. + + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + + +Required scope | `custom_code:read` +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from webflow import Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.sites.scripts.get_custom_code( + site_id="580e63e98c9a982ac9b8b741", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**site_id:** `str` — Unique identifier for a Site + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.sites.scripts.upsert_custom_code(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Apply registered scripts to a site. If you have multiple scripts your App needs to apply or maintain on a site, ensure they are always included in the request body for this endpoint. To remove individual scripts, simply call this endpoint without the script in the request body. + + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + + +Required scope | `custom_code:write` +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from webflow import ScriptApply, Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.sites.scripts.upsert_custom_code( + site_id="580e63e98c9a982ac9b8b741", + scripts=[ + ScriptApply( + id="cms_slider", + location="header", + version="1.0.0", + attributes={"my-attribute": "some-value"}, + ), + ScriptApply( + id="alert", + location="header", + version="0.0.1", + ), + ], +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**site_id:** `str` — Unique identifier for a Site + +
+
+ +
+
+ +**scripts:** `typing.Optional[typing.Sequence[ScriptApply]]` — A list of scripts applied to a Site or a Page + +
+
+ +
+
+ +**last_updated:** `typing.Optional[str]` — Date when the Site's scripts were last updated + +
+
+ +
+
+ +**created_on:** `typing.Optional[str]` — Date when the Site's scripts were created + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.sites.scripts.delete_custom_code(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Remove all scripts from a site applied by the App. This endpoint will not remove scripts from the site's registered scripts. + +To remove individual scripts applied by the App, use the [Add/Update Custom Code](/data/reference/custom-code/custom-code-sites/upsert-custom-code) endpoint. + +Access to this endpoint requires a bearer token obtained from an [OAuth Code Grant Flow](/data/reference/oauth-app). + +Required scope | `custom_code:write` +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from webflow import Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.sites.scripts.delete_custom_code( + site_id="580e63e98c9a982ac9b8b741", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**site_id:** `str` — Unique identifier for a Site + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.sites.scripts.list_custom_code_blocks(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Get a list of scripts that have been applied to a site and/or individual pages. + + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. + + See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + + +Required scope | `custom_code:read` +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from webflow import Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.sites.scripts.list_custom_code_blocks( + site_id="580e63e98c9a982ac9b8b741", + offset=1.1, + limit=1.1, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**site_id:** `str` — Unique identifier for a Site + +
+
+ +
+
+ +**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records + +
+
+ +
+
+ +**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Sites Forms +
client.sites.forms.list_submissions_by_site(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +List all form submissions for a given site with the ability to filter submissions by a centralized `elementId`. + +Add `elementId` when you want to filter form submissions to a specific form in a site. You can get the `elementId` from the [List forms endpoint](/data/reference/forms/forms/list) (displayed as `formElementId` in the response). + + +When a form is used in a Webflow component definition, each instance of the component will yield a unique form. Adding the `elementId` in this request ensures this API response includes all submissions from that core form, wherever that form is used in instantiated components. + + +Use the [List Form Submissions endpoint](/data/reference/forms/form-submissions/list-submissions) to list form submissions for a given form ID. + +Required scope | `forms:read` +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from webflow import Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.sites.forms.list_submissions_by_site( + site_id="580e63e98c9a982ac9b8b741", + element_id="18259716-3e5a-646a-5f41-5dc4b9405aa0", + offset=1.1, + limit=1.1, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**site_id:** `str` — Unique identifier for a Site + +
+
+ +
+
+ +**element_id:** `typing.Optional[str]` — Identifier for an element + +
+
+ +
+
+ +**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records + +
+
+ +
+
+ +**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.sites.forms.list_submissions(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +List form submissions for a given form ID within a specific site. + +Use the [List Form Submissions by Site endpoint](/data/reference/forms/form-submissions/list-submissions-by-site) to list form submissions for a given site with the ability to filter by a `formElementId`. + +Required scope | `forms:read` +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from webflow import Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.sites.forms.list_submissions( + site_id="580e63e98c9a982ac9b8b741", + form_id="580e63e98c9a982ac9b8b741", + offset=1.1, + limit=1.1, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**site_id:** `str` — Unique identifier for a Site + +
+
+ +
+
+ +**form_id:** `str` — Unique identifier for a Form + +
+
+ +
+
+ +**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records + +
+
+ +
+
+ +**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.sites.forms.get_submission(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Get information about a form submission within a specific site. + +Required scope | `forms:read` +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from webflow import Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.sites.forms.get_submission( + site_id="580e63e98c9a982ac9b8b741", + form_submission_id="580e63e98c9a982ac9b8b741", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**site_id:** `str` — Unique identifier for a Site + +
+
+ +
+
+ +**form_submission_id:** `str` — Unique identifier for a Form Submission + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.sites.forms.delete_submission(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Delete a form submission within a specific site. + +Required scope | `forms:write` +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from webflow import Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.sites.forms.delete_submission( + site_id="580e63e98c9a982ac9b8b741", + form_submission_id="580e63e98c9a982ac9b8b741", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**site_id:** `str` — Unique identifier for a Site + +
+
+ +
+
+ +**form_submission_id:** `str` — Unique identifier for a Form Submission + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.sites.forms.update_submission(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Update hidden fields on a form submission within a specific site. + +Required scope | `forms:write` +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from webflow import Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.sites.forms.update_submission( + site_id="580e63e98c9a982ac9b8b741", + form_submission_id="580e63e98c9a982ac9b8b741", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**site_id:** `str` — Unique identifier for a Site + +
+
+ +
+
+ +**form_submission_id:** `str` — Unique identifier for a Form Submission + +
+
+ +
+
+ +**form_submission_data:** `typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]` — An existing **hidden field** defined on the form schema, and the corresponding value to set + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Workspaces AuditLogs +
client.workspaces.audit_logs.get_workspace_audit_logs(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Get audit logs for a workspace. + +This endpoint requires an Enterprise workspace and a workspace token with the `workspace_activity:read` scope. Create a workspace token from your workspace dashboard integrations page to use this endpoint. + +Required scope | `workspace_activity:read` +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +import datetime + +from webflow import Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.workspaces.audit_logs.get_workspace_audit_logs( + workspace_id_or_slug="hitchhikers-workspace", + limit=1.1, + offset=1.1, + sort_order="asc", + event_type="user_access", + from_=datetime.datetime.fromisoformat( + "2025-06-22 16:00:31+00:00", + ), + to=datetime.datetime.fromisoformat( + "2025-07-22 16:00:31+00:00", + ), +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**workspace_id_or_slug:** `str` — Unique identifier or slug for a Workspace + +
+
+ +
+
+ +**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) + +
+
+ +
+
+ +**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records + +
+
+ +
+
+ +**sort_order:** `typing.Optional[AuditLogsGetWorkspaceAuditLogsRequestSortOrder]` — Sorts the results by asc or desc + +
+
+ +
+
+ +**event_type:** `typing.Optional[AuditLogsGetWorkspaceAuditLogsRequestEventType]` — The event type to filter by + +
+
+ +
+
+ +**from_:** `typing.Optional[dt.datetime]` — The start date to filter by + +
+
+ +
+
+ +**to:** `typing.Optional[dt.datetime]` — The end date to filter by
diff --git a/src/webflow/__init__.py b/src/webflow/__init__.py index 0d82d59..74aa370 100644 --- a/src/webflow/__init__.py +++ b/src/webflow/__init__.py @@ -20,6 +20,8 @@ BulkCollectionItemFieldData, Collection, CollectionItem, + CollectionItemChanged, + CollectionItemCreated, CollectionItemFieldData, CollectionItemList, CollectionItemListNoPagination, @@ -28,10 +30,31 @@ CollectionItemPatchSingleFieldData, CollectionItemPostSingle, CollectionItemPostSingleFieldData, + CollectionItemPublished, + CollectionItemRemoved, + CollectionItemRemovedPayload, + CollectionItemRemovedPayloadFieldData, + CollectionItemUnpublished, + CollectionItemUnpublishedPayload, + CollectionItemUnpublishedPayloadFieldData, CollectionItemWithIdInput, CollectionItemWithIdInputFieldData, CollectionList, CollectionListArrayItem, + Comment, + CommentPayload, + CommentPayloadAuthor, + CommentPayloadMentionedUsersItem, + CommentReply, + CommentReplyAuthor, + CommentReplyList, + CommentReplyListPagination, + CommentReplyMentionedUsersItem, + CommentThread, + CommentThreadAuthor, + CommentThreadList, + CommentThreadListPagination, + CommentThreadMentionedUsersItem, Component, ComponentDom, ComponentInstanceNodePropertyOverridesWrite, @@ -41,11 +64,15 @@ ComponentProperties, ComponentProperty, ComponentPropertyType, + Conflict, ConflictErrorBody, CustomCodeBlock, CustomCodeBlockType, CustomCodeHostedResponse, CustomCodeInlineResponse, + CustomRole, + CustomRoleAuditLogItem, + CustomRoleAuditLogItemEventSubType, Dom, Domain, Domains, @@ -54,7 +81,11 @@ Error, ErrorCode, Field, + FieldCreate, FieldType, + FieldValidations, + FieldValidationsAdditionalProperties, + FieldValidationsAdditionalPropertiesAdditionalProperties, ForbiddenErrorBody, Form, FormField, @@ -64,26 +95,43 @@ FormResponseSettings, FormSubmission, FormSubmissionList, + FormSubmissionTrigger, + FormSubmissionTriggerPayload, + FormSubmissionTriggerPayloadSchemaItem, + FormSubmissionTriggerPayloadSchemaItemFieldType, ImageNode, ImageNodeImage, InvalidDomain, InvalidScopes, InventoryItem, InventoryItemInventoryType, + ItemsListItemsLiveRequestLastPublished, + ItemsListItemsRequestLastPublished, ListCustomCodeBlocks, Locale, Locales, + Metadata, + MetadataOptionsItem, + NewOrder, NoDomains, Node, Node_ComponentInstance, Node_Image, + Node_SearchButton, + Node_Select, + Node_SubmitButton, Node_Text, + Node_TextInput, NotEnterprisePlanSite, NotEnterprisePlanWorkspace, + OptionField, Order, OrderAddress, OrderAddressJapanType, OrderAddressType, + OrderBillingAddress, + OrderBillingAddressJapanType, + OrderBillingAddressType, OrderCustomerInfo, OrderDisputeLastStatus, OrderDownloadFilesItem, @@ -94,15 +142,26 @@ OrderPurchasedItemVariantImage, OrderPurchasedItemVariantImageFile, OrderPurchasedItemVariantImageFileVariantsItem, + OrderShippingAddress, + OrderShippingAddressJapanType, + OrderShippingAddressType, OrderStatus, OrderTotals, OrderTotalsExtrasItem, OrderTotalsExtrasItemType, Page, + PageCreatedWebhook, + PageCreatedWebhookPayload, + PageDeletedWebhook, + PageDeletedWebhookPayload, PageList, + PageMetadataUpdatedWebhook, + PageMetadataUpdatedWebhookPayload, PageOpenGraph, PageSeo, Pagination, + Payload, + PayloadFieldData, PaypalDetails, Product, ProductAndSkUs, @@ -113,11 +172,24 @@ PublishStatus, Redirect, Redirects, + ReferenceField, + ReferenceFieldMetadata, + ReferenceFieldType, RegisteredScriptList, + Robots, + RobotsRulesItem, ScriptApply, ScriptApplyList, ScriptApplyLocation, Scripts, + SearchButtonNode, + SearchButtonNodeWrite, + Select, + SelectNode, + SelectNodeChoicesItem, + SelectNodeWriteChoicesItem, + SingleLocaleCreatedPayload, + SingleLocaleCreatedPayloadFieldData, Site, SiteActivityLogItem, SiteActivityLogItemEvent, @@ -125,9 +197,14 @@ SiteActivityLogItemUser, SiteActivityLogResponse, SiteDataCollectionType, + SiteMembership, + SiteMembershipAuditLogItem, + SiteMembershipAuditLogItemEventSubType, SitePlan, SitePlanId, SitePlanName, + SitePublish, + SitePublishPayload, Sites, Sku, SkuFieldData, @@ -141,16 +218,26 @@ SkuPropertyList, SkuPropertyListEnumItem, SkuValueList, + StaticField, + StaticFieldType, StripeCard, StripeCardBrand, StripeCardExpires, StripeDetails, + SubmitButtonNode, + SubmitButtonNodeWrite, Text, + TextInputNode, + TextInputNodeWrite, TextNode, TextNodeText, TextNodeWrite, TriggerType, + UpdatedOrder, User, + UserAccess, + UserAccessAuditLogItem, + UserAccessAuditLogItemEventSubType, UserAccessGroupsItem, UserAccessGroupsItemType, UserData, @@ -162,6 +249,34 @@ Webhook, WebhookFilter, WebhookList, + WorkspaceAuditLogItem, + WorkspaceAuditLogItemActor, + WorkspaceAuditLogItemPayloadSiteMembershipGranularAccess, + WorkspaceAuditLogItemPayloadSiteMembershipMethod, + WorkspaceAuditLogItemPayloadSiteMembershipSite, + WorkspaceAuditLogItemPayloadSiteMembershipTargetUser, + WorkspaceAuditLogItemPayloadSiteMembershipUserType, + WorkspaceAuditLogItemPayloadUserAccessMethod, + WorkspaceAuditLogItemPayloadWorkspaceInvitationMethod, + WorkspaceAuditLogItemPayloadWorkspaceInvitationTargetUser, + WorkspaceAuditLogItemPayloadWorkspaceInvitationTargetUsersItem, + WorkspaceAuditLogItemPayloadWorkspaceInvitationUserType, + WorkspaceAuditLogItemPayloadWorkspaceMembershipMethod, + WorkspaceAuditLogItemPayloadWorkspaceMembershipTargetUser, + WorkspaceAuditLogItemPayloadWorkspaceMembershipUserType, + WorkspaceAuditLogItemWorkspace, + WorkspaceAuditLogItem_CustomRole, + WorkspaceAuditLogItem_SiteMembership, + WorkspaceAuditLogItem_UserAccess, + WorkspaceAuditLogItem_WorkspaceInvitation, + WorkspaceAuditLogItem_WorkspaceMembership, + WorkspaceAuditLogResponse, + WorkspaceInvitation, + WorkspaceInvitationAuditLogItem, + WorkspaceInvitationAuditLogItemEventSubType, + WorkspaceMembership, + WorkspaceMembershipAuditLogItem, + WorkspaceMembershipAuditLogItemEventSubType, ) from .errors import ( BadRequestError, @@ -178,15 +293,28 @@ ComponentPropertiesWritePropertiesItem, ComponentsUpdateContentResponse, ComponentsUpdatePropertiesResponse, + EcommInventoryChangedPayload, InventoryUpdateRequestInventoryType, OrdersListRequestStatus, OrdersRefundRequestReason, PageDomWriteNodesItem, + PageMetadataWriteOpenGraph, + PageMetadataWriteSeo, + ProductSkuCreateProduct, + ProductSkuCreateSku, ProductsCreateSkuResponse, SitesPublishResponse, UpdateStaticContentResponse, + UserAccountAddedPayload, + UserAccountAddedPayloadPayload, + UserAccountAddedPayloadPayloadData, + UserAccountDeletedPayload, + UserAccountDeletedPayloadPayload, + UserAccountDeletedPayloadPayloadData, + UserAccountUpdatedPayload, + UserAccountUpdatedPayloadPayload, + UserAccountUpdatedPayloadPayloadData, UsersListRequestSort, - UsersUpdateRequestData, access_groups, assets, collections, @@ -202,6 +330,7 @@ token, users, webhooks, + workspaces, ) from .client import AsyncWebflow, Webflow from .environment import WebflowEnvironment @@ -230,6 +359,8 @@ "BulkCollectionItemFieldData", "Collection", "CollectionItem", + "CollectionItemChanged", + "CollectionItemCreated", "CollectionItemFieldData", "CollectionItemList", "CollectionItemListNoPagination", @@ -238,10 +369,31 @@ "CollectionItemPatchSingleFieldData", "CollectionItemPostSingle", "CollectionItemPostSingleFieldData", + "CollectionItemPublished", + "CollectionItemRemoved", + "CollectionItemRemovedPayload", + "CollectionItemRemovedPayloadFieldData", + "CollectionItemUnpublished", + "CollectionItemUnpublishedPayload", + "CollectionItemUnpublishedPayloadFieldData", "CollectionItemWithIdInput", "CollectionItemWithIdInputFieldData", "CollectionList", "CollectionListArrayItem", + "Comment", + "CommentPayload", + "CommentPayloadAuthor", + "CommentPayloadMentionedUsersItem", + "CommentReply", + "CommentReplyAuthor", + "CommentReplyList", + "CommentReplyListPagination", + "CommentReplyMentionedUsersItem", + "CommentThread", + "CommentThreadAuthor", + "CommentThreadList", + "CommentThreadListPagination", + "CommentThreadMentionedUsersItem", "Component", "ComponentDom", "ComponentDomWriteNodesItem", @@ -255,21 +407,30 @@ "ComponentPropertyType", "ComponentsUpdateContentResponse", "ComponentsUpdatePropertiesResponse", + "Conflict", "ConflictError", "ConflictErrorBody", "CustomCodeBlock", "CustomCodeBlockType", "CustomCodeHostedResponse", "CustomCodeInlineResponse", + "CustomRole", + "CustomRoleAuditLogItem", + "CustomRoleAuditLogItemEventSubType", "Dom", "Domain", "Domains", "DuplicateUserEmail", + "EcommInventoryChangedPayload", "EcommerceSettings", "Error", "ErrorCode", "Field", + "FieldCreate", "FieldType", + "FieldValidations", + "FieldValidationsAdditionalProperties", + "FieldValidationsAdditionalPropertiesAdditionalProperties", "ForbiddenError", "ForbiddenErrorBody", "Form", @@ -280,6 +441,10 @@ "FormResponseSettings", "FormSubmission", "FormSubmissionList", + "FormSubmissionTrigger", + "FormSubmissionTriggerPayload", + "FormSubmissionTriggerPayloadSchemaItem", + "FormSubmissionTriggerPayloadSchemaItemFieldType", "ImageNode", "ImageNodeImage", "InternalServerError", @@ -288,21 +453,34 @@ "InventoryItem", "InventoryItemInventoryType", "InventoryUpdateRequestInventoryType", + "ItemsListItemsLiveRequestLastPublished", + "ItemsListItemsRequestLastPublished", "ListCustomCodeBlocks", "Locale", "Locales", + "Metadata", + "MetadataOptionsItem", + "NewOrder", "NoDomains", "Node", "Node_ComponentInstance", "Node_Image", + "Node_SearchButton", + "Node_Select", + "Node_SubmitButton", "Node_Text", + "Node_TextInput", "NotEnterprisePlanSite", "NotEnterprisePlanWorkspace", "NotFoundError", + "OptionField", "Order", "OrderAddress", "OrderAddressJapanType", "OrderAddressType", + "OrderBillingAddress", + "OrderBillingAddressJapanType", + "OrderBillingAddressType", "OrderCustomerInfo", "OrderDisputeLastStatus", "OrderDownloadFilesItem", @@ -313,6 +491,9 @@ "OrderPurchasedItemVariantImage", "OrderPurchasedItemVariantImageFile", "OrderPurchasedItemVariantImageFileVariantsItem", + "OrderShippingAddress", + "OrderShippingAddressJapanType", + "OrderShippingAddressType", "OrderStatus", "OrderTotals", "OrderTotalsExtrasItem", @@ -320,11 +501,21 @@ "OrdersListRequestStatus", "OrdersRefundRequestReason", "Page", + "PageCreatedWebhook", + "PageCreatedWebhookPayload", + "PageDeletedWebhook", + "PageDeletedWebhookPayload", "PageDomWriteNodesItem", "PageList", + "PageMetadataUpdatedWebhook", + "PageMetadataUpdatedWebhookPayload", + "PageMetadataWriteOpenGraph", + "PageMetadataWriteSeo", "PageOpenGraph", "PageSeo", "Pagination", + "Payload", + "PayloadFieldData", "PaypalDetails", "Product", "ProductAndSkUs", @@ -332,15 +523,30 @@ "ProductFieldData", "ProductFieldDataEcProductType", "ProductFieldDataTaxCategory", + "ProductSkuCreateProduct", + "ProductSkuCreateSku", "ProductsCreateSkuResponse", "PublishStatus", "Redirect", "Redirects", + "ReferenceField", + "ReferenceFieldMetadata", + "ReferenceFieldType", "RegisteredScriptList", + "Robots", + "RobotsRulesItem", "ScriptApply", "ScriptApplyList", "ScriptApplyLocation", "Scripts", + "SearchButtonNode", + "SearchButtonNodeWrite", + "Select", + "SelectNode", + "SelectNodeChoicesItem", + "SelectNodeWriteChoicesItem", + "SingleLocaleCreatedPayload", + "SingleLocaleCreatedPayloadFieldData", "Site", "SiteActivityLogItem", "SiteActivityLogItemEvent", @@ -348,9 +554,14 @@ "SiteActivityLogItemUser", "SiteActivityLogResponse", "SiteDataCollectionType", + "SiteMembership", + "SiteMembershipAuditLogItem", + "SiteMembershipAuditLogItemEventSubType", "SitePlan", "SitePlanId", "SitePlanName", + "SitePublish", + "SitePublishPayload", "Sites", "SitesPublishResponse", "Sku", @@ -365,11 +576,17 @@ "SkuPropertyList", "SkuPropertyListEnumItem", "SkuValueList", + "StaticField", + "StaticFieldType", "StripeCard", "StripeCardBrand", "StripeCardExpires", "StripeDetails", + "SubmitButtonNode", + "SubmitButtonNodeWrite", "Text", + "TextInputNode", + "TextInputNodeWrite", "TextNode", "TextNodeText", "TextNodeWrite", @@ -377,9 +594,22 @@ "TriggerType", "UnauthorizedError", "UpdateStaticContentResponse", + "UpdatedOrder", "User", + "UserAccess", + "UserAccessAuditLogItem", + "UserAccessAuditLogItemEventSubType", "UserAccessGroupsItem", "UserAccessGroupsItemType", + "UserAccountAddedPayload", + "UserAccountAddedPayloadPayload", + "UserAccountAddedPayloadPayloadData", + "UserAccountDeletedPayload", + "UserAccountDeletedPayloadPayload", + "UserAccountDeletedPayloadPayloadData", + "UserAccountUpdatedPayload", + "UserAccountUpdatedPayloadPayload", + "UserAccountUpdatedPayloadPayloadData", "UserData", "UserDataData", "UserLimitReached", @@ -387,12 +617,39 @@ "UserStatus", "UsersListRequestSort", "UsersNotEnabled", - "UsersUpdateRequestData", "Webflow", "WebflowEnvironment", "Webhook", "WebhookFilter", "WebhookList", + "WorkspaceAuditLogItem", + "WorkspaceAuditLogItemActor", + "WorkspaceAuditLogItemPayloadSiteMembershipGranularAccess", + "WorkspaceAuditLogItemPayloadSiteMembershipMethod", + "WorkspaceAuditLogItemPayloadSiteMembershipSite", + "WorkspaceAuditLogItemPayloadSiteMembershipTargetUser", + "WorkspaceAuditLogItemPayloadSiteMembershipUserType", + "WorkspaceAuditLogItemPayloadUserAccessMethod", + "WorkspaceAuditLogItemPayloadWorkspaceInvitationMethod", + "WorkspaceAuditLogItemPayloadWorkspaceInvitationTargetUser", + "WorkspaceAuditLogItemPayloadWorkspaceInvitationTargetUsersItem", + "WorkspaceAuditLogItemPayloadWorkspaceInvitationUserType", + "WorkspaceAuditLogItemPayloadWorkspaceMembershipMethod", + "WorkspaceAuditLogItemPayloadWorkspaceMembershipTargetUser", + "WorkspaceAuditLogItemPayloadWorkspaceMembershipUserType", + "WorkspaceAuditLogItemWorkspace", + "WorkspaceAuditLogItem_CustomRole", + "WorkspaceAuditLogItem_SiteMembership", + "WorkspaceAuditLogItem_UserAccess", + "WorkspaceAuditLogItem_WorkspaceInvitation", + "WorkspaceAuditLogItem_WorkspaceMembership", + "WorkspaceAuditLogResponse", + "WorkspaceInvitation", + "WorkspaceInvitationAuditLogItem", + "WorkspaceInvitationAuditLogItemEventSubType", + "WorkspaceMembership", + "WorkspaceMembershipAuditLogItem", + "WorkspaceMembershipAuditLogItemEventSubType", "__version__", "access_groups", "assets", @@ -409,4 +666,5 @@ "token", "users", "webhooks", + "workspaces", ] diff --git a/src/webflow/client.py b/src/webflow/client.py index 90c233d..488b395 100644 --- a/src/webflow/client.py +++ b/src/webflow/client.py @@ -1,7 +1,7 @@ # This file was auto-generated by Fern from our API Definition. -import typing from .environment import WebflowEnvironment +import typing import httpx from .core.client_wrapper import SyncClientWrapper from .resources.token.client import TokenClient @@ -19,6 +19,7 @@ from .resources.orders.client import OrdersClient from .resources.inventory.client import InventoryClient from .resources.ecommerce.client import EcommerceClient +from .resources.workspaces.client import WorkspacesClient from .core.client_wrapper import AsyncClientWrapper from .resources.token.client import AsyncTokenClient from .resources.sites.client import AsyncSitesClient @@ -35,6 +36,7 @@ from .resources.orders.client import AsyncOrdersClient from .resources.inventory.client import AsyncInventoryClient from .resources.ecommerce.client import AsyncEcommerceClient +from .resources.workspaces.client import AsyncWorkspacesClient class Webflow: @@ -43,19 +45,16 @@ class Webflow: Parameters ---------- - base_url : typing.Optional[str] - The base url to use for requests from the client. - environment : WebflowEnvironment The environment to use for requests from the client. from .environment import WebflowEnvironment - Defaults to WebflowEnvironment.DEFAULT + Defaults to WebflowEnvironment.DATA_API - access_token : typing.Union[str, typing.Callable[[], str]] + access_token : typing.Optional[typing.Union[str, typing.Callable[[], str]]] timeout : typing.Optional[float] The timeout to be used, in seconds, for requests. By default the timeout is 60 seconds, unless a custom httpx client is used, in which case this default is not enforced. @@ -77,16 +76,15 @@ class Webflow: def __init__( self, *, - base_url: typing.Optional[str] = None, - environment: WebflowEnvironment = WebflowEnvironment.DEFAULT, - access_token: typing.Union[str, typing.Callable[[], str]], + environment: WebflowEnvironment = WebflowEnvironment.DATA_API, + access_token: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = None, timeout: typing.Optional[float] = None, follow_redirects: typing.Optional[bool] = True, httpx_client: typing.Optional[httpx.Client] = None, ): _defaulted_timeout = timeout if timeout is not None else 60 if httpx_client is None else None self._client_wrapper = SyncClientWrapper( - base_url=_get_base_url(base_url=base_url, environment=environment), + environment=environment, access_token=access_token, httpx_client=httpx_client if httpx_client is not None @@ -110,6 +108,7 @@ def __init__( self.orders = OrdersClient(client_wrapper=self._client_wrapper) self.inventory = InventoryClient(client_wrapper=self._client_wrapper) self.ecommerce = EcommerceClient(client_wrapper=self._client_wrapper) + self.workspaces = WorkspacesClient(client_wrapper=self._client_wrapper) class AsyncWebflow: @@ -118,19 +117,16 @@ class AsyncWebflow: Parameters ---------- - base_url : typing.Optional[str] - The base url to use for requests from the client. - environment : WebflowEnvironment The environment to use for requests from the client. from .environment import WebflowEnvironment - Defaults to WebflowEnvironment.DEFAULT + Defaults to WebflowEnvironment.DATA_API - access_token : typing.Union[str, typing.Callable[[], str]] + access_token : typing.Optional[typing.Union[str, typing.Callable[[], str]]] timeout : typing.Optional[float] The timeout to be used, in seconds, for requests. By default the timeout is 60 seconds, unless a custom httpx client is used, in which case this default is not enforced. @@ -152,16 +148,15 @@ class AsyncWebflow: def __init__( self, *, - base_url: typing.Optional[str] = None, - environment: WebflowEnvironment = WebflowEnvironment.DEFAULT, - access_token: typing.Union[str, typing.Callable[[], str]], + environment: WebflowEnvironment = WebflowEnvironment.DATA_API, + access_token: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = None, timeout: typing.Optional[float] = None, follow_redirects: typing.Optional[bool] = True, httpx_client: typing.Optional[httpx.AsyncClient] = None, ): _defaulted_timeout = timeout if timeout is not None else 60 if httpx_client is None else None self._client_wrapper = AsyncClientWrapper( - base_url=_get_base_url(base_url=base_url, environment=environment), + environment=environment, access_token=access_token, httpx_client=httpx_client if httpx_client is not None @@ -185,12 +180,4 @@ def __init__( self.orders = AsyncOrdersClient(client_wrapper=self._client_wrapper) self.inventory = AsyncInventoryClient(client_wrapper=self._client_wrapper) self.ecommerce = AsyncEcommerceClient(client_wrapper=self._client_wrapper) - - -def _get_base_url(*, base_url: typing.Optional[str] = None, environment: WebflowEnvironment) -> str: - if base_url is not None: - return base_url - elif environment is not None: - return environment.value - else: - raise Exception("Please pass in either base_url or environment to construct the client") + self.workspaces = AsyncWorkspacesClient(client_wrapper=self._client_wrapper) diff --git a/src/webflow/core/client_wrapper.py b/src/webflow/core/client_wrapper.py index a04487e..3849c42 100644 --- a/src/webflow/core/client_wrapper.py +++ b/src/webflow/core/client_wrapper.py @@ -1,6 +1,7 @@ # This file was auto-generated by Fern from our API Definition. import typing +from ..environment import WebflowEnvironment import httpx from .http_client import HttpClient from .http_client import AsyncHttpClient @@ -10,31 +11,33 @@ class BaseClientWrapper: def __init__( self, *, - access_token: typing.Union[str, typing.Callable[[], str]], - base_url: str, + access_token: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = None, + environment: WebflowEnvironment, timeout: typing.Optional[float] = None, ): self._access_token = access_token - self._base_url = base_url + self._environment = environment self._timeout = timeout def get_headers(self) -> typing.Dict[str, str]: headers: typing.Dict[str, str] = { "X-Fern-Language": "Python", "X-Fern-SDK-Name": "webflow", - "X-Fern-SDK-Version": "2.0.0b2", + "X-Fern-SDK-Version": "1.2.1", } - headers["Authorization"] = f"Bearer {self._get_access_token()}" + access_token = self._get_access_token() + if access_token is not None: + headers["Authorization"] = f"Bearer {access_token}" return headers - def _get_access_token(self) -> str: - if isinstance(self._access_token, str): + def _get_access_token(self) -> typing.Optional[str]: + if isinstance(self._access_token, str) or self._access_token is None: return self._access_token else: return self._access_token() - def get_base_url(self) -> str: - return self._base_url + def get_environment(self) -> WebflowEnvironment: + return self._environment def get_timeout(self) -> typing.Optional[float]: return self._timeout @@ -44,17 +47,14 @@ class SyncClientWrapper(BaseClientWrapper): def __init__( self, *, - access_token: typing.Union[str, typing.Callable[[], str]], - base_url: str, + access_token: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = None, + environment: WebflowEnvironment, timeout: typing.Optional[float] = None, httpx_client: httpx.Client, ): - super().__init__(access_token=access_token, base_url=base_url, timeout=timeout) + super().__init__(access_token=access_token, environment=environment, timeout=timeout) self.httpx_client = HttpClient( - httpx_client=httpx_client, - base_headers=self.get_headers, - base_timeout=self.get_timeout, - base_url=self.get_base_url, + httpx_client=httpx_client, base_headers=self.get_headers, base_timeout=self.get_timeout ) @@ -62,15 +62,12 @@ class AsyncClientWrapper(BaseClientWrapper): def __init__( self, *, - access_token: typing.Union[str, typing.Callable[[], str]], - base_url: str, + access_token: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = None, + environment: WebflowEnvironment, timeout: typing.Optional[float] = None, httpx_client: httpx.AsyncClient, ): - super().__init__(access_token=access_token, base_url=base_url, timeout=timeout) + super().__init__(access_token=access_token, environment=environment, timeout=timeout) self.httpx_client = AsyncHttpClient( - httpx_client=httpx_client, - base_headers=self.get_headers, - base_timeout=self.get_timeout, - base_url=self.get_base_url, + httpx_client=httpx_client, base_headers=self.get_headers, base_timeout=self.get_timeout ) diff --git a/src/webflow/environment.py b/src/webflow/environment.py index ed0e03d..07a5c81 100644 --- a/src/webflow/environment.py +++ b/src/webflow/environment.py @@ -1,7 +1,19 @@ # This file was auto-generated by Fern from our API Definition. -import enum +from __future__ import annotations -class WebflowEnvironment(enum.Enum): - DEFAULT = "https://api.webflow.com/v2" +class WebflowEnvironment: + DATA_API: WebflowEnvironment + + def __init__(self, *, base: str, data_api: str, content_delivery_api: str): + self.base = base + self.data_api = data_api + self.content_delivery_api = content_delivery_api + + +WebflowEnvironment.DATA_API = WebflowEnvironment( + base="https://api.webflow.com/v2", + data_api="https://api.webflow.com/v2", + content_delivery_api="https://api-cdn.webflow.com/v2", +) diff --git a/src/webflow/resources/__init__.py b/src/webflow/resources/__init__.py index 9122eee..54d7371 100644 --- a/src/webflow/resources/__init__.py +++ b/src/webflow/resources/__init__.py @@ -16,6 +16,7 @@ token, users, webhooks, + workspaces, ) from .access_groups import AccessGroupsListRequestSort from .components import ( @@ -24,12 +25,23 @@ ComponentsUpdateContentResponse, ComponentsUpdatePropertiesResponse, ) -from .inventory import InventoryUpdateRequestInventoryType +from .inventory import EcommInventoryChangedPayload, InventoryUpdateRequestInventoryType from .orders import OrdersListRequestStatus, OrdersRefundRequestReason -from .pages import PageDomWriteNodesItem, UpdateStaticContentResponse -from .products import ProductsCreateSkuResponse +from .pages import PageDomWriteNodesItem, PageMetadataWriteOpenGraph, PageMetadataWriteSeo, UpdateStaticContentResponse +from .products import ProductSkuCreateProduct, ProductSkuCreateSku, ProductsCreateSkuResponse from .sites import SitesPublishResponse -from .users import UsersListRequestSort, UsersUpdateRequestData +from .users import ( + UserAccountAddedPayload, + UserAccountAddedPayloadPayload, + UserAccountAddedPayloadPayloadData, + UserAccountDeletedPayload, + UserAccountDeletedPayloadPayload, + UserAccountDeletedPayloadPayloadData, + UserAccountUpdatedPayload, + UserAccountUpdatedPayloadPayload, + UserAccountUpdatedPayloadPayloadData, + UsersListRequestSort, +) __all__ = [ "AccessGroupsListRequestSort", @@ -37,15 +49,28 @@ "ComponentPropertiesWritePropertiesItem", "ComponentsUpdateContentResponse", "ComponentsUpdatePropertiesResponse", + "EcommInventoryChangedPayload", "InventoryUpdateRequestInventoryType", "OrdersListRequestStatus", "OrdersRefundRequestReason", "PageDomWriteNodesItem", + "PageMetadataWriteOpenGraph", + "PageMetadataWriteSeo", + "ProductSkuCreateProduct", + "ProductSkuCreateSku", "ProductsCreateSkuResponse", "SitesPublishResponse", "UpdateStaticContentResponse", + "UserAccountAddedPayload", + "UserAccountAddedPayloadPayload", + "UserAccountAddedPayloadPayloadData", + "UserAccountDeletedPayload", + "UserAccountDeletedPayloadPayload", + "UserAccountDeletedPayloadPayloadData", + "UserAccountUpdatedPayload", + "UserAccountUpdatedPayloadPayload", + "UserAccountUpdatedPayloadPayloadData", "UsersListRequestSort", - "UsersUpdateRequestData", "access_groups", "assets", "collections", @@ -61,4 +86,5 @@ "token", "users", "webhooks", + "workspaces", ] diff --git a/src/webflow/resources/access_groups/client.py b/src/webflow/resources/access_groups/client.py index ee7668a..99241be 100644 --- a/src/webflow/resources/access_groups/client.py +++ b/src/webflow/resources/access_groups/client.py @@ -69,10 +69,14 @@ def list( ) client.access_groups.list( site_id="580e63e98c9a982ac9b8b741", + offset=1.1, + limit=1.1, + sort="CreatedOn", ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/accessgroups", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "offset": offset, @@ -211,6 +215,9 @@ async def list( async def main() -> None: await client.access_groups.list( site_id="580e63e98c9a982ac9b8b741", + offset=1.1, + limit=1.1, + sort="CreatedOn", ) @@ -218,6 +225,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/accessgroups", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "offset": offset, diff --git a/src/webflow/resources/assets/client.py b/src/webflow/resources/assets/client.py index 61e141a..d517058 100644 --- a/src/webflow/resources/assets/client.py +++ b/src/webflow/resources/assets/client.py @@ -28,9 +28,16 @@ class AssetsClient: def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper - def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Assets: + def list( + self, + site_id: str, + *, + offset: typing.Optional[float] = None, + limit: typing.Optional[float] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> Assets: """ - List assets for a given site + List of assets uploaded to a site Required scope | `assets:read` @@ -39,6 +46,12 @@ def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] site_id : str Unique identifier for a Site + offset : typing.Optional[float] + Offset used for pagination if the results have more than limit records + + limit : typing.Optional[float] + Maximum number of records to be returned (max limit: 100) + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -56,11 +69,18 @@ def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] ) client.assets.list( site_id="580e63e98c9a982ac9b8b741", + offset=1.1, + limit=1.1, ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/assets", + base_url=self._client_wrapper.get_environment().base, method="GET", + params={ + "offset": offset, + "limit": limit, + }, request_options=request_options, ) try: @@ -137,15 +157,18 @@ def create( request_options: typing.Optional[RequestOptions] = None, ) -> AssetUpload: """ - Create a new asset entry. + The first step in uploading an asset to a site. This endpoint generates a response with the following information: `uploadUrl` and `uploadDetails`. - You can use these two properties to [upload the file to Amazon s3 by making a POST](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html) - request to the `uploadUrl` with the `uploadDetails` object as your header information in the request. - Required scope | `assets:write` + Use these properties in the header of a [POST request to Amazson s3](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html) to complete the upload. + + + To learn more about how to upload assets to Webflow, see our [assets guide](/data/docs/working-with-assets). + + Required scope | `assets:write` Parameters ---------- @@ -184,6 +207,7 @@ def create( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/assets", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "fileName": file_name, @@ -262,7 +286,7 @@ def create( def get(self, asset_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Asset: """ - Get an Asset + Get details about an asset Required scope | `assets:read` @@ -292,6 +316,7 @@ def get(self, asset_id: str, *, request_options: typing.Optional[RequestOptions] """ _response = self._client_wrapper.httpx_client.request( f"assets/{jsonable_encoder(asset_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -390,6 +415,7 @@ def delete(self, asset_id: str, *, request_options: typing.Optional[RequestOptio """ _response = self._client_wrapper.httpx_client.request( f"assets/{jsonable_encoder(asset_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -460,7 +486,7 @@ def update( request_options: typing.Optional[RequestOptions] = None, ) -> Asset: """ - Update an Asset + Update details of an Asset. Required scope | `assets:write` @@ -496,6 +522,7 @@ def update( """ _response = self._client_wrapper.httpx_client.request( f"assets/{jsonable_encoder(asset_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "localeId": locale_id, @@ -603,6 +630,7 @@ def list_folders(self, site_id: str, *, request_options: typing.Optional[Request """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/asset_folders", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -716,6 +744,7 @@ def create_folder( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/asset_folders", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "displayName": display_name, @@ -825,6 +854,7 @@ def get_folder( """ _response = self._client_wrapper.httpx_client.request( f"asset_folders/{jsonable_encoder(asset_folder_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -897,9 +927,16 @@ class AsyncAssetsClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper - async def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Assets: + async def list( + self, + site_id: str, + *, + offset: typing.Optional[float] = None, + limit: typing.Optional[float] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> Assets: """ - List assets for a given site + List of assets uploaded to a site Required scope | `assets:read` @@ -908,6 +945,12 @@ async def list(self, site_id: str, *, request_options: typing.Optional[RequestOp site_id : str Unique identifier for a Site + offset : typing.Optional[float] + Offset used for pagination if the results have more than limit records + + limit : typing.Optional[float] + Maximum number of records to be returned (max limit: 100) + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -930,6 +973,8 @@ async def list(self, site_id: str, *, request_options: typing.Optional[RequestOp async def main() -> None: await client.assets.list( site_id="580e63e98c9a982ac9b8b741", + offset=1.1, + limit=1.1, ) @@ -937,7 +982,12 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/assets", + base_url=self._client_wrapper.get_environment().base, method="GET", + params={ + "offset": offset, + "limit": limit, + }, request_options=request_options, ) try: @@ -1014,15 +1064,18 @@ async def create( request_options: typing.Optional[RequestOptions] = None, ) -> AssetUpload: """ - Create a new asset entry. + The first step in uploading an asset to a site. This endpoint generates a response with the following information: `uploadUrl` and `uploadDetails`. - You can use these two properties to [upload the file to Amazon s3 by making a POST](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html) - request to the `uploadUrl` with the `uploadDetails` object as your header information in the request. - Required scope | `assets:write` + Use these properties in the header of a [POST request to Amazson s3](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html) to complete the upload. + + + To learn more about how to upload assets to Webflow, see our [assets guide](/data/docs/working-with-assets). + + Required scope | `assets:write` Parameters ---------- @@ -1069,6 +1122,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/assets", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "fileName": file_name, @@ -1147,7 +1201,7 @@ async def main() -> None: async def get(self, asset_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Asset: """ - Get an Asset + Get details about an asset Required scope | `assets:read` @@ -1185,6 +1239,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"assets/{jsonable_encoder(asset_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -1291,6 +1346,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"assets/{jsonable_encoder(asset_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -1361,7 +1417,7 @@ async def update( request_options: typing.Optional[RequestOptions] = None, ) -> Asset: """ - Update an Asset + Update details of an Asset. Required scope | `assets:write` @@ -1405,6 +1461,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"assets/{jsonable_encoder(asset_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "localeId": locale_id, @@ -1522,6 +1579,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/asset_folders", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -1643,6 +1701,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/asset_folders", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "displayName": display_name, @@ -1760,6 +1819,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"asset_folders/{jsonable_encoder(asset_folder_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) diff --git a/src/webflow/resources/collections/__init__.py b/src/webflow/resources/collections/__init__.py index cb6aaf8..3796806 100644 --- a/src/webflow/resources/collections/__init__.py +++ b/src/webflow/resources/collections/__init__.py @@ -3,16 +3,20 @@ from .resources import ( CreateBulkCollectionItemRequestBodyFieldData, CreateBulkCollectionItemRequestBodyFieldDataItem, - FieldCreateType, - ItemsCreateItemLiveRequest, - ItemsCreateItemRequest, + ItemIDs, + ItemIDsWithLocales, + ItemsCreateItemLiveRequestBody, + ItemsCreateItemRequestBody, ItemsDeleteItemsLiveRequestItemsItem, ItemsDeleteItemsRequestItemsItem, ItemsListItemsLiveRequestSortBy, ItemsListItemsLiveRequestSortOrder, ItemsListItemsRequestSortBy, ItemsListItemsRequestSortOrder, + ItemsPublishItemRequest, + ItemsPublishItemRequestItemsItemsItem, ItemsPublishItemResponse, + ItemsUpdateItemsResponse, MultipleItems, MultipleLiveItems, SingleCmsItem, @@ -23,16 +27,20 @@ __all__ = [ "CreateBulkCollectionItemRequestBodyFieldData", "CreateBulkCollectionItemRequestBodyFieldDataItem", - "FieldCreateType", - "ItemsCreateItemLiveRequest", - "ItemsCreateItemRequest", + "ItemIDs", + "ItemIDsWithLocales", + "ItemsCreateItemLiveRequestBody", + "ItemsCreateItemRequestBody", "ItemsDeleteItemsLiveRequestItemsItem", "ItemsDeleteItemsRequestItemsItem", "ItemsListItemsLiveRequestSortBy", "ItemsListItemsLiveRequestSortOrder", "ItemsListItemsRequestSortBy", "ItemsListItemsRequestSortOrder", + "ItemsPublishItemRequest", + "ItemsPublishItemRequestItemsItemsItem", "ItemsPublishItemResponse", + "ItemsUpdateItemsResponse", "MultipleItems", "MultipleLiveItems", "SingleCmsItem", diff --git a/src/webflow/resources/collections/client.py b/src/webflow/resources/collections/client.py index 1e44aae..61495ae 100644 --- a/src/webflow/resources/collections/client.py +++ b/src/webflow/resources/collections/client.py @@ -16,7 +16,10 @@ from ...errors.internal_server_error import InternalServerError from json.decoder import JSONDecodeError from ...core.api_error import ApiError +from ...types.field_create import FieldCreate from ...types.collection import Collection +from ...core.serialization import convert_and_respect_annotation_metadata +from ...errors.conflict_error import ConflictError from ...core.client_wrapper import AsyncClientWrapper from .resources.fields.client import AsyncFieldsClient from .resources.items.client import AsyncItemsClient @@ -63,6 +66,7 @@ def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/collections", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -137,10 +141,13 @@ def create( display_name: str, singular_name: str, slug: typing.Optional[str] = OMIT, + fields: typing.Optional[typing.Sequence[FieldCreate]] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> Collection: """ - Create a Collection for a site. + Create a Collection for a site with collection fields. + + Each collection includes the required _name_ and _slug_ fields, which are generated automatically. You can update the `displayName` of these fields, but the slug for them cannot be changed. Fields slugs are automatically converted to lowercase. Spaces in slugs are replaced with hyphens. Required scope | `cms:write` @@ -158,6 +165,9 @@ def create( slug : typing.Optional[str] Part of a URL that identifier + fields : typing.Optional[typing.Sequence[FieldCreate]] + An array of custom fields to add to the collection + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -168,7 +178,7 @@ def create( Examples -------- - from webflow import Webflow + from webflow import ReferenceField, ReferenceFieldMetadata, StaticField, Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", @@ -178,15 +188,42 @@ def create( display_name="Blog Posts", singular_name="Blog Post", slug="posts", + fields=[ + StaticField( + is_required=True, + type="PlainText", + display_name="Title", + help_text="The title of the blog post", + ), + StaticField( + is_required=True, + type="RichText", + display_name="Content", + help_text="The content of the blog post", + ), + ReferenceField( + is_required=True, + type="Reference", + display_name="Author", + help_text="The author of the blog post", + metadata=ReferenceFieldMetadata( + collection_id="23cc2d952d4e4631ffd4345d2743db4e", + ), + ), + ], ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/collections", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "displayName": display_name, "singularName": singular_name, "slug": slug, + "fields": convert_and_respect_annotation_metadata( + object_=fields, annotation=typing.Sequence[FieldCreate], direction="write" + ), }, headers={ "content-type": "application/json", @@ -233,6 +270,16 @@ def create( ), ) ) + if _response.status_code == 409: + raise ConflictError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) if _response.status_code == 429: raise TooManyRequestsError( typing.cast( @@ -290,6 +337,7 @@ def get(self, collection_id: str, *, request_options: typing.Optional[RequestOpt """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -388,6 +436,7 @@ def delete(self, collection_id: str, *, request_options: typing.Optional[Request """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -496,6 +545,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/collections", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -570,10 +620,13 @@ async def create( display_name: str, singular_name: str, slug: typing.Optional[str] = OMIT, + fields: typing.Optional[typing.Sequence[FieldCreate]] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> Collection: """ - Create a Collection for a site. + Create a Collection for a site with collection fields. + + Each collection includes the required _name_ and _slug_ fields, which are generated automatically. You can update the `displayName` of these fields, but the slug for them cannot be changed. Fields slugs are automatically converted to lowercase. Spaces in slugs are replaced with hyphens. Required scope | `cms:write` @@ -591,6 +644,9 @@ async def create( slug : typing.Optional[str] Part of a URL that identifier + fields : typing.Optional[typing.Sequence[FieldCreate]] + An array of custom fields to add to the collection + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -603,7 +659,12 @@ async def create( -------- import asyncio - from webflow import AsyncWebflow + from webflow import ( + AsyncWebflow, + ReferenceField, + ReferenceFieldMetadata, + StaticField, + ) client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", @@ -616,6 +677,29 @@ async def main() -> None: display_name="Blog Posts", singular_name="Blog Post", slug="posts", + fields=[ + StaticField( + is_required=True, + type="PlainText", + display_name="Title", + help_text="The title of the blog post", + ), + StaticField( + is_required=True, + type="RichText", + display_name="Content", + help_text="The content of the blog post", + ), + ReferenceField( + is_required=True, + type="Reference", + display_name="Author", + help_text="The author of the blog post", + metadata=ReferenceFieldMetadata( + collection_id="23cc2d952d4e4631ffd4345d2743db4e", + ), + ), + ], ) @@ -623,11 +707,15 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/collections", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "displayName": display_name, "singularName": singular_name, "slug": slug, + "fields": convert_and_respect_annotation_metadata( + object_=fields, annotation=typing.Sequence[FieldCreate], direction="write" + ), }, headers={ "content-type": "application/json", @@ -674,6 +762,16 @@ async def main() -> None: ), ) ) + if _response.status_code == 409: + raise ConflictError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) if _response.status_code == 429: raise TooManyRequestsError( typing.cast( @@ -739,6 +837,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -845,6 +944,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) diff --git a/src/webflow/resources/collections/resources/__init__.py b/src/webflow/resources/collections/resources/__init__.py index f9325ee..4ad4d58 100644 --- a/src/webflow/resources/collections/resources/__init__.py +++ b/src/webflow/resources/collections/resources/__init__.py @@ -1,19 +1,23 @@ # This file was auto-generated by Fern from our API Definition. from . import fields, items -from .fields import FieldCreateType from .items import ( CreateBulkCollectionItemRequestBodyFieldData, CreateBulkCollectionItemRequestBodyFieldDataItem, - ItemsCreateItemLiveRequest, - ItemsCreateItemRequest, + ItemIDs, + ItemIDsWithLocales, + ItemsCreateItemLiveRequestBody, + ItemsCreateItemRequestBody, ItemsDeleteItemsLiveRequestItemsItem, ItemsDeleteItemsRequestItemsItem, ItemsListItemsLiveRequestSortBy, ItemsListItemsLiveRequestSortOrder, ItemsListItemsRequestSortBy, ItemsListItemsRequestSortOrder, + ItemsPublishItemRequest, + ItemsPublishItemRequestItemsItemsItem, ItemsPublishItemResponse, + ItemsUpdateItemsResponse, MultipleItems, MultipleLiveItems, SingleCmsItem, @@ -22,16 +26,20 @@ __all__ = [ "CreateBulkCollectionItemRequestBodyFieldData", "CreateBulkCollectionItemRequestBodyFieldDataItem", - "FieldCreateType", - "ItemsCreateItemLiveRequest", - "ItemsCreateItemRequest", + "ItemIDs", + "ItemIDsWithLocales", + "ItemsCreateItemLiveRequestBody", + "ItemsCreateItemRequestBody", "ItemsDeleteItemsLiveRequestItemsItem", "ItemsDeleteItemsRequestItemsItem", "ItemsListItemsLiveRequestSortBy", "ItemsListItemsLiveRequestSortOrder", "ItemsListItemsRequestSortBy", "ItemsListItemsRequestSortOrder", + "ItemsPublishItemRequest", + "ItemsPublishItemRequestItemsItemsItem", "ItemsPublishItemResponse", + "ItemsUpdateItemsResponse", "MultipleItems", "MultipleLiveItems", "SingleCmsItem", diff --git a/src/webflow/resources/collections/resources/fields/__init__.py b/src/webflow/resources/collections/resources/fields/__init__.py index 5a5b167..f3ea265 100644 --- a/src/webflow/resources/collections/resources/fields/__init__.py +++ b/src/webflow/resources/collections/resources/fields/__init__.py @@ -1,5 +1,2 @@ # This file was auto-generated by Fern from our API Definition. -from .types import FieldCreateType - -__all__ = ["FieldCreateType"] diff --git a/src/webflow/resources/collections/resources/fields/client.py b/src/webflow/resources/collections/resources/fields/client.py index 40b66cf..c2b7ebc 100644 --- a/src/webflow/resources/collections/resources/fields/client.py +++ b/src/webflow/resources/collections/resources/fields/client.py @@ -2,19 +2,21 @@ import typing from .....core.client_wrapper import SyncClientWrapper -from .types.field_create_type import FieldCreateType +from .....types.field_create import FieldCreate from .....core.request_options import RequestOptions -from .....types.field import Field from .....core.jsonable_encoder import jsonable_encoder +from .....core.serialization import convert_and_respect_annotation_metadata from .....core.pydantic_utilities import parse_obj_as from .....errors.bad_request_error import BadRequestError from .....errors.unauthorized_error import UnauthorizedError from .....types.error import Error from .....errors.not_found_error import NotFoundError +from .....errors.conflict_error import ConflictError from .....errors.too_many_requests_error import TooManyRequestsError from .....errors.internal_server_error import InternalServerError from json.decoder import JSONDecodeError from .....core.api_error import ApiError +from .....types.field import Field from .....core.client_wrapper import AsyncClientWrapper # this is used as the default value for optional parameters @@ -26,24 +28,14 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper def create( - self, - collection_id: str, - *, - type: FieldCreateType, - display_name: str, - is_required: typing.Optional[bool] = OMIT, - help_text: typing.Optional[str] = OMIT, - request_options: typing.Optional[RequestOptions] = None, - ) -> Field: + self, collection_id: str, *, request: FieldCreate, request_options: typing.Optional[RequestOptions] = None + ) -> FieldCreate: """ Create a custom field in a collection. - Slugs must be all lowercase letters without spaces. - If you pass a string with uppercase letters and/or spaces to the "Slug" property, Webflow will - convert the slug to lowercase and replace spaces with "-." + Field validation is currently not available through the API. - Only some field types can be created through the API. - This endpoint does not currently support bulk creation. + Bulk creation of fields is not supported with this endpoint. To add multiple fields at once, include them when you [create the collection.](/data/v2.0.0/reference/cms/collections/create) Required scope | `cms:write` @@ -52,62 +44,49 @@ def create( collection_id : str Unique identifier for a Collection - type : FieldCreateType - Choose these appropriate field type for your collection data - - display_name : str - The name of a field - - is_required : typing.Optional[bool] - define whether a field is required in a collection - - help_text : typing.Optional[str] - Additional text to help anyone filling out this field + request : FieldCreate request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - Field + FieldCreate Request was successful Examples -------- - from webflow import Webflow + from webflow import StaticField, Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.collections.fields.create( collection_id="580e63fc8c9a982ac9b8b745", - is_required=False, - type="RichText", - display_name="Post Body", - help_text="Add the body of your post here", + request=StaticField( + id="562ac0395358780a1f5e6fbc", + is_editable=True, + is_required=False, + type="RichText", + display_name="Post Body", + help_text="Add the body of your post here", + ), ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/fields", + base_url=self._client_wrapper.get_environment().base, method="POST", - json={ - "isRequired": is_required, - "type": type, - "displayName": display_name, - "helpText": help_text, - }, - headers={ - "content-type": "application/json", - }, + json=convert_and_respect_annotation_metadata(object_=request, annotation=FieldCreate, direction="write"), request_options=request_options, omit=OMIT, ) try: if 200 <= _response.status_code < 300: return typing.cast( - Field, + FieldCreate, parse_obj_as( - type_=Field, # type: ignore + type_=FieldCreate, # type: ignore object_=_response.json(), ), ) @@ -141,6 +120,16 @@ def create( ), ) ) + if _response.status_code == 409: + raise ConflictError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) if _response.status_code == 429: raise TooManyRequestsError( typing.cast( @@ -203,6 +192,7 @@ def delete( """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/fields/{jsonable_encoder(field_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -321,6 +311,7 @@ def update( """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/fields/{jsonable_encoder(field_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "isRequired": is_required, @@ -403,24 +394,14 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper async def create( - self, - collection_id: str, - *, - type: FieldCreateType, - display_name: str, - is_required: typing.Optional[bool] = OMIT, - help_text: typing.Optional[str] = OMIT, - request_options: typing.Optional[RequestOptions] = None, - ) -> Field: + self, collection_id: str, *, request: FieldCreate, request_options: typing.Optional[RequestOptions] = None + ) -> FieldCreate: """ Create a custom field in a collection. - Slugs must be all lowercase letters without spaces. - If you pass a string with uppercase letters and/or spaces to the "Slug" property, Webflow will - convert the slug to lowercase and replace spaces with "-." + Field validation is currently not available through the API. - Only some field types can be created through the API. - This endpoint does not currently support bulk creation. + Bulk creation of fields is not supported with this endpoint. To add multiple fields at once, include them when you [create the collection.](/data/v2.0.0/reference/cms/collections/create) Required scope | `cms:write` @@ -429,31 +410,21 @@ async def create( collection_id : str Unique identifier for a Collection - type : FieldCreateType - Choose these appropriate field type for your collection data - - display_name : str - The name of a field - - is_required : typing.Optional[bool] - define whether a field is required in a collection - - help_text : typing.Optional[str] - Additional text to help anyone filling out this field + request : FieldCreate request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - Field + FieldCreate Request was successful Examples -------- import asyncio - from webflow import AsyncWebflow + from webflow import AsyncWebflow, StaticField client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", @@ -463,10 +434,14 @@ async def create( async def main() -> None: await client.collections.fields.create( collection_id="580e63fc8c9a982ac9b8b745", - is_required=False, - type="RichText", - display_name="Post Body", - help_text="Add the body of your post here", + request=StaticField( + id="562ac0395358780a1f5e6fbc", + is_editable=True, + is_required=False, + type="RichText", + display_name="Post Body", + help_text="Add the body of your post here", + ), ) @@ -474,25 +449,18 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/fields", + base_url=self._client_wrapper.get_environment().base, method="POST", - json={ - "isRequired": is_required, - "type": type, - "displayName": display_name, - "helpText": help_text, - }, - headers={ - "content-type": "application/json", - }, + json=convert_and_respect_annotation_metadata(object_=request, annotation=FieldCreate, direction="write"), request_options=request_options, omit=OMIT, ) try: if 200 <= _response.status_code < 300: return typing.cast( - Field, + FieldCreate, parse_obj_as( - type_=Field, # type: ignore + type_=FieldCreate, # type: ignore object_=_response.json(), ), ) @@ -526,6 +494,16 @@ async def main() -> None: ), ) ) + if _response.status_code == 409: + raise ConflictError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) if _response.status_code == 429: raise TooManyRequestsError( typing.cast( @@ -596,6 +574,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/fields/{jsonable_encoder(field_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -722,6 +701,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/fields/{jsonable_encoder(field_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "isRequired": is_required, diff --git a/src/webflow/resources/collections/resources/fields/types/__init__.py b/src/webflow/resources/collections/resources/fields/types/__init__.py deleted file mode 100644 index c17230e..0000000 --- a/src/webflow/resources/collections/resources/fields/types/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from .field_create_type import FieldCreateType - -__all__ = ["FieldCreateType"] diff --git a/src/webflow/resources/collections/resources/items/__init__.py b/src/webflow/resources/collections/resources/items/__init__.py index fbccd1b..7dce40c 100644 --- a/src/webflow/resources/collections/resources/items/__init__.py +++ b/src/webflow/resources/collections/resources/items/__init__.py @@ -3,15 +3,20 @@ from .types import ( CreateBulkCollectionItemRequestBodyFieldData, CreateBulkCollectionItemRequestBodyFieldDataItem, - ItemsCreateItemLiveRequest, - ItemsCreateItemRequest, + ItemIDs, + ItemIDsWithLocales, + ItemsCreateItemLiveRequestBody, + ItemsCreateItemRequestBody, ItemsDeleteItemsLiveRequestItemsItem, ItemsDeleteItemsRequestItemsItem, ItemsListItemsLiveRequestSortBy, ItemsListItemsLiveRequestSortOrder, ItemsListItemsRequestSortBy, ItemsListItemsRequestSortOrder, + ItemsPublishItemRequest, + ItemsPublishItemRequestItemsItemsItem, ItemsPublishItemResponse, + ItemsUpdateItemsResponse, MultipleItems, MultipleLiveItems, SingleCmsItem, @@ -20,15 +25,20 @@ __all__ = [ "CreateBulkCollectionItemRequestBodyFieldData", "CreateBulkCollectionItemRequestBodyFieldDataItem", - "ItemsCreateItemLiveRequest", - "ItemsCreateItemRequest", + "ItemIDs", + "ItemIDsWithLocales", + "ItemsCreateItemLiveRequestBody", + "ItemsCreateItemRequestBody", "ItemsDeleteItemsLiveRequestItemsItem", "ItemsDeleteItemsRequestItemsItem", "ItemsListItemsLiveRequestSortBy", "ItemsListItemsLiveRequestSortOrder", "ItemsListItemsRequestSortBy", "ItemsListItemsRequestSortOrder", + "ItemsPublishItemRequest", + "ItemsPublishItemRequestItemsItemsItem", "ItemsPublishItemResponse", + "ItemsUpdateItemsResponse", "MultipleItems", "MultipleLiveItems", "SingleCmsItem", diff --git a/src/webflow/resources/collections/resources/items/client.py b/src/webflow/resources/collections/resources/items/client.py index 47f8f90..00cdf43 100644 --- a/src/webflow/resources/collections/resources/items/client.py +++ b/src/webflow/resources/collections/resources/items/client.py @@ -2,11 +2,13 @@ import typing from .....core.client_wrapper import SyncClientWrapper +from .....types.items_list_items_request_last_published import ItemsListItemsRequestLastPublished from .types.items_list_items_request_sort_by import ItemsListItemsRequestSortBy from .types.items_list_items_request_sort_order import ItemsListItemsRequestSortOrder from .....core.request_options import RequestOptions from .....types.collection_item_list import CollectionItemList from .....core.jsonable_encoder import jsonable_encoder +from .....core.serialization import convert_and_respect_annotation_metadata from .....core.pydantic_utilities import parse_obj_as from .....errors.bad_request_error import BadRequestError from .....errors.unauthorized_error import UnauthorizedError @@ -16,20 +18,22 @@ from .....errors.internal_server_error import InternalServerError from json.decoder import JSONDecodeError from .....core.api_error import ApiError -from .types.items_create_item_request import ItemsCreateItemRequest +from .types.items_create_item_request_body import ItemsCreateItemRequestBody from .....types.collection_item import CollectionItem -from .....core.serialization import convert_and_respect_annotation_metadata from .types.items_delete_items_request_items_item import ItemsDeleteItemsRequestItemsItem from .....errors.conflict_error import ConflictError from .....types.collection_item_with_id_input import CollectionItemWithIdInput +from .types.items_update_items_response import ItemsUpdateItemsResponse +from .....types.items_list_items_live_request_last_published import ItemsListItemsLiveRequestLastPublished from .types.items_list_items_live_request_sort_by import ItemsListItemsLiveRequestSortBy from .types.items_list_items_live_request_sort_order import ItemsListItemsLiveRequestSortOrder -from .types.items_create_item_live_request import ItemsCreateItemLiveRequest +from .types.items_create_item_live_request_body import ItemsCreateItemLiveRequestBody from .types.items_delete_items_live_request_items_item import ItemsDeleteItemsLiveRequestItemsItem from .....types.collection_item_list_no_pagination import CollectionItemListNoPagination from .types.create_bulk_collection_item_request_body_field_data import CreateBulkCollectionItemRequestBodyFieldData from .....types.bulk_collection_item import BulkCollectionItem from .....types.collection_item_patch_single_field_data import CollectionItemPatchSingleFieldData +from .types.items_publish_item_request import ItemsPublishItemRequest from .types.items_publish_item_response import ItemsPublishItemResponse from .....core.client_wrapper import AsyncClientWrapper @@ -50,6 +54,7 @@ def list_items( limit: typing.Optional[float] = None, name: typing.Optional[str] = None, slug: typing.Optional[str] = None, + last_published: typing.Optional[ItemsListItemsRequestLastPublished] = None, sort_by: typing.Optional[ItemsListItemsRequestSortBy] = None, sort_order: typing.Optional[ItemsListItemsRequestSortOrder] = None, request_options: typing.Optional[RequestOptions] = None, @@ -74,10 +79,13 @@ def list_items( Maximum number of records to be returned (max limit: 100) name : typing.Optional[str] - The name of the item(s) + Filter by the exact name of the item(s) slug : typing.Optional[str] - The slug of the item + Filter by the exact slug of the item + + last_published : typing.Optional[ItemsListItemsRequestLastPublished] + Filter by the last published date of the item(s) sort_by : typing.Optional[ItemsListItemsRequestSortBy] Sort results by the provided value @@ -102,10 +110,18 @@ def list_items( ) client.collections.items.list_items( collection_id="580e63fc8c9a982ac9b8b745", + cms_locale_id="cmsLocaleId", + offset=1.1, + limit=1.1, + name="name", + slug="slug", + sort_by="lastPublished", + sort_order="asc", ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "cmsLocaleId": cms_locale_id, @@ -113,6 +129,9 @@ def list_items( "limit": limit, "name": name, "slug": slug, + "lastPublished": convert_and_respect_annotation_metadata( + object_=last_published, annotation=ItemsListItemsRequestLastPublished, direction="write" + ), "sortBy": sort_by, "sortOrder": sort_order, }, @@ -186,14 +205,15 @@ def create_item( self, collection_id: str, *, - request: ItemsCreateItemRequest, + request: ItemsCreateItemRequestBody, + skip_invalid_files: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> CollectionItem: """ Create Item(s) in a Collection. - To create items across multiple locales, please use [this endpoint.](/v2.0.0/data/reference/cms/collection-items/staged-items/create-items) + To create items across multiple locales, please use [this endpoint.](/data/reference/cms/collection-items/staged-items/create-items) Required scope | `CMS:write` @@ -202,7 +222,10 @@ def create_item( collection_id : str Unique identifier for a Collection - request : ItemsCreateItemRequest + request : ItemsCreateItemRequestBody + + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -225,21 +248,26 @@ def create_item( ) client.collections.items.create_item( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, request=CollectionItemPostSingle( is_archived=False, is_draft=False, field_data=CollectionItemPostSingleFieldData( - name="Pan Galactic Gargle Blaster Recipe", - slug="pan-galactic-gargle-blaster", + name="The Hitchhiker's Guide to the Galaxy", + slug="hitchhikers-guide-to-the-galaxy", ), ), ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items", + base_url=self._client_wrapper.get_environment().base, method="POST", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json=convert_and_respect_annotation_metadata( - object_=request, annotation=ItemsCreateItemRequest, direction="write" + object_=request, annotation=ItemsCreateItemRequestBody, direction="write" ), request_options=request_options, omit=OMIT, @@ -312,13 +340,13 @@ def delete_items( self, collection_id: str, *, - items: typing.Optional[typing.Sequence[ItemsDeleteItemsRequestItemsItem]] = OMIT, + items: typing.Sequence[ItemsDeleteItemsRequestItemsItem], request_options: typing.Optional[RequestOptions] = None, ) -> None: """ Delete Items from a Collection. - **Note:** If the `cmsLocaleId` parameter is undefined or empty and the items are localized, items will be deleted only in the primary locale. + Items will only be deleted in the primary locale unless a `cmsLocaleId` is included in the request. Required scope | `CMS:write` @@ -327,7 +355,7 @@ def delete_items( collection_id : str Unique identifier for a Collection - items : typing.Optional[typing.Sequence[ItemsDeleteItemsRequestItemsItem]] + items : typing.Sequence[ItemsDeleteItemsRequestItemsItem] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -339,16 +367,25 @@ def delete_items( Examples -------- from webflow import Webflow + from webflow.resources.collections.resources.items import ( + ItemsDeleteItemsRequestItemsItem, + ) client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.collections.items.delete_items( collection_id="580e63fc8c9a982ac9b8b745", + items=[ + ItemsDeleteItemsRequestItemsItem( + id="580e64008c9a982ac9b8b754", + ) + ], ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items", + base_url=self._client_wrapper.get_environment().base, method="DELETE", json={ "items": convert_and_respect_annotation_metadata( @@ -433,13 +470,16 @@ def update_items( self, collection_id: str, *, + skip_invalid_files: typing.Optional[bool] = None, items: typing.Optional[typing.Sequence[CollectionItemWithIdInput]] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> CollectionItem: + ) -> ItemsUpdateItemsResponse: """ - Update a single item or multiple items (up to 100) in a Collection. + Update a single item or multiple items in a Collection. - **Note:** If the `cmsLocaleId` parameter is undefined or empty and the items are localized, items will be updated only in the primary locale. + The limit for this endpoint is 100 items. + + Items will only be updated in the primary locale, unless a `cmsLocaleId` is included in the request. Required scope | `CMS:write` @@ -448,6 +488,9 @@ def update_items( collection_id : str Unique identifier for a Collection + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + items : typing.Optional[typing.Sequence[CollectionItemWithIdInput]] request_options : typing.Optional[RequestOptions] @@ -455,7 +498,7 @@ def update_items( Returns ------- - CollectionItem + ItemsUpdateItemsResponse Request was successful Examples @@ -471,6 +514,7 @@ def update_items( ) client.collections.items.update_items( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, items=[ CollectionItemWithIdInput( id="66f6ed9576ddacf3149d5ea6", @@ -509,7 +553,11 @@ def update_items( """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items", + base_url=self._client_wrapper.get_environment().base, method="PATCH", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json={ "items": convert_and_respect_annotation_metadata( object_=items, annotation=typing.Sequence[CollectionItemWithIdInput], direction="write" @@ -524,9 +572,9 @@ def update_items( try: if 200 <= _response.status_code < 300: return typing.cast( - CollectionItem, + ItemsUpdateItemsResponse, parse_obj_as( - type_=CollectionItem, # type: ignore + type_=ItemsUpdateItemsResponse, # type: ignore object_=_response.json(), ), ) @@ -594,12 +642,17 @@ def list_items_live( limit: typing.Optional[float] = None, name: typing.Optional[str] = None, slug: typing.Optional[str] = None, + last_published: typing.Optional[ItemsListItemsLiveRequestLastPublished] = None, sort_by: typing.Optional[ItemsListItemsLiveRequestSortBy] = None, sort_order: typing.Optional[ItemsListItemsLiveRequestSortOrder] = None, request_options: typing.Optional[RequestOptions] = None, ) -> CollectionItemList: """ - List of all live Items within a Collection. + List all published items in a collection. + + + Serving data to applications in real-time? Use the Content Delivery API at `api-cdn.webflow.com` for better performance. The CDN-backed endpoint is optimized for high-volume reads, while the Data API is designed for writes and management operations. + Required scope | `CMS:read` @@ -618,10 +671,13 @@ def list_items_live( Maximum number of records to be returned (max limit: 100) name : typing.Optional[str] - The name of the item(s) + Filter by the exact name of the item(s) slug : typing.Optional[str] - The slug of the item + Filter by the exact slug of the item + + last_published : typing.Optional[ItemsListItemsLiveRequestLastPublished] + Filter by the last published date of the item(s) sort_by : typing.Optional[ItemsListItemsLiveRequestSortBy] Sort results by the provided value @@ -646,10 +702,18 @@ def list_items_live( ) client.collections.items.list_items_live( collection_id="580e63fc8c9a982ac9b8b745", + cms_locale_id="cmsLocaleId", + offset=1.1, + limit=1.1, + name="name", + slug="slug", + sort_by="lastPublished", + sort_order="asc", ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/live", + base_url=self._client_wrapper.get_environment().data_api, method="GET", params={ "cmsLocaleId": cms_locale_id, @@ -657,6 +721,9 @@ def list_items_live( "limit": limit, "name": name, "slug": slug, + "lastPublished": convert_and_respect_annotation_metadata( + object_=last_published, annotation=ItemsListItemsLiveRequestLastPublished, direction="write" + ), "sortBy": sort_by, "sortOrder": sort_order, }, @@ -730,14 +797,15 @@ def create_item_live( self, collection_id: str, *, - request: ItemsCreateItemLiveRequest, + request: ItemsCreateItemLiveRequestBody, + skip_invalid_files: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> CollectionItem: """ - Create live Item(s) in a Collection. The Item(s) will be published to the live site. + Create item(s) in a collection that will be immediately published to the live site. - To create items across multiple locales, [please use this endpoint.](/v2.0.0/data/reference/cms/collection-items/staged-items/create-items) + To create items across multiple locales, [please use this endpoint.](/data/reference/cms/collection-items/staged-items/create-items) Required scope | `CMS:write` @@ -747,7 +815,10 @@ def create_item_live( collection_id : str Unique identifier for a Collection - request : ItemsCreateItemLiveRequest + request : ItemsCreateItemLiveRequestBody + + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -766,21 +837,26 @@ def create_item_live( ) client.collections.items.create_item_live( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, request=CollectionItem( is_archived=False, is_draft=False, field_data=CollectionItemFieldData( - name="Pan Galactic Gargle Blaster Recipe", - slug="pan-galactic-gargle-blaster", + name="The Hitchhiker's Guide to the Galaxy", + slug="hitchhikers-guide-to-the-galaxy", ), ), ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/live", + base_url=self._client_wrapper.get_environment().base, method="POST", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json=convert_and_respect_annotation_metadata( - object_=request, annotation=ItemsCreateItemLiveRequest, direction="write" + object_=request, annotation=ItemsCreateItemLiveRequestBody, direction="write" ), request_options=request_options, omit=OMIT, @@ -853,13 +929,13 @@ def delete_items_live( self, collection_id: str, *, - items: typing.Optional[typing.Sequence[ItemsDeleteItemsLiveRequestItemsItem]] = OMIT, + items: typing.Sequence[ItemsDeleteItemsLiveRequestItemsItem], request_options: typing.Optional[RequestOptions] = None, ) -> None: """ - Remove an item or multiple items (up to 100 items) from the live site. Deleting published items will unpublish the items from the live site and set them to draft. + Unpublish up to 100 items from the live site and set the `isDraft` property to `true`. - **Note:** If the `cmsLocaleId` parameter is undefined or empty and the items are localized, items will be unpublished only in the primary locale. + Items will only be unpublished in the primary locale unless a `cmsLocaleId` is included in the request. Required scope | `CMS:write` @@ -868,7 +944,7 @@ def delete_items_live( collection_id : str Unique identifier for a Collection - items : typing.Optional[typing.Sequence[ItemsDeleteItemsLiveRequestItemsItem]] + items : typing.Sequence[ItemsDeleteItemsLiveRequestItemsItem] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -880,16 +956,25 @@ def delete_items_live( Examples -------- from webflow import Webflow + from webflow.resources.collections.resources.items import ( + ItemsDeleteItemsLiveRequestItemsItem, + ) client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.collections.items.delete_items_live( collection_id="580e63fc8c9a982ac9b8b745", + items=[ + ItemsDeleteItemsLiveRequestItemsItem( + id="580e64008c9a982ac9b8b754", + ) + ], ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/live", + base_url=self._client_wrapper.get_environment().base, method="DELETE", json={ "items": convert_and_respect_annotation_metadata( @@ -964,13 +1049,14 @@ def update_items_live( self, collection_id: str, *, + skip_invalid_files: typing.Optional[bool] = None, items: typing.Optional[typing.Sequence[CollectionItemWithIdInput]] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> CollectionItemListNoPagination: """ - Update a single live item or multiple live items (up to 100) in a Collection + Update a single published item or multiple published items (up to 100) in a Collection - **Note:** If the `cmsLocaleId` parameter is undefined or empty and the items are localized, items will be updated only in the primary locale. + Items will only be updated in the primary locale, unless a `cmsLocaleId` is included in the request. Required scope | `CMS:write` @@ -979,6 +1065,9 @@ def update_items_live( collection_id : str Unique identifier for a Collection + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + items : typing.Optional[typing.Sequence[CollectionItemWithIdInput]] request_options : typing.Optional[RequestOptions] @@ -1002,6 +1091,7 @@ def update_items_live( ) client.collections.items.update_items_live( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, items=[ CollectionItemWithIdInput( id="66f6ed9576ddacf3149d5ea6", @@ -1040,7 +1130,11 @@ def update_items_live( """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/live", + base_url=self._client_wrapper.get_environment().base, method="PATCH", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json={ "items": convert_and_respect_annotation_metadata( object_=items, annotation=typing.Sequence[CollectionItemWithIdInput], direction="write" @@ -1091,6 +1185,16 @@ def update_items_live( ), ) ) + if _response.status_code == 409: + raise ConflictError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) if _response.status_code == 429: raise TooManyRequestsError( typing.cast( @@ -1121,6 +1225,7 @@ def create_items( collection_id: str, *, field_data: CreateBulkCollectionItemRequestBodyFieldData, + skip_invalid_files: typing.Optional[bool] = None, cms_locale_ids: typing.Optional[typing.Sequence[str]] = OMIT, is_archived: typing.Optional[bool] = OMIT, is_draft: typing.Optional[bool] = OMIT, @@ -1129,9 +1234,10 @@ def create_items( """ Create an item or multiple items in a CMS Collection across multiple corresponding locales. - **Notes:** + - This endpoint can create up to 100 items in a request. - - If the `cmsLocaleIds` parameter is undefined or empty and localization is enabled, items will only be created in the primary locale. + - If the `cmsLocaleIds` parameter is not included in the request, an item will only be created in the primary locale. + Required scope | `CMS:write` @@ -1142,6 +1248,9 @@ def create_items( field_data : CreateBulkCollectionItemRequestBodyFieldData + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + cms_locale_ids : typing.Optional[typing.Sequence[str]] Array of identifiers for the locales where the item will be created @@ -1169,6 +1278,7 @@ def create_items( ) client.collections.items.create_items( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, cms_locale_ids=[ "66f6e966c9e1dc700a857ca3", "66f6e966c9e1dc700a857ca4", @@ -1184,7 +1294,11 @@ def create_items( """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/bulk", + base_url=self._client_wrapper.get_environment().base, method="POST", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json={ "cmsLocaleIds": cms_locale_ids, "isArchived": is_archived, @@ -1305,10 +1419,12 @@ def get_item( client.collections.items.get_item( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + cms_locale_id="cmsLocaleId", ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "cmsLocaleId": cms_locale_id, @@ -1388,7 +1504,7 @@ def delete_item( request_options: typing.Optional[RequestOptions] = None, ) -> None: """ - Delete an Item from a Collection. This endpoint does not currently support bulk deletion. + Delete an item from a collection. Required scope | `CMS:write` @@ -1420,10 +1536,12 @@ def delete_item( client.collections.items.delete_item( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + cms_locale_id="cmsLocaleId", ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", params={ "cmsLocaleId": cms_locale_id, @@ -1493,6 +1611,7 @@ def update_item( collection_id: str, item_id: str, *, + skip_invalid_files: typing.Optional[bool] = None, id: typing.Optional[str] = OMIT, cms_locale_id: typing.Optional[str] = OMIT, last_published: typing.Optional[str] = OMIT, @@ -1516,6 +1635,9 @@ def update_item( item_id : str Unique identifier for an Item + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + id : typing.Optional[str] Unique identifier for the Item @@ -1557,17 +1679,22 @@ def update_item( client.collections.items.update_item( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + skip_invalid_files=True, is_archived=False, is_draft=False, field_data=CollectionItemPatchSingleFieldData( - name="Pan Galactic Gargle Blaster Recipe", - slug="pan-galactic-gargle-blaster", + name="The Hitchhiker's Guide to the Galaxy", + slug="hitchhikers-guide-to-the-galaxy", ), ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json={ "id": id, "cmsLocaleId": cms_locale_id, @@ -1658,6 +1785,10 @@ def get_item_live( """ Get details of a selected Collection live Item. + + Serving data to applications in real-time? Use the Content Delivery API at `api-cdn.webflow.com` for better performance. The CDN-backed endpoint is optimized for high-volume reads, while the Data API is designed for writes and management operations. + + Required scope | `CMS:read` Parameters @@ -1689,10 +1820,12 @@ def get_item_live( client.collections.items.get_item_live( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + cms_locale_id="cmsLocaleId", ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/live", + base_url=self._client_wrapper.get_environment().data_api, method="GET", params={ "cmsLocaleId": cms_locale_id, @@ -1772,9 +1905,9 @@ def delete_item_live( request_options: typing.Optional[RequestOptions] = None, ) -> None: """ - Remove a live item from the site. Removing a published item will unpublish the item from the live site and set it to draft. + Unpublish a live item from the site and set the `isDraft` property to `true`. - This endpoint does not currently support bulk deletion. + For bulk unpublishing, please use [this endpoint.](/data/v2.0.0/reference/cms/collection-items/live-items/delete-items-live) Required scope | `CMS:write` @@ -1806,10 +1939,12 @@ def delete_item_live( client.collections.items.delete_item_live( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + cms_locale_id="cmsLocaleId", ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/live", + base_url=self._client_wrapper.get_environment().base, method="DELETE", params={ "cmsLocaleId": cms_locale_id, @@ -1879,6 +2014,7 @@ def update_item_live( collection_id: str, item_id: str, *, + skip_invalid_files: typing.Optional[bool] = None, id: typing.Optional[str] = OMIT, cms_locale_id: typing.Optional[str] = OMIT, last_published: typing.Optional[str] = OMIT, @@ -1902,6 +2038,9 @@ def update_item_live( item_id : str Unique identifier for an Item + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + id : typing.Optional[str] Unique identifier for the Item @@ -1943,17 +2082,22 @@ def update_item_live( client.collections.items.update_item_live( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + skip_invalid_files=True, is_archived=False, is_draft=False, field_data=CollectionItemPatchSingleFieldData( - name="Pan Galactic Gargle Blaster Recipe", - slug="pan-galactic-gargle-blaster", + name="The Hitchhiker's Guide to the Galaxy", + slug="hitchhikers-guide-to-the-galaxy", ), ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/live", + base_url=self._client_wrapper.get_environment().base, method="PATCH", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json={ "id": id, "cmsLocaleId": cms_locale_id, @@ -2008,6 +2152,16 @@ def update_item_live( ), ) ) + if _response.status_code == 409: + raise ConflictError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) if _response.status_code == 429: raise TooManyRequestsError( typing.cast( @@ -2037,7 +2191,7 @@ def publish_item( self, collection_id: str, *, - item_ids: typing.Sequence[str], + request: ItemsPublishItemRequest, request_options: typing.Optional[RequestOptions] = None, ) -> ItemsPublishItemResponse: """ @@ -2050,7 +2204,7 @@ def publish_item( collection_id : str Unique identifier for a Collection - item_ids : typing.Sequence[str] + request : ItemsPublishItemRequest request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2063,24 +2217,29 @@ def publish_item( Examples -------- from webflow import Webflow + from webflow.resources.collections.resources.items import ItemIDs client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.collections.items.publish_item( collection_id="580e63fc8c9a982ac9b8b745", - item_ids=["itemIds"], + request=ItemIDs( + item_ids=[ + "643fd856d66b6528195ee2ca", + "643fd856d66b6528195ee2cb", + "643fd856d66b6528195ee2cc", + ], + ), ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/publish", + base_url=self._client_wrapper.get_environment().base, method="POST", - json={ - "itemIds": item_ids, - }, - headers={ - "content-type": "application/json", - }, + json=convert_and_respect_annotation_metadata( + object_=request, annotation=ItemsPublishItemRequest, direction="write" + ), request_options=request_options, omit=OMIT, ) @@ -2172,6 +2331,7 @@ async def list_items( limit: typing.Optional[float] = None, name: typing.Optional[str] = None, slug: typing.Optional[str] = None, + last_published: typing.Optional[ItemsListItemsRequestLastPublished] = None, sort_by: typing.Optional[ItemsListItemsRequestSortBy] = None, sort_order: typing.Optional[ItemsListItemsRequestSortOrder] = None, request_options: typing.Optional[RequestOptions] = None, @@ -2196,10 +2356,13 @@ async def list_items( Maximum number of records to be returned (max limit: 100) name : typing.Optional[str] - The name of the item(s) + Filter by the exact name of the item(s) slug : typing.Optional[str] - The slug of the item + Filter by the exact slug of the item + + last_published : typing.Optional[ItemsListItemsRequestLastPublished] + Filter by the last published date of the item(s) sort_by : typing.Optional[ItemsListItemsRequestSortBy] Sort results by the provided value @@ -2229,6 +2392,13 @@ async def list_items( async def main() -> None: await client.collections.items.list_items( collection_id="580e63fc8c9a982ac9b8b745", + cms_locale_id="cmsLocaleId", + offset=1.1, + limit=1.1, + name="name", + slug="slug", + sort_by="lastPublished", + sort_order="asc", ) @@ -2236,6 +2406,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "cmsLocaleId": cms_locale_id, @@ -2243,6 +2414,9 @@ async def main() -> None: "limit": limit, "name": name, "slug": slug, + "lastPublished": convert_and_respect_annotation_metadata( + object_=last_published, annotation=ItemsListItemsRequestLastPublished, direction="write" + ), "sortBy": sort_by, "sortOrder": sort_order, }, @@ -2316,14 +2490,15 @@ async def create_item( self, collection_id: str, *, - request: ItemsCreateItemRequest, + request: ItemsCreateItemRequestBody, + skip_invalid_files: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> CollectionItem: """ Create Item(s) in a Collection. - To create items across multiple locales, please use [this endpoint.](/v2.0.0/data/reference/cms/collection-items/staged-items/create-items) + To create items across multiple locales, please use [this endpoint.](/data/reference/cms/collection-items/staged-items/create-items) Required scope | `CMS:write` @@ -2332,7 +2507,10 @@ async def create_item( collection_id : str Unique identifier for a Collection - request : ItemsCreateItemRequest + request : ItemsCreateItemRequestBody + + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2360,12 +2538,13 @@ async def create_item( async def main() -> None: await client.collections.items.create_item( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, request=CollectionItemPostSingle( is_archived=False, is_draft=False, field_data=CollectionItemPostSingleFieldData( - name="Pan Galactic Gargle Blaster Recipe", - slug="pan-galactic-gargle-blaster", + name="The Hitchhiker's Guide to the Galaxy", + slug="hitchhikers-guide-to-the-galaxy", ), ), ) @@ -2375,9 +2554,13 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items", + base_url=self._client_wrapper.get_environment().base, method="POST", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json=convert_and_respect_annotation_metadata( - object_=request, annotation=ItemsCreateItemRequest, direction="write" + object_=request, annotation=ItemsCreateItemRequestBody, direction="write" ), request_options=request_options, omit=OMIT, @@ -2450,13 +2633,13 @@ async def delete_items( self, collection_id: str, *, - items: typing.Optional[typing.Sequence[ItemsDeleteItemsRequestItemsItem]] = OMIT, + items: typing.Sequence[ItemsDeleteItemsRequestItemsItem], request_options: typing.Optional[RequestOptions] = None, ) -> None: """ Delete Items from a Collection. - **Note:** If the `cmsLocaleId` parameter is undefined or empty and the items are localized, items will be deleted only in the primary locale. + Items will only be deleted in the primary locale unless a `cmsLocaleId` is included in the request. Required scope | `CMS:write` @@ -2465,7 +2648,7 @@ async def delete_items( collection_id : str Unique identifier for a Collection - items : typing.Optional[typing.Sequence[ItemsDeleteItemsRequestItemsItem]] + items : typing.Sequence[ItemsDeleteItemsRequestItemsItem] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2479,6 +2662,9 @@ async def delete_items( import asyncio from webflow import AsyncWebflow + from webflow.resources.collections.resources.items import ( + ItemsDeleteItemsRequestItemsItem, + ) client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", @@ -2488,6 +2674,11 @@ async def delete_items( async def main() -> None: await client.collections.items.delete_items( collection_id="580e63fc8c9a982ac9b8b745", + items=[ + ItemsDeleteItemsRequestItemsItem( + id="580e64008c9a982ac9b8b754", + ) + ], ) @@ -2495,6 +2686,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items", + base_url=self._client_wrapper.get_environment().base, method="DELETE", json={ "items": convert_and_respect_annotation_metadata( @@ -2579,13 +2771,16 @@ async def update_items( self, collection_id: str, *, + skip_invalid_files: typing.Optional[bool] = None, items: typing.Optional[typing.Sequence[CollectionItemWithIdInput]] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> CollectionItem: + ) -> ItemsUpdateItemsResponse: """ - Update a single item or multiple items (up to 100) in a Collection. + Update a single item or multiple items in a Collection. + + The limit for this endpoint is 100 items. - **Note:** If the `cmsLocaleId` parameter is undefined or empty and the items are localized, items will be updated only in the primary locale. + Items will only be updated in the primary locale, unless a `cmsLocaleId` is included in the request. Required scope | `CMS:write` @@ -2594,6 +2789,9 @@ async def update_items( collection_id : str Unique identifier for a Collection + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + items : typing.Optional[typing.Sequence[CollectionItemWithIdInput]] request_options : typing.Optional[RequestOptions] @@ -2601,7 +2799,7 @@ async def update_items( Returns ------- - CollectionItem + ItemsUpdateItemsResponse Request was successful Examples @@ -2622,6 +2820,7 @@ async def update_items( async def main() -> None: await client.collections.items.update_items( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, items=[ CollectionItemWithIdInput( id="66f6ed9576ddacf3149d5ea6", @@ -2663,7 +2862,11 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items", + base_url=self._client_wrapper.get_environment().base, method="PATCH", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json={ "items": convert_and_respect_annotation_metadata( object_=items, annotation=typing.Sequence[CollectionItemWithIdInput], direction="write" @@ -2678,9 +2881,9 @@ async def main() -> None: try: if 200 <= _response.status_code < 300: return typing.cast( - CollectionItem, + ItemsUpdateItemsResponse, parse_obj_as( - type_=CollectionItem, # type: ignore + type_=ItemsUpdateItemsResponse, # type: ignore object_=_response.json(), ), ) @@ -2748,12 +2951,17 @@ async def list_items_live( limit: typing.Optional[float] = None, name: typing.Optional[str] = None, slug: typing.Optional[str] = None, + last_published: typing.Optional[ItemsListItemsLiveRequestLastPublished] = None, sort_by: typing.Optional[ItemsListItemsLiveRequestSortBy] = None, sort_order: typing.Optional[ItemsListItemsLiveRequestSortOrder] = None, request_options: typing.Optional[RequestOptions] = None, ) -> CollectionItemList: """ - List of all live Items within a Collection. + List all published items in a collection. + + + Serving data to applications in real-time? Use the Content Delivery API at `api-cdn.webflow.com` for better performance. The CDN-backed endpoint is optimized for high-volume reads, while the Data API is designed for writes and management operations. + Required scope | `CMS:read` @@ -2772,10 +2980,13 @@ async def list_items_live( Maximum number of records to be returned (max limit: 100) name : typing.Optional[str] - The name of the item(s) + Filter by the exact name of the item(s) slug : typing.Optional[str] - The slug of the item + Filter by the exact slug of the item + + last_published : typing.Optional[ItemsListItemsLiveRequestLastPublished] + Filter by the last published date of the item(s) sort_by : typing.Optional[ItemsListItemsLiveRequestSortBy] Sort results by the provided value @@ -2805,6 +3016,13 @@ async def list_items_live( async def main() -> None: await client.collections.items.list_items_live( collection_id="580e63fc8c9a982ac9b8b745", + cms_locale_id="cmsLocaleId", + offset=1.1, + limit=1.1, + name="name", + slug="slug", + sort_by="lastPublished", + sort_order="asc", ) @@ -2812,6 +3030,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/live", + base_url=self._client_wrapper.get_environment().data_api, method="GET", params={ "cmsLocaleId": cms_locale_id, @@ -2819,6 +3038,9 @@ async def main() -> None: "limit": limit, "name": name, "slug": slug, + "lastPublished": convert_and_respect_annotation_metadata( + object_=last_published, annotation=ItemsListItemsLiveRequestLastPublished, direction="write" + ), "sortBy": sort_by, "sortOrder": sort_order, }, @@ -2892,14 +3114,15 @@ async def create_item_live( self, collection_id: str, *, - request: ItemsCreateItemLiveRequest, + request: ItemsCreateItemLiveRequestBody, + skip_invalid_files: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> CollectionItem: """ - Create live Item(s) in a Collection. The Item(s) will be published to the live site. + Create item(s) in a collection that will be immediately published to the live site. - To create items across multiple locales, [please use this endpoint.](/v2.0.0/data/reference/cms/collection-items/staged-items/create-items) + To create items across multiple locales, [please use this endpoint.](/data/reference/cms/collection-items/staged-items/create-items) Required scope | `CMS:write` @@ -2909,7 +3132,10 @@ async def create_item_live( collection_id : str Unique identifier for a Collection - request : ItemsCreateItemLiveRequest + request : ItemsCreateItemLiveRequestBody + + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2933,12 +3159,13 @@ async def create_item_live( async def main() -> None: await client.collections.items.create_item_live( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, request=CollectionItem( is_archived=False, is_draft=False, field_data=CollectionItemFieldData( - name="Pan Galactic Gargle Blaster Recipe", - slug="pan-galactic-gargle-blaster", + name="The Hitchhiker's Guide to the Galaxy", + slug="hitchhikers-guide-to-the-galaxy", ), ), ) @@ -2948,9 +3175,13 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/live", + base_url=self._client_wrapper.get_environment().base, method="POST", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json=convert_and_respect_annotation_metadata( - object_=request, annotation=ItemsCreateItemLiveRequest, direction="write" + object_=request, annotation=ItemsCreateItemLiveRequestBody, direction="write" ), request_options=request_options, omit=OMIT, @@ -3023,13 +3254,13 @@ async def delete_items_live( self, collection_id: str, *, - items: typing.Optional[typing.Sequence[ItemsDeleteItemsLiveRequestItemsItem]] = OMIT, + items: typing.Sequence[ItemsDeleteItemsLiveRequestItemsItem], request_options: typing.Optional[RequestOptions] = None, ) -> None: """ - Remove an item or multiple items (up to 100 items) from the live site. Deleting published items will unpublish the items from the live site and set them to draft. + Unpublish up to 100 items from the live site and set the `isDraft` property to `true`. - **Note:** If the `cmsLocaleId` parameter is undefined or empty and the items are localized, items will be unpublished only in the primary locale. + Items will only be unpublished in the primary locale unless a `cmsLocaleId` is included in the request. Required scope | `CMS:write` @@ -3038,7 +3269,7 @@ async def delete_items_live( collection_id : str Unique identifier for a Collection - items : typing.Optional[typing.Sequence[ItemsDeleteItemsLiveRequestItemsItem]] + items : typing.Sequence[ItemsDeleteItemsLiveRequestItemsItem] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -3052,6 +3283,9 @@ async def delete_items_live( import asyncio from webflow import AsyncWebflow + from webflow.resources.collections.resources.items import ( + ItemsDeleteItemsLiveRequestItemsItem, + ) client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", @@ -3061,6 +3295,11 @@ async def delete_items_live( async def main() -> None: await client.collections.items.delete_items_live( collection_id="580e63fc8c9a982ac9b8b745", + items=[ + ItemsDeleteItemsLiveRequestItemsItem( + id="580e64008c9a982ac9b8b754", + ) + ], ) @@ -3068,6 +3307,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/live", + base_url=self._client_wrapper.get_environment().base, method="DELETE", json={ "items": convert_and_respect_annotation_metadata( @@ -3142,13 +3382,14 @@ async def update_items_live( self, collection_id: str, *, + skip_invalid_files: typing.Optional[bool] = None, items: typing.Optional[typing.Sequence[CollectionItemWithIdInput]] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> CollectionItemListNoPagination: """ - Update a single live item or multiple live items (up to 100) in a Collection + Update a single published item or multiple published items (up to 100) in a Collection - **Note:** If the `cmsLocaleId` parameter is undefined or empty and the items are localized, items will be updated only in the primary locale. + Items will only be updated in the primary locale, unless a `cmsLocaleId` is included in the request. Required scope | `CMS:write` @@ -3157,6 +3398,9 @@ async def update_items_live( collection_id : str Unique identifier for a Collection + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + items : typing.Optional[typing.Sequence[CollectionItemWithIdInput]] request_options : typing.Optional[RequestOptions] @@ -3185,6 +3429,7 @@ async def update_items_live( async def main() -> None: await client.collections.items.update_items_live( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, items=[ CollectionItemWithIdInput( id="66f6ed9576ddacf3149d5ea6", @@ -3226,7 +3471,11 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/live", + base_url=self._client_wrapper.get_environment().base, method="PATCH", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json={ "items": convert_and_respect_annotation_metadata( object_=items, annotation=typing.Sequence[CollectionItemWithIdInput], direction="write" @@ -3277,6 +3526,16 @@ async def main() -> None: ), ) ) + if _response.status_code == 409: + raise ConflictError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) if _response.status_code == 429: raise TooManyRequestsError( typing.cast( @@ -3307,6 +3566,7 @@ async def create_items( collection_id: str, *, field_data: CreateBulkCollectionItemRequestBodyFieldData, + skip_invalid_files: typing.Optional[bool] = None, cms_locale_ids: typing.Optional[typing.Sequence[str]] = OMIT, is_archived: typing.Optional[bool] = OMIT, is_draft: typing.Optional[bool] = OMIT, @@ -3315,9 +3575,10 @@ async def create_items( """ Create an item or multiple items in a CMS Collection across multiple corresponding locales. - **Notes:** + - This endpoint can create up to 100 items in a request. - - If the `cmsLocaleIds` parameter is undefined or empty and localization is enabled, items will only be created in the primary locale. + - If the `cmsLocaleIds` parameter is not included in the request, an item will only be created in the primary locale. + Required scope | `CMS:write` @@ -3328,6 +3589,9 @@ async def create_items( field_data : CreateBulkCollectionItemRequestBodyFieldData + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + cms_locale_ids : typing.Optional[typing.Sequence[str]] Array of identifiers for the locales where the item will be created @@ -3360,6 +3624,7 @@ async def create_items( async def main() -> None: await client.collections.items.create_items( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, cms_locale_ids=[ "66f6e966c9e1dc700a857ca3", "66f6e966c9e1dc700a857ca4", @@ -3378,7 +3643,11 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/bulk", + base_url=self._client_wrapper.get_environment().base, method="POST", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json={ "cmsLocaleIds": cms_locale_ids, "isArchived": is_archived, @@ -3504,6 +3773,7 @@ async def main() -> None: await client.collections.items.get_item( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + cms_locale_id="cmsLocaleId", ) @@ -3511,6 +3781,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "cmsLocaleId": cms_locale_id, @@ -3590,7 +3861,7 @@ async def delete_item( request_options: typing.Optional[RequestOptions] = None, ) -> None: """ - Delete an Item from a Collection. This endpoint does not currently support bulk deletion. + Delete an item from a collection. Required scope | `CMS:write` @@ -3627,6 +3898,7 @@ async def main() -> None: await client.collections.items.delete_item( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + cms_locale_id="cmsLocaleId", ) @@ -3634,6 +3906,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", params={ "cmsLocaleId": cms_locale_id, @@ -3703,6 +3976,7 @@ async def update_item( collection_id: str, item_id: str, *, + skip_invalid_files: typing.Optional[bool] = None, id: typing.Optional[str] = OMIT, cms_locale_id: typing.Optional[str] = OMIT, last_published: typing.Optional[str] = OMIT, @@ -3726,6 +4000,9 @@ async def update_item( item_id : str Unique identifier for an Item + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + id : typing.Optional[str] Unique identifier for the Item @@ -3772,11 +4049,12 @@ async def main() -> None: await client.collections.items.update_item( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + skip_invalid_files=True, is_archived=False, is_draft=False, field_data=CollectionItemPatchSingleFieldData( - name="Pan Galactic Gargle Blaster Recipe", - slug="pan-galactic-gargle-blaster", + name="The Hitchhiker's Guide to the Galaxy", + slug="hitchhikers-guide-to-the-galaxy", ), ) @@ -3785,7 +4063,11 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json={ "id": id, "cmsLocaleId": cms_locale_id, @@ -3876,6 +4158,10 @@ async def get_item_live( """ Get details of a selected Collection live Item. + + Serving data to applications in real-time? Use the Content Delivery API at `api-cdn.webflow.com` for better performance. The CDN-backed endpoint is optimized for high-volume reads, while the Data API is designed for writes and management operations. + + Required scope | `CMS:read` Parameters @@ -3912,6 +4198,7 @@ async def main() -> None: await client.collections.items.get_item_live( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + cms_locale_id="cmsLocaleId", ) @@ -3919,6 +4206,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/live", + base_url=self._client_wrapper.get_environment().data_api, method="GET", params={ "cmsLocaleId": cms_locale_id, @@ -3998,9 +4286,9 @@ async def delete_item_live( request_options: typing.Optional[RequestOptions] = None, ) -> None: """ - Remove a live item from the site. Removing a published item will unpublish the item from the live site and set it to draft. + Unpublish a live item from the site and set the `isDraft` property to `true`. - This endpoint does not currently support bulk deletion. + For bulk unpublishing, please use [this endpoint.](/data/v2.0.0/reference/cms/collection-items/live-items/delete-items-live) Required scope | `CMS:write` @@ -4037,6 +4325,7 @@ async def main() -> None: await client.collections.items.delete_item_live( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + cms_locale_id="cmsLocaleId", ) @@ -4044,6 +4333,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/live", + base_url=self._client_wrapper.get_environment().base, method="DELETE", params={ "cmsLocaleId": cms_locale_id, @@ -4113,6 +4403,7 @@ async def update_item_live( collection_id: str, item_id: str, *, + skip_invalid_files: typing.Optional[bool] = None, id: typing.Optional[str] = OMIT, cms_locale_id: typing.Optional[str] = OMIT, last_published: typing.Optional[str] = OMIT, @@ -4136,6 +4427,9 @@ async def update_item_live( item_id : str Unique identifier for an Item + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + id : typing.Optional[str] Unique identifier for the Item @@ -4182,11 +4476,12 @@ async def main() -> None: await client.collections.items.update_item_live( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + skip_invalid_files=True, is_archived=False, is_draft=False, field_data=CollectionItemPatchSingleFieldData( - name="Pan Galactic Gargle Blaster Recipe", - slug="pan-galactic-gargle-blaster", + name="The Hitchhiker's Guide to the Galaxy", + slug="hitchhikers-guide-to-the-galaxy", ), ) @@ -4195,7 +4490,11 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/live", + base_url=self._client_wrapper.get_environment().base, method="PATCH", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json={ "id": id, "cmsLocaleId": cms_locale_id, @@ -4250,6 +4549,16 @@ async def main() -> None: ), ) ) + if _response.status_code == 409: + raise ConflictError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) if _response.status_code == 429: raise TooManyRequestsError( typing.cast( @@ -4279,7 +4588,7 @@ async def publish_item( self, collection_id: str, *, - item_ids: typing.Sequence[str], + request: ItemsPublishItemRequest, request_options: typing.Optional[RequestOptions] = None, ) -> ItemsPublishItemResponse: """ @@ -4292,7 +4601,7 @@ async def publish_item( collection_id : str Unique identifier for a Collection - item_ids : typing.Sequence[str] + request : ItemsPublishItemRequest request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -4307,6 +4616,7 @@ async def publish_item( import asyncio from webflow import AsyncWebflow + from webflow.resources.collections.resources.items import ItemIDs client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", @@ -4316,7 +4626,13 @@ async def publish_item( async def main() -> None: await client.collections.items.publish_item( collection_id="580e63fc8c9a982ac9b8b745", - item_ids=["itemIds"], + request=ItemIDs( + item_ids=[ + "643fd856d66b6528195ee2ca", + "643fd856d66b6528195ee2cb", + "643fd856d66b6528195ee2cc", + ], + ), ) @@ -4324,13 +4640,11 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/publish", + base_url=self._client_wrapper.get_environment().base, method="POST", - json={ - "itemIds": item_ids, - }, - headers={ - "content-type": "application/json", - }, + json=convert_and_respect_annotation_metadata( + object_=request, annotation=ItemsPublishItemRequest, direction="write" + ), request_options=request_options, omit=OMIT, ) diff --git a/src/webflow/resources/collections/resources/items/types/__init__.py b/src/webflow/resources/collections/resources/items/types/__init__.py index 67040fb..2d9a604 100644 --- a/src/webflow/resources/collections/resources/items/types/__init__.py +++ b/src/webflow/resources/collections/resources/items/types/__init__.py @@ -2,15 +2,20 @@ from .create_bulk_collection_item_request_body_field_data import CreateBulkCollectionItemRequestBodyFieldData from .create_bulk_collection_item_request_body_field_data_item import CreateBulkCollectionItemRequestBodyFieldDataItem -from .items_create_item_live_request import ItemsCreateItemLiveRequest -from .items_create_item_request import ItemsCreateItemRequest +from .item_i_ds import ItemIDs +from .item_i_ds_with_locales import ItemIDsWithLocales +from .items_create_item_live_request_body import ItemsCreateItemLiveRequestBody +from .items_create_item_request_body import ItemsCreateItemRequestBody from .items_delete_items_live_request_items_item import ItemsDeleteItemsLiveRequestItemsItem from .items_delete_items_request_items_item import ItemsDeleteItemsRequestItemsItem from .items_list_items_live_request_sort_by import ItemsListItemsLiveRequestSortBy from .items_list_items_live_request_sort_order import ItemsListItemsLiveRequestSortOrder from .items_list_items_request_sort_by import ItemsListItemsRequestSortBy from .items_list_items_request_sort_order import ItemsListItemsRequestSortOrder +from .items_publish_item_request import ItemsPublishItemRequest +from .items_publish_item_request_items_items_item import ItemsPublishItemRequestItemsItemsItem from .items_publish_item_response import ItemsPublishItemResponse +from .items_update_items_response import ItemsUpdateItemsResponse from .multiple_items import MultipleItems from .multiple_live_items import MultipleLiveItems from .single_cms_item import SingleCmsItem @@ -18,15 +23,20 @@ __all__ = [ "CreateBulkCollectionItemRequestBodyFieldData", "CreateBulkCollectionItemRequestBodyFieldDataItem", - "ItemsCreateItemLiveRequest", - "ItemsCreateItemRequest", + "ItemIDs", + "ItemIDsWithLocales", + "ItemsCreateItemLiveRequestBody", + "ItemsCreateItemRequestBody", "ItemsDeleteItemsLiveRequestItemsItem", "ItemsDeleteItemsRequestItemsItem", "ItemsListItemsLiveRequestSortBy", "ItemsListItemsLiveRequestSortOrder", "ItemsListItemsRequestSortBy", "ItemsListItemsRequestSortOrder", + "ItemsPublishItemRequest", + "ItemsPublishItemRequestItemsItemsItem", "ItemsPublishItemResponse", + "ItemsUpdateItemsResponse", "MultipleItems", "MultipleLiveItems", "SingleCmsItem", diff --git a/src/webflow/resources/collections/resources/items/types/item_i_ds.py b/src/webflow/resources/collections/resources/items/types/item_i_ds.py new file mode 100644 index 0000000..b9b138e --- /dev/null +++ b/src/webflow/resources/collections/resources/items/types/item_i_ds.py @@ -0,0 +1,25 @@ +# This file was auto-generated by Fern from our API Definition. + +from ......core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ......core.serialization import FieldMetadata +from ......core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class ItemIDs(UniversalBaseModel): + """ + An array of Item IDs in a single locale + """ + + item_ids: typing_extensions.Annotated[typing.Optional[typing.List[str]], FieldMetadata(alias="itemIds")] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/resources/collections/resources/items/types/item_i_ds_with_locales.py b/src/webflow/resources/collections/resources/items/types/item_i_ds_with_locales.py new file mode 100644 index 0000000..ba98ae7 --- /dev/null +++ b/src/webflow/resources/collections/resources/items/types/item_i_ds_with_locales.py @@ -0,0 +1,24 @@ +# This file was auto-generated by Fern from our API Definition. + +from ......core.pydantic_utilities import UniversalBaseModel +import typing +from .items_publish_item_request_items_items_item import ItemsPublishItemRequestItemsItemsItem +from ......core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class ItemIDsWithLocales(UniversalBaseModel): + """ + An array of Item IDs with included `cmsLocaleIds` + """ + + items: typing.Optional[typing.List[ItemsPublishItemRequestItemsItemsItem]] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/resources/collections/resources/items/types/items_create_item_live_request.py b/src/webflow/resources/collections/resources/items/types/items_create_item_live_request_body.py similarity index 69% rename from src/webflow/resources/collections/resources/items/types/items_create_item_live_request.py rename to src/webflow/resources/collections/resources/items/types/items_create_item_live_request_body.py index dc2f963..348e0be 100644 --- a/src/webflow/resources/collections/resources/items/types/items_create_item_live_request.py +++ b/src/webflow/resources/collections/resources/items/types/items_create_item_live_request_body.py @@ -4,4 +4,4 @@ from ......types.collection_item import CollectionItem from .multiple_live_items import MultipleLiveItems -ItemsCreateItemLiveRequest = typing.Union[CollectionItem, MultipleLiveItems] +ItemsCreateItemLiveRequestBody = typing.Union[CollectionItem, MultipleLiveItems] diff --git a/src/webflow/resources/collections/resources/items/types/items_create_item_request.py b/src/webflow/resources/collections/resources/items/types/items_create_item_request_body.py similarity index 70% rename from src/webflow/resources/collections/resources/items/types/items_create_item_request.py rename to src/webflow/resources/collections/resources/items/types/items_create_item_request_body.py index 7627c55..af4860a 100644 --- a/src/webflow/resources/collections/resources/items/types/items_create_item_request.py +++ b/src/webflow/resources/collections/resources/items/types/items_create_item_request_body.py @@ -4,4 +4,4 @@ from ......types.collection_item_post_single import CollectionItemPostSingle from .multiple_items import MultipleItems -ItemsCreateItemRequest = typing.Union[CollectionItemPostSingle, MultipleItems] +ItemsCreateItemRequestBody = typing.Union[CollectionItemPostSingle, MultipleItems] diff --git a/src/webflow/resources/collections/resources/items/types/items_delete_items_live_request_items_item.py b/src/webflow/resources/collections/resources/items/types/items_delete_items_live_request_items_item.py index 63e00bc..544df88 100644 --- a/src/webflow/resources/collections/resources/items/types/items_delete_items_live_request_items_item.py +++ b/src/webflow/resources/collections/resources/items/types/items_delete_items_live_request_items_item.py @@ -1,15 +1,15 @@ # This file was auto-generated by Fern from our API Definition. from ......core.pydantic_utilities import UniversalBaseModel -import typing_extensions -from ......core.serialization import FieldMetadata import pydantic +import typing_extensions import typing +from ......core.serialization import FieldMetadata from ......core.pydantic_utilities import IS_PYDANTIC_V2 class ItemsDeleteItemsLiveRequestItemsItem(UniversalBaseModel): - item_id: typing_extensions.Annotated[str, FieldMetadata(alias="itemId")] = pydantic.Field() + id: str = pydantic.Field() """ Unique identifier for the Item """ diff --git a/src/webflow/resources/collections/resources/items/types/items_publish_item_request.py b/src/webflow/resources/collections/resources/items/types/items_publish_item_request.py new file mode 100644 index 0000000..4f7a82b --- /dev/null +++ b/src/webflow/resources/collections/resources/items/types/items_publish_item_request.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from .item_i_ds import ItemIDs +from .item_i_ds_with_locales import ItemIDsWithLocales + +ItemsPublishItemRequest = typing.Union[ItemIDs, ItemIDsWithLocales] diff --git a/src/webflow/resources/collections/resources/items/types/items_publish_item_request_items_items_item.py b/src/webflow/resources/collections/resources/items/types/items_publish_item_request_items_items_item.py new file mode 100644 index 0000000..08b2e17 --- /dev/null +++ b/src/webflow/resources/collections/resources/items/types/items_publish_item_request_items_items_item.py @@ -0,0 +1,31 @@ +# This file was auto-generated by Fern from our API Definition. + +from ......core.pydantic_utilities import UniversalBaseModel +import pydantic +import typing_extensions +import typing +from ......core.serialization import FieldMetadata +from ......core.pydantic_utilities import IS_PYDANTIC_V2 + + +class ItemsPublishItemRequestItemsItemsItem(UniversalBaseModel): + id: str = pydantic.Field() + """ + The ID of the CMS item + """ + + cms_locale_ids: typing_extensions.Annotated[ + typing.Optional[typing.List[str]], FieldMetadata(alias="cmsLocaleIds") + ] = pydantic.Field(default=None) + """ + Array of identifiers for the locales where the item will be published + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/resources/collections/resources/items/types/items_update_items_response.py b/src/webflow/resources/collections/resources/items/types/items_update_items_response.py new file mode 100644 index 0000000..c073f18 --- /dev/null +++ b/src/webflow/resources/collections/resources/items/types/items_update_items_response.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from ......types.collection_item import CollectionItem +from ......types.collection_item_list import CollectionItemList + +ItemsUpdateItemsResponse = typing.Union[CollectionItem, CollectionItemList] diff --git a/src/webflow/resources/components/client.py b/src/webflow/resources/components/client.py index ef50ac9..f4b008e 100644 --- a/src/webflow/resources/components/client.py +++ b/src/webflow/resources/components/client.py @@ -36,6 +36,7 @@ def list( self, site_id: str, *, + branch_id: typing.Optional[str] = None, limit: typing.Optional[float] = None, offset: typing.Optional[float] = None, request_options: typing.Optional[RequestOptions] = None, @@ -50,6 +51,9 @@ def list( site_id : str Unique identifier for a Site + branch_id : typing.Optional[str] + Scope the operation to work on a specific branch. + limit : typing.Optional[float] Maximum number of records to be returned (max limit: 100) @@ -73,12 +77,17 @@ def list( ) client.components.list( site_id="580e63e98c9a982ac9b8b741", + branch_id="68026fa68ef6dc744c75b833", + limit=1.1, + offset=1.1, ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/components", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ + "branchId": branch_id, "limit": limit, "offset": offset, }, @@ -154,12 +163,13 @@ def get_content( component_id: str, *, locale_id: typing.Optional[str] = None, + branch_id: typing.Optional[str] = None, limit: typing.Optional[float] = None, offset: typing.Optional[float] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ComponentDom: """ - Get static content from a component definition. This includes text nodes, image nodes and nested component instances. + Get static content from a component definition. This includes text nodes, image nodes, select nodes, text input nodes, submit button nodes, and nested component instances. To retrieve dynamic content set by component properties, use the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint. If you do not provide a Locale ID in your request, the response will return any content that can be localized from the Primary locale. @@ -175,7 +185,12 @@ def get_content( Unique identifier for a Component locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + branch_id : typing.Optional[str] + Scope the operation to work on a specific branch. limit : typing.Optional[float] Maximum number of records to be returned (max limit: 100) @@ -202,13 +217,18 @@ def get_content( site_id="580e63e98c9a982ac9b8b741", component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", locale_id="65427cf400e02b306eaa04a0", + branch_id="68026fa68ef6dc744c75b833", + limit=1.1, + offset=1.1, ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/components/{jsonable_encoder(component_id)}/dom", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "localeId": locale_id, + "branchId": branch_id, "limit": limit, "offset": offset, }, @@ -285,14 +305,16 @@ def update_content( *, nodes: typing.Sequence[ComponentDomWriteNodesItem], locale_id: typing.Optional[str] = None, + branch_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ComponentsUpdateContentResponse: """ This endpoint updates content within a component defintion for **secondary locales**. It supports updating up to 1000 nodes in a single request. Before making updates: - 1. Use the [get component content](/data/reference/pages-and-components/components/get-content) endpoint to identify available content nodes and their types - 2. If your component definition has a component instance nested within it, retrieve the nested component instance's properties that you'll override using the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint + 1. Use the [get component content](/data/reference/pages-and-components/components/get-content) endpoint to identify available content nodes and their types. + 2. If your component definition has a component instance nested within it, retrieve the nested component instance's properties that you'll override using the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint. + 3. DOM elements may include a `data-w-id` attribute. This attribute is used by Webflow to maintain custom attributes and links across locales. Always include the original `data-w-id` value in your update requests to ensure consistent behavior across all locales. This endpoint is specifically for localizing component definitions. Ensure that the specified `localeId` is a valid **secondary locale** for the site otherwise the request will fail. @@ -312,7 +334,12 @@ def update_content( List of DOM Nodes with the new content that will be updated in each node. locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + branch_id : typing.Optional[str] + Scope the operation to work on a specific branch. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -327,6 +354,10 @@ def update_content( from webflow import ( ComponentInstanceNodePropertyOverridesWrite, ComponentInstanceNodePropertyOverridesWritePropertyOverridesItem, + Select, + SelectNodeWriteChoicesItem, + SubmitButtonNodeWrite, + TextInputNodeWrite, TextNodeWrite, Webflow, ) @@ -338,6 +369,7 @@ def update_content( site_id="580e63e98c9a982ac9b8b741", component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", locale_id="65427cf400e02b306eaa04a0", + branch_id="68026fa68ef6dc744c75b833", nodes=[ TextNodeWrite( node_id="a245c12d-995b-55ee-5ec7-aa36a6cad623", @@ -347,6 +379,28 @@ def update_content( node_id="a245c12d-995b-55ee-5ec7-aa36a6cad627", text="

Don't Panic!

Always know where your towel is.

", ), + Select( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad635", + choices=[ + SelectNodeWriteChoicesItem( + value="choice-1", + text="First choice", + ), + SelectNodeWriteChoicesItem( + value="choice-2", + text="Second choice", + ), + ], + ), + TextInputNodeWrite( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad642", + placeholder="Enter something here...", + ), + SubmitButtonNodeWrite( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad671", + value="Submit", + waiting_text="Submitting...", + ), ComponentInstanceNodePropertyOverridesWrite( node_id="a245c12d-995b-55ee-5ec7-aa36a6cad629", property_overrides=[ @@ -365,9 +419,11 @@ def update_content( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/components/{jsonable_encoder(component_id)}/dom", + base_url=self._client_wrapper.get_environment().base, method="POST", params={ "localeId": locale_id, + "branchId": branch_id, }, json={ "nodes": convert_and_respect_annotation_metadata( @@ -460,14 +516,15 @@ def get_properties( component_id: str, *, locale_id: typing.Optional[str] = None, + branch_id: typing.Optional[str] = None, limit: typing.Optional[float] = None, offset: typing.Optional[float] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ComponentProperties: """ - Get the property default values of a component definition. + Get the default property values of a component definition. - If you do not provide a Locale ID in your request, the response will return any properties that can be localized from the Primary locale. + If you do not include a `localeId` in your request, the response will return any properties that can be localized from the Primary locale. Required scope | `components:read` @@ -480,7 +537,12 @@ def get_properties( Unique identifier for a Component locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + branch_id : typing.Optional[str] + Scope the operation to work on a specific branch. limit : typing.Optional[float] Maximum number of records to be returned (max limit: 100) @@ -507,13 +569,18 @@ def get_properties( site_id="580e63e98c9a982ac9b8b741", component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", locale_id="65427cf400e02b306eaa04a0", + branch_id="68026fa68ef6dc744c75b833", + limit=1.1, + offset=1.1, ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/components/{jsonable_encoder(component_id)}/properties", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "localeId": locale_id, + "branchId": branch_id, "limit": limit, "offset": offset, }, @@ -590,15 +657,17 @@ def update_properties( *, properties: typing.Sequence[ComponentPropertiesWritePropertiesItem], locale_id: typing.Optional[str] = None, + branch_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ComponentsUpdatePropertiesResponse: """ - Update the property default values of a component definition in a specificed locale. + Update the default property values of a component definition in a specificed locale. Before making updates: - 1. Use the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint to identify available properties + 1. Use the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint to identify properties that can be updated in a secondary locale. + 2. Rich Text properties may include a `data-w-id` attribute. This attribute is used by Webflow to maintain links across locales. Always include the original `data-w-id` value in your update requests to ensure consistent behavior across all locales. - The request requires a secondary locale ID. If a locale is missing, the request will not be processed and will result in an error. + The request requires a secondary locale ID. If a `localeId` is missing, the request will not be processed and will result in an error. Required scope | `components:write` @@ -614,7 +683,12 @@ def update_properties( A list of component properties to update within the specified secondary locale. locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + branch_id : typing.Optional[str] + Scope the operation to work on a specific branch. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -636,6 +710,7 @@ def update_properties( site_id="580e63e98c9a982ac9b8b741", component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", locale_id="65427cf400e02b306eaa04a0", + branch_id="68026fa68ef6dc744c75b833", properties=[ ComponentPropertiesWritePropertiesItem( property_id="a245c12d-995b-55ee-5ec7-aa36a6cad623", @@ -650,9 +725,11 @@ def update_properties( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/components/{jsonable_encoder(component_id)}/properties", + base_url=self._client_wrapper.get_environment().base, method="POST", params={ "localeId": locale_id, + "branchId": branch_id, }, json={ "properties": convert_and_respect_annotation_metadata( @@ -740,6 +817,7 @@ async def list( self, site_id: str, *, + branch_id: typing.Optional[str] = None, limit: typing.Optional[float] = None, offset: typing.Optional[float] = None, request_options: typing.Optional[RequestOptions] = None, @@ -754,6 +832,9 @@ async def list( site_id : str Unique identifier for a Site + branch_id : typing.Optional[str] + Scope the operation to work on a specific branch. + limit : typing.Optional[float] Maximum number of records to be returned (max limit: 100) @@ -782,6 +863,9 @@ async def list( async def main() -> None: await client.components.list( site_id="580e63e98c9a982ac9b8b741", + branch_id="68026fa68ef6dc744c75b833", + limit=1.1, + offset=1.1, ) @@ -789,8 +873,10 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/components", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ + "branchId": branch_id, "limit": limit, "offset": offset, }, @@ -866,12 +952,13 @@ async def get_content( component_id: str, *, locale_id: typing.Optional[str] = None, + branch_id: typing.Optional[str] = None, limit: typing.Optional[float] = None, offset: typing.Optional[float] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ComponentDom: """ - Get static content from a component definition. This includes text nodes, image nodes and nested component instances. + Get static content from a component definition. This includes text nodes, image nodes, select nodes, text input nodes, submit button nodes, and nested component instances. To retrieve dynamic content set by component properties, use the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint. If you do not provide a Locale ID in your request, the response will return any content that can be localized from the Primary locale. @@ -887,7 +974,12 @@ async def get_content( Unique identifier for a Component locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + branch_id : typing.Optional[str] + Scope the operation to work on a specific branch. limit : typing.Optional[float] Maximum number of records to be returned (max limit: 100) @@ -919,6 +1011,9 @@ async def main() -> None: site_id="580e63e98c9a982ac9b8b741", component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", locale_id="65427cf400e02b306eaa04a0", + branch_id="68026fa68ef6dc744c75b833", + limit=1.1, + offset=1.1, ) @@ -926,9 +1021,11 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/components/{jsonable_encoder(component_id)}/dom", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "localeId": locale_id, + "branchId": branch_id, "limit": limit, "offset": offset, }, @@ -1005,14 +1102,16 @@ async def update_content( *, nodes: typing.Sequence[ComponentDomWriteNodesItem], locale_id: typing.Optional[str] = None, + branch_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ComponentsUpdateContentResponse: """ This endpoint updates content within a component defintion for **secondary locales**. It supports updating up to 1000 nodes in a single request. Before making updates: - 1. Use the [get component content](/data/reference/pages-and-components/components/get-content) endpoint to identify available content nodes and their types - 2. If your component definition has a component instance nested within it, retrieve the nested component instance's properties that you'll override using the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint + 1. Use the [get component content](/data/reference/pages-and-components/components/get-content) endpoint to identify available content nodes and their types. + 2. If your component definition has a component instance nested within it, retrieve the nested component instance's properties that you'll override using the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint. + 3. DOM elements may include a `data-w-id` attribute. This attribute is used by Webflow to maintain custom attributes and links across locales. Always include the original `data-w-id` value in your update requests to ensure consistent behavior across all locales. This endpoint is specifically for localizing component definitions. Ensure that the specified `localeId` is a valid **secondary locale** for the site otherwise the request will fail. @@ -1032,7 +1131,12 @@ async def update_content( List of DOM Nodes with the new content that will be updated in each node. locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + branch_id : typing.Optional[str] + Scope the operation to work on a specific branch. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1050,6 +1154,10 @@ async def update_content( AsyncWebflow, ComponentInstanceNodePropertyOverridesWrite, ComponentInstanceNodePropertyOverridesWritePropertyOverridesItem, + Select, + SelectNodeWriteChoicesItem, + SubmitButtonNodeWrite, + TextInputNodeWrite, TextNodeWrite, ) @@ -1063,6 +1171,7 @@ async def main() -> None: site_id="580e63e98c9a982ac9b8b741", component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", locale_id="65427cf400e02b306eaa04a0", + branch_id="68026fa68ef6dc744c75b833", nodes=[ TextNodeWrite( node_id="a245c12d-995b-55ee-5ec7-aa36a6cad623", @@ -1072,6 +1181,28 @@ async def main() -> None: node_id="a245c12d-995b-55ee-5ec7-aa36a6cad627", text="

Don't Panic!

Always know where your towel is.

", ), + Select( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad635", + choices=[ + SelectNodeWriteChoicesItem( + value="choice-1", + text="First choice", + ), + SelectNodeWriteChoicesItem( + value="choice-2", + text="Second choice", + ), + ], + ), + TextInputNodeWrite( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad642", + placeholder="Enter something here...", + ), + SubmitButtonNodeWrite( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad671", + value="Submit", + waiting_text="Submitting...", + ), ComponentInstanceNodePropertyOverridesWrite( node_id="a245c12d-995b-55ee-5ec7-aa36a6cad629", property_overrides=[ @@ -1093,9 +1224,11 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/components/{jsonable_encoder(component_id)}/dom", + base_url=self._client_wrapper.get_environment().base, method="POST", params={ "localeId": locale_id, + "branchId": branch_id, }, json={ "nodes": convert_and_respect_annotation_metadata( @@ -1188,14 +1321,15 @@ async def get_properties( component_id: str, *, locale_id: typing.Optional[str] = None, + branch_id: typing.Optional[str] = None, limit: typing.Optional[float] = None, offset: typing.Optional[float] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ComponentProperties: """ - Get the property default values of a component definition. + Get the default property values of a component definition. - If you do not provide a Locale ID in your request, the response will return any properties that can be localized from the Primary locale. + If you do not include a `localeId` in your request, the response will return any properties that can be localized from the Primary locale. Required scope | `components:read` @@ -1208,7 +1342,12 @@ async def get_properties( Unique identifier for a Component locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + branch_id : typing.Optional[str] + Scope the operation to work on a specific branch. limit : typing.Optional[float] Maximum number of records to be returned (max limit: 100) @@ -1240,6 +1379,9 @@ async def main() -> None: site_id="580e63e98c9a982ac9b8b741", component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", locale_id="65427cf400e02b306eaa04a0", + branch_id="68026fa68ef6dc744c75b833", + limit=1.1, + offset=1.1, ) @@ -1247,9 +1389,11 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/components/{jsonable_encoder(component_id)}/properties", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "localeId": locale_id, + "branchId": branch_id, "limit": limit, "offset": offset, }, @@ -1326,15 +1470,17 @@ async def update_properties( *, properties: typing.Sequence[ComponentPropertiesWritePropertiesItem], locale_id: typing.Optional[str] = None, + branch_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ComponentsUpdatePropertiesResponse: """ - Update the property default values of a component definition in a specificed locale. + Update the default property values of a component definition in a specificed locale. Before making updates: - 1. Use the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint to identify available properties + 1. Use the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint to identify properties that can be updated in a secondary locale. + 2. Rich Text properties may include a `data-w-id` attribute. This attribute is used by Webflow to maintain links across locales. Always include the original `data-w-id` value in your update requests to ensure consistent behavior across all locales. - The request requires a secondary locale ID. If a locale is missing, the request will not be processed and will result in an error. + The request requires a secondary locale ID. If a `localeId` is missing, the request will not be processed and will result in an error. Required scope | `components:write` @@ -1350,7 +1496,12 @@ async def update_properties( A list of component properties to update within the specified secondary locale. locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + branch_id : typing.Optional[str] + Scope the operation to work on a specific branch. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1377,6 +1528,7 @@ async def main() -> None: site_id="580e63e98c9a982ac9b8b741", component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", locale_id="65427cf400e02b306eaa04a0", + branch_id="68026fa68ef6dc744c75b833", properties=[ ComponentPropertiesWritePropertiesItem( property_id="a245c12d-995b-55ee-5ec7-aa36a6cad623", @@ -1394,9 +1546,11 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/components/{jsonable_encoder(component_id)}/properties", + base_url=self._client_wrapper.get_environment().base, method="POST", params={ "localeId": locale_id, + "branchId": branch_id, }, json={ "properties": convert_and_respect_annotation_metadata( diff --git a/src/webflow/resources/components/types/component_dom_write_nodes_item.py b/src/webflow/resources/components/types/component_dom_write_nodes_item.py index 27888e6..1b1789c 100644 --- a/src/webflow/resources/components/types/component_dom_write_nodes_item.py +++ b/src/webflow/resources/components/types/component_dom_write_nodes_item.py @@ -3,5 +3,16 @@ import typing from ....types.text_node_write import TextNodeWrite from ....types.component_instance_node_property_overrides_write import ComponentInstanceNodePropertyOverridesWrite +from ....types.select import Select +from ....types.text_input_node_write import TextInputNodeWrite +from ....types.submit_button_node_write import SubmitButtonNodeWrite +from ....types.search_button_node_write import SearchButtonNodeWrite -ComponentDomWriteNodesItem = typing.Union[TextNodeWrite, ComponentInstanceNodePropertyOverridesWrite] +ComponentDomWriteNodesItem = typing.Union[ + TextNodeWrite, + ComponentInstanceNodePropertyOverridesWrite, + Select, + TextInputNodeWrite, + SubmitButtonNodeWrite, + SearchButtonNodeWrite, +] diff --git a/src/webflow/resources/ecommerce/client.py b/src/webflow/resources/ecommerce/client.py index bbd3a5d..04ddba6 100644 --- a/src/webflow/resources/ecommerce/client.py +++ b/src/webflow/resources/ecommerce/client.py @@ -57,6 +57,7 @@ def get_settings( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/ecommerce/settings", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -191,6 +192,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/ecommerce/settings", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) diff --git a/src/webflow/resources/forms/client.py b/src/webflow/resources/forms/client.py index 515b631..63d538e 100644 --- a/src/webflow/resources/forms/client.py +++ b/src/webflow/resources/forms/client.py @@ -70,10 +70,13 @@ def list( ) client.forms.list( site_id="580e63e98c9a982ac9b8b741", + limit=1.1, + offset=1.1, ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/forms", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "limit": limit, @@ -197,6 +200,7 @@ def get(self, form_id: str, *, request_options: typing.Optional[RequestOptions] """ _response = self._client_wrapper.httpx_client.request( f"forms/{jsonable_encoder(form_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -285,6 +289,12 @@ def list_submissions( """ List form submissions for a given form + + When a form is used in a component definition, each instance of the form is considered a unique form. + + To get a combined list of submissions for a form that appears across multiple component instances, use the [List Form Submissions by Site](/data/reference/forms/form-submissions/list-submissions-by-site) endpoint. + + Required scope | `forms:read` Parameters @@ -315,10 +325,13 @@ def list_submissions( ) client.forms.list_submissions( form_id="580e63e98c9a982ac9b8b741", + offset=1.1, + limit=1.1, ) """ _response = self._client_wrapper.httpx_client.request( f"forms/{jsonable_encoder(form_id)}/submissions", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "offset": offset, @@ -434,6 +447,7 @@ def get_submission( """ _response = self._client_wrapper.httpx_client.request( f"form_submissions/{jsonable_encoder(form_submission_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -511,6 +525,122 @@ def get_submission( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) + def delete_submission( + self, form_submission_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> None: + """ + Delete a form submission + + + Required scope | `forms:write` + + Parameters + ---------- + form_submission_id : str + Unique identifier for a Form Submission + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + from webflow import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.forms.delete_submission( + form_submission_id="580e63e98c9a982ac9b8b741", + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"form_submissions/{jsonable_encoder(form_submission_id)}", + base_url=self._client_wrapper.get_environment().base, + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 403: + raise ForbiddenError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 409: + raise ConflictError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + def update_submission( self, form_submission_id: str, @@ -552,6 +682,7 @@ def update_submission( """ _response = self._client_wrapper.httpx_client.request( f"form_submissions/{jsonable_encoder(form_submission_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "formSubmissionData": form_submission_data, @@ -697,6 +828,8 @@ async def list( async def main() -> None: await client.forms.list( site_id="580e63e98c9a982ac9b8b741", + limit=1.1, + offset=1.1, ) @@ -704,6 +837,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/forms", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "limit": limit, @@ -835,6 +969,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"forms/{jsonable_encoder(form_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -923,6 +1058,12 @@ async def list_submissions( """ List form submissions for a given form + + When a form is used in a component definition, each instance of the form is considered a unique form. + + To get a combined list of submissions for a form that appears across multiple component instances, use the [List Form Submissions by Site](/data/reference/forms/form-submissions/list-submissions-by-site) endpoint. + + Required scope | `forms:read` Parameters @@ -958,6 +1099,8 @@ async def list_submissions( async def main() -> None: await client.forms.list_submissions( form_id="580e63e98c9a982ac9b8b741", + offset=1.1, + limit=1.1, ) @@ -965,6 +1108,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"forms/{jsonable_encoder(form_id)}/submissions", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "offset": offset, @@ -1088,6 +1232,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"form_submissions/{jsonable_encoder(form_submission_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -1165,6 +1310,130 @@ async def main() -> None: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) + async def delete_submission( + self, form_submission_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> None: + """ + Delete a form submission + + + Required scope | `forms:write` + + Parameters + ---------- + form_submission_id : str + Unique identifier for a Form Submission + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + import asyncio + + from webflow import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + + + async def main() -> None: + await client.forms.delete_submission( + form_submission_id="580e63e98c9a982ac9b8b741", + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"form_submissions/{jsonable_encoder(form_submission_id)}", + base_url=self._client_wrapper.get_environment().base, + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 403: + raise ForbiddenError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 409: + raise ConflictError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + async def update_submission( self, form_submission_id: str, @@ -1214,6 +1483,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"form_submissions/{jsonable_encoder(form_submission_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "formSubmissionData": form_submission_data, diff --git a/src/webflow/resources/inventory/__init__.py b/src/webflow/resources/inventory/__init__.py index f95deee..e76ae2e 100644 --- a/src/webflow/resources/inventory/__init__.py +++ b/src/webflow/resources/inventory/__init__.py @@ -1,5 +1,5 @@ # This file was auto-generated by Fern from our API Definition. -from .types import InventoryUpdateRequestInventoryType +from .types import EcommInventoryChangedPayload, InventoryUpdateRequestInventoryType -__all__ = ["InventoryUpdateRequestInventoryType"] +__all__ = ["EcommInventoryChangedPayload", "InventoryUpdateRequestInventoryType"] diff --git a/src/webflow/resources/inventory/client.py b/src/webflow/resources/inventory/client.py index 27e4f3c..db582a9 100644 --- a/src/webflow/resources/inventory/client.py +++ b/src/webflow/resources/inventory/client.py @@ -28,7 +28,7 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper def list( - self, collection_id: str, item_id: str, *, request_options: typing.Optional[RequestOptions] = None + self, sku_collection_id: str, sku_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> InventoryItem: """ List the current inventory levels for a particular SKU item. @@ -37,11 +37,11 @@ def list( Parameters ---------- - collection_id : str - Unique identifier for a Collection + sku_collection_id : str + Unique identifier for a SKU collection. Use the List Collections API to find this ID. - item_id : str - Unique identifier for an Item + sku_id : str + Unique identifier for a SKU request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -59,12 +59,13 @@ def list( access_token="YOUR_ACCESS_TOKEN", ) client.inventory.list( - collection_id="580e63fc8c9a982ac9b8b745", - item_id="580e64008c9a982ac9b8b754", + sku_collection_id="6377a7c4b7a79608c34a46f7", + sku_id="5e8518516e147040726cc415", ) """ _response = self._client_wrapper.httpx_client.request( - f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/inventory", + f"collections/{jsonable_encoder(sku_collection_id)}/items/{jsonable_encoder(sku_id)}/inventory", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -154,8 +155,8 @@ def list( def update( self, - collection_id: str, - item_id: str, + sku_collection_id: str, + sku_id: str, *, inventory_type: InventoryUpdateRequestInventoryType, update_quantity: typing.Optional[float] = OMIT, @@ -173,11 +174,11 @@ def update( Parameters ---------- - collection_id : str - Unique identifier for a Collection + sku_collection_id : str + Unique identifier for a SKU collection. Use the List Collections API to find this ID. - item_id : str - Unique identifier for an Item + sku_id : str + Unique identifier for a SKU inventory_type : InventoryUpdateRequestInventoryType infinite or finite @@ -204,13 +205,14 @@ def update( access_token="YOUR_ACCESS_TOKEN", ) client.inventory.update( - collection_id="580e63fc8c9a982ac9b8b745", - item_id="580e64008c9a982ac9b8b754", + sku_collection_id="6377a7c4b7a79608c34a46f7", + sku_id="5e8518516e147040726cc415", inventory_type="infinite", ) """ _response = self._client_wrapper.httpx_client.request( - f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/inventory", + f"collections/{jsonable_encoder(sku_collection_id)}/items/{jsonable_encoder(sku_id)}/inventory", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "inventoryType": inventory_type, @@ -313,7 +315,7 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper async def list( - self, collection_id: str, item_id: str, *, request_options: typing.Optional[RequestOptions] = None + self, sku_collection_id: str, sku_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> InventoryItem: """ List the current inventory levels for a particular SKU item. @@ -322,11 +324,11 @@ async def list( Parameters ---------- - collection_id : str - Unique identifier for a Collection + sku_collection_id : str + Unique identifier for a SKU collection. Use the List Collections API to find this ID. - item_id : str - Unique identifier for an Item + sku_id : str + Unique identifier for a SKU request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -349,15 +351,16 @@ async def list( async def main() -> None: await client.inventory.list( - collection_id="580e63fc8c9a982ac9b8b745", - item_id="580e64008c9a982ac9b8b754", + sku_collection_id="6377a7c4b7a79608c34a46f7", + sku_id="5e8518516e147040726cc415", ) asyncio.run(main()) """ _response = await self._client_wrapper.httpx_client.request( - f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/inventory", + f"collections/{jsonable_encoder(sku_collection_id)}/items/{jsonable_encoder(sku_id)}/inventory", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -447,8 +450,8 @@ async def main() -> None: async def update( self, - collection_id: str, - item_id: str, + sku_collection_id: str, + sku_id: str, *, inventory_type: InventoryUpdateRequestInventoryType, update_quantity: typing.Optional[float] = OMIT, @@ -466,11 +469,11 @@ async def update( Parameters ---------- - collection_id : str - Unique identifier for a Collection + sku_collection_id : str + Unique identifier for a SKU collection. Use the List Collections API to find this ID. - item_id : str - Unique identifier for an Item + sku_id : str + Unique identifier for a SKU inventory_type : InventoryUpdateRequestInventoryType infinite or finite @@ -502,8 +505,8 @@ async def update( async def main() -> None: await client.inventory.update( - collection_id="580e63fc8c9a982ac9b8b745", - item_id="580e64008c9a982ac9b8b754", + sku_collection_id="6377a7c4b7a79608c34a46f7", + sku_id="5e8518516e147040726cc415", inventory_type="infinite", ) @@ -511,7 +514,8 @@ async def main() -> None: asyncio.run(main()) """ _response = await self._client_wrapper.httpx_client.request( - f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/inventory", + f"collections/{jsonable_encoder(sku_collection_id)}/items/{jsonable_encoder(sku_id)}/inventory", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "inventoryType": inventory_type, diff --git a/src/webflow/resources/inventory/types/__init__.py b/src/webflow/resources/inventory/types/__init__.py index e929f4e..4cf7822 100644 --- a/src/webflow/resources/inventory/types/__init__.py +++ b/src/webflow/resources/inventory/types/__init__.py @@ -1,5 +1,6 @@ # This file was auto-generated by Fern from our API Definition. +from .ecomm_inventory_changed_payload import EcommInventoryChangedPayload from .inventory_update_request_inventory_type import InventoryUpdateRequestInventoryType -__all__ = ["InventoryUpdateRequestInventoryType"] +__all__ = ["EcommInventoryChangedPayload", "InventoryUpdateRequestInventoryType"] diff --git a/src/webflow/resources/inventory/types/ecomm_inventory_changed_payload.py b/src/webflow/resources/inventory/types/ecomm_inventory_changed_payload.py new file mode 100644 index 0000000..f4a969e --- /dev/null +++ b/src/webflow/resources/inventory/types/ecomm_inventory_changed_payload.py @@ -0,0 +1,25 @@ +# This file was auto-generated by Fern from our API Definition. + +from ....core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ....core.serialization import FieldMetadata +from ....types.inventory_item import InventoryItem +from ....core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class EcommInventoryChangedPayload(UniversalBaseModel): + trigger_type: typing_extensions.Annotated[ + typing.Optional[typing.Literal["ecomm_inventory_changed"]], FieldMetadata(alias="triggerType") + ] = None + payload: typing.Optional[InventoryItem] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/resources/orders/client.py b/src/webflow/resources/orders/client.py index 4aa4b77..89e5693 100644 --- a/src/webflow/resources/orders/client.py +++ b/src/webflow/resources/orders/client.py @@ -74,10 +74,14 @@ def list( ) client.orders.list( site_id="580e63e98c9a982ac9b8b741", + status="pending", + offset=1.1, + limit=1.1, ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/orders", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "status": status, @@ -207,6 +211,7 @@ def get(self, site_id: str, order_id: str, *, request_options: typing.Optional[R """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -354,6 +359,7 @@ def update( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "comment": comment, @@ -497,6 +503,7 @@ def update_fulfill( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}/fulfill", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "sendOrderFulfilledEmail": send_order_fulfilled_email, @@ -629,6 +636,7 @@ def update_unfulfill( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}/unfulfill", + base_url=self._client_wrapper.get_environment().base, method="POST", request_options=request_options, ) @@ -763,6 +771,7 @@ def refund( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}/refund", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "reason": reason, @@ -912,6 +921,9 @@ async def list( async def main() -> None: await client.orders.list( site_id="580e63e98c9a982ac9b8b741", + status="pending", + offset=1.1, + limit=1.1, ) @@ -919,6 +931,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/orders", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "status": status, @@ -1058,6 +1071,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -1213,6 +1227,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "comment": comment, @@ -1364,6 +1379,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}/fulfill", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "sendOrderFulfilledEmail": send_order_fulfilled_email, @@ -1504,6 +1520,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}/unfulfill", + base_url=self._client_wrapper.get_environment().base, method="POST", request_options=request_options, ) @@ -1646,6 +1663,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}/refund", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "reason": reason, diff --git a/src/webflow/resources/pages/__init__.py b/src/webflow/resources/pages/__init__.py index 0fed8e6..898d3de 100644 --- a/src/webflow/resources/pages/__init__.py +++ b/src/webflow/resources/pages/__init__.py @@ -1,6 +1,12 @@ # This file was auto-generated by Fern from our API Definition. -from .types import PageDomWriteNodesItem, UpdateStaticContentResponse +from .types import PageDomWriteNodesItem, PageMetadataWriteOpenGraph, PageMetadataWriteSeo, UpdateStaticContentResponse from .resources import scripts -__all__ = ["PageDomWriteNodesItem", "UpdateStaticContentResponse", "scripts"] +__all__ = [ + "PageDomWriteNodesItem", + "PageMetadataWriteOpenGraph", + "PageMetadataWriteSeo", + "UpdateStaticContentResponse", + "scripts", +] diff --git a/src/webflow/resources/pages/client.py b/src/webflow/resources/pages/client.py index 851f4e7..8f6a34d 100644 --- a/src/webflow/resources/pages/client.py +++ b/src/webflow/resources/pages/client.py @@ -16,9 +16,8 @@ from json.decoder import JSONDecodeError from ...core.api_error import ApiError from ...types.page import Page -import datetime as dt -from ...types.page_seo import PageSeo -from ...types.page_open_graph import PageOpenGraph +from .types.page_metadata_write_seo import PageMetadataWriteSeo +from .types.page_metadata_write_open_graph import PageMetadataWriteOpenGraph from ...core.serialization import convert_and_respect_annotation_metadata from ...types.dom import Dom from ...errors.forbidden_error import ForbiddenError @@ -56,7 +55,9 @@ def list( Unique identifier for a Site locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) limit : typing.Optional[float] Maximum number of records to be returned (max limit: 100) @@ -82,10 +83,13 @@ def list( client.pages.list( site_id="580e63e98c9a982ac9b8b741", locale_id="65427cf400e02b306eaa04a0", + limit=1.1, + offset=1.1, ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/pages", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "localeId": locale_id, @@ -176,7 +180,9 @@ def get_metadata( Unique identifier for a Page locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -200,6 +206,7 @@ def get_metadata( """ _response = self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "localeId": locale_id, @@ -274,24 +281,11 @@ def update_page_settings( self, page_id: str, *, - id: str, locale_id: typing.Optional[str] = None, - site_id: typing.Optional[str] = OMIT, title: typing.Optional[str] = OMIT, slug: typing.Optional[str] = OMIT, - parent_id: typing.Optional[str] = OMIT, - collection_id: typing.Optional[str] = OMIT, - created_on: typing.Optional[dt.datetime] = OMIT, - last_updated: typing.Optional[dt.datetime] = OMIT, - archived: typing.Optional[bool] = OMIT, - draft: typing.Optional[bool] = OMIT, - can_branch: typing.Optional[bool] = OMIT, - is_branch: typing.Optional[bool] = OMIT, - is_members_only: typing.Optional[bool] = OMIT, - seo: typing.Optional[PageSeo] = OMIT, - open_graph: typing.Optional[PageOpenGraph] = OMIT, - page_locale_id: typing.Optional[str] = OMIT, - published_path: typing.Optional[str] = OMIT, + seo: typing.Optional[PageMetadataWriteSeo] = OMIT, + open_graph: typing.Optional[PageMetadataWriteOpenGraph] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> Page: """ @@ -304,60 +298,26 @@ def update_page_settings( page_id : str Unique identifier for a Page - id : str - Unique identifier for the Page - locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. - site_id : typing.Optional[str] - Unique identifier for the Site + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) title : typing.Optional[str] - Title of the Page + Title for the page slug : typing.Optional[str] - slug of the Page (derived from title) - - parent_id : typing.Optional[str] - Identifier of the parent folder - - collection_id : typing.Optional[str] - Unique identifier for a linked Collection, value will be null if the Page is not part of a Collection. - - created_on : typing.Optional[dt.datetime] - The date the Page was created - - last_updated : typing.Optional[dt.datetime] - The date the Page was most recently updated - - archived : typing.Optional[bool] - Whether the Page has been archived + Slug for the page. - draft : typing.Optional[bool] - Whether the Page is a draft - can_branch : typing.Optional[bool] - Indicates whether the Page supports [Page Branching](https://university.webflow.com/lesson/page-branching) + **Note:** Updating slugs in secondary locales is only supported in Advanced and Enterprise localization add-on plans. - is_branch : typing.Optional[bool] - Indicates whether the Page is a Branch of another Page [Page Branching](https://university.webflow.com/lesson/page-branching) - - is_members_only : typing.Optional[bool] - Indicates whether the Page is restricted by [Memberships Controls](https://university.webflow.com/lesson/webflow-memberships-overview#how-to-manage-page-restrictions) - - seo : typing.Optional[PageSeo] + seo : typing.Optional[PageMetadataWriteSeo] SEO-related fields for the Page - open_graph : typing.Optional[PageOpenGraph] + open_graph : typing.Optional[PageMetadataWriteOpenGraph] Open Graph fields for the Page - page_locale_id : typing.Optional[str] - Unique ID of the page locale - - published_path : typing.Optional[str] - Relative path of the published page URL - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -368,9 +328,11 @@ def update_page_settings( Examples -------- - import datetime - - from webflow import PageOpenGraph, PageSeo, Webflow + from webflow import Webflow + from webflow.resources.pages import ( + PageMetadataWriteOpenGraph, + PageMetadataWriteSeo, + ) client = Webflow( access_token="YOUR_ACCESS_TOKEN", @@ -378,60 +340,39 @@ def update_page_settings( client.pages.update_page_settings( page_id="63c720f9347c2139b248e552", locale_id="65427cf400e02b306eaa04a0", - id="6596da6045e56dee495bcbba", - site_id="6258612d1ee792848f805dcf", title="Guide to the Galaxy", slug="guide-to-the-galaxy", - created_on=datetime.datetime.fromisoformat( - "2024-03-11 10:42:00+00:00", - ), - last_updated=datetime.datetime.fromisoformat( - "2024-03-11 10:42:42+00:00", - ), - archived=False, - draft=False, - can_branch=True, - is_branch=False, - seo=PageSeo( + seo=PageMetadataWriteSeo( title="The Ultimate Hitchhiker's Guide to the Galaxy", description="Everything you need to know about the galaxy, from avoiding Vogon poetry to the importance of towels.", ), - open_graph=PageOpenGraph( + open_graph=PageMetadataWriteOpenGraph( title="Explore the Cosmos with The Ultimate Guide", title_copied=False, description="Dive deep into the mysteries of the universe with your guide to everything galactic.", description_copied=False, ), - page_locale_id="653fd9af6a07fc9cfd7a5e57", - published_path="/en-us/guide-to-the-galaxy", ) """ _response = self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}", + base_url=self._client_wrapper.get_environment().base, method="PUT", params={ "localeId": locale_id, }, json={ - "id": id, - "siteId": site_id, "title": title, "slug": slug, - "parentId": parent_id, - "collectionId": collection_id, - "createdOn": created_on, - "lastUpdated": last_updated, - "archived": archived, - "draft": draft, - "canBranch": can_branch, - "isBranch": is_branch, - "isMembersOnly": is_members_only, - "seo": convert_and_respect_annotation_metadata(object_=seo, annotation=PageSeo, direction="write"), + "seo": convert_and_respect_annotation_metadata( + object_=seo, annotation=PageMetadataWriteSeo, direction="write" + ), "openGraph": convert_and_respect_annotation_metadata( - object_=open_graph, annotation=PageOpenGraph, direction="write" + object_=open_graph, annotation=PageMetadataWriteOpenGraph, direction="write" ), - "localeId": locale_id, - "publishedPath": published_path, + }, + headers={ + "content-type": "application/json", }, request_options=request_options, omit=OMIT, @@ -510,10 +451,9 @@ def get_content( request_options: typing.Optional[RequestOptions] = None, ) -> Dom: """ - Get static content from a static page. This includes text nodes, image nodes and component instances. - To retrieve the contents of components in the page use the [get component content](/data/reference/pages-and-components/components/get-content) endpoint. + Get text and component instance content from a static page. - If you do not provide a Locale ID in your request, the response will return any content that can be localized from the Primary locale. + Localization Required scope | `pages:read` @@ -523,7 +463,9 @@ def get_content( Unique identifier for a Page locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) limit : typing.Optional[float] Maximum number of records to be returned (max limit: 100) @@ -549,10 +491,13 @@ def get_content( client.pages.get_content( page_id="63c720f9347c2139b248e552", locale_id="65427cf400e02b306eaa04a0", + limit=1.1, + offset=1.1, ) """ _response = self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}/dom", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "localeId": locale_id, @@ -647,8 +592,9 @@ def update_static_content( This endpoint updates content on a static page in **secondary locales**. It supports updating up to 1000 nodes in a single request. Before making updates: - 1. Use the [get page content](/data/reference/pages-and-components/pages/get-content) endpoint to identify available content nodes and their types - 2. If the page has component instances, retrieve the component's properties that you'll override using the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint + 1. Use the [get page content](/data/reference/pages-and-components/pages/get-content) endpoint to identify available content nodes and their types. + 2. If the page has component instances, retrieve the component's properties that you'll override using the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint. + 3. DOM elements may include a `data-w-id` attribute. This attribute is used by Webflow to maintain custom attributes and links across locales. Always include the original `data-w-id` value in your update requests to ensure consistent behavior across all locales. This endpoint is specifically for localized pages. Ensure that the specified `localeId` is a valid **secondary locale** for the site otherwise the request will fail. @@ -680,6 +626,10 @@ def update_static_content( from webflow import ( ComponentInstanceNodePropertyOverridesWrite, ComponentInstanceNodePropertyOverridesWritePropertyOverridesItem, + Select, + SelectNodeWriteChoicesItem, + SubmitButtonNodeWrite, + TextInputNodeWrite, TextNodeWrite, Webflow, ) @@ -699,6 +649,28 @@ def update_static_content( node_id="a245c12d-995b-55ee-5ec7-aa36a6cad627", text="

Don't Panic!

Always know where your towel is.

", ), + Select( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad635", + choices=[ + SelectNodeWriteChoicesItem( + value="choice-1", + text="First choice", + ), + SelectNodeWriteChoicesItem( + value="choice-2", + text="Second choice", + ), + ], + ), + TextInputNodeWrite( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad642", + placeholder="Enter something here...", + ), + SubmitButtonNodeWrite( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad671", + value="Submit", + waiting_text="Submitting...", + ), ComponentInstanceNodePropertyOverridesWrite( node_id="a245c12d-995b-55ee-5ec7-aa36a6cad629", property_overrides=[ @@ -717,6 +689,7 @@ def update_static_content( """ _response = self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}/dom", + base_url=self._client_wrapper.get_environment().base, method="POST", params={ "localeId": locale_id, @@ -832,7 +805,9 @@ async def list( Unique identifier for a Site locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) limit : typing.Optional[float] Maximum number of records to be returned (max limit: 100) @@ -863,6 +838,8 @@ async def main() -> None: await client.pages.list( site_id="580e63e98c9a982ac9b8b741", locale_id="65427cf400e02b306eaa04a0", + limit=1.1, + offset=1.1, ) @@ -870,6 +847,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/pages", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "localeId": locale_id, @@ -960,7 +938,9 @@ async def get_metadata( Unique identifier for a Page locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -992,6 +972,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "localeId": locale_id, @@ -1066,24 +1047,11 @@ async def update_page_settings( self, page_id: str, *, - id: str, locale_id: typing.Optional[str] = None, - site_id: typing.Optional[str] = OMIT, title: typing.Optional[str] = OMIT, slug: typing.Optional[str] = OMIT, - parent_id: typing.Optional[str] = OMIT, - collection_id: typing.Optional[str] = OMIT, - created_on: typing.Optional[dt.datetime] = OMIT, - last_updated: typing.Optional[dt.datetime] = OMIT, - archived: typing.Optional[bool] = OMIT, - draft: typing.Optional[bool] = OMIT, - can_branch: typing.Optional[bool] = OMIT, - is_branch: typing.Optional[bool] = OMIT, - is_members_only: typing.Optional[bool] = OMIT, - seo: typing.Optional[PageSeo] = OMIT, - open_graph: typing.Optional[PageOpenGraph] = OMIT, - page_locale_id: typing.Optional[str] = OMIT, - published_path: typing.Optional[str] = OMIT, + seo: typing.Optional[PageMetadataWriteSeo] = OMIT, + open_graph: typing.Optional[PageMetadataWriteOpenGraph] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> Page: """ @@ -1096,60 +1064,26 @@ async def update_page_settings( page_id : str Unique identifier for a Page - id : str - Unique identifier for the Page - locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. - site_id : typing.Optional[str] - Unique identifier for the Site + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) title : typing.Optional[str] - Title of the Page + Title for the page slug : typing.Optional[str] - slug of the Page (derived from title) - - parent_id : typing.Optional[str] - Identifier of the parent folder - - collection_id : typing.Optional[str] - Unique identifier for a linked Collection, value will be null if the Page is not part of a Collection. - - created_on : typing.Optional[dt.datetime] - The date the Page was created - - last_updated : typing.Optional[dt.datetime] - The date the Page was most recently updated + Slug for the page. - archived : typing.Optional[bool] - Whether the Page has been archived - draft : typing.Optional[bool] - Whether the Page is a draft + **Note:** Updating slugs in secondary locales is only supported in Advanced and Enterprise localization add-on plans. - can_branch : typing.Optional[bool] - Indicates whether the Page supports [Page Branching](https://university.webflow.com/lesson/page-branching) - - is_branch : typing.Optional[bool] - Indicates whether the Page is a Branch of another Page [Page Branching](https://university.webflow.com/lesson/page-branching) - - is_members_only : typing.Optional[bool] - Indicates whether the Page is restricted by [Memberships Controls](https://university.webflow.com/lesson/webflow-memberships-overview#how-to-manage-page-restrictions) - - seo : typing.Optional[PageSeo] + seo : typing.Optional[PageMetadataWriteSeo] SEO-related fields for the Page - open_graph : typing.Optional[PageOpenGraph] + open_graph : typing.Optional[PageMetadataWriteOpenGraph] Open Graph fields for the Page - page_locale_id : typing.Optional[str] - Unique ID of the page locale - - published_path : typing.Optional[str] - Relative path of the published page URL - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1161,9 +1095,12 @@ async def update_page_settings( Examples -------- import asyncio - import datetime - from webflow import AsyncWebflow, PageOpenGraph, PageSeo + from webflow import AsyncWebflow + from webflow.resources.pages import ( + PageMetadataWriteOpenGraph, + PageMetadataWriteSeo, + ) client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", @@ -1174,32 +1111,18 @@ async def main() -> None: await client.pages.update_page_settings( page_id="63c720f9347c2139b248e552", locale_id="65427cf400e02b306eaa04a0", - id="6596da6045e56dee495bcbba", - site_id="6258612d1ee792848f805dcf", title="Guide to the Galaxy", slug="guide-to-the-galaxy", - created_on=datetime.datetime.fromisoformat( - "2024-03-11 10:42:00+00:00", - ), - last_updated=datetime.datetime.fromisoformat( - "2024-03-11 10:42:42+00:00", - ), - archived=False, - draft=False, - can_branch=True, - is_branch=False, - seo=PageSeo( + seo=PageMetadataWriteSeo( title="The Ultimate Hitchhiker's Guide to the Galaxy", description="Everything you need to know about the galaxy, from avoiding Vogon poetry to the importance of towels.", ), - open_graph=PageOpenGraph( + open_graph=PageMetadataWriteOpenGraph( title="Explore the Cosmos with The Ultimate Guide", title_copied=False, description="Dive deep into the mysteries of the universe with your guide to everything galactic.", description_copied=False, ), - page_locale_id="653fd9af6a07fc9cfd7a5e57", - published_path="/en-us/guide-to-the-galaxy", ) @@ -1207,30 +1130,23 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}", + base_url=self._client_wrapper.get_environment().base, method="PUT", params={ "localeId": locale_id, }, json={ - "id": id, - "siteId": site_id, "title": title, "slug": slug, - "parentId": parent_id, - "collectionId": collection_id, - "createdOn": created_on, - "lastUpdated": last_updated, - "archived": archived, - "draft": draft, - "canBranch": can_branch, - "isBranch": is_branch, - "isMembersOnly": is_members_only, - "seo": convert_and_respect_annotation_metadata(object_=seo, annotation=PageSeo, direction="write"), + "seo": convert_and_respect_annotation_metadata( + object_=seo, annotation=PageMetadataWriteSeo, direction="write" + ), "openGraph": convert_and_respect_annotation_metadata( - object_=open_graph, annotation=PageOpenGraph, direction="write" + object_=open_graph, annotation=PageMetadataWriteOpenGraph, direction="write" ), - "localeId": locale_id, - "publishedPath": published_path, + }, + headers={ + "content-type": "application/json", }, request_options=request_options, omit=OMIT, @@ -1309,10 +1225,9 @@ async def get_content( request_options: typing.Optional[RequestOptions] = None, ) -> Dom: """ - Get static content from a static page. This includes text nodes, image nodes and component instances. - To retrieve the contents of components in the page use the [get component content](/data/reference/pages-and-components/components/get-content) endpoint. + Get text and component instance content from a static page. - If you do not provide a Locale ID in your request, the response will return any content that can be localized from the Primary locale. + Localization Required scope | `pages:read` @@ -1322,7 +1237,9 @@ async def get_content( Unique identifier for a Page locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) limit : typing.Optional[float] Maximum number of records to be returned (max limit: 100) @@ -1353,6 +1270,8 @@ async def main() -> None: await client.pages.get_content( page_id="63c720f9347c2139b248e552", locale_id="65427cf400e02b306eaa04a0", + limit=1.1, + offset=1.1, ) @@ -1360,6 +1279,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}/dom", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "localeId": locale_id, @@ -1454,8 +1374,9 @@ async def update_static_content( This endpoint updates content on a static page in **secondary locales**. It supports updating up to 1000 nodes in a single request. Before making updates: - 1. Use the [get page content](/data/reference/pages-and-components/pages/get-content) endpoint to identify available content nodes and their types - 2. If the page has component instances, retrieve the component's properties that you'll override using the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint + 1. Use the [get page content](/data/reference/pages-and-components/pages/get-content) endpoint to identify available content nodes and their types. + 2. If the page has component instances, retrieve the component's properties that you'll override using the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint. + 3. DOM elements may include a `data-w-id` attribute. This attribute is used by Webflow to maintain custom attributes and links across locales. Always include the original `data-w-id` value in your update requests to ensure consistent behavior across all locales. This endpoint is specifically for localized pages. Ensure that the specified `localeId` is a valid **secondary locale** for the site otherwise the request will fail. @@ -1490,6 +1411,10 @@ async def update_static_content( AsyncWebflow, ComponentInstanceNodePropertyOverridesWrite, ComponentInstanceNodePropertyOverridesWritePropertyOverridesItem, + Select, + SelectNodeWriteChoicesItem, + SubmitButtonNodeWrite, + TextInputNodeWrite, TextNodeWrite, ) @@ -1511,6 +1436,28 @@ async def main() -> None: node_id="a245c12d-995b-55ee-5ec7-aa36a6cad627", text="

Don't Panic!

Always know where your towel is.

", ), + Select( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad635", + choices=[ + SelectNodeWriteChoicesItem( + value="choice-1", + text="First choice", + ), + SelectNodeWriteChoicesItem( + value="choice-2", + text="Second choice", + ), + ], + ), + TextInputNodeWrite( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad642", + placeholder="Enter something here...", + ), + SubmitButtonNodeWrite( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad671", + value="Submit", + waiting_text="Submitting...", + ), ComponentInstanceNodePropertyOverridesWrite( node_id="a245c12d-995b-55ee-5ec7-aa36a6cad629", property_overrides=[ @@ -1532,6 +1479,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}/dom", + base_url=self._client_wrapper.get_environment().base, method="POST", params={ "localeId": locale_id, diff --git a/src/webflow/resources/pages/resources/scripts/client.py b/src/webflow/resources/pages/resources/scripts/client.py index 56bd39a..cd1086f 100644 --- a/src/webflow/resources/pages/resources/scripts/client.py +++ b/src/webflow/resources/pages/resources/scripts/client.py @@ -31,13 +31,7 @@ def get_custom_code( self, page_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> ScriptApplyList: """ - Get all registered scripts that have been applied to a specific Page. - - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. - - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + Get all scripts applied to a page. Required scope | `custom_code:read` @@ -67,6 +61,7 @@ def get_custom_code( """ _response = self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}/custom_code", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -144,15 +139,11 @@ def upsert_custom_code( request_options: typing.Optional[RequestOptions] = None, ) -> ScriptApplyList: """ - Add a registered script to a Page. - - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. - - A site can have a maximum of 800 registered scripts. + Apply registered scripts to a page. If you have multiple scripts your App needs to apply or maintain on a page, ensure they are always included in the request body for this endpoint. To remove individual scripts, simply call this endpoint without the script in the request body. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a page, the script must first be registered to a Site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:write` @@ -204,6 +195,7 @@ def upsert_custom_code( """ _response = self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}/custom_code", + base_url=self._client_wrapper.get_environment().base, method="PUT", json={ "scripts": convert_and_respect_annotation_metadata( @@ -291,13 +283,11 @@ def upsert_custom_code( def delete_custom_code(self, page_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None: """ - Delete the custom code block that an app has created for a page + Remove all scripts from a page applied by the App. This endpoint will not remove scripts from the site's registered scripts. - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. + To remove individual scripts applied by the App, use the [Add/Update Custom Code](/data/reference/custom-code/custom-code-pages/upsert-custom-code) endpoint. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + Access to this endpoint requires a bearer token obtained from an [OAuth Code Grant Flow](/data/reference/oauth-app). Required scope | `custom_code:write` @@ -326,6 +316,7 @@ def delete_custom_code(self, page_id: str, *, request_options: typing.Optional[R """ _response = self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}/custom_code", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -396,13 +387,7 @@ async def get_custom_code( self, page_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> ScriptApplyList: """ - Get all registered scripts that have been applied to a specific Page. - - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. - - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + Get all scripts applied to a page. Required scope | `custom_code:read` @@ -440,6 +425,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}/custom_code", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -517,15 +503,11 @@ async def upsert_custom_code( request_options: typing.Optional[RequestOptions] = None, ) -> ScriptApplyList: """ - Add a registered script to a Page. - - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. - - A site can have a maximum of 800 registered scripts. + Apply registered scripts to a page. If you have multiple scripts your App needs to apply or maintain on a page, ensure they are always included in the request body for this endpoint. To remove individual scripts, simply call this endpoint without the script in the request body. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a page, the script must first be registered to a Site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:write` @@ -585,6 +567,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}/custom_code", + base_url=self._client_wrapper.get_environment().base, method="PUT", json={ "scripts": convert_and_respect_annotation_metadata( @@ -674,13 +657,11 @@ async def delete_custom_code( self, page_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> None: """ - Delete the custom code block that an app has created for a page + Remove all scripts from a page applied by the App. This endpoint will not remove scripts from the site's registered scripts. - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. + To remove individual scripts applied by the App, use the [Add/Update Custom Code](/data/reference/custom-code/custom-code-pages/upsert-custom-code) endpoint. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + Access to this endpoint requires a bearer token obtained from an [OAuth Code Grant Flow](/data/reference/oauth-app). Required scope | `custom_code:write` @@ -717,6 +698,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}/custom_code", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) diff --git a/src/webflow/resources/pages/types/__init__.py b/src/webflow/resources/pages/types/__init__.py index 08c0325..6e07bcf 100644 --- a/src/webflow/resources/pages/types/__init__.py +++ b/src/webflow/resources/pages/types/__init__.py @@ -1,6 +1,8 @@ # This file was auto-generated by Fern from our API Definition. from .page_dom_write_nodes_item import PageDomWriteNodesItem +from .page_metadata_write_open_graph import PageMetadataWriteOpenGraph +from .page_metadata_write_seo import PageMetadataWriteSeo from .update_static_content_response import UpdateStaticContentResponse -__all__ = ["PageDomWriteNodesItem", "UpdateStaticContentResponse"] +__all__ = ["PageDomWriteNodesItem", "PageMetadataWriteOpenGraph", "PageMetadataWriteSeo", "UpdateStaticContentResponse"] diff --git a/src/webflow/resources/pages/types/page_dom_write_nodes_item.py b/src/webflow/resources/pages/types/page_dom_write_nodes_item.py index 05d1f3f..7c616d9 100644 --- a/src/webflow/resources/pages/types/page_dom_write_nodes_item.py +++ b/src/webflow/resources/pages/types/page_dom_write_nodes_item.py @@ -3,5 +3,16 @@ import typing from ....types.text_node_write import TextNodeWrite from ....types.component_instance_node_property_overrides_write import ComponentInstanceNodePropertyOverridesWrite +from ....types.select import Select +from ....types.text_input_node_write import TextInputNodeWrite +from ....types.submit_button_node_write import SubmitButtonNodeWrite +from ....types.search_button_node_write import SearchButtonNodeWrite -PageDomWriteNodesItem = typing.Union[TextNodeWrite, ComponentInstanceNodePropertyOverridesWrite] +PageDomWriteNodesItem = typing.Union[ + TextNodeWrite, + ComponentInstanceNodePropertyOverridesWrite, + Select, + TextInputNodeWrite, + SubmitButtonNodeWrite, + SearchButtonNodeWrite, +] diff --git a/src/webflow/resources/pages/types/page_metadata_write_open_graph.py b/src/webflow/resources/pages/types/page_metadata_write_open_graph.py new file mode 100644 index 0000000..7b6a099 --- /dev/null +++ b/src/webflow/resources/pages/types/page_metadata_write_open_graph.py @@ -0,0 +1,47 @@ +# This file was auto-generated by Fern from our API Definition. + +from ....core.pydantic_utilities import UniversalBaseModel +import typing +import pydantic +import typing_extensions +from ....core.serialization import FieldMetadata +from ....core.pydantic_utilities import IS_PYDANTIC_V2 + + +class PageMetadataWriteOpenGraph(UniversalBaseModel): + """ + Open Graph fields for the Page + """ + + title: typing.Optional[str] = pydantic.Field(default=None) + """ + The title supplied to Open Graph annotations + """ + + title_copied: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="titleCopied")] = ( + pydantic.Field(default=None) + ) + """ + Indicates the Open Graph title was copied from the SEO title + """ + + description: typing.Optional[str] = pydantic.Field(default=None) + """ + The description supplied to Open Graph annotations + """ + + description_copied: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="descriptionCopied")] = ( + pydantic.Field(default=None) + ) + """ + Indicates the Open Graph description was copied from the SEO description + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/resources/pages/types/page_metadata_write_seo.py b/src/webflow/resources/pages/types/page_metadata_write_seo.py new file mode 100644 index 0000000..1b339a0 --- /dev/null +++ b/src/webflow/resources/pages/types/page_metadata_write_seo.py @@ -0,0 +1,31 @@ +# This file was auto-generated by Fern from our API Definition. + +from ....core.pydantic_utilities import UniversalBaseModel +import typing +import pydantic +from ....core.pydantic_utilities import IS_PYDANTIC_V2 + + +class PageMetadataWriteSeo(UniversalBaseModel): + """ + SEO-related fields for the Page + """ + + title: typing.Optional[str] = pydantic.Field(default=None) + """ + The Page title shown in search engine results + """ + + description: typing.Optional[str] = pydantic.Field(default=None) + """ + The Page description shown in search engine results + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/resources/products/__init__.py b/src/webflow/resources/products/__init__.py index 9fced2c..adf933b 100644 --- a/src/webflow/resources/products/__init__.py +++ b/src/webflow/resources/products/__init__.py @@ -1,5 +1,5 @@ # This file was auto-generated by Fern from our API Definition. -from .types import ProductsCreateSkuResponse +from .types import ProductSkuCreateProduct, ProductSkuCreateSku, ProductsCreateSkuResponse -__all__ = ["ProductsCreateSkuResponse"] +__all__ = ["ProductSkuCreateProduct", "ProductSkuCreateSku", "ProductsCreateSkuResponse"] diff --git a/src/webflow/resources/products/client.py b/src/webflow/resources/products/client.py index c856fef..8ef35ce 100644 --- a/src/webflow/resources/products/client.py +++ b/src/webflow/resources/products/client.py @@ -16,11 +16,13 @@ from ...errors.internal_server_error import InternalServerError from json.decoder import JSONDecodeError from ...core.api_error import ApiError +from .types.product_sku_create_product import ProductSkuCreateProduct +from .types.product_sku_create_sku import ProductSkuCreateSku from ...types.publish_status import PublishStatus -from ...types.product import Product -from ...types.sku import Sku from ...types.product_and_sk_us import ProductAndSkUs from ...core.serialization import convert_and_respect_annotation_metadata +from ...types.product import Product +from ...types.sku import Sku from .types.products_create_sku_response import ProductsCreateSkuResponse from ...core.client_wrapper import AsyncClientWrapper @@ -76,10 +78,13 @@ def list( ) client.products.list( site_id="580e63e98c9a982ac9b8b741", + offset=1.1, + limit=1.1, ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/products", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "offset": offset, @@ -175,22 +180,18 @@ def create( self, site_id: str, *, + product: ProductSkuCreateProduct, + sku: ProductSkuCreateSku, publish_status: typing.Optional[PublishStatus] = OMIT, - product: typing.Optional[Product] = OMIT, - sku: typing.Optional[Sku] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> ProductAndSkUs: """ - Create a new product and SKU. - - When you create a product, you will always create a SKU, since a Product Item must have, at minimum, a single SKU. + Create a new ecommerce product and defaultSKU. A product, at minimum, must have a single SKU. - To create a Product with multiple SKUs - for example a T-shirt in sizes small, medium and large: - - Create parameters in `sku-properties`, also known as [product options and variants.](https://help.webflow.com/hc/en-us/articles/33961334531347-Create-product-options-and-variants). - - A single `sku-property` would be `color`. Within the `color` property, list the various colors of T-shirts as an array of `enum` values: `royal-blue`, `crimson-red`, and `forrest-green`. - - Once, you've created a Product and its `sku-properties` with `enum` values, Webflow will create a **default SKU**, which will automatically be a combination of the first `sku-properties` you've created. - - In our example, the default SKU will be a Royal Blue T-Shirt, because our first `enum` of our Color `sku-property` is Royal Blue. - - After you've created your product, you can create additional SKUs using the [Create SKU endpoint.](/data/reference/ecommerce/products/create-sku) + To create a product with multiple SKUs: + - First, create a list of `sku-properties`, also known as [product options](https://help.webflow.com/hc/en-us/articles/33961334531347-Create-product-options-and-variants). For example, a T-shirt product may have a "color" `sku-property`, with a list of enum values: red, yellow, and blue, another `sku-property` may be "size", with a list of enum values: small, medium, and large. + - Once, a product is created with a list of `sku-properties`, Webflow will create a **default SKU**, which is always a combination of the first `enum` values of each `sku-property`. (e.g. Small - Red - T-Shirt) + - After creation, you can create additional SKUs for the product, using the [Create SKUs endpoint.](/data/reference/ecommerce/products/create-sku) Upon creation, the default product type will be `Advanced`, which ensures all Product and SKU fields will be shown to users in the Designer. @@ -201,11 +202,11 @@ def create( site_id : str Unique identifier for a Site - publish_status : typing.Optional[PublishStatus] + product : ProductSkuCreateProduct - product : typing.Optional[Product] + sku : ProductSkuCreateSku - sku : typing.Optional[Sku] + publish_status : typing.Optional[PublishStatus] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -217,24 +218,102 @@ def create( Examples -------- - from webflow import Webflow + from webflow import ( + ProductFieldData, + SkuFieldData, + SkuFieldDataPrice, + SkuPropertyList, + SkuPropertyListEnumItem, + Webflow, + ) + from webflow.resources.products import ( + ProductSkuCreateProduct, + ProductSkuCreateSku, + ) client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.products.create( site_id="580e63e98c9a982ac9b8b741", + publish_status="staging", + product=ProductSkuCreateProduct( + field_data=ProductFieldData( + name="Colorful T-shirt", + slug="colorful-t-shirt", + description="Our best-selling t-shirt available in multiple colors and sizes", + sku_properties=[ + SkuPropertyList( + id="color", + name="Color", + enum=[ + SkuPropertyListEnumItem( + id="red", + name="Red", + slug="red", + ), + SkuPropertyListEnumItem( + id="yellow", + name="Yellow", + slug="yellow", + ), + SkuPropertyListEnumItem( + id="blue", + name="Blue", + slug="blue", + ), + ], + ), + SkuPropertyList( + id="size", + name="Size", + enum=[ + SkuPropertyListEnumItem( + id="small", + name="Small", + slug="small", + ), + SkuPropertyListEnumItem( + id="medium", + name="Medium", + slug="medium", + ), + SkuPropertyListEnumItem( + id="large", + name="Large", + slug="large", + ), + ], + ), + ], + ), + ), + sku=ProductSkuCreateSku( + field_data=SkuFieldData( + name="Colorful T-shirt - Red Small", + slug="colorful-t-shirt-red-small", + price=SkuFieldDataPrice( + value=2499.0, + unit="USD", + currency="USD", + ), + main_image="https://rocketamp-sample-store.myshopify.com/cdn/shop/products/Gildan_2000_Antique_Cherry_Red_Front_1024x1024.jpg?v=1527232987", + ), + ), ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/products", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "publishStatus": publish_status, "product": convert_and_respect_annotation_metadata( - object_=product, annotation=Product, direction="write" + object_=product, annotation=ProductSkuCreateProduct, direction="write" + ), + "sku": convert_and_respect_annotation_metadata( + object_=sku, annotation=ProductSkuCreateSku, direction="write" ), - "sku": convert_and_respect_annotation_metadata(object_=sku, annotation=Sku, direction="write"), }, headers={ "content-type": "application/json", @@ -365,6 +444,7 @@ def get( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/products/{jsonable_encoder(product_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -505,6 +585,7 @@ def update( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/products/{jsonable_encoder(product_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "publishStatus": publish_status, @@ -642,7 +723,9 @@ def create_sku( Examples -------- - from webflow import Sku, Webflow + import datetime + + from webflow import Sku, SkuFieldData, SkuFieldDataPrice, Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", @@ -650,11 +733,35 @@ def create_sku( client.products.create_sku( site_id="580e63e98c9a982ac9b8b741", product_id="580e63fc8c9a982ac9b8b745", - skus=[Sku()], + skus=[ + Sku( + id="66072fb71b89448912e2681c", + cms_locale_id="653ad57de882f528b32e810e", + last_published=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + last_updated=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + created_on=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + field_data=SkuFieldData( + name="Colorful T-shirt - Default", + slug="colorful-t-shirt-default", + price=SkuFieldDataPrice( + value=2499.0, + unit="USD", + currency="USD", + ), + ), + ) + ], ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/products/{jsonable_encoder(product_id)}/skus", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "publishStatus": publish_status, @@ -794,7 +901,9 @@ def update_sku( Examples -------- - from webflow import Sku, Webflow + import datetime + + from webflow import Sku, SkuFieldData, SkuFieldDataPrice, Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", @@ -803,11 +912,33 @@ def update_sku( site_id="580e63e98c9a982ac9b8b741", product_id="580e63fc8c9a982ac9b8b745", sku_id="5e8518516e147040726cc415", - sku=Sku(), + sku=Sku( + id="66072fb71b89448912e2681c", + cms_locale_id="653ad57de882f528b32e810e", + last_published=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + last_updated=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + created_on=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + field_data=SkuFieldData( + name="Colorful T-shirt - Default", + slug="colorful-t-shirt-default", + price=SkuFieldDataPrice( + value=2499.0, + unit="USD", + currency="USD", + ), + ), + ), ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/products/{jsonable_encoder(product_id)}/skus/{jsonable_encoder(sku_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "publishStatus": publish_status, @@ -957,6 +1088,8 @@ async def list( async def main() -> None: await client.products.list( site_id="580e63e98c9a982ac9b8b741", + offset=1.1, + limit=1.1, ) @@ -964,6 +1097,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/products", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "offset": offset, @@ -1059,22 +1193,18 @@ async def create( self, site_id: str, *, + product: ProductSkuCreateProduct, + sku: ProductSkuCreateSku, publish_status: typing.Optional[PublishStatus] = OMIT, - product: typing.Optional[Product] = OMIT, - sku: typing.Optional[Sku] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> ProductAndSkUs: """ - Create a new product and SKU. + Create a new ecommerce product and defaultSKU. A product, at minimum, must have a single SKU. - When you create a product, you will always create a SKU, since a Product Item must have, at minimum, a single SKU. - - To create a Product with multiple SKUs - for example a T-shirt in sizes small, medium and large: - - Create parameters in `sku-properties`, also known as [product options and variants.](https://help.webflow.com/hc/en-us/articles/33961334531347-Create-product-options-and-variants). - - A single `sku-property` would be `color`. Within the `color` property, list the various colors of T-shirts as an array of `enum` values: `royal-blue`, `crimson-red`, and `forrest-green`. - - Once, you've created a Product and its `sku-properties` with `enum` values, Webflow will create a **default SKU**, which will automatically be a combination of the first `sku-properties` you've created. - - In our example, the default SKU will be a Royal Blue T-Shirt, because our first `enum` of our Color `sku-property` is Royal Blue. - - After you've created your product, you can create additional SKUs using the [Create SKU endpoint.](/data/reference/ecommerce/products/create-sku) + To create a product with multiple SKUs: + - First, create a list of `sku-properties`, also known as [product options](https://help.webflow.com/hc/en-us/articles/33961334531347-Create-product-options-and-variants). For example, a T-shirt product may have a "color" `sku-property`, with a list of enum values: red, yellow, and blue, another `sku-property` may be "size", with a list of enum values: small, medium, and large. + - Once, a product is created with a list of `sku-properties`, Webflow will create a **default SKU**, which is always a combination of the first `enum` values of each `sku-property`. (e.g. Small - Red - T-Shirt) + - After creation, you can create additional SKUs for the product, using the [Create SKUs endpoint.](/data/reference/ecommerce/products/create-sku) Upon creation, the default product type will be `Advanced`, which ensures all Product and SKU fields will be shown to users in the Designer. @@ -1085,11 +1215,11 @@ async def create( site_id : str Unique identifier for a Site - publish_status : typing.Optional[PublishStatus] + product : ProductSkuCreateProduct - product : typing.Optional[Product] + sku : ProductSkuCreateSku - sku : typing.Optional[Sku] + publish_status : typing.Optional[PublishStatus] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1103,7 +1233,18 @@ async def create( -------- import asyncio - from webflow import AsyncWebflow + from webflow import ( + AsyncWebflow, + ProductFieldData, + SkuFieldData, + SkuFieldDataPrice, + SkuPropertyList, + SkuPropertyListEnumItem, + ) + from webflow.resources.products import ( + ProductSkuCreateProduct, + ProductSkuCreateSku, + ) client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", @@ -1113,6 +1254,70 @@ async def create( async def main() -> None: await client.products.create( site_id="580e63e98c9a982ac9b8b741", + publish_status="staging", + product=ProductSkuCreateProduct( + field_data=ProductFieldData( + name="Colorful T-shirt", + slug="colorful-t-shirt", + description="Our best-selling t-shirt available in multiple colors and sizes", + sku_properties=[ + SkuPropertyList( + id="color", + name="Color", + enum=[ + SkuPropertyListEnumItem( + id="red", + name="Red", + slug="red", + ), + SkuPropertyListEnumItem( + id="yellow", + name="Yellow", + slug="yellow", + ), + SkuPropertyListEnumItem( + id="blue", + name="Blue", + slug="blue", + ), + ], + ), + SkuPropertyList( + id="size", + name="Size", + enum=[ + SkuPropertyListEnumItem( + id="small", + name="Small", + slug="small", + ), + SkuPropertyListEnumItem( + id="medium", + name="Medium", + slug="medium", + ), + SkuPropertyListEnumItem( + id="large", + name="Large", + slug="large", + ), + ], + ), + ], + ), + ), + sku=ProductSkuCreateSku( + field_data=SkuFieldData( + name="Colorful T-shirt - Red Small", + slug="colorful-t-shirt-red-small", + price=SkuFieldDataPrice( + value=2499.0, + unit="USD", + currency="USD", + ), + main_image="https://rocketamp-sample-store.myshopify.com/cdn/shop/products/Gildan_2000_Antique_Cherry_Red_Front_1024x1024.jpg?v=1527232987", + ), + ), ) @@ -1120,13 +1325,16 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/products", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "publishStatus": publish_status, "product": convert_and_respect_annotation_metadata( - object_=product, annotation=Product, direction="write" + object_=product, annotation=ProductSkuCreateProduct, direction="write" + ), + "sku": convert_and_respect_annotation_metadata( + object_=sku, annotation=ProductSkuCreateSku, direction="write" ), - "sku": convert_and_respect_annotation_metadata(object_=sku, annotation=Sku, direction="write"), }, headers={ "content-type": "application/json", @@ -1265,6 +1473,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/products/{jsonable_encoder(product_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -1413,6 +1622,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/products/{jsonable_encoder(product_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "publishStatus": publish_status, @@ -1551,8 +1761,9 @@ async def create_sku( Examples -------- import asyncio + import datetime - from webflow import AsyncWebflow, Sku + from webflow import AsyncWebflow, Sku, SkuFieldData, SkuFieldDataPrice client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", @@ -1563,7 +1774,30 @@ async def main() -> None: await client.products.create_sku( site_id="580e63e98c9a982ac9b8b741", product_id="580e63fc8c9a982ac9b8b745", - skus=[Sku()], + skus=[ + Sku( + id="66072fb71b89448912e2681c", + cms_locale_id="653ad57de882f528b32e810e", + last_published=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + last_updated=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + created_on=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + field_data=SkuFieldData( + name="Colorful T-shirt - Default", + slug="colorful-t-shirt-default", + price=SkuFieldDataPrice( + value=2499.0, + unit="USD", + currency="USD", + ), + ), + ) + ], ) @@ -1571,6 +1805,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/products/{jsonable_encoder(product_id)}/skus", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "publishStatus": publish_status, @@ -1711,8 +1946,9 @@ async def update_sku( Examples -------- import asyncio + import datetime - from webflow import AsyncWebflow, Sku + from webflow import AsyncWebflow, Sku, SkuFieldData, SkuFieldDataPrice client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", @@ -1724,7 +1960,28 @@ async def main() -> None: site_id="580e63e98c9a982ac9b8b741", product_id="580e63fc8c9a982ac9b8b745", sku_id="5e8518516e147040726cc415", - sku=Sku(), + sku=Sku( + id="66072fb71b89448912e2681c", + cms_locale_id="653ad57de882f528b32e810e", + last_published=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + last_updated=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + created_on=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + field_data=SkuFieldData( + name="Colorful T-shirt - Default", + slug="colorful-t-shirt-default", + price=SkuFieldDataPrice( + value=2499.0, + unit="USD", + currency="USD", + ), + ), + ), ) @@ -1732,6 +1989,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/products/{jsonable_encoder(product_id)}/skus/{jsonable_encoder(sku_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "publishStatus": publish_status, diff --git a/src/webflow/resources/products/types/__init__.py b/src/webflow/resources/products/types/__init__.py index b078afe..5b6d9b4 100644 --- a/src/webflow/resources/products/types/__init__.py +++ b/src/webflow/resources/products/types/__init__.py @@ -1,5 +1,7 @@ # This file was auto-generated by Fern from our API Definition. +from .product_sku_create_product import ProductSkuCreateProduct +from .product_sku_create_sku import ProductSkuCreateSku from .products_create_sku_response import ProductsCreateSkuResponse -__all__ = ["ProductsCreateSkuResponse"] +__all__ = ["ProductSkuCreateProduct", "ProductSkuCreateSku", "ProductsCreateSkuResponse"] diff --git a/src/webflow/resources/products/types/product_sku_create_product.py b/src/webflow/resources/products/types/product_sku_create_product.py new file mode 100644 index 0000000..750e5f4 --- /dev/null +++ b/src/webflow/resources/products/types/product_sku_create_product.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +from ....core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ....types.product_field_data import ProductFieldData +from ....core.serialization import FieldMetadata +from ....core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class ProductSkuCreateProduct(UniversalBaseModel): + field_data: typing_extensions.Annotated[typing.Optional[ProductFieldData], FieldMetadata(alias="fieldData")] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/resources/products/types/product_sku_create_sku.py b/src/webflow/resources/products/types/product_sku_create_sku.py new file mode 100644 index 0000000..2762a9a --- /dev/null +++ b/src/webflow/resources/products/types/product_sku_create_sku.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +from ....core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ....types.sku_field_data import SkuFieldData +from ....core.serialization import FieldMetadata +from ....core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class ProductSkuCreateSku(UniversalBaseModel): + field_data: typing_extensions.Annotated[typing.Optional[SkuFieldData], FieldMetadata(alias="fieldData")] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/resources/products/types/products_create_sku_response.py b/src/webflow/resources/products/types/products_create_sku_response.py index e694930..cd68c3d 100644 --- a/src/webflow/resources/products/types/products_create_sku_response.py +++ b/src/webflow/resources/products/types/products_create_sku_response.py @@ -8,7 +8,7 @@ class ProductsCreateSkuResponse(UniversalBaseModel): - skus: typing.Optional[typing.List[Sku]] = None + skus: typing.List[Sku] if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/webflow/resources/scripts/client.py b/src/webflow/resources/scripts/client.py index e9112fb..80026d9 100644 --- a/src/webflow/resources/scripts/client.py +++ b/src/webflow/resources/scripts/client.py @@ -28,14 +28,11 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> RegisteredScriptList: """ - List of scripts registered to a Site. + Get a list of scripts that have been registered to a site. A site can have a maximum of 800 registered scripts. - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. - Additionally, Scripts can be remotely hosted, or registered as inline snippets. - - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:read` @@ -65,6 +62,7 @@ def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/registered_scripts", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -144,14 +142,11 @@ def register_hosted( request_options: typing.Optional[RequestOptions] = None, ) -> CustomCodeHostedResponse: """ - Add a script to a Site's Custom Code registry. - - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. - Additionally, Scripts can be remotely hosted, or registered as inline snippets. + Register a hosted script to a site. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:write` @@ -200,6 +195,7 @@ def register_hosted( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/registered_scripts/hosted", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "hostedLocation": hosted_location, @@ -290,13 +286,11 @@ def register_inline( request_options: typing.Optional[RequestOptions] = None, ) -> CustomCodeInlineResponse: """ - Add a script to a Site's Custom Code registry. Inline scripts can be between 1 and 2000 characters. - - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. + Register an inline script to a site. Inline scripts are limited to 2000 characters. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:write` @@ -344,6 +338,7 @@ def register_inline( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/registered_scripts/inline", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "sourceCode": source_code, @@ -431,14 +426,11 @@ async def list( self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> RegisteredScriptList: """ - List of scripts registered to a Site. + Get a list of scripts that have been registered to a site. A site can have a maximum of 800 registered scripts. - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. - Additionally, Scripts can be remotely hosted, or registered as inline snippets. - - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:read` @@ -476,6 +468,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/registered_scripts", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -555,14 +548,11 @@ async def register_hosted( request_options: typing.Optional[RequestOptions] = None, ) -> CustomCodeHostedResponse: """ - Add a script to a Site's Custom Code registry. - - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. - Additionally, Scripts can be remotely hosted, or registered as inline snippets. + Register a hosted script to a site. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:write` @@ -619,6 +609,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/registered_scripts/hosted", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "hostedLocation": hosted_location, @@ -709,13 +700,11 @@ async def register_inline( request_options: typing.Optional[RequestOptions] = None, ) -> CustomCodeInlineResponse: """ - Add a script to a Site's Custom Code registry. Inline scripts can be between 1 and 2000 characters. - - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. + Register an inline script to a site. Inline scripts are limited to 2000 characters. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:write` @@ -771,6 +760,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/registered_scripts/inline", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "sourceCode": source_code, diff --git a/src/webflow/resources/sites/__init__.py b/src/webflow/resources/sites/__init__.py index 3ec19db..c070ab2 100644 --- a/src/webflow/resources/sites/__init__.py +++ b/src/webflow/resources/sites/__init__.py @@ -1,6 +1,39 @@ # This file was auto-generated by Fern from our API Definition. from .types import SitesPublishResponse -from .resources import activity_logs, plans, redirects, scripts +from .resources import ( + CommentsGetCommentThreadRequestSortBy, + CommentsGetCommentThreadRequestSortOrder, + CommentsListCommentRepliesRequestSortBy, + CommentsListCommentRepliesRequestSortOrder, + CommentsListCommentThreadsRequestSortBy, + CommentsListCommentThreadsRequestSortOrder, + WellKnownFileContentType, + activity_logs, + comments, + forms, + plans, + redirects, + robots_txt, + scripts, + well_known, +) -__all__ = ["SitesPublishResponse", "activity_logs", "plans", "redirects", "scripts"] +__all__ = [ + "CommentsGetCommentThreadRequestSortBy", + "CommentsGetCommentThreadRequestSortOrder", + "CommentsListCommentRepliesRequestSortBy", + "CommentsListCommentRepliesRequestSortOrder", + "CommentsListCommentThreadsRequestSortBy", + "CommentsListCommentThreadsRequestSortOrder", + "SitesPublishResponse", + "WellKnownFileContentType", + "activity_logs", + "comments", + "forms", + "plans", + "redirects", + "robots_txt", + "scripts", + "well_known", +] diff --git a/src/webflow/resources/sites/client.py b/src/webflow/resources/sites/client.py index c2a4468..84b91bd 100644 --- a/src/webflow/resources/sites/client.py +++ b/src/webflow/resources/sites/client.py @@ -4,8 +4,12 @@ from ...core.client_wrapper import SyncClientWrapper from .resources.redirects.client import RedirectsClient from .resources.plans.client import PlansClient +from .resources.robots_txt.client import RobotsTxtClient +from .resources.well_known.client import WellKnownClient from .resources.activity_logs.client import ActivityLogsClient +from .resources.comments.client import CommentsClient from .resources.scripts.client import ScriptsClient +from .resources.forms.client import FormsClient from ...core.request_options import RequestOptions from ...types.site import Site from ...core.jsonable_encoder import jsonable_encoder @@ -25,8 +29,12 @@ from ...core.client_wrapper import AsyncClientWrapper from .resources.redirects.client import AsyncRedirectsClient from .resources.plans.client import AsyncPlansClient +from .resources.robots_txt.client import AsyncRobotsTxtClient +from .resources.well_known.client import AsyncWellKnownClient from .resources.activity_logs.client import AsyncActivityLogsClient +from .resources.comments.client import AsyncCommentsClient from .resources.scripts.client import AsyncScriptsClient +from .resources.forms.client import AsyncFormsClient # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -37,8 +45,12 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper self.redirects = RedirectsClient(client_wrapper=self._client_wrapper) self.plans = PlansClient(client_wrapper=self._client_wrapper) + self.robots_txt = RobotsTxtClient(client_wrapper=self._client_wrapper) + self.well_known = WellKnownClient(client_wrapper=self._client_wrapper) self.activity_logs = ActivityLogsClient(client_wrapper=self._client_wrapper) + self.comments = CommentsClient(client_wrapper=self._client_wrapper) self.scripts = ScriptsClient(client_wrapper=self._client_wrapper) + self.forms = FormsClient(client_wrapper=self._client_wrapper) def create( self, @@ -50,7 +62,9 @@ def create( request_options: typing.Optional[RequestOptions] = None, ) -> Site: """ - Create a site. This endpoint requires an Enterprise workspace. + Create a site. + + This endpoint requires an Enterprise workspace. Required scope | `workspace:write` @@ -90,6 +104,7 @@ def create( """ _response = self._client_wrapper.httpx_client.request( f"workspaces/{jsonable_encoder(workspace_id)}/sites", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "name": name, @@ -203,6 +218,7 @@ def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> Si """ _response = self._client_wrapper.httpx_client.request( "sites", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -282,6 +298,7 @@ def get(self, site_id: str, *, request_options: typing.Optional[RequestOptions] """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -351,7 +368,9 @@ def get(self, site_id: str, *, request_options: typing.Optional[RequestOptions] def delete(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None: """ - Delete a site. This endpoint requires an Enterprise workspace. + Delete a site. + + This endpoint requires an Enterprise workspace. Required scope | `sites:write` @@ -380,6 +399,7 @@ def delete(self, site_id: str, *, request_options: typing.Optional[RequestOption """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -460,7 +480,9 @@ def update( request_options: typing.Optional[RequestOptions] = None, ) -> Site: """ - Update a site. This endpoint requires an Enterprise workspace. + Update a site. + + This endpoint requires an Enterprise workspace. Required scope | `sites:write` @@ -496,6 +518,7 @@ def update( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "name": name, @@ -613,6 +636,7 @@ def get_custom_domain(self, site_id: str, *, request_options: typing.Optional[Re """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/custom_domains", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -691,7 +715,9 @@ def publish( """ Publishes a site to one or more more domains. - This endpoint has a limit of one successful publish queue per minute. + To publish to a specific custom domain, use the domain IDs from the [Get Custom Domains](/data/reference/sites/get-custom-domain) endpoint. + + This endpoint has a specific rate limit of one successful publish queue per minute. Required scope | `sites:write` @@ -723,10 +749,13 @@ def publish( ) client.sites.publish( site_id="580e63e98c9a982ac9b8b741", + custom_domains=["660c6449dd97ebc7346ac629", "660c6449dd97ebc7346ac62f"], + publish_to_webflow_subdomain=False, ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/publish", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "customDomains": custom_domains, @@ -808,8 +837,12 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper self.redirects = AsyncRedirectsClient(client_wrapper=self._client_wrapper) self.plans = AsyncPlansClient(client_wrapper=self._client_wrapper) + self.robots_txt = AsyncRobotsTxtClient(client_wrapper=self._client_wrapper) + self.well_known = AsyncWellKnownClient(client_wrapper=self._client_wrapper) self.activity_logs = AsyncActivityLogsClient(client_wrapper=self._client_wrapper) + self.comments = AsyncCommentsClient(client_wrapper=self._client_wrapper) self.scripts = AsyncScriptsClient(client_wrapper=self._client_wrapper) + self.forms = AsyncFormsClient(client_wrapper=self._client_wrapper) async def create( self, @@ -821,7 +854,9 @@ async def create( request_options: typing.Optional[RequestOptions] = None, ) -> Site: """ - Create a site. This endpoint requires an Enterprise workspace. + Create a site. + + This endpoint requires an Enterprise workspace. Required scope | `workspace:write` @@ -869,6 +904,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"workspaces/{jsonable_encoder(workspace_id)}/sites", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "name": name, @@ -990,6 +1026,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( "sites", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -1077,6 +1114,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -1146,7 +1184,9 @@ async def main() -> None: async def delete(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None: """ - Delete a site. This endpoint requires an Enterprise workspace. + Delete a site. + + This endpoint requires an Enterprise workspace. Required scope | `sites:write` @@ -1183,6 +1223,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -1263,7 +1304,9 @@ async def update( request_options: typing.Optional[RequestOptions] = None, ) -> Site: """ - Update a site. This endpoint requires an Enterprise workspace. + Update a site. + + This endpoint requires an Enterprise workspace. Required scope | `sites:write` @@ -1307,6 +1350,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "name": name, @@ -1434,6 +1478,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/custom_domains", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -1512,7 +1557,9 @@ async def publish( """ Publishes a site to one or more more domains. - This endpoint has a limit of one successful publish queue per minute. + To publish to a specific custom domain, use the domain IDs from the [Get Custom Domains](/data/reference/sites/get-custom-domain) endpoint. + + This endpoint has a specific rate limit of one successful publish queue per minute. Required scope | `sites:write` @@ -1549,6 +1596,8 @@ async def publish( async def main() -> None: await client.sites.publish( site_id="580e63e98c9a982ac9b8b741", + custom_domains=["660c6449dd97ebc7346ac629", "660c6449dd97ebc7346ac62f"], + publish_to_webflow_subdomain=False, ) @@ -1556,6 +1605,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/publish", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "customDomains": custom_domains, diff --git a/src/webflow/resources/sites/resources/__init__.py b/src/webflow/resources/sites/resources/__init__.py index 1197a83..578d8dc 100644 --- a/src/webflow/resources/sites/resources/__init__.py +++ b/src/webflow/resources/sites/resources/__init__.py @@ -1,5 +1,30 @@ # This file was auto-generated by Fern from our API Definition. -from . import activity_logs, plans, redirects, scripts +from . import activity_logs, comments, forms, plans, redirects, robots_txt, scripts, well_known +from .comments import ( + CommentsGetCommentThreadRequestSortBy, + CommentsGetCommentThreadRequestSortOrder, + CommentsListCommentRepliesRequestSortBy, + CommentsListCommentRepliesRequestSortOrder, + CommentsListCommentThreadsRequestSortBy, + CommentsListCommentThreadsRequestSortOrder, +) +from .well_known import WellKnownFileContentType -__all__ = ["activity_logs", "plans", "redirects", "scripts"] +__all__ = [ + "CommentsGetCommentThreadRequestSortBy", + "CommentsGetCommentThreadRequestSortOrder", + "CommentsListCommentRepliesRequestSortBy", + "CommentsListCommentRepliesRequestSortOrder", + "CommentsListCommentThreadsRequestSortBy", + "CommentsListCommentThreadsRequestSortOrder", + "WellKnownFileContentType", + "activity_logs", + "comments", + "forms", + "plans", + "redirects", + "robots_txt", + "scripts", + "well_known", +] diff --git a/src/webflow/resources/sites/resources/activity_logs/client.py b/src/webflow/resources/sites/resources/activity_logs/client.py index cf4e1b3..e48e501 100644 --- a/src/webflow/resources/sites/resources/activity_logs/client.py +++ b/src/webflow/resources/sites/resources/activity_logs/client.py @@ -29,7 +29,11 @@ def list( request_options: typing.Optional[RequestOptions] = None, ) -> SiteActivityLogResponse: """ - Retrieve Activity Logs for a specific Site. Requires Site to be on an Enterprise plan.

Required scope | `site_activity:read` + Retrieve Activity Logs for a specific Site. + + This endpoint requires an Enterprise workspace. + + Required scope: `site_activity:read` Parameters ---------- @@ -59,10 +63,13 @@ def list( ) client.sites.activity_logs.list( site_id="580e63e98c9a982ac9b8b741", + limit=1.1, + offset=1.1, ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/activity_logs", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "limit": limit, @@ -138,7 +145,11 @@ async def list( request_options: typing.Optional[RequestOptions] = None, ) -> SiteActivityLogResponse: """ - Retrieve Activity Logs for a specific Site. Requires Site to be on an Enterprise plan.

Required scope | `site_activity:read` + Retrieve Activity Logs for a specific Site. + + This endpoint requires an Enterprise workspace. + + Required scope: `site_activity:read` Parameters ---------- @@ -173,6 +184,8 @@ async def list( async def main() -> None: await client.sites.activity_logs.list( site_id="580e63e98c9a982ac9b8b741", + limit=1.1, + offset=1.1, ) @@ -180,6 +193,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/activity_logs", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "limit": limit, diff --git a/src/webflow/resources/sites/resources/comments/__init__.py b/src/webflow/resources/sites/resources/comments/__init__.py new file mode 100644 index 0000000..1bf96a0 --- /dev/null +++ b/src/webflow/resources/sites/resources/comments/__init__.py @@ -0,0 +1,19 @@ +# This file was auto-generated by Fern from our API Definition. + +from .types import ( + CommentsGetCommentThreadRequestSortBy, + CommentsGetCommentThreadRequestSortOrder, + CommentsListCommentRepliesRequestSortBy, + CommentsListCommentRepliesRequestSortOrder, + CommentsListCommentThreadsRequestSortBy, + CommentsListCommentThreadsRequestSortOrder, +) + +__all__ = [ + "CommentsGetCommentThreadRequestSortBy", + "CommentsGetCommentThreadRequestSortOrder", + "CommentsListCommentRepliesRequestSortBy", + "CommentsListCommentRepliesRequestSortOrder", + "CommentsListCommentThreadsRequestSortBy", + "CommentsListCommentThreadsRequestSortOrder", +] diff --git a/src/webflow/resources/sites/resources/comments/client.py b/src/webflow/resources/sites/resources/comments/client.py new file mode 100644 index 0000000..8d9f12b --- /dev/null +++ b/src/webflow/resources/sites/resources/comments/client.py @@ -0,0 +1,937 @@ +# This file was auto-generated by Fern from our API Definition. + +from .....core.client_wrapper import SyncClientWrapper +import typing +from .types.comments_list_comment_threads_request_sort_by import CommentsListCommentThreadsRequestSortBy +from .types.comments_list_comment_threads_request_sort_order import CommentsListCommentThreadsRequestSortOrder +from .....core.request_options import RequestOptions +from .....types.comment_thread_list import CommentThreadList +from .....core.jsonable_encoder import jsonable_encoder +from .....core.pydantic_utilities import parse_obj_as +from .....errors.bad_request_error import BadRequestError +from .....errors.unauthorized_error import UnauthorizedError +from .....types.error import Error +from .....errors.not_found_error import NotFoundError +from .....errors.too_many_requests_error import TooManyRequestsError +from .....errors.internal_server_error import InternalServerError +from json.decoder import JSONDecodeError +from .....core.api_error import ApiError +from .types.comments_get_comment_thread_request_sort_by import CommentsGetCommentThreadRequestSortBy +from .types.comments_get_comment_thread_request_sort_order import CommentsGetCommentThreadRequestSortOrder +from .....types.comment_thread import CommentThread +from .types.comments_list_comment_replies_request_sort_by import CommentsListCommentRepliesRequestSortBy +from .types.comments_list_comment_replies_request_sort_order import CommentsListCommentRepliesRequestSortOrder +from .....types.comment_reply_list import CommentReplyList +from .....core.client_wrapper import AsyncClientWrapper + + +class CommentsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list_comment_threads( + self, + site_id: str, + *, + locale_id: typing.Optional[str] = None, + offset: typing.Optional[float] = None, + limit: typing.Optional[float] = None, + sort_by: typing.Optional[CommentsListCommentThreadsRequestSortBy] = None, + sort_order: typing.Optional[CommentsListCommentThreadsRequestSortOrder] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> CommentThreadList: + """ + List all comment threads for a site. + + + There may be a delay of up to 5 minutes before new comments appear in the system. + + + Required scope | `comments:read` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + locale_id : typing.Optional[str] + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + offset : typing.Optional[float] + Offset used for pagination if the results have more than limit records + + limit : typing.Optional[float] + Maximum number of records to be returned (max limit: 100) + + sort_by : typing.Optional[CommentsListCommentThreadsRequestSortBy] + Sort results by the provided value. Only allowed when sortOrder is provided. + + sort_order : typing.Optional[CommentsListCommentThreadsRequestSortOrder] + Sorts the results by asc or desc + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CommentThreadList + Request was successful + + Examples + -------- + from webflow import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.sites.comments.list_comment_threads( + site_id="580e63e98c9a982ac9b8b741", + locale_id="65427cf400e02b306eaa04a0", + offset=1.1, + limit=1.1, + sort_by="createdOn", + sort_order="asc", + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/comments", + base_url=self._client_wrapper.get_environment().base, + method="GET", + params={ + "localeId": locale_id, + "offset": offset, + "limit": limit, + "sortBy": sort_by, + "sortOrder": sort_order, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + CommentThreadList, + parse_obj_as( + type_=CommentThreadList, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def get_comment_thread( + self, + site_id: str, + comment_thread_id: str, + *, + locale_id: typing.Optional[str] = None, + offset: typing.Optional[float] = None, + limit: typing.Optional[float] = None, + sort_by: typing.Optional[CommentsGetCommentThreadRequestSortBy] = None, + sort_order: typing.Optional[CommentsGetCommentThreadRequestSortOrder] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> CommentThread: + """ + Get details of a specific comment thread. + + + There may be a delay of up to 5 minutes before new comments appear in the system. + + + Required scope | `comments:read` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + comment_thread_id : str + Unique identifier for a Comment Thread + + locale_id : typing.Optional[str] + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + offset : typing.Optional[float] + Offset used for pagination if the results have more than limit records + + limit : typing.Optional[float] + Maximum number of records to be returned (max limit: 100) + + sort_by : typing.Optional[CommentsGetCommentThreadRequestSortBy] + Sort results by the provided value. Only allowed when sortOrder is provided. + + sort_order : typing.Optional[CommentsGetCommentThreadRequestSortOrder] + Sorts the results by asc or desc + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CommentThread + Request was successful + + Examples + -------- + from webflow import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.sites.comments.get_comment_thread( + site_id="580e63e98c9a982ac9b8b741", + comment_thread_id="580e63e98c9a982ac9b8b741", + locale_id="65427cf400e02b306eaa04a0", + offset=1.1, + limit=1.1, + sort_by="createdOn", + sort_order="asc", + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/comments/{jsonable_encoder(comment_thread_id)}", + base_url=self._client_wrapper.get_environment().base, + method="GET", + params={ + "localeId": locale_id, + "offset": offset, + "limit": limit, + "sortBy": sort_by, + "sortOrder": sort_order, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + CommentThread, + parse_obj_as( + type_=CommentThread, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def list_comment_replies( + self, + site_id: str, + comment_thread_id: str, + *, + locale_id: typing.Optional[str] = None, + offset: typing.Optional[float] = None, + limit: typing.Optional[float] = None, + sort_by: typing.Optional[CommentsListCommentRepliesRequestSortBy] = None, + sort_order: typing.Optional[CommentsListCommentRepliesRequestSortOrder] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> CommentReplyList: + """ + List all replies to a specific comment thread. + + + There may be a delay of up to 5 minutes before new comments appear in the system. + + + Required scope | `comments:read` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + comment_thread_id : str + Unique identifier for a Comment Thread + + locale_id : typing.Optional[str] + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + offset : typing.Optional[float] + Offset used for pagination if the results have more than limit records + + limit : typing.Optional[float] + Maximum number of records to be returned (max limit: 100) + + sort_by : typing.Optional[CommentsListCommentRepliesRequestSortBy] + Sort results by the provided value. Only allowed when sortOrder is provided. + + sort_order : typing.Optional[CommentsListCommentRepliesRequestSortOrder] + Sorts the results by asc or desc + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CommentReplyList + Request was successful + + Examples + -------- + from webflow import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.sites.comments.list_comment_replies( + site_id="580e63e98c9a982ac9b8b741", + comment_thread_id="580e63e98c9a982ac9b8b741", + locale_id="65427cf400e02b306eaa04a0", + offset=1.1, + limit=1.1, + sort_by="createdOn", + sort_order="asc", + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/comments/{jsonable_encoder(comment_thread_id)}/replies", + base_url=self._client_wrapper.get_environment().base, + method="GET", + params={ + "localeId": locale_id, + "offset": offset, + "limit": limit, + "sortBy": sort_by, + "sortOrder": sort_order, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + CommentReplyList, + parse_obj_as( + type_=CommentReplyList, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + +class AsyncCommentsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list_comment_threads( + self, + site_id: str, + *, + locale_id: typing.Optional[str] = None, + offset: typing.Optional[float] = None, + limit: typing.Optional[float] = None, + sort_by: typing.Optional[CommentsListCommentThreadsRequestSortBy] = None, + sort_order: typing.Optional[CommentsListCommentThreadsRequestSortOrder] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> CommentThreadList: + """ + List all comment threads for a site. + + + There may be a delay of up to 5 minutes before new comments appear in the system. + + + Required scope | `comments:read` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + locale_id : typing.Optional[str] + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + offset : typing.Optional[float] + Offset used for pagination if the results have more than limit records + + limit : typing.Optional[float] + Maximum number of records to be returned (max limit: 100) + + sort_by : typing.Optional[CommentsListCommentThreadsRequestSortBy] + Sort results by the provided value. Only allowed when sortOrder is provided. + + sort_order : typing.Optional[CommentsListCommentThreadsRequestSortOrder] + Sorts the results by asc or desc + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CommentThreadList + Request was successful + + Examples + -------- + import asyncio + + from webflow import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + + + async def main() -> None: + await client.sites.comments.list_comment_threads( + site_id="580e63e98c9a982ac9b8b741", + locale_id="65427cf400e02b306eaa04a0", + offset=1.1, + limit=1.1, + sort_by="createdOn", + sort_order="asc", + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/comments", + base_url=self._client_wrapper.get_environment().base, + method="GET", + params={ + "localeId": locale_id, + "offset": offset, + "limit": limit, + "sortBy": sort_by, + "sortOrder": sort_order, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + CommentThreadList, + parse_obj_as( + type_=CommentThreadList, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def get_comment_thread( + self, + site_id: str, + comment_thread_id: str, + *, + locale_id: typing.Optional[str] = None, + offset: typing.Optional[float] = None, + limit: typing.Optional[float] = None, + sort_by: typing.Optional[CommentsGetCommentThreadRequestSortBy] = None, + sort_order: typing.Optional[CommentsGetCommentThreadRequestSortOrder] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> CommentThread: + """ + Get details of a specific comment thread. + + + There may be a delay of up to 5 minutes before new comments appear in the system. + + + Required scope | `comments:read` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + comment_thread_id : str + Unique identifier for a Comment Thread + + locale_id : typing.Optional[str] + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + offset : typing.Optional[float] + Offset used for pagination if the results have more than limit records + + limit : typing.Optional[float] + Maximum number of records to be returned (max limit: 100) + + sort_by : typing.Optional[CommentsGetCommentThreadRequestSortBy] + Sort results by the provided value. Only allowed when sortOrder is provided. + + sort_order : typing.Optional[CommentsGetCommentThreadRequestSortOrder] + Sorts the results by asc or desc + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CommentThread + Request was successful + + Examples + -------- + import asyncio + + from webflow import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + + + async def main() -> None: + await client.sites.comments.get_comment_thread( + site_id="580e63e98c9a982ac9b8b741", + comment_thread_id="580e63e98c9a982ac9b8b741", + locale_id="65427cf400e02b306eaa04a0", + offset=1.1, + limit=1.1, + sort_by="createdOn", + sort_order="asc", + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/comments/{jsonable_encoder(comment_thread_id)}", + base_url=self._client_wrapper.get_environment().base, + method="GET", + params={ + "localeId": locale_id, + "offset": offset, + "limit": limit, + "sortBy": sort_by, + "sortOrder": sort_order, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + CommentThread, + parse_obj_as( + type_=CommentThread, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def list_comment_replies( + self, + site_id: str, + comment_thread_id: str, + *, + locale_id: typing.Optional[str] = None, + offset: typing.Optional[float] = None, + limit: typing.Optional[float] = None, + sort_by: typing.Optional[CommentsListCommentRepliesRequestSortBy] = None, + sort_order: typing.Optional[CommentsListCommentRepliesRequestSortOrder] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> CommentReplyList: + """ + List all replies to a specific comment thread. + + + There may be a delay of up to 5 minutes before new comments appear in the system. + + + Required scope | `comments:read` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + comment_thread_id : str + Unique identifier for a Comment Thread + + locale_id : typing.Optional[str] + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + offset : typing.Optional[float] + Offset used for pagination if the results have more than limit records + + limit : typing.Optional[float] + Maximum number of records to be returned (max limit: 100) + + sort_by : typing.Optional[CommentsListCommentRepliesRequestSortBy] + Sort results by the provided value. Only allowed when sortOrder is provided. + + sort_order : typing.Optional[CommentsListCommentRepliesRequestSortOrder] + Sorts the results by asc or desc + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CommentReplyList + Request was successful + + Examples + -------- + import asyncio + + from webflow import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + + + async def main() -> None: + await client.sites.comments.list_comment_replies( + site_id="580e63e98c9a982ac9b8b741", + comment_thread_id="580e63e98c9a982ac9b8b741", + locale_id="65427cf400e02b306eaa04a0", + offset=1.1, + limit=1.1, + sort_by="createdOn", + sort_order="asc", + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/comments/{jsonable_encoder(comment_thread_id)}/replies", + base_url=self._client_wrapper.get_environment().base, + method="GET", + params={ + "localeId": locale_id, + "offset": offset, + "limit": limit, + "sortBy": sort_by, + "sortOrder": sort_order, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + CommentReplyList, + parse_obj_as( + type_=CommentReplyList, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) diff --git a/src/webflow/resources/sites/resources/comments/types/__init__.py b/src/webflow/resources/sites/resources/comments/types/__init__.py new file mode 100644 index 0000000..380d194 --- /dev/null +++ b/src/webflow/resources/sites/resources/comments/types/__init__.py @@ -0,0 +1,17 @@ +# This file was auto-generated by Fern from our API Definition. + +from .comments_get_comment_thread_request_sort_by import CommentsGetCommentThreadRequestSortBy +from .comments_get_comment_thread_request_sort_order import CommentsGetCommentThreadRequestSortOrder +from .comments_list_comment_replies_request_sort_by import CommentsListCommentRepliesRequestSortBy +from .comments_list_comment_replies_request_sort_order import CommentsListCommentRepliesRequestSortOrder +from .comments_list_comment_threads_request_sort_by import CommentsListCommentThreadsRequestSortBy +from .comments_list_comment_threads_request_sort_order import CommentsListCommentThreadsRequestSortOrder + +__all__ = [ + "CommentsGetCommentThreadRequestSortBy", + "CommentsGetCommentThreadRequestSortOrder", + "CommentsListCommentRepliesRequestSortBy", + "CommentsListCommentRepliesRequestSortOrder", + "CommentsListCommentThreadsRequestSortBy", + "CommentsListCommentThreadsRequestSortOrder", +] diff --git a/src/webflow/resources/sites/resources/comments/types/comments_get_comment_thread_request_sort_by.py b/src/webflow/resources/sites/resources/comments/types/comments_get_comment_thread_request_sort_by.py new file mode 100644 index 0000000..14daabb --- /dev/null +++ b/src/webflow/resources/sites/resources/comments/types/comments_get_comment_thread_request_sort_by.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CommentsGetCommentThreadRequestSortBy = typing.Union[typing.Literal["createdOn", "lastUpdated"], typing.Any] diff --git a/src/webflow/resources/sites/resources/comments/types/comments_get_comment_thread_request_sort_order.py b/src/webflow/resources/sites/resources/comments/types/comments_get_comment_thread_request_sort_order.py new file mode 100644 index 0000000..3da3ffc --- /dev/null +++ b/src/webflow/resources/sites/resources/comments/types/comments_get_comment_thread_request_sort_order.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CommentsGetCommentThreadRequestSortOrder = typing.Union[typing.Literal["asc", "desc"], typing.Any] diff --git a/src/webflow/resources/sites/resources/comments/types/comments_list_comment_replies_request_sort_by.py b/src/webflow/resources/sites/resources/comments/types/comments_list_comment_replies_request_sort_by.py new file mode 100644 index 0000000..67fcb98 --- /dev/null +++ b/src/webflow/resources/sites/resources/comments/types/comments_list_comment_replies_request_sort_by.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CommentsListCommentRepliesRequestSortBy = typing.Union[typing.Literal["createdOn", "lastUpdated"], typing.Any] diff --git a/src/webflow/resources/sites/resources/comments/types/comments_list_comment_replies_request_sort_order.py b/src/webflow/resources/sites/resources/comments/types/comments_list_comment_replies_request_sort_order.py new file mode 100644 index 0000000..03c42c3 --- /dev/null +++ b/src/webflow/resources/sites/resources/comments/types/comments_list_comment_replies_request_sort_order.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CommentsListCommentRepliesRequestSortOrder = typing.Union[typing.Literal["asc", "desc"], typing.Any] diff --git a/src/webflow/resources/sites/resources/comments/types/comments_list_comment_threads_request_sort_by.py b/src/webflow/resources/sites/resources/comments/types/comments_list_comment_threads_request_sort_by.py new file mode 100644 index 0000000..1d541ce --- /dev/null +++ b/src/webflow/resources/sites/resources/comments/types/comments_list_comment_threads_request_sort_by.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CommentsListCommentThreadsRequestSortBy = typing.Union[typing.Literal["createdOn", "lastUpdated"], typing.Any] diff --git a/src/webflow/resources/sites/resources/comments/types/comments_list_comment_threads_request_sort_order.py b/src/webflow/resources/sites/resources/comments/types/comments_list_comment_threads_request_sort_order.py new file mode 100644 index 0000000..d2c2606 --- /dev/null +++ b/src/webflow/resources/sites/resources/comments/types/comments_list_comment_threads_request_sort_order.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CommentsListCommentThreadsRequestSortOrder = typing.Union[typing.Literal["asc", "desc"], typing.Any] diff --git a/tests/__init__.py b/src/webflow/resources/sites/resources/forms/__init__.py similarity index 100% rename from tests/__init__.py rename to src/webflow/resources/sites/resources/forms/__init__.py diff --git a/src/webflow/resources/sites/resources/forms/client.py b/src/webflow/resources/sites/resources/forms/client.py new file mode 100644 index 0000000..d480225 --- /dev/null +++ b/src/webflow/resources/sites/resources/forms/client.py @@ -0,0 +1,1383 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from .....core.client_wrapper import SyncClientWrapper +from .....core.request_options import RequestOptions +from .....types.form_submission_list import FormSubmissionList +from .....core.jsonable_encoder import jsonable_encoder +from .....core.pydantic_utilities import parse_obj_as +from .....errors.bad_request_error import BadRequestError +from .....errors.unauthorized_error import UnauthorizedError +from .....types.error import Error +from .....errors.forbidden_error import ForbiddenError +from .....errors.not_found_error import NotFoundError +from .....errors.too_many_requests_error import TooManyRequestsError +from .....errors.internal_server_error import InternalServerError +from json.decoder import JSONDecodeError +from .....core.api_error import ApiError +from .....types.form_submission import FormSubmission +from .....errors.conflict_error import ConflictError +from .....core.client_wrapper import AsyncClientWrapper + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class FormsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list_submissions_by_site( + self, + site_id: str, + *, + element_id: typing.Optional[str] = None, + offset: typing.Optional[float] = None, + limit: typing.Optional[float] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> FormSubmissionList: + """ + List all form submissions for a given site with the ability to filter submissions by a centralized `elementId`. + + Add `elementId` when you want to filter form submissions to a specific form in a site. You can get the `elementId` from the [List forms endpoint](/data/reference/forms/forms/list) (displayed as `formElementId` in the response). + + + When a form is used in a Webflow component definition, each instance of the component will yield a unique form. Adding the `elementId` in this request ensures this API response includes all submissions from that core form, wherever that form is used in instantiated components. + + + Use the [List Form Submissions endpoint](/data/reference/forms/form-submissions/list-submissions) to list form submissions for a given form ID. + + Required scope | `forms:read` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + element_id : typing.Optional[str] + Identifier for an element + + offset : typing.Optional[float] + Offset used for pagination if the results have more than limit records + + limit : typing.Optional[float] + Maximum number of records to be returned (max limit: 100) + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + FormSubmissionList + Request was successful + + Examples + -------- + from webflow import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.sites.forms.list_submissions_by_site( + site_id="580e63e98c9a982ac9b8b741", + element_id="18259716-3e5a-646a-5f41-5dc4b9405aa0", + offset=1.1, + limit=1.1, + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/form_submissions", + base_url=self._client_wrapper.get_environment().base, + method="GET", + params={ + "elementId": element_id, + "offset": offset, + "limit": limit, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + FormSubmissionList, + parse_obj_as( + type_=FormSubmissionList, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 403: + raise ForbiddenError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def list_submissions( + self, + site_id: str, + form_id: str, + *, + offset: typing.Optional[float] = None, + limit: typing.Optional[float] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> FormSubmissionList: + """ + List form submissions for a given form ID within a specific site. + + Use the [List Form Submissions by Site endpoint](/data/reference/forms/form-submissions/list-submissions-by-site) to list form submissions for a given site with the ability to filter by a `formElementId`. + + Required scope | `forms:read` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + form_id : str + Unique identifier for a Form + + offset : typing.Optional[float] + Offset used for pagination if the results have more than limit records + + limit : typing.Optional[float] + Maximum number of records to be returned (max limit: 100) + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + FormSubmissionList + Request was successful + + Examples + -------- + from webflow import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.sites.forms.list_submissions( + site_id="580e63e98c9a982ac9b8b741", + form_id="580e63e98c9a982ac9b8b741", + offset=1.1, + limit=1.1, + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/forms/{jsonable_encoder(form_id)}/submissions", + base_url=self._client_wrapper.get_environment().base, + method="GET", + params={ + "offset": offset, + "limit": limit, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + FormSubmissionList, + parse_obj_as( + type_=FormSubmissionList, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 403: + raise ForbiddenError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def get_submission( + self, site_id: str, form_submission_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> FormSubmission: + """ + Get information about a form submission within a specific site. + + Required scope | `forms:read` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + form_submission_id : str + Unique identifier for a Form Submission + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + FormSubmission + Request was successful + + Examples + -------- + from webflow import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.sites.forms.get_submission( + site_id="580e63e98c9a982ac9b8b741", + form_submission_id="580e63e98c9a982ac9b8b741", + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/form_submissions/{jsonable_encoder(form_submission_id)}", + base_url=self._client_wrapper.get_environment().base, + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + FormSubmission, + parse_obj_as( + type_=FormSubmission, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 403: + raise ForbiddenError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def delete_submission( + self, site_id: str, form_submission_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> None: + """ + Delete a form submission within a specific site. + + Required scope | `forms:write` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + form_submission_id : str + Unique identifier for a Form Submission + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + from webflow import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.sites.forms.delete_submission( + site_id="580e63e98c9a982ac9b8b741", + form_submission_id="580e63e98c9a982ac9b8b741", + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/form_submissions/{jsonable_encoder(form_submission_id)}", + base_url=self._client_wrapper.get_environment().base, + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 403: + raise ForbiddenError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 409: + raise ConflictError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def update_submission( + self, + site_id: str, + form_submission_id: str, + *, + form_submission_data: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> FormSubmission: + """ + Update hidden fields on a form submission within a specific site. + + Required scope | `forms:write` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + form_submission_id : str + Unique identifier for a Form Submission + + form_submission_data : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] + An existing **hidden field** defined on the form schema, and the corresponding value to set + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + FormSubmission + Request was successful + + Examples + -------- + from webflow import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.sites.forms.update_submission( + site_id="580e63e98c9a982ac9b8b741", + form_submission_id="580e63e98c9a982ac9b8b741", + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/form_submissions/{jsonable_encoder(form_submission_id)}", + base_url=self._client_wrapper.get_environment().base, + method="PATCH", + json={ + "formSubmissionData": form_submission_data, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + FormSubmission, + parse_obj_as( + type_=FormSubmission, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 403: + raise ForbiddenError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 409: + raise ConflictError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + +class AsyncFormsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list_submissions_by_site( + self, + site_id: str, + *, + element_id: typing.Optional[str] = None, + offset: typing.Optional[float] = None, + limit: typing.Optional[float] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> FormSubmissionList: + """ + List all form submissions for a given site with the ability to filter submissions by a centralized `elementId`. + + Add `elementId` when you want to filter form submissions to a specific form in a site. You can get the `elementId` from the [List forms endpoint](/data/reference/forms/forms/list) (displayed as `formElementId` in the response). + + + When a form is used in a Webflow component definition, each instance of the component will yield a unique form. Adding the `elementId` in this request ensures this API response includes all submissions from that core form, wherever that form is used in instantiated components. + + + Use the [List Form Submissions endpoint](/data/reference/forms/form-submissions/list-submissions) to list form submissions for a given form ID. + + Required scope | `forms:read` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + element_id : typing.Optional[str] + Identifier for an element + + offset : typing.Optional[float] + Offset used for pagination if the results have more than limit records + + limit : typing.Optional[float] + Maximum number of records to be returned (max limit: 100) + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + FormSubmissionList + Request was successful + + Examples + -------- + import asyncio + + from webflow import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + + + async def main() -> None: + await client.sites.forms.list_submissions_by_site( + site_id="580e63e98c9a982ac9b8b741", + element_id="18259716-3e5a-646a-5f41-5dc4b9405aa0", + offset=1.1, + limit=1.1, + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/form_submissions", + base_url=self._client_wrapper.get_environment().base, + method="GET", + params={ + "elementId": element_id, + "offset": offset, + "limit": limit, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + FormSubmissionList, + parse_obj_as( + type_=FormSubmissionList, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 403: + raise ForbiddenError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def list_submissions( + self, + site_id: str, + form_id: str, + *, + offset: typing.Optional[float] = None, + limit: typing.Optional[float] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> FormSubmissionList: + """ + List form submissions for a given form ID within a specific site. + + Use the [List Form Submissions by Site endpoint](/data/reference/forms/form-submissions/list-submissions-by-site) to list form submissions for a given site with the ability to filter by a `formElementId`. + + Required scope | `forms:read` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + form_id : str + Unique identifier for a Form + + offset : typing.Optional[float] + Offset used for pagination if the results have more than limit records + + limit : typing.Optional[float] + Maximum number of records to be returned (max limit: 100) + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + FormSubmissionList + Request was successful + + Examples + -------- + import asyncio + + from webflow import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + + + async def main() -> None: + await client.sites.forms.list_submissions( + site_id="580e63e98c9a982ac9b8b741", + form_id="580e63e98c9a982ac9b8b741", + offset=1.1, + limit=1.1, + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/forms/{jsonable_encoder(form_id)}/submissions", + base_url=self._client_wrapper.get_environment().base, + method="GET", + params={ + "offset": offset, + "limit": limit, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + FormSubmissionList, + parse_obj_as( + type_=FormSubmissionList, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 403: + raise ForbiddenError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def get_submission( + self, site_id: str, form_submission_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> FormSubmission: + """ + Get information about a form submission within a specific site. + + Required scope | `forms:read` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + form_submission_id : str + Unique identifier for a Form Submission + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + FormSubmission + Request was successful + + Examples + -------- + import asyncio + + from webflow import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + + + async def main() -> None: + await client.sites.forms.get_submission( + site_id="580e63e98c9a982ac9b8b741", + form_submission_id="580e63e98c9a982ac9b8b741", + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/form_submissions/{jsonable_encoder(form_submission_id)}", + base_url=self._client_wrapper.get_environment().base, + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + FormSubmission, + parse_obj_as( + type_=FormSubmission, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 403: + raise ForbiddenError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def delete_submission( + self, site_id: str, form_submission_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> None: + """ + Delete a form submission within a specific site. + + Required scope | `forms:write` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + form_submission_id : str + Unique identifier for a Form Submission + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + import asyncio + + from webflow import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + + + async def main() -> None: + await client.sites.forms.delete_submission( + site_id="580e63e98c9a982ac9b8b741", + form_submission_id="580e63e98c9a982ac9b8b741", + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/form_submissions/{jsonable_encoder(form_submission_id)}", + base_url=self._client_wrapper.get_environment().base, + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 403: + raise ForbiddenError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 409: + raise ConflictError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def update_submission( + self, + site_id: str, + form_submission_id: str, + *, + form_submission_data: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> FormSubmission: + """ + Update hidden fields on a form submission within a specific site. + + Required scope | `forms:write` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + form_submission_id : str + Unique identifier for a Form Submission + + form_submission_data : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] + An existing **hidden field** defined on the form schema, and the corresponding value to set + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + FormSubmission + Request was successful + + Examples + -------- + import asyncio + + from webflow import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + + + async def main() -> None: + await client.sites.forms.update_submission( + site_id="580e63e98c9a982ac9b8b741", + form_submission_id="580e63e98c9a982ac9b8b741", + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/form_submissions/{jsonable_encoder(form_submission_id)}", + base_url=self._client_wrapper.get_environment().base, + method="PATCH", + json={ + "formSubmissionData": form_submission_data, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + FormSubmission, + parse_obj_as( + type_=FormSubmission, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 403: + raise ForbiddenError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 409: + raise ConflictError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) diff --git a/src/webflow/resources/sites/resources/plans/client.py b/src/webflow/resources/sites/resources/plans/client.py index 291231a..a3309bb 100644 --- a/src/webflow/resources/sites/resources/plans/client.py +++ b/src/webflow/resources/sites/resources/plans/client.py @@ -25,6 +25,8 @@ def get_site_plan(self, site_id: str, *, request_options: typing.Optional[Reques """ Get site plan details for the specified Site. + This endpoint requires an Enterprise workspace. + Required scope | `sites:read` Parameters @@ -53,6 +55,7 @@ def get_site_plan(self, site_id: str, *, request_options: typing.Optional[Reques """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/plan", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -129,6 +132,8 @@ async def get_site_plan(self, site_id: str, *, request_options: typing.Optional[ """ Get site plan details for the specified Site. + This endpoint requires an Enterprise workspace. + Required scope | `sites:read` Parameters @@ -165,6 +170,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/plan", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) diff --git a/src/webflow/resources/sites/resources/redirects/client.py b/src/webflow/resources/sites/resources/redirects/client.py index 4bc0e7b..1ac17b4 100644 --- a/src/webflow/resources/sites/resources/redirects/client.py +++ b/src/webflow/resources/sites/resources/redirects/client.py @@ -27,10 +27,11 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Redirects: """ - Fetch a list of all URL redirect rules configured for a specific site. + Fetch a list of all 301 redirect rules configured for a specific site. Use this endpoint to review, audit, or manage the redirection rules that control how traffic is rerouted on your site. + This endpoint requires an Enterprise workspace. Required scope: `sites:read` @@ -60,6 +61,7 @@ def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/redirects", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -137,10 +139,12 @@ def create( request_options: typing.Optional[RequestOptions] = None, ) -> Redirect: """ - Add a new URL redirection rule to a site. + Add a new 301 redirection rule to a site. This endpoint allows you to define a source path (`fromUrl`) and its corresponding destination path (`toUrl`), which will dictate how traffic is rerouted on your site. This is useful for managing site changes, restructuring URLs, or handling outdated links. + This endpoint requires an Enterprise workspace. + Required scope: `sites:write` Parameters @@ -181,6 +185,7 @@ def create( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/redirects", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "id": id, @@ -258,8 +263,12 @@ def delete( self, site_id: str, redirect_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> Redirects: """ - Remove a URL redirection rule from a site. + Remove a 301 redirection rule from a site. + This is useful for cleaning up outdated or unnecessary redirects, ensuring that your site's routing behavior remains efficient and up-to-date. + + This endpoint requires an Enterprise workspace. + Required scope: `sites:write` Parameters @@ -292,6 +301,7 @@ def delete( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/redirects/{jsonable_encoder(redirect_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -370,7 +380,10 @@ def update( request_options: typing.Optional[RequestOptions] = None, ) -> Redirect: """ - Update a URL redirection rule from a site. + Update a 301 redirection rule from a site. + + This endpoint requires an Enterprise workspace. + Required scope: `sites:write` Parameters @@ -415,6 +428,7 @@ def update( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/redirects/{jsonable_encoder(redirect_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "id": id, @@ -495,10 +509,11 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): async def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Redirects: """ - Fetch a list of all URL redirect rules configured for a specific site. + Fetch a list of all 301 redirect rules configured for a specific site. Use this endpoint to review, audit, or manage the redirection rules that control how traffic is rerouted on your site. + This endpoint requires an Enterprise workspace. Required scope: `sites:read` @@ -536,6 +551,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/redirects", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -613,10 +629,12 @@ async def create( request_options: typing.Optional[RequestOptions] = None, ) -> Redirect: """ - Add a new URL redirection rule to a site. + Add a new 301 redirection rule to a site. This endpoint allows you to define a source path (`fromUrl`) and its corresponding destination path (`toUrl`), which will dictate how traffic is rerouted on your site. This is useful for managing site changes, restructuring URLs, or handling outdated links. + This endpoint requires an Enterprise workspace. + Required scope: `sites:write` Parameters @@ -665,6 +683,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/redirects", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "id": id, @@ -742,8 +761,12 @@ async def delete( self, site_id: str, redirect_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> Redirects: """ - Remove a URL redirection rule from a site. + Remove a 301 redirection rule from a site. + This is useful for cleaning up outdated or unnecessary redirects, ensuring that your site's routing behavior remains efficient and up-to-date. + + This endpoint requires an Enterprise workspace. + Required scope: `sites:write` Parameters @@ -784,6 +807,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/redirects/{jsonable_encoder(redirect_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -862,7 +886,10 @@ async def update( request_options: typing.Optional[RequestOptions] = None, ) -> Redirect: """ - Update a URL redirection rule from a site. + Update a 301 redirection rule from a site. + + This endpoint requires an Enterprise workspace. + Required scope: `sites:write` Parameters @@ -915,6 +942,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/redirects/{jsonable_encoder(redirect_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "id": id, diff --git a/tests/collections/__init__.py b/src/webflow/resources/sites/resources/robots_txt/__init__.py similarity index 100% rename from tests/collections/__init__.py rename to src/webflow/resources/sites/resources/robots_txt/__init__.py diff --git a/src/webflow/resources/sites/resources/robots_txt/client.py b/src/webflow/resources/sites/resources/robots_txt/client.py new file mode 100644 index 0000000..a0bc59b --- /dev/null +++ b/src/webflow/resources/sites/resources/robots_txt/client.py @@ -0,0 +1,1050 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from .....core.client_wrapper import SyncClientWrapper +from .....core.request_options import RequestOptions +from .....types.robots import Robots +from .....core.jsonable_encoder import jsonable_encoder +from .....core.pydantic_utilities import parse_obj_as +from .....errors.bad_request_error import BadRequestError +from .....errors.unauthorized_error import UnauthorizedError +from .....types.error import Error +from .....errors.not_found_error import NotFoundError +from .....errors.too_many_requests_error import TooManyRequestsError +from .....errors.internal_server_error import InternalServerError +from json.decoder import JSONDecodeError +from .....core.api_error import ApiError +from .....types.robots_rules_item import RobotsRulesItem +from .....core.serialization import convert_and_respect_annotation_metadata +from .....core.client_wrapper import AsyncClientWrapper + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RobotsTxtClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def get(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Robots: + """ + Retrieve the robots.txt configuration for various user agents. + + This endpoint requires an Enterprise workspace. + + Required scope: `site_config:read` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Robots + Request was successful + + Examples + -------- + from webflow import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.sites.robots_txt.get( + site_id="580e63e98c9a982ac9b8b741", + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/robots_txt", + base_url=self._client_wrapper.get_environment().base, + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + Robots, + parse_obj_as( + type_=Robots, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def put( + self, + site_id: str, + *, + rules: typing.Optional[typing.Sequence[RobotsRulesItem]] = OMIT, + sitemap: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> Robots: + """ + Replace the `robots.txt` configuration for various user agents. + + This endpoint requires an Enterprise workspace. + + Required scope | `site_config:write` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + rules : typing.Optional[typing.Sequence[RobotsRulesItem]] + List of rules for user agents. + + sitemap : typing.Optional[str] + URL to the sitemap. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Robots + Request was successful + + Examples + -------- + from webflow import RobotsRulesItem, Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.sites.robots_txt.put( + site_id="580e63e98c9a982ac9b8b741", + rules=[ + RobotsRulesItem( + user_agent="googlebot", + allows=["/public"], + disallows=["/vogon-poetry", "/total-perspective-vortex"], + ) + ], + sitemap="https://heartofgold.ship/sitemap.xml", + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/robots_txt", + base_url=self._client_wrapper.get_environment().base, + method="PUT", + json={ + "rules": convert_and_respect_annotation_metadata( + object_=rules, annotation=typing.Sequence[RobotsRulesItem], direction="write" + ), + "sitemap": sitemap, + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + Robots, + parse_obj_as( + type_=Robots, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def delete( + self, + site_id: str, + *, + rules: typing.Optional[typing.Sequence[RobotsRulesItem]] = OMIT, + sitemap: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> Robots: + """ + Remove specific rules for a user-agent in your `robots.txt` file. To delete all rules for a user-agent, provide an empty rule set. This will remove the user-agent's entry entirely, leaving it subject to your site's default crawling behavior. + + **Note:** Deleting a user-agent with no rules will make the user-agent's access unrestricted unless other directives apply. + + This endpoint requires an Enterprise workspace. + + Required scope: `site_config:write` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + rules : typing.Optional[typing.Sequence[RobotsRulesItem]] + List of rules for user agents. + + sitemap : typing.Optional[str] + URL to the sitemap. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Robots + Request was successful + + Examples + -------- + from webflow import RobotsRulesItem, Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.sites.robots_txt.delete( + site_id="580e63e98c9a982ac9b8b741", + rules=[ + RobotsRulesItem( + user_agent="*", + allows=["/public"], + disallows=["/bubbles"], + ) + ], + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/robots_txt", + base_url=self._client_wrapper.get_environment().base, + method="DELETE", + json={ + "rules": convert_and_respect_annotation_metadata( + object_=rules, annotation=typing.Sequence[RobotsRulesItem], direction="write" + ), + "sitemap": sitemap, + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + Robots, + parse_obj_as( + type_=Robots, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def patch( + self, + site_id: str, + *, + rules: typing.Optional[typing.Sequence[RobotsRulesItem]] = OMIT, + sitemap: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> Robots: + """ + Update the `robots.txt` configuration for various user agents. + + This endpoint requires an Enterprise workspace. + + Required scope | `site_config:write` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + rules : typing.Optional[typing.Sequence[RobotsRulesItem]] + List of rules for user agents. + + sitemap : typing.Optional[str] + URL to the sitemap. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Robots + Request was successful + + Examples + -------- + from webflow import RobotsRulesItem, Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.sites.robots_txt.patch( + site_id="580e63e98c9a982ac9b8b741", + rules=[ + RobotsRulesItem( + user_agent="googlebot", + allows=["/public"], + disallows=["/vogon-poetry", "/total-perspective-vortex"], + ) + ], + sitemap="https://heartofgold.ship/sitemap.xml", + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/robots_txt", + base_url=self._client_wrapper.get_environment().base, + method="PATCH", + json={ + "rules": convert_and_respect_annotation_metadata( + object_=rules, annotation=typing.Sequence[RobotsRulesItem], direction="write" + ), + "sitemap": sitemap, + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + Robots, + parse_obj_as( + type_=Robots, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + +class AsyncRobotsTxtClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def get(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Robots: + """ + Retrieve the robots.txt configuration for various user agents. + + This endpoint requires an Enterprise workspace. + + Required scope: `site_config:read` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Robots + Request was successful + + Examples + -------- + import asyncio + + from webflow import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + + + async def main() -> None: + await client.sites.robots_txt.get( + site_id="580e63e98c9a982ac9b8b741", + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/robots_txt", + base_url=self._client_wrapper.get_environment().base, + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + Robots, + parse_obj_as( + type_=Robots, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def put( + self, + site_id: str, + *, + rules: typing.Optional[typing.Sequence[RobotsRulesItem]] = OMIT, + sitemap: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> Robots: + """ + Replace the `robots.txt` configuration for various user agents. + + This endpoint requires an Enterprise workspace. + + Required scope | `site_config:write` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + rules : typing.Optional[typing.Sequence[RobotsRulesItem]] + List of rules for user agents. + + sitemap : typing.Optional[str] + URL to the sitemap. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Robots + Request was successful + + Examples + -------- + import asyncio + + from webflow import AsyncWebflow, RobotsRulesItem + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + + + async def main() -> None: + await client.sites.robots_txt.put( + site_id="580e63e98c9a982ac9b8b741", + rules=[ + RobotsRulesItem( + user_agent="googlebot", + allows=["/public"], + disallows=["/vogon-poetry", "/total-perspective-vortex"], + ) + ], + sitemap="https://heartofgold.ship/sitemap.xml", + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/robots_txt", + base_url=self._client_wrapper.get_environment().base, + method="PUT", + json={ + "rules": convert_and_respect_annotation_metadata( + object_=rules, annotation=typing.Sequence[RobotsRulesItem], direction="write" + ), + "sitemap": sitemap, + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + Robots, + parse_obj_as( + type_=Robots, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def delete( + self, + site_id: str, + *, + rules: typing.Optional[typing.Sequence[RobotsRulesItem]] = OMIT, + sitemap: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> Robots: + """ + Remove specific rules for a user-agent in your `robots.txt` file. To delete all rules for a user-agent, provide an empty rule set. This will remove the user-agent's entry entirely, leaving it subject to your site's default crawling behavior. + + **Note:** Deleting a user-agent with no rules will make the user-agent's access unrestricted unless other directives apply. + + This endpoint requires an Enterprise workspace. + + Required scope: `site_config:write` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + rules : typing.Optional[typing.Sequence[RobotsRulesItem]] + List of rules for user agents. + + sitemap : typing.Optional[str] + URL to the sitemap. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Robots + Request was successful + + Examples + -------- + import asyncio + + from webflow import AsyncWebflow, RobotsRulesItem + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + + + async def main() -> None: + await client.sites.robots_txt.delete( + site_id="580e63e98c9a982ac9b8b741", + rules=[ + RobotsRulesItem( + user_agent="*", + allows=["/public"], + disallows=["/bubbles"], + ) + ], + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/robots_txt", + base_url=self._client_wrapper.get_environment().base, + method="DELETE", + json={ + "rules": convert_and_respect_annotation_metadata( + object_=rules, annotation=typing.Sequence[RobotsRulesItem], direction="write" + ), + "sitemap": sitemap, + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + Robots, + parse_obj_as( + type_=Robots, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def patch( + self, + site_id: str, + *, + rules: typing.Optional[typing.Sequence[RobotsRulesItem]] = OMIT, + sitemap: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> Robots: + """ + Update the `robots.txt` configuration for various user agents. + + This endpoint requires an Enterprise workspace. + + Required scope | `site_config:write` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + rules : typing.Optional[typing.Sequence[RobotsRulesItem]] + List of rules for user agents. + + sitemap : typing.Optional[str] + URL to the sitemap. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Robots + Request was successful + + Examples + -------- + import asyncio + + from webflow import AsyncWebflow, RobotsRulesItem + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + + + async def main() -> None: + await client.sites.robots_txt.patch( + site_id="580e63e98c9a982ac9b8b741", + rules=[ + RobotsRulesItem( + user_agent="googlebot", + allows=["/public"], + disallows=["/vogon-poetry", "/total-perspective-vortex"], + ) + ], + sitemap="https://heartofgold.ship/sitemap.xml", + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/robots_txt", + base_url=self._client_wrapper.get_environment().base, + method="PATCH", + json={ + "rules": convert_and_respect_annotation_metadata( + object_=rules, annotation=typing.Sequence[RobotsRulesItem], direction="write" + ), + "sitemap": sitemap, + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + Robots, + parse_obj_as( + type_=Robots, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) diff --git a/src/webflow/resources/sites/resources/scripts/client.py b/src/webflow/resources/sites/resources/scripts/client.py index 1954842..cd62c14 100644 --- a/src/webflow/resources/sites/resources/scripts/client.py +++ b/src/webflow/resources/sites/resources/scripts/client.py @@ -31,9 +31,11 @@ def get_custom_code( self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> ScriptApplyList: """ - Get all registered scripts that have been applied to a specific Site. + Get all scripts applied to a site by the App. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:read` @@ -63,6 +65,7 @@ def get_custom_code( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/custom_code", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -140,13 +143,11 @@ def upsert_custom_code( request_options: typing.Optional[RequestOptions] = None, ) -> ScriptApplyList: """ - Add a registered script to a Site. + Apply registered scripts to a site. If you have multiple scripts your App needs to apply or maintain on a site, ensure they are always included in the request body for this endpoint. To remove individual scripts, simply call this endpoint without the script in the request body. - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. - - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:write` @@ -198,6 +199,7 @@ def upsert_custom_code( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/custom_code", + base_url=self._client_wrapper.get_environment().base, method="PUT", json={ "scripts": convert_and_respect_annotation_metadata( @@ -275,9 +277,11 @@ def upsert_custom_code( def delete_custom_code(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None: """ - Delete the custom code block that an app created for a Site + Remove all scripts from a site applied by the App. This endpoint will not remove scripts from the site's registered scripts. + + To remove individual scripts applied by the App, use the [Add/Update Custom Code](/data/reference/custom-code/custom-code-sites/upsert-custom-code) endpoint. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + Access to this endpoint requires a bearer token obtained from an [OAuth Code Grant Flow](/data/reference/oauth-app). Required scope | `custom_code:write` @@ -306,6 +310,7 @@ def delete_custom_code(self, site_id: str, *, request_options: typing.Optional[R """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/custom_code", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -376,9 +381,13 @@ def list_custom_code_blocks( request_options: typing.Optional[RequestOptions] = None, ) -> ListCustomCodeBlocks: """ - Get all instances of Custom Code applied to a Site or Pages. + Get a list of scripts that have been applied to a site and/or individual pages. + + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:read` @@ -410,10 +419,13 @@ def list_custom_code_blocks( ) client.sites.scripts.list_custom_code_blocks( site_id="580e63e98c9a982ac9b8b741", + offset=1.1, + limit=1.1, ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/custom_code/blocks", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "offset": offset, @@ -494,9 +506,11 @@ async def get_custom_code( self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> ScriptApplyList: """ - Get all registered scripts that have been applied to a specific Site. + Get all scripts applied to a site by the App. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:read` @@ -534,6 +548,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/custom_code", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -611,13 +626,11 @@ async def upsert_custom_code( request_options: typing.Optional[RequestOptions] = None, ) -> ScriptApplyList: """ - Add a registered script to a Site. + Apply registered scripts to a site. If you have multiple scripts your App needs to apply or maintain on a site, ensure they are always included in the request body for this endpoint. To remove individual scripts, simply call this endpoint without the script in the request body. - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. - - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:write` @@ -677,6 +690,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/custom_code", + base_url=self._client_wrapper.get_environment().base, method="PUT", json={ "scripts": convert_and_respect_annotation_metadata( @@ -756,9 +770,11 @@ async def delete_custom_code( self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> None: """ - Delete the custom code block that an app created for a Site + Remove all scripts from a site applied by the App. This endpoint will not remove scripts from the site's registered scripts. + + To remove individual scripts applied by the App, use the [Add/Update Custom Code](/data/reference/custom-code/custom-code-sites/upsert-custom-code) endpoint. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + Access to this endpoint requires a bearer token obtained from an [OAuth Code Grant Flow](/data/reference/oauth-app). Required scope | `custom_code:write` @@ -795,6 +811,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/custom_code", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -865,9 +882,13 @@ async def list_custom_code_blocks( request_options: typing.Optional[RequestOptions] = None, ) -> ListCustomCodeBlocks: """ - Get all instances of Custom Code applied to a Site or Pages. + Get a list of scripts that have been applied to a site and/or individual pages. + + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:read` @@ -904,6 +925,8 @@ async def list_custom_code_blocks( async def main() -> None: await client.sites.scripts.list_custom_code_blocks( site_id="580e63e98c9a982ac9b8b741", + offset=1.1, + limit=1.1, ) @@ -911,6 +934,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/custom_code/blocks", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "offset": offset, diff --git a/src/webflow/resources/sites/resources/well_known/__init__.py b/src/webflow/resources/sites/resources/well_known/__init__.py new file mode 100644 index 0000000..323b6bd --- /dev/null +++ b/src/webflow/resources/sites/resources/well_known/__init__.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from .types import WellKnownFileContentType + +__all__ = ["WellKnownFileContentType"] diff --git a/src/webflow/resources/sites/resources/well_known/client.py b/src/webflow/resources/sites/resources/well_known/client.py new file mode 100644 index 0000000..3bba9ab --- /dev/null +++ b/src/webflow/resources/sites/resources/well_known/client.py @@ -0,0 +1,534 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from .....core.client_wrapper import SyncClientWrapper +from .types.well_known_file_content_type import WellKnownFileContentType +from .....core.request_options import RequestOptions +from .....core.jsonable_encoder import jsonable_encoder +from .....errors.bad_request_error import BadRequestError +from .....core.pydantic_utilities import parse_obj_as +from .....errors.unauthorized_error import UnauthorizedError +from .....types.error import Error +from .....errors.not_found_error import NotFoundError +from .....errors.too_many_requests_error import TooManyRequestsError +from .....errors.internal_server_error import InternalServerError +from json.decoder import JSONDecodeError +from .....core.api_error import ApiError +from .....core.client_wrapper import AsyncClientWrapper + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class WellKnownClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def put( + self, + site_id: str, + *, + file_name: str, + file_data: str, + content_type: typing.Optional[WellKnownFileContentType] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> None: + """ + Upload a supported well-known file to a site. + + The current restrictions on well-known files are as follows: + - Each file must be smaller than 100kb + - Less than 30 total files + - Have one of the following file extensions (or no extension): `.txt`, `.json`, `.noext` + + + `.noext` is a special file extension that removes other extensions. For example, `apple-app-site-association.noext.txt` will be uploaded as `apple-app-site-association`. Use this extension for tools that have trouble uploading extensionless files. + + + This endpoint requires an Enterprise workspace. + + Required scope: `site_config:write` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + file_name : str + The name of the file + + file_data : str + The contents of the file + + content_type : typing.Optional[WellKnownFileContentType] + The content type of the file. Defaults to application/json + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + from webflow import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.sites.well_known.put( + site_id="580e63e98c9a982ac9b8b741", + file_name="apple-app-site-association.txt", + file_data='{\n "applinks": {\n "apps": [],\n "details": [\n {\n "appID": "ABCDE12345.com.example.app",\n "paths": [ "/*", "/some/path/*" ]\n }\n ]\n }\n}\n', + content_type="application/json", + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/well_known", + base_url=self._client_wrapper.get_environment().base, + method="PUT", + json={ + "fileName": file_name, + "fileData": file_data, + "contentType": content_type, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def delete( + self, + site_id: str, + *, + file_names: typing.Optional[typing.Sequence[str]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> None: + """ + Delete existing well-known files from a site. + + This endpoint requires an Enterprise workspace. + + Required scope: `site_config:write` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + file_names : typing.Optional[typing.Sequence[str]] + A list of file names to delete + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + from webflow import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.sites.well_known.delete( + site_id="580e63e98c9a982ac9b8b741", + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/well_known", + base_url=self._client_wrapper.get_environment().base, + method="DELETE", + json={ + "fileNames": file_names, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + +class AsyncWellKnownClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def put( + self, + site_id: str, + *, + file_name: str, + file_data: str, + content_type: typing.Optional[WellKnownFileContentType] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> None: + """ + Upload a supported well-known file to a site. + + The current restrictions on well-known files are as follows: + - Each file must be smaller than 100kb + - Less than 30 total files + - Have one of the following file extensions (or no extension): `.txt`, `.json`, `.noext` + + + `.noext` is a special file extension that removes other extensions. For example, `apple-app-site-association.noext.txt` will be uploaded as `apple-app-site-association`. Use this extension for tools that have trouble uploading extensionless files. + + + This endpoint requires an Enterprise workspace. + + Required scope: `site_config:write` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + file_name : str + The name of the file + + file_data : str + The contents of the file + + content_type : typing.Optional[WellKnownFileContentType] + The content type of the file. Defaults to application/json + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + import asyncio + + from webflow import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + + + async def main() -> None: + await client.sites.well_known.put( + site_id="580e63e98c9a982ac9b8b741", + file_name="apple-app-site-association.txt", + file_data='{\n "applinks": {\n "apps": [],\n "details": [\n {\n "appID": "ABCDE12345.com.example.app",\n "paths": [ "/*", "/some/path/*" ]\n }\n ]\n }\n}\n', + content_type="application/json", + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/well_known", + base_url=self._client_wrapper.get_environment().base, + method="PUT", + json={ + "fileName": file_name, + "fileData": file_data, + "contentType": content_type, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def delete( + self, + site_id: str, + *, + file_names: typing.Optional[typing.Sequence[str]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> None: + """ + Delete existing well-known files from a site. + + This endpoint requires an Enterprise workspace. + + Required scope: `site_config:write` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + file_names : typing.Optional[typing.Sequence[str]] + A list of file names to delete + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + import asyncio + + from webflow import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + + + async def main() -> None: + await client.sites.well_known.delete( + site_id="580e63e98c9a982ac9b8b741", + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/well_known", + base_url=self._client_wrapper.get_environment().base, + method="DELETE", + json={ + "fileNames": file_names, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) diff --git a/src/webflow/resources/sites/resources/well_known/types/__init__.py b/src/webflow/resources/sites/resources/well_known/types/__init__.py new file mode 100644 index 0000000..4fc9c09 --- /dev/null +++ b/src/webflow/resources/sites/resources/well_known/types/__init__.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from .well_known_file_content_type import WellKnownFileContentType + +__all__ = ["WellKnownFileContentType"] diff --git a/src/webflow/resources/sites/resources/well_known/types/well_known_file_content_type.py b/src/webflow/resources/sites/resources/well_known/types/well_known_file_content_type.py new file mode 100644 index 0000000..be135b4 --- /dev/null +++ b/src/webflow/resources/sites/resources/well_known/types/well_known_file_content_type.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +WellKnownFileContentType = typing.Union[typing.Literal["application/json", "text/plain"], typing.Any] diff --git a/src/webflow/resources/token/client.py b/src/webflow/resources/token/client.py index 628ce3a..d8cfd16 100644 --- a/src/webflow/resources/token/client.py +++ b/src/webflow/resources/token/client.py @@ -45,6 +45,7 @@ def authorized_by(self, *, request_options: typing.Optional[RequestOptions] = No """ _response = self._client_wrapper.httpx_client.request( "token/authorized_by", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -109,6 +110,7 @@ def introspect(self, *, request_options: typing.Optional[RequestOptions] = None) """ _response = self._client_wrapper.httpx_client.request( "token/introspect", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -176,6 +178,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( "token/authorized_by", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -248,6 +251,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( "token/introspect", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) diff --git a/src/webflow/resources/users/__init__.py b/src/webflow/resources/users/__init__.py index 88e72a2..b191e61 100644 --- a/src/webflow/resources/users/__init__.py +++ b/src/webflow/resources/users/__init__.py @@ -1,5 +1,27 @@ # This file was auto-generated by Fern from our API Definition. -from .types import UsersListRequestSort, UsersUpdateRequestData +from .types import ( + UserAccountAddedPayload, + UserAccountAddedPayloadPayload, + UserAccountAddedPayloadPayloadData, + UserAccountDeletedPayload, + UserAccountDeletedPayloadPayload, + UserAccountDeletedPayloadPayloadData, + UserAccountUpdatedPayload, + UserAccountUpdatedPayloadPayload, + UserAccountUpdatedPayloadPayloadData, + UsersListRequestSort, +) -__all__ = ["UsersListRequestSort", "UsersUpdateRequestData"] +__all__ = [ + "UserAccountAddedPayload", + "UserAccountAddedPayloadPayload", + "UserAccountAddedPayloadPayloadData", + "UserAccountDeletedPayload", + "UserAccountDeletedPayloadPayload", + "UserAccountDeletedPayloadPayloadData", + "UserAccountUpdatedPayload", + "UserAccountUpdatedPayloadPayload", + "UserAccountUpdatedPayloadPayloadData", + "UsersListRequestSort", +] diff --git a/src/webflow/resources/users/client.py b/src/webflow/resources/users/client.py index d690c0f..3a8af3f 100644 --- a/src/webflow/resources/users/client.py +++ b/src/webflow/resources/users/client.py @@ -17,7 +17,10 @@ from json.decoder import JSONDecodeError from ...core.api_error import ApiError from ...types.user import User -from .types.users_update_request_data import UsersUpdateRequestData +import datetime as dt +from ...types.user_status import UserStatus +from ...types.user_access_groups_item import UserAccessGroupsItem +from ...types.user_data import UserData from ...core.serialization import convert_and_respect_annotation_metadata from ...errors.conflict_error import ConflictError from ...core.client_wrapper import AsyncClientWrapper @@ -79,10 +82,14 @@ def list( ) client.users.list( site_id="580e63e98c9a982ac9b8b741", + offset=1.1, + limit=1.1, + sort="CreatedOn", ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/users", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "offset": offset, @@ -201,6 +208,7 @@ def get(self, site_id: str, user_id: str, *, request_options: typing.Optional[Re """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/users/{jsonable_encoder(user_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -313,6 +321,7 @@ def delete(self, site_id: str, user_id: str, *, request_options: typing.Optional """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/users/{jsonable_encoder(user_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -389,8 +398,15 @@ def update( site_id: str, user_id: str, *, - data: typing.Optional[UsersUpdateRequestData] = OMIT, - access_groups: typing.Optional[typing.Sequence[str]] = OMIT, + id: typing.Optional[str] = OMIT, + is_email_verified: typing.Optional[bool] = OMIT, + last_updated: typing.Optional[dt.datetime] = OMIT, + invited_on: typing.Optional[dt.datetime] = OMIT, + created_on: typing.Optional[dt.datetime] = OMIT, + last_login: typing.Optional[dt.datetime] = OMIT, + status: typing.Optional[UserStatus] = OMIT, + access_groups: typing.Optional[typing.Sequence[UserAccessGroupsItem]] = OMIT, + data: typing.Optional[UserData] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> User: """ @@ -409,11 +425,30 @@ def update( user_id : str Unique identifier for a User - data : typing.Optional[UsersUpdateRequestData] + id : typing.Optional[str] + Unique identifier for the User - access_groups : typing.Optional[typing.Sequence[str]] - An array of access group slugs. Access groups are assigned to the user as type `admin` and the user remains in the group until removed. + is_email_verified : typing.Optional[bool] + Shows whether the user has verified their email address + + last_updated : typing.Optional[dt.datetime] + The timestamp the user was updated + + invited_on : typing.Optional[dt.datetime] + The timestamp the user was invited + created_on : typing.Optional[dt.datetime] + The timestamp the user was created + + last_login : typing.Optional[dt.datetime] + The timestamp the user was logged in + + status : typing.Optional[UserStatus] + + access_groups : typing.Optional[typing.Sequence[UserAccessGroupsItem]] + Access groups the user belongs to + + data : typing.Optional[UserData] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -425,8 +460,9 @@ def update( Examples -------- - from webflow import Webflow - from webflow.resources.users import UsersUpdateRequestData + import datetime + + from webflow import UserAccessGroupsItem, Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", @@ -434,25 +470,45 @@ def update( client.users.update( site_id="580e63e98c9a982ac9b8b741", user_id="580e63e98c9a982ac9b8b741", - data=UsersUpdateRequestData( - name="Some One", - accept_privacy=False, - accept_communications=False, + id="6287ec36a841b25637c663df", + is_email_verified=True, + last_updated=datetime.datetime.fromisoformat( + "2022-05-20 13:46:12+00:00", + ), + invited_on=datetime.datetime.fromisoformat( + "2022-05-20 13:46:12+00:00", + ), + created_on=datetime.datetime.fromisoformat( + "2022-05-20 13:46:12+00:00", ), - access_groups=["webflowers", "platinum", "free-tier"], + last_login=datetime.datetime.fromisoformat( + "2022-05-20 13:46:12+00:00", + ), + status="verified", + access_groups=[ + UserAccessGroupsItem( + slug="webflowers", + type="admin", + ) + ], ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/users/{jsonable_encoder(user_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ - "data": convert_and_respect_annotation_metadata( - object_=data, annotation=UsersUpdateRequestData, direction="write" + "id": id, + "isEmailVerified": is_email_verified, + "lastUpdated": last_updated, + "invitedOn": invited_on, + "createdOn": created_on, + "lastLogin": last_login, + "status": status, + "accessGroups": convert_and_respect_annotation_metadata( + object_=access_groups, annotation=typing.Sequence[UserAccessGroupsItem], direction="write" ), - "accessGroups": access_groups, - }, - headers={ - "content-type": "application/json", + "data": convert_and_respect_annotation_metadata(object_=data, annotation=UserData, direction="write"), }, request_options=request_options, omit=OMIT, @@ -557,7 +613,6 @@ def invite( access_groups : typing.Optional[typing.Sequence[str]] An array of access group slugs. Access groups are assigned to the user as type `admin` and the user remains in the group until removed. - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -576,11 +631,12 @@ def invite( client.users.invite( site_id="580e63e98c9a982ac9b8b741", email="some.one@home.com", - access_groups=["webflowers"], + access_groups=["accessGroups"], ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/users/invite", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "email": email, @@ -735,6 +791,9 @@ async def list( async def main() -> None: await client.users.list( site_id="580e63e98c9a982ac9b8b741", + offset=1.1, + limit=1.1, + sort="CreatedOn", ) @@ -742,6 +801,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/users", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "offset": offset, @@ -868,6 +928,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/users/{jsonable_encoder(user_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -990,6 +1051,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/users/{jsonable_encoder(user_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -1066,8 +1128,15 @@ async def update( site_id: str, user_id: str, *, - data: typing.Optional[UsersUpdateRequestData] = OMIT, - access_groups: typing.Optional[typing.Sequence[str]] = OMIT, + id: typing.Optional[str] = OMIT, + is_email_verified: typing.Optional[bool] = OMIT, + last_updated: typing.Optional[dt.datetime] = OMIT, + invited_on: typing.Optional[dt.datetime] = OMIT, + created_on: typing.Optional[dt.datetime] = OMIT, + last_login: typing.Optional[dt.datetime] = OMIT, + status: typing.Optional[UserStatus] = OMIT, + access_groups: typing.Optional[typing.Sequence[UserAccessGroupsItem]] = OMIT, + data: typing.Optional[UserData] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> User: """ @@ -1086,11 +1155,30 @@ async def update( user_id : str Unique identifier for a User - data : typing.Optional[UsersUpdateRequestData] + id : typing.Optional[str] + Unique identifier for the User - access_groups : typing.Optional[typing.Sequence[str]] - An array of access group slugs. Access groups are assigned to the user as type `admin` and the user remains in the group until removed. + is_email_verified : typing.Optional[bool] + Shows whether the user has verified their email address + + last_updated : typing.Optional[dt.datetime] + The timestamp the user was updated + + invited_on : typing.Optional[dt.datetime] + The timestamp the user was invited + created_on : typing.Optional[dt.datetime] + The timestamp the user was created + + last_login : typing.Optional[dt.datetime] + The timestamp the user was logged in + + status : typing.Optional[UserStatus] + + access_groups : typing.Optional[typing.Sequence[UserAccessGroupsItem]] + Access groups the user belongs to + + data : typing.Optional[UserData] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1103,9 +1191,9 @@ async def update( Examples -------- import asyncio + import datetime - from webflow import AsyncWebflow - from webflow.resources.users import UsersUpdateRequestData + from webflow import AsyncWebflow, UserAccessGroupsItem client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", @@ -1116,12 +1204,27 @@ async def main() -> None: await client.users.update( site_id="580e63e98c9a982ac9b8b741", user_id="580e63e98c9a982ac9b8b741", - data=UsersUpdateRequestData( - name="Some One", - accept_privacy=False, - accept_communications=False, + id="6287ec36a841b25637c663df", + is_email_verified=True, + last_updated=datetime.datetime.fromisoformat( + "2022-05-20 13:46:12+00:00", ), - access_groups=["webflowers", "platinum", "free-tier"], + invited_on=datetime.datetime.fromisoformat( + "2022-05-20 13:46:12+00:00", + ), + created_on=datetime.datetime.fromisoformat( + "2022-05-20 13:46:12+00:00", + ), + last_login=datetime.datetime.fromisoformat( + "2022-05-20 13:46:12+00:00", + ), + status="verified", + access_groups=[ + UserAccessGroupsItem( + slug="webflowers", + type="admin", + ) + ], ) @@ -1129,15 +1232,20 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/users/{jsonable_encoder(user_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ - "data": convert_and_respect_annotation_metadata( - object_=data, annotation=UsersUpdateRequestData, direction="write" + "id": id, + "isEmailVerified": is_email_verified, + "lastUpdated": last_updated, + "invitedOn": invited_on, + "createdOn": created_on, + "lastLogin": last_login, + "status": status, + "accessGroups": convert_and_respect_annotation_metadata( + object_=access_groups, annotation=typing.Sequence[UserAccessGroupsItem], direction="write" ), - "accessGroups": access_groups, - }, - headers={ - "content-type": "application/json", + "data": convert_and_respect_annotation_metadata(object_=data, annotation=UserData, direction="write"), }, request_options=request_options, omit=OMIT, @@ -1242,7 +1350,6 @@ async def invite( access_groups : typing.Optional[typing.Sequence[str]] An array of access group slugs. Access groups are assigned to the user as type `admin` and the user remains in the group until removed. - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1266,7 +1373,7 @@ async def main() -> None: await client.users.invite( site_id="580e63e98c9a982ac9b8b741", email="some.one@home.com", - access_groups=["webflowers"], + access_groups=["accessGroups"], ) @@ -1274,6 +1381,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/users/invite", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "email": email, diff --git a/src/webflow/resources/users/types/__init__.py b/src/webflow/resources/users/types/__init__.py index cadf367..ca99b25 100644 --- a/src/webflow/resources/users/types/__init__.py +++ b/src/webflow/resources/users/types/__init__.py @@ -1,6 +1,25 @@ # This file was auto-generated by Fern from our API Definition. +from .user_account_added_payload import UserAccountAddedPayload +from .user_account_added_payload_payload import UserAccountAddedPayloadPayload +from .user_account_added_payload_payload_data import UserAccountAddedPayloadPayloadData +from .user_account_deleted_payload import UserAccountDeletedPayload +from .user_account_deleted_payload_payload import UserAccountDeletedPayloadPayload +from .user_account_deleted_payload_payload_data import UserAccountDeletedPayloadPayloadData +from .user_account_updated_payload import UserAccountUpdatedPayload +from .user_account_updated_payload_payload import UserAccountUpdatedPayloadPayload +from .user_account_updated_payload_payload_data import UserAccountUpdatedPayloadPayloadData from .users_list_request_sort import UsersListRequestSort -from .users_update_request_data import UsersUpdateRequestData -__all__ = ["UsersListRequestSort", "UsersUpdateRequestData"] +__all__ = [ + "UserAccountAddedPayload", + "UserAccountAddedPayloadPayload", + "UserAccountAddedPayloadPayloadData", + "UserAccountDeletedPayload", + "UserAccountDeletedPayloadPayload", + "UserAccountDeletedPayloadPayloadData", + "UserAccountUpdatedPayload", + "UserAccountUpdatedPayloadPayload", + "UserAccountUpdatedPayloadPayloadData", + "UsersListRequestSort", +] diff --git a/src/webflow/resources/users/types/user_account_added_payload.py b/src/webflow/resources/users/types/user_account_added_payload.py new file mode 100644 index 0000000..40e4e20 --- /dev/null +++ b/src/webflow/resources/users/types/user_account_added_payload.py @@ -0,0 +1,25 @@ +# This file was auto-generated by Fern from our API Definition. + +from ....core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ....core.serialization import FieldMetadata +from .user_account_added_payload_payload import UserAccountAddedPayloadPayload +from ....core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class UserAccountAddedPayload(UniversalBaseModel): + trigger_type: typing_extensions.Annotated[ + typing.Optional[typing.Literal["user_account_added"]], FieldMetadata(alias="triggerType") + ] = None + payload: typing.Optional[UserAccountAddedPayloadPayload] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/resources/users/types/user_account_added_payload_payload.py b/src/webflow/resources/users/types/user_account_added_payload_payload.py new file mode 100644 index 0000000..318b7d3 --- /dev/null +++ b/src/webflow/resources/users/types/user_account_added_payload_payload.py @@ -0,0 +1,76 @@ +# This file was auto-generated by Fern from our API Definition. + +from ....core.pydantic_utilities import UniversalBaseModel +import typing +from .user_account_added_payload_payload_data import UserAccountAddedPayloadPayloadData +import pydantic +import typing_extensions +from ....core.serialization import FieldMetadata +import datetime as dt +from ....types.user_status import UserStatus +from ....types.user_access_groups_item import UserAccessGroupsItem +from ....core.pydantic_utilities import IS_PYDANTIC_V2 + + +class UserAccountAddedPayloadPayload(UniversalBaseModel): + data: typing.Optional[UserAccountAddedPayloadPayloadData] = pydantic.Field(default=None) + """ + The data about the user account that was added + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + Unique identifier for the User + """ + + is_email_verified: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="isEmailVerified")] = ( + pydantic.Field(default=None) + ) + """ + Shows whether the user has verified their email address + """ + + last_updated: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="lastUpdated")] = ( + pydantic.Field(default=None) + ) + """ + The timestamp the user was updated + """ + + invited_on: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="invitedOn")] = ( + pydantic.Field(default=None) + ) + """ + The timestamp the user was invited + """ + + created_on: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="createdOn")] = ( + pydantic.Field(default=None) + ) + """ + The timestamp the user was created + """ + + last_login: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="lastLogin")] = ( + pydantic.Field(default=None) + ) + """ + The timestamp the user was logged in + """ + + status: typing.Optional[UserStatus] = None + access_groups: typing_extensions.Annotated[ + typing.Optional[typing.List[UserAccessGroupsItem]], FieldMetadata(alias="accessGroups") + ] = pydantic.Field(default=None) + """ + Access groups the user belongs to + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/resources/users/types/users_update_request_data.py b/src/webflow/resources/users/types/user_account_added_payload_payload_data.py similarity index 59% rename from src/webflow/resources/users/types/users_update_request_data.py rename to src/webflow/resources/users/types/user_account_added_payload_payload_data.py index 919406c..c5a668a 100644 --- a/src/webflow/resources/users/types/users_update_request_data.py +++ b/src/webflow/resources/users/types/user_account_added_payload_payload_data.py @@ -1,32 +1,26 @@ # This file was auto-generated by Fern from our API Definition. from ....core.pydantic_utilities import UniversalBaseModel -import typing -import pydantic import typing_extensions +import typing from ....core.serialization import FieldMetadata from ....core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic -class UsersUpdateRequestData(UniversalBaseModel): - name: typing.Optional[str] = pydantic.Field(default=None) +class UserAccountAddedPayloadPayloadData(UniversalBaseModel): """ - The name of the user - """ - - accept_privacy: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="accept-privacy")] = ( - pydantic.Field(default=None) - ) - """ - Boolean indicating if the user has accepted the privacy policy + The data about the user account that was added """ + accept_privacy_policy: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="accept-privacy-policy") + ] = None accept_communications: typing_extensions.Annotated[ typing.Optional[bool], FieldMetadata(alias="accept-communications") - ] = pydantic.Field(default=None) - """ - Boolean indicating if the user has accepted to receive communications - """ + ] = None + email: typing.Optional[str] = None + name: typing.Optional[str] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/webflow/resources/users/types/user_account_deleted_payload.py b/src/webflow/resources/users/types/user_account_deleted_payload.py new file mode 100644 index 0000000..2d2aef8 --- /dev/null +++ b/src/webflow/resources/users/types/user_account_deleted_payload.py @@ -0,0 +1,25 @@ +# This file was auto-generated by Fern from our API Definition. + +from ....core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ....core.serialization import FieldMetadata +from .user_account_deleted_payload_payload import UserAccountDeletedPayloadPayload +from ....core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class UserAccountDeletedPayload(UniversalBaseModel): + trigger_type: typing_extensions.Annotated[ + typing.Optional[typing.Literal["user_account_deleted"]], FieldMetadata(alias="triggerType") + ] = None + payload: typing.Optional[UserAccountDeletedPayloadPayload] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/resources/users/types/user_account_deleted_payload_payload.py b/src/webflow/resources/users/types/user_account_deleted_payload_payload.py new file mode 100644 index 0000000..a839489 --- /dev/null +++ b/src/webflow/resources/users/types/user_account_deleted_payload_payload.py @@ -0,0 +1,76 @@ +# This file was auto-generated by Fern from our API Definition. + +from ....core.pydantic_utilities import UniversalBaseModel +import typing +from .user_account_deleted_payload_payload_data import UserAccountDeletedPayloadPayloadData +import pydantic +import typing_extensions +from ....core.serialization import FieldMetadata +import datetime as dt +from ....types.user_status import UserStatus +from ....types.user_access_groups_item import UserAccessGroupsItem +from ....core.pydantic_utilities import IS_PYDANTIC_V2 + + +class UserAccountDeletedPayloadPayload(UniversalBaseModel): + data: typing.Optional[UserAccountDeletedPayloadPayloadData] = pydantic.Field(default=None) + """ + The data about the user account that was added + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + Unique identifier for the User + """ + + is_email_verified: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="isEmailVerified")] = ( + pydantic.Field(default=None) + ) + """ + Shows whether the user has verified their email address + """ + + last_updated: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="lastUpdated")] = ( + pydantic.Field(default=None) + ) + """ + The timestamp the user was updated + """ + + invited_on: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="invitedOn")] = ( + pydantic.Field(default=None) + ) + """ + The timestamp the user was invited + """ + + created_on: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="createdOn")] = ( + pydantic.Field(default=None) + ) + """ + The timestamp the user was created + """ + + last_login: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="lastLogin")] = ( + pydantic.Field(default=None) + ) + """ + The timestamp the user was logged in + """ + + status: typing.Optional[UserStatus] = None + access_groups: typing_extensions.Annotated[ + typing.Optional[typing.List[UserAccessGroupsItem]], FieldMetadata(alias="accessGroups") + ] = pydantic.Field(default=None) + """ + Access groups the user belongs to + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/resources/users/types/user_account_deleted_payload_payload_data.py b/src/webflow/resources/users/types/user_account_deleted_payload_payload_data.py new file mode 100644 index 0000000..2d65fd3 --- /dev/null +++ b/src/webflow/resources/users/types/user_account_deleted_payload_payload_data.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +from ....core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ....core.serialization import FieldMetadata +from ....core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class UserAccountDeletedPayloadPayloadData(UniversalBaseModel): + """ + The data about the user account that was added + """ + + accept_privacy_policy: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="accept-privacy-policy") + ] = None + accept_communications: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="accept-communications") + ] = None + email: typing.Optional[str] = None + name: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/resources/users/types/user_account_updated_payload.py b/src/webflow/resources/users/types/user_account_updated_payload.py new file mode 100644 index 0000000..6c733c1 --- /dev/null +++ b/src/webflow/resources/users/types/user_account_updated_payload.py @@ -0,0 +1,25 @@ +# This file was auto-generated by Fern from our API Definition. + +from ....core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ....core.serialization import FieldMetadata +from .user_account_updated_payload_payload import UserAccountUpdatedPayloadPayload +from ....core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class UserAccountUpdatedPayload(UniversalBaseModel): + trigger_type: typing_extensions.Annotated[ + typing.Optional[typing.Literal["user_account_updated"]], FieldMetadata(alias="triggerType") + ] = None + payload: typing.Optional[UserAccountUpdatedPayloadPayload] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/resources/users/types/user_account_updated_payload_payload.py b/src/webflow/resources/users/types/user_account_updated_payload_payload.py new file mode 100644 index 0000000..fc3a2d2 --- /dev/null +++ b/src/webflow/resources/users/types/user_account_updated_payload_payload.py @@ -0,0 +1,76 @@ +# This file was auto-generated by Fern from our API Definition. + +from ....core.pydantic_utilities import UniversalBaseModel +import typing +from .user_account_updated_payload_payload_data import UserAccountUpdatedPayloadPayloadData +import pydantic +import typing_extensions +from ....core.serialization import FieldMetadata +import datetime as dt +from ....types.user_status import UserStatus +from ....types.user_access_groups_item import UserAccessGroupsItem +from ....core.pydantic_utilities import IS_PYDANTIC_V2 + + +class UserAccountUpdatedPayloadPayload(UniversalBaseModel): + data: typing.Optional[UserAccountUpdatedPayloadPayloadData] = pydantic.Field(default=None) + """ + The data about the user account that was added + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + Unique identifier for the User + """ + + is_email_verified: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="isEmailVerified")] = ( + pydantic.Field(default=None) + ) + """ + Shows whether the user has verified their email address + """ + + last_updated: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="lastUpdated")] = ( + pydantic.Field(default=None) + ) + """ + The timestamp the user was updated + """ + + invited_on: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="invitedOn")] = ( + pydantic.Field(default=None) + ) + """ + The timestamp the user was invited + """ + + created_on: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="createdOn")] = ( + pydantic.Field(default=None) + ) + """ + The timestamp the user was created + """ + + last_login: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="lastLogin")] = ( + pydantic.Field(default=None) + ) + """ + The timestamp the user was logged in + """ + + status: typing.Optional[UserStatus] = None + access_groups: typing_extensions.Annotated[ + typing.Optional[typing.List[UserAccessGroupsItem]], FieldMetadata(alias="accessGroups") + ] = pydantic.Field(default=None) + """ + Access groups the user belongs to + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/resources/users/types/user_account_updated_payload_payload_data.py b/src/webflow/resources/users/types/user_account_updated_payload_payload_data.py new file mode 100644 index 0000000..1a572a3 --- /dev/null +++ b/src/webflow/resources/users/types/user_account_updated_payload_payload_data.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +from ....core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ....core.serialization import FieldMetadata +from ....core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class UserAccountUpdatedPayloadPayloadData(UniversalBaseModel): + """ + The data about the user account that was added + """ + + accept_privacy_policy: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="accept-privacy-policy") + ] = None + accept_communications: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="accept-communications") + ] = None + email: typing.Optional[str] = None + name: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/resources/webhooks/client.py b/src/webflow/resources/webhooks/client.py index ded9a2f..c6821a9 100644 --- a/src/webflow/resources/webhooks/client.py +++ b/src/webflow/resources/webhooks/client.py @@ -61,6 +61,7 @@ def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/webhooks", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -212,6 +213,7 @@ def create( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id_)}/webhooks", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "id": id, @@ -324,6 +326,7 @@ def get(self, webhook_id: str, *, request_options: typing.Optional[RequestOption """ _response = self._client_wrapper.httpx_client.request( f"webhooks/{jsonable_encoder(webhook_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -422,6 +425,7 @@ def delete(self, webhook_id: str, *, request_options: typing.Optional[RequestOpt """ _response = self._client_wrapper.httpx_client.request( f"webhooks/{jsonable_encoder(webhook_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -528,6 +532,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/webhooks", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -686,6 +691,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id_)}/webhooks", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "id": id, @@ -806,6 +812,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"webhooks/{jsonable_encoder(webhook_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -912,6 +919,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"webhooks/{jsonable_encoder(webhook_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) diff --git a/src/webflow/resources/workspaces/__init__.py b/src/webflow/resources/workspaces/__init__.py new file mode 100644 index 0000000..d6cc054 --- /dev/null +++ b/src/webflow/resources/workspaces/__init__.py @@ -0,0 +1,13 @@ +# This file was auto-generated by Fern from our API Definition. + +from .resources import ( + AuditLogsGetWorkspaceAuditLogsRequestEventType, + AuditLogsGetWorkspaceAuditLogsRequestSortOrder, + audit_logs, +) + +__all__ = [ + "AuditLogsGetWorkspaceAuditLogsRequestEventType", + "AuditLogsGetWorkspaceAuditLogsRequestSortOrder", + "audit_logs", +] diff --git a/src/webflow/resources/workspaces/client.py b/src/webflow/resources/workspaces/client.py new file mode 100644 index 0000000..de70ca5 --- /dev/null +++ b/src/webflow/resources/workspaces/client.py @@ -0,0 +1,18 @@ +# This file was auto-generated by Fern from our API Definition. + +from ...core.client_wrapper import SyncClientWrapper +from .resources.audit_logs.client import AuditLogsClient +from ...core.client_wrapper import AsyncClientWrapper +from .resources.audit_logs.client import AsyncAuditLogsClient + + +class WorkspacesClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + self.audit_logs = AuditLogsClient(client_wrapper=self._client_wrapper) + + +class AsyncWorkspacesClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + self.audit_logs = AsyncAuditLogsClient(client_wrapper=self._client_wrapper) diff --git a/src/webflow/resources/workspaces/resources/__init__.py b/src/webflow/resources/workspaces/resources/__init__.py new file mode 100644 index 0000000..0e96a0e --- /dev/null +++ b/src/webflow/resources/workspaces/resources/__init__.py @@ -0,0 +1,10 @@ +# This file was auto-generated by Fern from our API Definition. + +from . import audit_logs +from .audit_logs import AuditLogsGetWorkspaceAuditLogsRequestEventType, AuditLogsGetWorkspaceAuditLogsRequestSortOrder + +__all__ = [ + "AuditLogsGetWorkspaceAuditLogsRequestEventType", + "AuditLogsGetWorkspaceAuditLogsRequestSortOrder", + "audit_logs", +] diff --git a/src/webflow/resources/workspaces/resources/audit_logs/__init__.py b/src/webflow/resources/workspaces/resources/audit_logs/__init__.py new file mode 100644 index 0000000..dab3df1 --- /dev/null +++ b/src/webflow/resources/workspaces/resources/audit_logs/__init__.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from .types import AuditLogsGetWorkspaceAuditLogsRequestEventType, AuditLogsGetWorkspaceAuditLogsRequestSortOrder + +__all__ = ["AuditLogsGetWorkspaceAuditLogsRequestEventType", "AuditLogsGetWorkspaceAuditLogsRequestSortOrder"] diff --git a/src/webflow/resources/workspaces/resources/audit_logs/client.py b/src/webflow/resources/workspaces/resources/audit_logs/client.py new file mode 100644 index 0000000..7ce8c3e --- /dev/null +++ b/src/webflow/resources/workspaces/resources/audit_logs/client.py @@ -0,0 +1,340 @@ +# This file was auto-generated by Fern from our API Definition. + +from .....core.client_wrapper import SyncClientWrapper +import typing +from .types.audit_logs_get_workspace_audit_logs_request_sort_order import AuditLogsGetWorkspaceAuditLogsRequestSortOrder +from .types.audit_logs_get_workspace_audit_logs_request_event_type import AuditLogsGetWorkspaceAuditLogsRequestEventType +import datetime as dt +from .....core.request_options import RequestOptions +from .....types.workspace_audit_log_response import WorkspaceAuditLogResponse +from .....core.jsonable_encoder import jsonable_encoder +from .....core.datetime_utils import serialize_datetime +from .....core.pydantic_utilities import parse_obj_as +from .....errors.unauthorized_error import UnauthorizedError +from .....types.error import Error +from .....errors.forbidden_error import ForbiddenError +from .....errors.not_found_error import NotFoundError +from .....errors.too_many_requests_error import TooManyRequestsError +from .....errors.internal_server_error import InternalServerError +from json.decoder import JSONDecodeError +from .....core.api_error import ApiError +from .....core.client_wrapper import AsyncClientWrapper + + +class AuditLogsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def get_workspace_audit_logs( + self, + workspace_id_or_slug: str, + *, + limit: typing.Optional[float] = None, + offset: typing.Optional[float] = None, + sort_order: typing.Optional[AuditLogsGetWorkspaceAuditLogsRequestSortOrder] = None, + event_type: typing.Optional[AuditLogsGetWorkspaceAuditLogsRequestEventType] = None, + from_: typing.Optional[dt.datetime] = None, + to: typing.Optional[dt.datetime] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> WorkspaceAuditLogResponse: + """ + Get audit logs for a workspace. + + This endpoint requires an Enterprise workspace and a workspace token with the `workspace_activity:read` scope. Create a workspace token from your workspace dashboard integrations page to use this endpoint. + + Required scope | `workspace_activity:read` + + Parameters + ---------- + workspace_id_or_slug : str + Unique identifier or slug for a Workspace + + limit : typing.Optional[float] + Maximum number of records to be returned (max limit: 100) + + offset : typing.Optional[float] + Offset used for pagination if the results have more than limit records + + sort_order : typing.Optional[AuditLogsGetWorkspaceAuditLogsRequestSortOrder] + Sorts the results by asc or desc + + event_type : typing.Optional[AuditLogsGetWorkspaceAuditLogsRequestEventType] + The event type to filter by + + from_ : typing.Optional[dt.datetime] + The start date to filter by + + to : typing.Optional[dt.datetime] + The end date to filter by + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + WorkspaceAuditLogResponse + A list of workspace audit logs + + Examples + -------- + import datetime + + from webflow import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.workspaces.audit_logs.get_workspace_audit_logs( + workspace_id_or_slug="hitchhikers-workspace", + limit=1.1, + offset=1.1, + sort_order="asc", + event_type="user_access", + from_=datetime.datetime.fromisoformat( + "2025-06-22 16:00:31+00:00", + ), + to=datetime.datetime.fromisoformat( + "2025-07-22 16:00:31+00:00", + ), + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"workspaces/{jsonable_encoder(workspace_id_or_slug)}/audit_logs", + base_url=self._client_wrapper.get_environment().base, + method="GET", + params={ + "limit": limit, + "offset": offset, + "sortOrder": sort_order, + "eventType": event_type, + "from": serialize_datetime(from_) if from_ is not None else None, + "to": serialize_datetime(to) if to is not None else None, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + WorkspaceAuditLogResponse, + parse_obj_as( + type_=WorkspaceAuditLogResponse, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 403: + raise ForbiddenError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + +class AsyncAuditLogsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def get_workspace_audit_logs( + self, + workspace_id_or_slug: str, + *, + limit: typing.Optional[float] = None, + offset: typing.Optional[float] = None, + sort_order: typing.Optional[AuditLogsGetWorkspaceAuditLogsRequestSortOrder] = None, + event_type: typing.Optional[AuditLogsGetWorkspaceAuditLogsRequestEventType] = None, + from_: typing.Optional[dt.datetime] = None, + to: typing.Optional[dt.datetime] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> WorkspaceAuditLogResponse: + """ + Get audit logs for a workspace. + + This endpoint requires an Enterprise workspace and a workspace token with the `workspace_activity:read` scope. Create a workspace token from your workspace dashboard integrations page to use this endpoint. + + Required scope | `workspace_activity:read` + + Parameters + ---------- + workspace_id_or_slug : str + Unique identifier or slug for a Workspace + + limit : typing.Optional[float] + Maximum number of records to be returned (max limit: 100) + + offset : typing.Optional[float] + Offset used for pagination if the results have more than limit records + + sort_order : typing.Optional[AuditLogsGetWorkspaceAuditLogsRequestSortOrder] + Sorts the results by asc or desc + + event_type : typing.Optional[AuditLogsGetWorkspaceAuditLogsRequestEventType] + The event type to filter by + + from_ : typing.Optional[dt.datetime] + The start date to filter by + + to : typing.Optional[dt.datetime] + The end date to filter by + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + WorkspaceAuditLogResponse + A list of workspace audit logs + + Examples + -------- + import asyncio + import datetime + + from webflow import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + + + async def main() -> None: + await client.workspaces.audit_logs.get_workspace_audit_logs( + workspace_id_or_slug="hitchhikers-workspace", + limit=1.1, + offset=1.1, + sort_order="asc", + event_type="user_access", + from_=datetime.datetime.fromisoformat( + "2025-06-22 16:00:31+00:00", + ), + to=datetime.datetime.fromisoformat( + "2025-07-22 16:00:31+00:00", + ), + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"workspaces/{jsonable_encoder(workspace_id_or_slug)}/audit_logs", + base_url=self._client_wrapper.get_environment().base, + method="GET", + params={ + "limit": limit, + "offset": offset, + "sortOrder": sort_order, + "eventType": event_type, + "from": serialize_datetime(from_) if from_ is not None else None, + "to": serialize_datetime(to) if to is not None else None, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + WorkspaceAuditLogResponse, + parse_obj_as( + type_=WorkspaceAuditLogResponse, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 403: + raise ForbiddenError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) diff --git a/src/webflow/resources/workspaces/resources/audit_logs/types/__init__.py b/src/webflow/resources/workspaces/resources/audit_logs/types/__init__.py new file mode 100644 index 0000000..3decf29 --- /dev/null +++ b/src/webflow/resources/workspaces/resources/audit_logs/types/__init__.py @@ -0,0 +1,6 @@ +# This file was auto-generated by Fern from our API Definition. + +from .audit_logs_get_workspace_audit_logs_request_event_type import AuditLogsGetWorkspaceAuditLogsRequestEventType +from .audit_logs_get_workspace_audit_logs_request_sort_order import AuditLogsGetWorkspaceAuditLogsRequestSortOrder + +__all__ = ["AuditLogsGetWorkspaceAuditLogsRequestEventType", "AuditLogsGetWorkspaceAuditLogsRequestSortOrder"] diff --git a/src/webflow/resources/workspaces/resources/audit_logs/types/audit_logs_get_workspace_audit_logs_request_event_type.py b/src/webflow/resources/workspaces/resources/audit_logs/types/audit_logs_get_workspace_audit_logs_request_event_type.py new file mode 100644 index 0000000..950e45b --- /dev/null +++ b/src/webflow/resources/workspaces/resources/audit_logs/types/audit_logs_get_workspace_audit_logs_request_event_type.py @@ -0,0 +1,8 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AuditLogsGetWorkspaceAuditLogsRequestEventType = typing.Union[ + typing.Literal["user_access", "custom_role", "workspace_membership", "site_membership", "workspace_invitation"], + typing.Any, +] diff --git a/src/webflow/resources/workspaces/resources/audit_logs/types/audit_logs_get_workspace_audit_logs_request_sort_order.py b/src/webflow/resources/workspaces/resources/audit_logs/types/audit_logs_get_workspace_audit_logs_request_sort_order.py new file mode 100644 index 0000000..dd90d5f --- /dev/null +++ b/src/webflow/resources/workspaces/resources/audit_logs/types/audit_logs_get_workspace_audit_logs_request_sort_order.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AuditLogsGetWorkspaceAuditLogsRequestSortOrder = typing.Union[typing.Literal["asc", "desc"], typing.Any] diff --git a/src/webflow/types/__init__.py b/src/webflow/types/__init__.py index 5b2d8c6..fefa916 100644 --- a/src/webflow/types/__init__.py +++ b/src/webflow/types/__init__.py @@ -19,6 +19,8 @@ from .bulk_collection_item_field_data import BulkCollectionItemFieldData from .collection import Collection from .collection_item import CollectionItem +from .collection_item_changed import CollectionItemChanged +from .collection_item_created import CollectionItemCreated from .collection_item_field_data import CollectionItemFieldData from .collection_item_list import CollectionItemList from .collection_item_list_no_pagination import CollectionItemListNoPagination @@ -27,10 +29,31 @@ from .collection_item_patch_single_field_data import CollectionItemPatchSingleFieldData from .collection_item_post_single import CollectionItemPostSingle from .collection_item_post_single_field_data import CollectionItemPostSingleFieldData +from .collection_item_published import CollectionItemPublished +from .collection_item_removed import CollectionItemRemoved +from .collection_item_removed_payload import CollectionItemRemovedPayload +from .collection_item_removed_payload_field_data import CollectionItemRemovedPayloadFieldData +from .collection_item_unpublished import CollectionItemUnpublished +from .collection_item_unpublished_payload import CollectionItemUnpublishedPayload +from .collection_item_unpublished_payload_field_data import CollectionItemUnpublishedPayloadFieldData from .collection_item_with_id_input import CollectionItemWithIdInput from .collection_item_with_id_input_field_data import CollectionItemWithIdInputFieldData from .collection_list import CollectionList from .collection_list_array_item import CollectionListArrayItem +from .comment import Comment +from .comment_payload import CommentPayload +from .comment_payload_author import CommentPayloadAuthor +from .comment_payload_mentioned_users_item import CommentPayloadMentionedUsersItem +from .comment_reply import CommentReply +from .comment_reply_author import CommentReplyAuthor +from .comment_reply_list import CommentReplyList +from .comment_reply_list_pagination import CommentReplyListPagination +from .comment_reply_mentioned_users_item import CommentReplyMentionedUsersItem +from .comment_thread import CommentThread +from .comment_thread_author import CommentThreadAuthor +from .comment_thread_list import CommentThreadList +from .comment_thread_list_pagination import CommentThreadListPagination +from .comment_thread_mentioned_users_item import CommentThreadMentionedUsersItem from .component import Component from .component_dom import ComponentDom from .component_instance_node_property_overrides_write import ComponentInstanceNodePropertyOverridesWrite @@ -42,11 +65,15 @@ from .component_properties import ComponentProperties from .component_property import ComponentProperty from .component_property_type import ComponentPropertyType +from .conflict import Conflict from .conflict_error_body import ConflictErrorBody from .custom_code_block import CustomCodeBlock from .custom_code_block_type import CustomCodeBlockType from .custom_code_hosted_response import CustomCodeHostedResponse from .custom_code_inline_response import CustomCodeInlineResponse +from .custom_role import CustomRole +from .custom_role_audit_log_item import CustomRoleAuditLogItem +from .custom_role_audit_log_item_event_sub_type import CustomRoleAuditLogItemEventSubType from .dom import Dom from .domain import Domain from .domains import Domains @@ -55,7 +82,13 @@ from .error import Error from .error_code import ErrorCode from .field import Field +from .field_create import FieldCreate from .field_type import FieldType +from .field_validations import FieldValidations +from .field_validations_additional_properties import FieldValidationsAdditionalProperties +from .field_validations_additional_properties_additional_properties import ( + FieldValidationsAdditionalPropertiesAdditionalProperties, +) from .forbidden_error_body import ForbiddenErrorBody from .form import Form from .form_field import FormField @@ -65,23 +98,45 @@ from .form_response_settings import FormResponseSettings from .form_submission import FormSubmission from .form_submission_list import FormSubmissionList +from .form_submission_trigger import FormSubmissionTrigger +from .form_submission_trigger_payload import FormSubmissionTriggerPayload +from .form_submission_trigger_payload_schema_item import FormSubmissionTriggerPayloadSchemaItem +from .form_submission_trigger_payload_schema_item_field_type import FormSubmissionTriggerPayloadSchemaItemFieldType from .image_node import ImageNode from .image_node_image import ImageNodeImage from .invalid_domain import InvalidDomain from .invalid_scopes import InvalidScopes from .inventory_item import InventoryItem from .inventory_item_inventory_type import InventoryItemInventoryType +from .items_list_items_live_request_last_published import ItemsListItemsLiveRequestLastPublished +from .items_list_items_request_last_published import ItemsListItemsRequestLastPublished from .list_custom_code_blocks import ListCustomCodeBlocks from .locale import Locale from .locales import Locales +from .metadata import Metadata +from .metadata_options_item import MetadataOptionsItem +from .new_order import NewOrder from .no_domains import NoDomains -from .node import Node, Node_ComponentInstance, Node_Image, Node_Text +from .node import ( + Node, + Node_ComponentInstance, + Node_Image, + Node_SearchButton, + Node_Select, + Node_SubmitButton, + Node_Text, + Node_TextInput, +) from .not_enterprise_plan_site import NotEnterprisePlanSite from .not_enterprise_plan_workspace import NotEnterprisePlanWorkspace +from .option_field import OptionField from .order import Order from .order_address import OrderAddress from .order_address_japan_type import OrderAddressJapanType from .order_address_type import OrderAddressType +from .order_billing_address import OrderBillingAddress +from .order_billing_address_japan_type import OrderBillingAddressJapanType +from .order_billing_address_type import OrderBillingAddressType from .order_customer_info import OrderCustomerInfo from .order_dispute_last_status import OrderDisputeLastStatus from .order_download_files_item import OrderDownloadFilesItem @@ -92,15 +147,26 @@ from .order_purchased_item_variant_image import OrderPurchasedItemVariantImage from .order_purchased_item_variant_image_file import OrderPurchasedItemVariantImageFile from .order_purchased_item_variant_image_file_variants_item import OrderPurchasedItemVariantImageFileVariantsItem +from .order_shipping_address import OrderShippingAddress +from .order_shipping_address_japan_type import OrderShippingAddressJapanType +from .order_shipping_address_type import OrderShippingAddressType from .order_status import OrderStatus from .order_totals import OrderTotals from .order_totals_extras_item import OrderTotalsExtrasItem from .order_totals_extras_item_type import OrderTotalsExtrasItemType from .page import Page +from .page_created_webhook import PageCreatedWebhook +from .page_created_webhook_payload import PageCreatedWebhookPayload +from .page_deleted_webhook import PageDeletedWebhook +from .page_deleted_webhook_payload import PageDeletedWebhookPayload from .page_list import PageList +from .page_metadata_updated_webhook import PageMetadataUpdatedWebhook +from .page_metadata_updated_webhook_payload import PageMetadataUpdatedWebhookPayload from .page_open_graph import PageOpenGraph from .page_seo import PageSeo from .pagination import Pagination +from .payload import Payload +from .payload_field_data import PayloadFieldData from .paypal_details import PaypalDetails from .product import Product from .product_and_sk_us import ProductAndSkUs @@ -111,11 +177,24 @@ from .publish_status import PublishStatus from .redirect import Redirect from .redirects import Redirects +from .reference_field import ReferenceField +from .reference_field_metadata import ReferenceFieldMetadata +from .reference_field_type import ReferenceFieldType from .registered_script_list import RegisteredScriptList +from .robots import Robots +from .robots_rules_item import RobotsRulesItem from .script_apply import ScriptApply from .script_apply_list import ScriptApplyList from .script_apply_location import ScriptApplyLocation from .scripts import Scripts +from .search_button_node import SearchButtonNode +from .search_button_node_write import SearchButtonNodeWrite +from .select import Select +from .select_node import SelectNode +from .select_node_choices_item import SelectNodeChoicesItem +from .select_node_write_choices_item import SelectNodeWriteChoicesItem +from .single_locale_created_payload import SingleLocaleCreatedPayload +from .single_locale_created_payload_field_data import SingleLocaleCreatedPayloadFieldData from .site import Site from .site_activity_log_item import SiteActivityLogItem from .site_activity_log_item_event import SiteActivityLogItemEvent @@ -123,9 +202,14 @@ from .site_activity_log_item_user import SiteActivityLogItemUser from .site_activity_log_response import SiteActivityLogResponse from .site_data_collection_type import SiteDataCollectionType +from .site_membership import SiteMembership +from .site_membership_audit_log_item import SiteMembershipAuditLogItem +from .site_membership_audit_log_item_event_sub_type import SiteMembershipAuditLogItemEventSubType from .site_plan import SitePlan from .site_plan_id import SitePlanId from .site_plan_name import SitePlanName +from .site_publish import SitePublish +from .site_publish_payload import SitePublishPayload from .sites import Sites from .sku import Sku from .sku_field_data import SkuFieldData @@ -139,16 +223,26 @@ from .sku_property_list import SkuPropertyList from .sku_property_list_enum_item import SkuPropertyListEnumItem from .sku_value_list import SkuValueList +from .static_field import StaticField +from .static_field_type import StaticFieldType from .stripe_card import StripeCard from .stripe_card_brand import StripeCardBrand from .stripe_card_expires import StripeCardExpires from .stripe_details import StripeDetails +from .submit_button_node import SubmitButtonNode +from .submit_button_node_write import SubmitButtonNodeWrite from .text import Text +from .text_input_node import TextInputNode +from .text_input_node_write import TextInputNodeWrite from .text_node import TextNode from .text_node_text import TextNodeText from .text_node_write import TextNodeWrite from .trigger_type import TriggerType +from .updated_order import UpdatedOrder from .user import User +from .user_access import UserAccess +from .user_access_audit_log_item import UserAccessAuditLogItem +from .user_access_audit_log_item_event_sub_type import UserAccessAuditLogItemEventSubType from .user_access_groups_item import UserAccessGroupsItem from .user_access_groups_item_type import UserAccessGroupsItemType from .user_data import UserData @@ -160,6 +254,56 @@ from .webhook import Webhook from .webhook_filter import WebhookFilter from .webhook_list import WebhookList +from .workspace_audit_log_item import ( + WorkspaceAuditLogItem, + WorkspaceAuditLogItem_CustomRole, + WorkspaceAuditLogItem_SiteMembership, + WorkspaceAuditLogItem_UserAccess, + WorkspaceAuditLogItem_WorkspaceInvitation, + WorkspaceAuditLogItem_WorkspaceMembership, +) +from .workspace_audit_log_item_actor import WorkspaceAuditLogItemActor +from .workspace_audit_log_item_payload_site_membership_granular_access import ( + WorkspaceAuditLogItemPayloadSiteMembershipGranularAccess, +) +from .workspace_audit_log_item_payload_site_membership_method import WorkspaceAuditLogItemPayloadSiteMembershipMethod +from .workspace_audit_log_item_payload_site_membership_site import WorkspaceAuditLogItemPayloadSiteMembershipSite +from .workspace_audit_log_item_payload_site_membership_target_user import ( + WorkspaceAuditLogItemPayloadSiteMembershipTargetUser, +) +from .workspace_audit_log_item_payload_site_membership_user_type import ( + WorkspaceAuditLogItemPayloadSiteMembershipUserType, +) +from .workspace_audit_log_item_payload_user_access_method import WorkspaceAuditLogItemPayloadUserAccessMethod +from .workspace_audit_log_item_payload_workspace_invitation_method import ( + WorkspaceAuditLogItemPayloadWorkspaceInvitationMethod, +) +from .workspace_audit_log_item_payload_workspace_invitation_target_user import ( + WorkspaceAuditLogItemPayloadWorkspaceInvitationTargetUser, +) +from .workspace_audit_log_item_payload_workspace_invitation_target_users_item import ( + WorkspaceAuditLogItemPayloadWorkspaceInvitationTargetUsersItem, +) +from .workspace_audit_log_item_payload_workspace_invitation_user_type import ( + WorkspaceAuditLogItemPayloadWorkspaceInvitationUserType, +) +from .workspace_audit_log_item_payload_workspace_membership_method import ( + WorkspaceAuditLogItemPayloadWorkspaceMembershipMethod, +) +from .workspace_audit_log_item_payload_workspace_membership_target_user import ( + WorkspaceAuditLogItemPayloadWorkspaceMembershipTargetUser, +) +from .workspace_audit_log_item_payload_workspace_membership_user_type import ( + WorkspaceAuditLogItemPayloadWorkspaceMembershipUserType, +) +from .workspace_audit_log_item_workspace import WorkspaceAuditLogItemWorkspace +from .workspace_audit_log_response import WorkspaceAuditLogResponse +from .workspace_invitation import WorkspaceInvitation +from .workspace_invitation_audit_log_item import WorkspaceInvitationAuditLogItem +from .workspace_invitation_audit_log_item_event_sub_type import WorkspaceInvitationAuditLogItemEventSubType +from .workspace_membership import WorkspaceMembership +from .workspace_membership_audit_log_item import WorkspaceMembershipAuditLogItem +from .workspace_membership_audit_log_item_event_sub_type import WorkspaceMembershipAuditLogItemEventSubType __all__ = [ "AccessGroup", @@ -181,6 +325,8 @@ "BulkCollectionItemFieldData", "Collection", "CollectionItem", + "CollectionItemChanged", + "CollectionItemCreated", "CollectionItemFieldData", "CollectionItemList", "CollectionItemListNoPagination", @@ -189,10 +335,31 @@ "CollectionItemPatchSingleFieldData", "CollectionItemPostSingle", "CollectionItemPostSingleFieldData", + "CollectionItemPublished", + "CollectionItemRemoved", + "CollectionItemRemovedPayload", + "CollectionItemRemovedPayloadFieldData", + "CollectionItemUnpublished", + "CollectionItemUnpublishedPayload", + "CollectionItemUnpublishedPayloadFieldData", "CollectionItemWithIdInput", "CollectionItemWithIdInputFieldData", "CollectionList", "CollectionListArrayItem", + "Comment", + "CommentPayload", + "CommentPayloadAuthor", + "CommentPayloadMentionedUsersItem", + "CommentReply", + "CommentReplyAuthor", + "CommentReplyList", + "CommentReplyListPagination", + "CommentReplyMentionedUsersItem", + "CommentThread", + "CommentThreadAuthor", + "CommentThreadList", + "CommentThreadListPagination", + "CommentThreadMentionedUsersItem", "Component", "ComponentDom", "ComponentInstanceNodePropertyOverridesWrite", @@ -202,11 +369,15 @@ "ComponentProperties", "ComponentProperty", "ComponentPropertyType", + "Conflict", "ConflictErrorBody", "CustomCodeBlock", "CustomCodeBlockType", "CustomCodeHostedResponse", "CustomCodeInlineResponse", + "CustomRole", + "CustomRoleAuditLogItem", + "CustomRoleAuditLogItemEventSubType", "Dom", "Domain", "Domains", @@ -215,7 +386,11 @@ "Error", "ErrorCode", "Field", + "FieldCreate", "FieldType", + "FieldValidations", + "FieldValidationsAdditionalProperties", + "FieldValidationsAdditionalPropertiesAdditionalProperties", "ForbiddenErrorBody", "Form", "FormField", @@ -225,26 +400,43 @@ "FormResponseSettings", "FormSubmission", "FormSubmissionList", + "FormSubmissionTrigger", + "FormSubmissionTriggerPayload", + "FormSubmissionTriggerPayloadSchemaItem", + "FormSubmissionTriggerPayloadSchemaItemFieldType", "ImageNode", "ImageNodeImage", "InvalidDomain", "InvalidScopes", "InventoryItem", "InventoryItemInventoryType", + "ItemsListItemsLiveRequestLastPublished", + "ItemsListItemsRequestLastPublished", "ListCustomCodeBlocks", "Locale", "Locales", + "Metadata", + "MetadataOptionsItem", + "NewOrder", "NoDomains", "Node", "Node_ComponentInstance", "Node_Image", + "Node_SearchButton", + "Node_Select", + "Node_SubmitButton", "Node_Text", + "Node_TextInput", "NotEnterprisePlanSite", "NotEnterprisePlanWorkspace", + "OptionField", "Order", "OrderAddress", "OrderAddressJapanType", "OrderAddressType", + "OrderBillingAddress", + "OrderBillingAddressJapanType", + "OrderBillingAddressType", "OrderCustomerInfo", "OrderDisputeLastStatus", "OrderDownloadFilesItem", @@ -255,15 +447,26 @@ "OrderPurchasedItemVariantImage", "OrderPurchasedItemVariantImageFile", "OrderPurchasedItemVariantImageFileVariantsItem", + "OrderShippingAddress", + "OrderShippingAddressJapanType", + "OrderShippingAddressType", "OrderStatus", "OrderTotals", "OrderTotalsExtrasItem", "OrderTotalsExtrasItemType", "Page", + "PageCreatedWebhook", + "PageCreatedWebhookPayload", + "PageDeletedWebhook", + "PageDeletedWebhookPayload", "PageList", + "PageMetadataUpdatedWebhook", + "PageMetadataUpdatedWebhookPayload", "PageOpenGraph", "PageSeo", "Pagination", + "Payload", + "PayloadFieldData", "PaypalDetails", "Product", "ProductAndSkUs", @@ -274,11 +477,24 @@ "PublishStatus", "Redirect", "Redirects", + "ReferenceField", + "ReferenceFieldMetadata", + "ReferenceFieldType", "RegisteredScriptList", + "Robots", + "RobotsRulesItem", "ScriptApply", "ScriptApplyList", "ScriptApplyLocation", "Scripts", + "SearchButtonNode", + "SearchButtonNodeWrite", + "Select", + "SelectNode", + "SelectNodeChoicesItem", + "SelectNodeWriteChoicesItem", + "SingleLocaleCreatedPayload", + "SingleLocaleCreatedPayloadFieldData", "Site", "SiteActivityLogItem", "SiteActivityLogItemEvent", @@ -286,9 +502,14 @@ "SiteActivityLogItemUser", "SiteActivityLogResponse", "SiteDataCollectionType", + "SiteMembership", + "SiteMembershipAuditLogItem", + "SiteMembershipAuditLogItemEventSubType", "SitePlan", "SitePlanId", "SitePlanName", + "SitePublish", + "SitePublishPayload", "Sites", "Sku", "SkuFieldData", @@ -302,16 +523,26 @@ "SkuPropertyList", "SkuPropertyListEnumItem", "SkuValueList", + "StaticField", + "StaticFieldType", "StripeCard", "StripeCardBrand", "StripeCardExpires", "StripeDetails", + "SubmitButtonNode", + "SubmitButtonNodeWrite", "Text", + "TextInputNode", + "TextInputNodeWrite", "TextNode", "TextNodeText", "TextNodeWrite", "TriggerType", + "UpdatedOrder", "User", + "UserAccess", + "UserAccessAuditLogItem", + "UserAccessAuditLogItemEventSubType", "UserAccessGroupsItem", "UserAccessGroupsItemType", "UserData", @@ -323,4 +554,32 @@ "Webhook", "WebhookFilter", "WebhookList", + "WorkspaceAuditLogItem", + "WorkspaceAuditLogItemActor", + "WorkspaceAuditLogItemPayloadSiteMembershipGranularAccess", + "WorkspaceAuditLogItemPayloadSiteMembershipMethod", + "WorkspaceAuditLogItemPayloadSiteMembershipSite", + "WorkspaceAuditLogItemPayloadSiteMembershipTargetUser", + "WorkspaceAuditLogItemPayloadSiteMembershipUserType", + "WorkspaceAuditLogItemPayloadUserAccessMethod", + "WorkspaceAuditLogItemPayloadWorkspaceInvitationMethod", + "WorkspaceAuditLogItemPayloadWorkspaceInvitationTargetUser", + "WorkspaceAuditLogItemPayloadWorkspaceInvitationTargetUsersItem", + "WorkspaceAuditLogItemPayloadWorkspaceInvitationUserType", + "WorkspaceAuditLogItemPayloadWorkspaceMembershipMethod", + "WorkspaceAuditLogItemPayloadWorkspaceMembershipTargetUser", + "WorkspaceAuditLogItemPayloadWorkspaceMembershipUserType", + "WorkspaceAuditLogItemWorkspace", + "WorkspaceAuditLogItem_CustomRole", + "WorkspaceAuditLogItem_SiteMembership", + "WorkspaceAuditLogItem_UserAccess", + "WorkspaceAuditLogItem_WorkspaceInvitation", + "WorkspaceAuditLogItem_WorkspaceMembership", + "WorkspaceAuditLogResponse", + "WorkspaceInvitation", + "WorkspaceInvitationAuditLogItem", + "WorkspaceInvitationAuditLogItemEventSubType", + "WorkspaceMembership", + "WorkspaceMembershipAuditLogItem", + "WorkspaceMembershipAuditLogItemEventSubType", ] diff --git a/src/webflow/types/application.py b/src/webflow/types/application.py index ac819f0..b11f910 100644 --- a/src/webflow/types/application.py +++ b/src/webflow/types/application.py @@ -1,5 +1,41 @@ # This file was auto-generated by Fern from our API Definition. +from ..core.pydantic_utilities import UniversalBaseModel import typing +import pydantic +import typing_extensions +from ..core.serialization import FieldMetadata +from ..core.pydantic_utilities import IS_PYDANTIC_V2 -Application = typing.Optional[typing.Any] + +class Application(UniversalBaseModel): + id: typing.Optional[str] = pydantic.Field(default=None) + """ + Unique identifier for the Application + """ + + description: typing.Optional[str] = pydantic.Field(default=None) + """ + Application description provided by the developer + """ + + homepage: typing.Optional[str] = pydantic.Field(default=None) + """ + Application homepage URL provided by the developer + """ + + display_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="displayName")] = ( + pydantic.Field(default=None) + ) + """ + Application name provided by the developer + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/asset.py b/src/webflow/types/asset.py index b67cefa..8ebad3b 100644 --- a/src/webflow/types/asset.py +++ b/src/webflow/types/asset.py @@ -11,6 +11,10 @@ class Asset(UniversalBaseModel): + """ + Asset details + """ + id: typing.Optional[str] = pydantic.Field(default=None) """ Unique identifier for this asset @@ -49,9 +53,7 @@ class Asset(UniversalBaseModel): Original file name at the time of upload """ - display_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="displayName")] = ( - pydantic.Field(default=None) - ) + display_name: typing_extensions.Annotated[str, FieldMetadata(alias="displayName")] = pydantic.Field() """ Display name of the asset """ @@ -70,7 +72,11 @@ class Asset(UniversalBaseModel): Date the asset metadata was created """ - variants: typing.Optional[typing.List[AssetVariant]] = None + variants: typing.List[AssetVariant] = pydantic.Field() + """ + A list of [asset variants](https://help.webflow.com/hc/en-us/articles/33961378697107-Responsive-images) created by Webflow to serve your site responsively. + """ + alt_text: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="altText")] = pydantic.Field( default=None ) diff --git a/src/webflow/types/asset_variant.py b/src/webflow/types/asset_variant.py index 5278667..0ad16f1 100644 --- a/src/webflow/types/asset_variant.py +++ b/src/webflow/types/asset_variant.py @@ -2,40 +2,38 @@ from ..core.pydantic_utilities import UniversalBaseModel import typing_extensions -import typing from ..core.serialization import FieldMetadata import pydantic +import typing from ..core.pydantic_utilities import IS_PYDANTIC_V2 class AssetVariant(UniversalBaseModel): - hosted_url: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="hostedUrl")] = pydantic.Field( - default=None - ) + """ + Asset variant details + """ + + hosted_url: typing_extensions.Annotated[str, FieldMetadata(alias="hostedUrl")] = pydantic.Field() """ URL of where the asset variant is hosted """ - original_file_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="originalFileName")] = ( - pydantic.Field(default=None) - ) + original_file_name: typing_extensions.Annotated[str, FieldMetadata(alias="originalFileName")] = pydantic.Field() """ Original file name of the variant """ - display_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="displayName")] = ( - pydantic.Field(default=None) - ) + display_name: typing_extensions.Annotated[str, FieldMetadata(alias="displayName")] = pydantic.Field() """ Display name of the variant """ - format: typing.Optional[str] = pydantic.Field(default=None) + format: str = pydantic.Field() """ format of the variant """ - width: typing.Optional[int] = pydantic.Field(default=None) + width: int = pydantic.Field() """ Width in pixels """ @@ -45,7 +43,7 @@ class AssetVariant(UniversalBaseModel): Height in pixels """ - quality: typing.Optional[int] = pydantic.Field(default=None) + quality: int = pydantic.Field() """ Value between 0 and 100 representing the image quality """ diff --git a/src/webflow/types/assets.py b/src/webflow/types/assets.py index 380b0de..bd5f8ea 100644 --- a/src/webflow/types/assets.py +++ b/src/webflow/types/assets.py @@ -3,6 +3,7 @@ from ..core.pydantic_utilities import UniversalBaseModel import typing from .asset import Asset +from .pagination import Pagination from ..core.pydantic_utilities import IS_PYDANTIC_V2 import pydantic @@ -13,6 +14,7 @@ class Assets(UniversalBaseModel): """ assets: typing.Optional[typing.List[Asset]] = None + pagination: typing.Optional[Pagination] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/webflow/types/bulk_collection_item.py b/src/webflow/types/bulk_collection_item.py index 4d17d13..de8e770 100644 --- a/src/webflow/types/bulk_collection_item.py +++ b/src/webflow/types/bulk_collection_item.py @@ -1,9 +1,9 @@ # This file was auto-generated by Fern from our API Definition. from ..core.pydantic_utilities import UniversalBaseModel +import typing import pydantic import typing_extensions -import typing from ..core.serialization import FieldMetadata from .bulk_collection_item_field_data import BulkCollectionItemFieldData from ..core.pydantic_utilities import IS_PYDANTIC_V2 @@ -14,7 +14,7 @@ class BulkCollectionItem(UniversalBaseModel): The fields that define the schema for a given Item are based on the Collection that Item belongs to. Beyond the user defined fields, there are a handful of additional fields that are automatically created for all items """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ Unique identifier for the Item """ diff --git a/src/webflow/types/collection.py b/src/webflow/types/collection.py index 81e0f90..561a535 100644 --- a/src/webflow/types/collection.py +++ b/src/webflow/types/collection.py @@ -3,8 +3,8 @@ from ..core.pydantic_utilities import UniversalBaseModel import pydantic import typing_extensions -import typing from ..core.serialization import FieldMetadata +import typing import datetime as dt from .field import Field from ..core.pydantic_utilities import IS_PYDANTIC_V2 @@ -20,16 +20,12 @@ class Collection(UniversalBaseModel): Unique identifier for a Collection """ - display_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="displayName")] = ( - pydantic.Field(default=None) - ) + display_name: typing_extensions.Annotated[str, FieldMetadata(alias="displayName")] = pydantic.Field() """ Name given to the Collection """ - singular_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="singularName")] = ( - pydantic.Field(default=None) - ) + singular_name: typing_extensions.Annotated[str, FieldMetadata(alias="singularName")] = pydantic.Field() """ The name of one Item in Collection (e.g. ”Blog Post” if the Collection is called “Blog Posts”) """ diff --git a/src/webflow/types/collection_item_changed.py b/src/webflow/types/collection_item_changed.py new file mode 100644 index 0000000..4484722 --- /dev/null +++ b/src/webflow/types/collection_item_changed.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ..core.serialization import FieldMetadata +import pydantic +from .single_locale_created_payload import SingleLocaleCreatedPayload +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class CollectionItemChanged(UniversalBaseModel): + """ + The Webhook payload for when a Collection Item is changed + """ + + trigger_type: typing_extensions.Annotated[ + typing.Literal["collection_item_changed"], FieldMetadata(alias="triggerType") + ] = pydantic.Field(default="collection_item_changed") + """ + The type of event that triggered the request + """ + + payload: SingleLocaleCreatedPayload + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/collection_item_created.py b/src/webflow/types/collection_item_created.py new file mode 100644 index 0000000..bc6233c --- /dev/null +++ b/src/webflow/types/collection_item_created.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ..core.serialization import FieldMetadata +import pydantic +from .single_locale_created_payload import SingleLocaleCreatedPayload +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class CollectionItemCreated(UniversalBaseModel): + """ + The Webhook payload for when a Collection Item is created + """ + + trigger_type: typing_extensions.Annotated[ + typing.Literal["collection_item_created"], FieldMetadata(alias="triggerType") + ] = pydantic.Field(default="collection_item_created") + """ + The type of event that triggered the request + """ + + payload: SingleLocaleCreatedPayload + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/collection_item_published.py b/src/webflow/types/collection_item_published.py new file mode 100644 index 0000000..c315f37 --- /dev/null +++ b/src/webflow/types/collection_item_published.py @@ -0,0 +1,29 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ..core.serialization import FieldMetadata +import pydantic +from .payload import Payload +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class CollectionItemPublished(UniversalBaseModel): + trigger_type: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="triggerType")] = ( + pydantic.Field(default=None) + ) + """ + The type of event that triggered the request + """ + + payload: typing.Optional[Payload] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/collection_item_removed.py b/src/webflow/types/collection_item_removed.py new file mode 100644 index 0000000..fb09cd7 --- /dev/null +++ b/src/webflow/types/collection_item_removed.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ..core.serialization import FieldMetadata +import pydantic +from .collection_item_removed_payload import CollectionItemRemovedPayload +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class CollectionItemRemoved(UniversalBaseModel): + trigger_type: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="triggerType")] = ( + pydantic.Field(default=None) + ) + """ + The type of event that triggered the request + """ + + payload: typing.Optional[CollectionItemRemovedPayload] = pydantic.Field(default=None) + """ + The payload of data sent from Webflow + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/collection_item_removed_payload.py b/src/webflow/types/collection_item_removed_payload.py new file mode 100644 index 0000000..745cf3c --- /dev/null +++ b/src/webflow/types/collection_item_removed_payload.py @@ -0,0 +1,69 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +import pydantic +import typing_extensions +from ..core.serialization import FieldMetadata +import datetime as dt +from .collection_item_removed_payload_field_data import CollectionItemRemovedPayloadFieldData +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class CollectionItemRemovedPayload(UniversalBaseModel): + """ + The payload of data sent from Webflow + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + The ID of the collection item that was deleted + """ + + site_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="siteId")] = pydantic.Field( + default=None + ) + """ + The ID of the site + """ + + workspace_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="workspaceId")] = ( + pydantic.Field(default=None) + ) + """ + The ID of the workspace + """ + + collection_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="collectionId")] = ( + pydantic.Field(default=None) + ) + """ + The ID of the collection + """ + + cms_locale_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="cmsLocaleId")] = ( + pydantic.Field(default=None) + ) + """ + Unique identifier of the CMS locale for this item + """ + + last_published: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="lastPublished")] = ( + None + ) + last_updated: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="lastUpdated")] = None + created_on: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="createdOn")] = None + is_archived: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="isArchived")] = None + is_draft: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="isDraft")] = None + field_data: typing_extensions.Annotated[ + typing.Optional[CollectionItemRemovedPayloadFieldData], FieldMetadata(alias="fieldData") + ] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/collection_item_removed_payload_field_data.py b/src/webflow/types/collection_item_removed_payload_field_data.py new file mode 100644 index 0000000..bca5629 --- /dev/null +++ b/src/webflow/types/collection_item_removed_payload_field_data.py @@ -0,0 +1,20 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import typing +import pydantic + + +class CollectionItemRemovedPayloadFieldData(UniversalBaseModel): + name: str + slug: str + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/collection_item_unpublished.py b/src/webflow/types/collection_item_unpublished.py new file mode 100644 index 0000000..ce23d7f --- /dev/null +++ b/src/webflow/types/collection_item_unpublished.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ..core.serialization import FieldMetadata +import pydantic +from .collection_item_unpublished_payload import CollectionItemUnpublishedPayload +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class CollectionItemUnpublished(UniversalBaseModel): + trigger_type: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="triggerType")] = ( + pydantic.Field(default=None) + ) + """ + The type of event that triggered the request + """ + + payload: typing.Optional[CollectionItemUnpublishedPayload] = pydantic.Field(default=None) + """ + The payload of data sent from Webflow + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/collection_item_unpublished_payload.py b/src/webflow/types/collection_item_unpublished_payload.py new file mode 100644 index 0000000..7250b24 --- /dev/null +++ b/src/webflow/types/collection_item_unpublished_payload.py @@ -0,0 +1,69 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +import pydantic +import typing_extensions +from ..core.serialization import FieldMetadata +import datetime as dt +from .collection_item_unpublished_payload_field_data import CollectionItemUnpublishedPayloadFieldData +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class CollectionItemUnpublishedPayload(UniversalBaseModel): + """ + The payload of data sent from Webflow + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + The ID of the collection item that was unpublished + """ + + site_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="siteId")] = pydantic.Field( + default=None + ) + """ + The ID of the site + """ + + workspace_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="workspaceId")] = ( + pydantic.Field(default=None) + ) + """ + The ID of the workspace + """ + + collection_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="collectionId")] = ( + pydantic.Field(default=None) + ) + """ + The ID of the collection + """ + + cms_locale_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="cmsLocaleId")] = ( + pydantic.Field(default=None) + ) + """ + Unique identifier of the CMS locale for this item + """ + + last_published: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="lastPublished")] = ( + None + ) + last_updated: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="lastUpdated")] = None + created_on: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="createdOn")] = None + is_archived: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="isArchived")] = None + is_draft: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="isDraft")] = None + field_data: typing_extensions.Annotated[ + typing.Optional[CollectionItemUnpublishedPayloadFieldData], FieldMetadata(alias="fieldData") + ] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/collection_item_unpublished_payload_field_data.py b/src/webflow/types/collection_item_unpublished_payload_field_data.py new file mode 100644 index 0000000..8ae8719 --- /dev/null +++ b/src/webflow/types/collection_item_unpublished_payload_field_data.py @@ -0,0 +1,20 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import typing +import pydantic + + +class CollectionItemUnpublishedPayloadFieldData(UniversalBaseModel): + name: str + slug: str + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/comment.py b/src/webflow/types/comment.py new file mode 100644 index 0000000..b5df7e7 --- /dev/null +++ b/src/webflow/types/comment.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ..core.serialization import FieldMetadata +import pydantic +from .comment_payload import CommentPayload +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class Comment(UniversalBaseModel): + """ + The Webhook payload for when a comment thread or reply is made on a Site + """ + + trigger_type: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="triggerType")] = ( + pydantic.Field(default=None) + ) + """ + The type of event that triggered the request + """ + + payload: typing.Optional[CommentPayload] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/comment_payload.py b/src/webflow/types/comment_payload.py new file mode 100644 index 0000000..c6b6a38 --- /dev/null +++ b/src/webflow/types/comment_payload.py @@ -0,0 +1,114 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ..core.serialization import FieldMetadata +import pydantic +from .comment_payload_author import CommentPayloadAuthor +from .comment_payload_mentioned_users_item import CommentPayloadMentionedUsersItem +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class CommentPayload(UniversalBaseModel): + """ + The comment webhook payload contains data for the thread and for replies. Check the type to determine if the payload is for a thread or a reply. The webhook payload may be delayed by up to 5 minutes. + """ + + thread_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="threadId")] = pydantic.Field( + default=None + ) + """ + Unique identifier for the comment thread + """ + + comment_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="commentId")] = pydantic.Field( + default=None + ) + """ + Unique identifier for the comment reply + """ + + type: typing.Optional[str] = pydantic.Field(default=None) + """ + The type of comment payload + """ + + site_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="siteId")] = pydantic.Field( + default=None + ) + """ + The site unique identifier + """ + + page_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="pageId")] = pydantic.Field( + default=None + ) + """ + The page unique identifier + """ + + locale_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="localeId")] = pydantic.Field( + default=None + ) + """ + The locale unique identifier + """ + + item_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="itemId")] = pydantic.Field( + default=None + ) + """ + The item unique identifier + """ + + breakpoint: typing.Optional[str] = pydantic.Field(default=None) + """ + The breakpoint the comment was left on + """ + + url: typing.Optional[str] = pydantic.Field(default=None) + """ + The URL of the page the comment was left on + """ + + content: str = pydantic.Field() + """ + The content of the comment reply + """ + + is_resolved: typing_extensions.Annotated[bool, FieldMetadata(alias="isResolved")] = pydantic.Field() + """ + Boolean determining if the comment thread is resolved + """ + + author: CommentPayloadAuthor + mentioned_users: typing_extensions.Annotated[ + typing.List[CommentPayloadMentionedUsersItem], FieldMetadata(alias="mentionedUsers") + ] = pydantic.Field() + """ + List of mentioned users. This is an empty array until email notifications are sent, which can take up to 5 minutes after the comment is created. + """ + + created_on: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="createdOn")] = pydantic.Field( + default=None + ) + """ + The date the item was created + """ + + last_updated: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="lastUpdated")] = ( + pydantic.Field(default=None) + ) + """ + The date the item was last updated + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/comment_payload_author.py b/src/webflow/types/comment_payload_author.py new file mode 100644 index 0000000..04c9ba8 --- /dev/null +++ b/src/webflow/types/comment_payload_author.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +from ..core.serialization import FieldMetadata +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import typing + + +class CommentPayloadAuthor(UniversalBaseModel): + user_id: typing_extensions.Annotated[str, FieldMetadata(alias="userId")] = pydantic.Field() + """ + The unique identifier of the author + """ + + email: str = pydantic.Field() + """ + Email of the author + """ + + name: str = pydantic.Field() + """ + Name of the author + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/comment_payload_mentioned_users_item.py b/src/webflow/types/comment_payload_mentioned_users_item.py new file mode 100644 index 0000000..7a63d83 --- /dev/null +++ b/src/webflow/types/comment_payload_mentioned_users_item.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +from ..core.serialization import FieldMetadata +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import typing + + +class CommentPayloadMentionedUsersItem(UniversalBaseModel): + user_id: typing_extensions.Annotated[str, FieldMetadata(alias="userId")] = pydantic.Field() + """ + The unique identifier of the mentioned user + """ + + email: str = pydantic.Field() + """ + Email of the user + """ + + name: str = pydantic.Field() + """ + Name of the User + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/comment_reply.py b/src/webflow/types/comment_reply.py new file mode 100644 index 0000000..1017249 --- /dev/null +++ b/src/webflow/types/comment_reply.py @@ -0,0 +1,89 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import pydantic +import typing_extensions +from ..core.serialization import FieldMetadata +import typing +from .comment_reply_author import CommentReplyAuthor +from .comment_reply_mentioned_users_item import CommentReplyMentionedUsersItem +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class CommentReply(UniversalBaseModel): + """ + A comment thread represents a conversation between users on a specific page. Each comment thread has a unique identifier and can contain multiple comments. + """ + + id: str = pydantic.Field() + """ + Unique identifier for the comment thread + """ + + comment_id: typing_extensions.Annotated[str, FieldMetadata(alias="commentId")] = pydantic.Field() + """ + The comment reply unique identifier + """ + + site_id: typing_extensions.Annotated[str, FieldMetadata(alias="siteId")] = pydantic.Field() + """ + The site unique identifier + """ + + page_id: typing_extensions.Annotated[str, FieldMetadata(alias="pageId")] = pydantic.Field() + """ + The page unique identifier + """ + + locale_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="localeId")] = pydantic.Field( + default=None + ) + """ + The locale unique identifier + """ + + breakpoint: str = pydantic.Field() + """ + The breakpoint the comment was left on + """ + + content: str = pydantic.Field() + """ + The content of the comment reply + """ + + is_resolved: typing_extensions.Annotated[bool, FieldMetadata(alias="isResolved")] = pydantic.Field() + """ + Boolean determining if the comment thread is resolved + """ + + author: CommentReplyAuthor + mentioned_users: typing_extensions.Annotated[ + typing.Optional[typing.List[CommentReplyMentionedUsersItem]], FieldMetadata(alias="mentionedUsers") + ] = pydantic.Field(default=None) + """ + List of mentioned users is an empty array until email notifications are sent. + """ + + last_updated: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="lastUpdated")] = ( + pydantic.Field(default=None) + ) + """ + The date the item was last updated + """ + + created_on: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="createdOn")] = pydantic.Field( + default=None + ) + """ + The date the item was created + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/comment_reply_author.py b/src/webflow/types/comment_reply_author.py new file mode 100644 index 0000000..7509b7e --- /dev/null +++ b/src/webflow/types/comment_reply_author.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import typing + + +class CommentReplyAuthor(UniversalBaseModel): + id: str = pydantic.Field() + """ + The unique identifier of the author + """ + + email: str = pydantic.Field() + """ + Email of the author + """ + + name: str = pydantic.Field() + """ + Name of the author + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/comment_reply_list.py b/src/webflow/types/comment_reply_list.py new file mode 100644 index 0000000..c382932 --- /dev/null +++ b/src/webflow/types/comment_reply_list.py @@ -0,0 +1,26 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +from .comment_reply import CommentReply +from .comment_reply_list_pagination import CommentReplyListPagination +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class CommentReplyList(UniversalBaseModel): + """ + A list of comment replies. + """ + + comments: typing.List[CommentReply] + pagination: CommentReplyListPagination + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/comment_reply_list_pagination.py b/src/webflow/types/comment_reply_list_pagination.py new file mode 100644 index 0000000..7fa5c8e --- /dev/null +++ b/src/webflow/types/comment_reply_list_pagination.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import typing + + +class CommentReplyListPagination(UniversalBaseModel): + limit: float = pydantic.Field() + """ + The limit specified in the request (default 100) + """ + + offset: float = pydantic.Field() + """ + The offset specified for pagination + """ + + total: float = pydantic.Field() + """ + Total number of comment replies + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/comment_reply_mentioned_users_item.py b/src/webflow/types/comment_reply_mentioned_users_item.py new file mode 100644 index 0000000..12324d9 --- /dev/null +++ b/src/webflow/types/comment_reply_mentioned_users_item.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import typing + + +class CommentReplyMentionedUsersItem(UniversalBaseModel): + id: str = pydantic.Field() + """ + The unique identifier of the mentioned user + """ + + email: str = pydantic.Field() + """ + Email of the user + """ + + name: str = pydantic.Field() + """ + Name of the User + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/comment_thread.py b/src/webflow/types/comment_thread.py new file mode 100644 index 0000000..0694916 --- /dev/null +++ b/src/webflow/types/comment_thread.py @@ -0,0 +1,92 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import pydantic +import typing_extensions +from ..core.serialization import FieldMetadata +import typing +from .comment_thread_author import CommentThreadAuthor +from .comment_thread_mentioned_users_item import CommentThreadMentionedUsersItem +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class CommentThread(UniversalBaseModel): + """ + A comment thread represents a conversation between users on a specific page. Each comment thread has a unique identifier and can contain multiple comments. Retrieve comment replies using the replies API endpoint. + """ + + id: str = pydantic.Field() + """ + Unique identifier for the comment thread + """ + + site_id: typing_extensions.Annotated[str, FieldMetadata(alias="siteId")] = pydantic.Field() + """ + The site unique identifier + """ + + page_id: typing_extensions.Annotated[str, FieldMetadata(alias="pageId")] = pydantic.Field() + """ + The page unique identifier + """ + + locale_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="localeId")] = pydantic.Field( + default=None + ) + """ + The locale unique identifier + """ + + item_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="itemId")] = pydantic.Field( + default=None + ) + """ + The item unique identifier + """ + + breakpoint: str = pydantic.Field() + """ + The breakpoint the comment was left on + """ + + url: str = pydantic.Field() + """ + The URL of the page the comment was left on + """ + + content: str = pydantic.Field() + """ + The content of the comment reply + """ + + is_resolved: typing_extensions.Annotated[bool, FieldMetadata(alias="isResolved")] = pydantic.Field() + """ + Boolean determining if the comment thread is resolved + """ + + author: CommentThreadAuthor + mentioned_users: typing_extensions.Annotated[ + typing.List[CommentThreadMentionedUsersItem], FieldMetadata(alias="mentionedUsers") + ] = pydantic.Field() + """ + List of mentioned users. This is an empty array until email notifications are sent, which can take up to 5 minutes after the comment is created. + """ + + created_on: typing_extensions.Annotated[str, FieldMetadata(alias="createdOn")] = pydantic.Field() + """ + The date the item was created + """ + + last_updated: typing_extensions.Annotated[str, FieldMetadata(alias="lastUpdated")] = pydantic.Field() + """ + The date the item was last updated + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/comment_thread_author.py b/src/webflow/types/comment_thread_author.py new file mode 100644 index 0000000..c2f1b1e --- /dev/null +++ b/src/webflow/types/comment_thread_author.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +from ..core.serialization import FieldMetadata +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import typing + + +class CommentThreadAuthor(UniversalBaseModel): + user_id: typing_extensions.Annotated[str, FieldMetadata(alias="userId")] = pydantic.Field() + """ + The unique identifier of the author + """ + + email: str = pydantic.Field() + """ + Email of the author + """ + + name: str = pydantic.Field() + """ + Name of the author + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/comment_thread_list.py b/src/webflow/types/comment_thread_list.py new file mode 100644 index 0000000..f46e6bd --- /dev/null +++ b/src/webflow/types/comment_thread_list.py @@ -0,0 +1,26 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +from .comment_thread import CommentThread +from .comment_thread_list_pagination import CommentThreadListPagination +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class CommentThreadList(UniversalBaseModel): + """ + A list of comment threads on the site. Contains the content of the first reply. + """ + + comments: typing.List[CommentThread] + pagination: CommentThreadListPagination + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/comment_thread_list_pagination.py b/src/webflow/types/comment_thread_list_pagination.py new file mode 100644 index 0000000..e5d55bb --- /dev/null +++ b/src/webflow/types/comment_thread_list_pagination.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import typing + + +class CommentThreadListPagination(UniversalBaseModel): + limit: float = pydantic.Field() + """ + The limit specified in the request (default 100) + """ + + offset: float = pydantic.Field() + """ + The offset specified for pagination + """ + + total: float = pydantic.Field() + """ + Total number of comment threads + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/comment_thread_mentioned_users_item.py b/src/webflow/types/comment_thread_mentioned_users_item.py new file mode 100644 index 0000000..f9a20df --- /dev/null +++ b/src/webflow/types/comment_thread_mentioned_users_item.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +from ..core.serialization import FieldMetadata +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import typing + + +class CommentThreadMentionedUsersItem(UniversalBaseModel): + user_id: typing_extensions.Annotated[str, FieldMetadata(alias="userId")] = pydantic.Field() + """ + The unique identifier of the mentioned user + """ + + email: str = pydantic.Field() + """ + Email of the user + """ + + name: str = pydantic.Field() + """ + Name of the User + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/component_dom.py b/src/webflow/types/component_dom.py index 3f76c81..2f70fc4 100644 --- a/src/webflow/types/component_dom.py +++ b/src/webflow/types/component_dom.py @@ -12,7 +12,7 @@ class ComponentDom(UniversalBaseModel): """ - The Component DOM schema represents the content structure of a component. Similar to Page DOM, it captures various content nodes and their associated attributes, but specifically for a component's structure. Each node has a unique identifier and can contain text, images, or nested component instances. + The Component DOM schema represents the content structure of a component. Similar to Page DOM, it captures various content nodes and their associated attributes, but specifically for a component's structure. Each node has a unique identifier and can contain text, images, select or text inputs, submit buttons, or nested component instances. """ component_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="componentId")] = ( diff --git a/src/webflow/types/component_node.py b/src/webflow/types/component_node.py index fa5f69d..6735289 100644 --- a/src/webflow/types/component_node.py +++ b/src/webflow/types/component_node.py @@ -1,10 +1,10 @@ # This file was auto-generated by Fern from our API Definition. from ..core.pydantic_utilities import UniversalBaseModel -import typing import pydantic import typing_extensions from ..core.serialization import FieldMetadata +import typing from .component_property import ComponentProperty from ..core.pydantic_utilities import IS_PYDANTIC_V2 @@ -14,21 +14,19 @@ class ComponentNode(UniversalBaseModel): Represents a component instance within the DOM. It contains details about the component instance, such as its type and properties. """ - id: typing.Optional[str] = pydantic.Field(default=None) + id: str = pydantic.Field() """ - Node UUID + The unique identifier of the component instance node """ - component_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="componentId")] = ( - pydantic.Field(default=None) - ) + component_id: typing_extensions.Annotated[str, FieldMetadata(alias="componentId")] = pydantic.Field() """ - Component ID + The unique identifier of the component """ property_overrides: typing_extensions.Annotated[ - typing.Optional[typing.List[ComponentProperty]], FieldMetadata(alias="propertyOverrides") - ] = pydantic.Field(default=None) + typing.List[ComponentProperty], FieldMetadata(alias="propertyOverrides") + ] = pydantic.Field() """ List of component properties with overrides for a component instance. """ diff --git a/tests/pages/__init__.py b/src/webflow/types/conflict.py similarity index 54% rename from tests/pages/__init__.py rename to src/webflow/types/conflict.py index f3ea265..30b9809 100644 --- a/tests/pages/__init__.py +++ b/src/webflow/types/conflict.py @@ -1,2 +1,5 @@ # This file was auto-generated by Fern from our API Definition. +import typing + +Conflict = typing.Optional[typing.Any] diff --git a/src/webflow/types/custom_role.py b/src/webflow/types/custom_role.py new file mode 100644 index 0000000..f8c9440 --- /dev/null +++ b/src/webflow/types/custom_role.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ..core.serialization import FieldMetadata +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class CustomRole(UniversalBaseModel): + role_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="roleName")] = pydantic.Field( + default=None + ) + """ + The name of the custom role + """ + + previous_role_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="previousRoleName")] = ( + pydantic.Field(default=None) + ) + """ + The previous name of the custom role + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/custom_role_audit_log_item.py b/src/webflow/types/custom_role_audit_log_item.py new file mode 100644 index 0000000..336aa26 --- /dev/null +++ b/src/webflow/types/custom_role_audit_log_item.py @@ -0,0 +1,26 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from .custom_role_audit_log_item_event_sub_type import CustomRoleAuditLogItemEventSubType +from ..core.serialization import FieldMetadata +from .custom_role import CustomRole +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class CustomRoleAuditLogItem(UniversalBaseModel): + event_sub_type: typing_extensions.Annotated[ + typing.Optional[CustomRoleAuditLogItemEventSubType], FieldMetadata(alias="eventSubType") + ] = None + payload: typing.Optional[CustomRole] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/custom_role_audit_log_item_event_sub_type.py b/src/webflow/types/custom_role_audit_log_item_event_sub_type.py new file mode 100644 index 0000000..38d177b --- /dev/null +++ b/src/webflow/types/custom_role_audit_log_item_event_sub_type.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CustomRoleAuditLogItemEventSubType = typing.Union[ + typing.Literal["role_created", "role_updated", "role_deleted"], typing.Any +] diff --git a/src/webflow/types/dom.py b/src/webflow/types/dom.py index ce15a6a..45c87b4 100644 --- a/src/webflow/types/dom.py +++ b/src/webflow/types/dom.py @@ -7,6 +7,7 @@ import pydantic from .node import Node from .pagination import Pagination +import datetime as dt from ..core.pydantic_utilities import IS_PYDANTIC_V2 @@ -22,8 +23,21 @@ class Dom(UniversalBaseModel): Page ID """ + branch_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="branchId")] = pydantic.Field( + default=None + ) + """ + The unique identifier of a [specific page branch.](https://help.webflow.com/hc/en-us/articles/33961355506195-Page-branching) + """ + nodes: typing.Optional[typing.List[Node]] = None pagination: typing.Optional[Pagination] = None + last_updated: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="lastUpdated")] = ( + pydantic.Field(default=None) + ) + """ + The date the page dom was most recently updated + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/webflow/types/field.py b/src/webflow/types/field.py index 40233a9..9543092 100644 --- a/src/webflow/types/field.py +++ b/src/webflow/types/field.py @@ -6,6 +6,7 @@ from ..core.serialization import FieldMetadata import typing from .field_type import FieldType +from .field_validations import FieldValidations from ..core.pydantic_utilities import IS_PYDANTIC_V2 @@ -53,6 +54,11 @@ class Field(UniversalBaseModel): Additional text to help anyone filling out this field """ + validations: typing.Optional[FieldValidations] = pydantic.Field(default=None) + """ + The validations for the field + """ + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 else: diff --git a/src/webflow/types/field_create.py b/src/webflow/types/field_create.py new file mode 100644 index 0000000..1c9cf61 --- /dev/null +++ b/src/webflow/types/field_create.py @@ -0,0 +1,8 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from .static_field import StaticField +from .option_field import OptionField +from .reference_field import ReferenceField + +FieldCreate = typing.Union[StaticField, OptionField, ReferenceField] diff --git a/src/webflow/types/field_type.py b/src/webflow/types/field_type.py index 6318a3d..e3495ce 100644 --- a/src/webflow/types/field_type.py +++ b/src/webflow/types/field_type.py @@ -8,15 +8,19 @@ "DateTime", "Email", "ExtFileRef", + "File", "Image", "Link", "MultiImage", + "MultiReference", "Number", + "Option", "Phone", "PlainText", + "Reference", "RichText", "Switch", - "Video", + "VideoLink", ], typing.Any, ] diff --git a/src/webflow/types/field_validations.py b/src/webflow/types/field_validations.py new file mode 100644 index 0000000..ca58a0b --- /dev/null +++ b/src/webflow/types/field_validations.py @@ -0,0 +1,28 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from .field_validations_additional_properties import FieldValidationsAdditionalProperties +from ..core.serialization import FieldMetadata +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class FieldValidations(UniversalBaseModel): + """ + The validations for the field + """ + + additional_properties: typing_extensions.Annotated[ + typing.Optional[FieldValidationsAdditionalProperties], FieldMetadata(alias="additionalProperties") + ] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/field_validations_additional_properties.py b/src/webflow/types/field_validations_additional_properties.py new file mode 100644 index 0000000..ba31807 --- /dev/null +++ b/src/webflow/types/field_validations_additional_properties.py @@ -0,0 +1,10 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from .field_validations_additional_properties_additional_properties import ( + FieldValidationsAdditionalPropertiesAdditionalProperties, +) + +FieldValidationsAdditionalProperties = typing.Union[ + str, float, bool, int, FieldValidationsAdditionalPropertiesAdditionalProperties +] diff --git a/src/webflow/types/field_validations_additional_properties_additional_properties.py b/src/webflow/types/field_validations_additional_properties_additional_properties.py new file mode 100644 index 0000000..aa6c548 --- /dev/null +++ b/src/webflow/types/field_validations_additional_properties_additional_properties.py @@ -0,0 +1,23 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ..core.serialization import FieldMetadata +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class FieldValidationsAdditionalPropertiesAdditionalProperties(UniversalBaseModel): + additional_properties: typing_extensions.Annotated[ + typing.Optional[typing.Any], FieldMetadata(alias="additionalProperties") + ] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/form_submission_trigger.py b/src/webflow/types/form_submission_trigger.py new file mode 100644 index 0000000..82f1eaf --- /dev/null +++ b/src/webflow/types/form_submission_trigger.py @@ -0,0 +1,36 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ..core.serialization import FieldMetadata +import pydantic +from .form_submission_trigger_payload import FormSubmissionTriggerPayload +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class FormSubmissionTrigger(UniversalBaseModel): + """ + The Webhook payload for when a form is submitted + """ + + trigger_type: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="triggerType")] = ( + pydantic.Field(default=None) + ) + """ + The type of event that triggered the request + """ + + payload: typing.Optional[FormSubmissionTriggerPayload] = pydantic.Field(default=None) + """ + The payload of data sent from Webflow + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/form_submission_trigger_payload.py b/src/webflow/types/form_submission_trigger_payload.py new file mode 100644 index 0000000..f192a9f --- /dev/null +++ b/src/webflow/types/form_submission_trigger_payload.py @@ -0,0 +1,74 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +import pydantic +import typing_extensions +from ..core.serialization import FieldMetadata +from .form_submission_trigger_payload_schema_item import FormSubmissionTriggerPayloadSchemaItem +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class FormSubmissionTriggerPayload(UniversalBaseModel): + """ + The payload of data sent from Webflow + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the form + """ + + site_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="siteId")] = pydantic.Field( + default=None + ) + """ + The ID of the site that the form was submitted from + """ + + data: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = pydantic.Field(default=None) + """ + The data submitted in the form + """ + + schema_: typing_extensions.Annotated[ + typing.Optional[typing.List[FormSubmissionTriggerPayloadSchemaItem]], FieldMetadata(alias="schema") + ] = pydantic.Field(default=None) + """ + A list of fields from the submitted form + """ + + submitted_at: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="submittedAt")] = ( + pydantic.Field(default=None) + ) + """ + The timestamp the form was submitted + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + the ID of the event + """ + + form_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="formId")] = pydantic.Field( + default=None + ) + """ + The ID of the form submission + """ + + form_element_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="formElementId")] = ( + pydantic.Field(default=None) + ) + """ + The uniqueID of the Form element + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/form_submission_trigger_payload_schema_item.py b/src/webflow/types/form_submission_trigger_payload_schema_item.py new file mode 100644 index 0000000..014322f --- /dev/null +++ b/src/webflow/types/form_submission_trigger_payload_schema_item.py @@ -0,0 +1,41 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ..core.serialization import FieldMetadata +import pydantic +from .form_submission_trigger_payload_schema_item_field_type import FormSubmissionTriggerPayloadSchemaItemFieldType +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class FormSubmissionTriggerPayloadSchemaItem(UniversalBaseModel): + field_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="fieldName")] = pydantic.Field( + default=None + ) + """ + Form field name + """ + + field_type: typing_extensions.Annotated[ + typing.Optional[FormSubmissionTriggerPayloadSchemaItemFieldType], FieldMetadata(alias="fieldType") + ] = pydantic.Field(default=None) + """ + Form field type + """ + + field_element_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="fieldElementId")] = ( + pydantic.Field(default=None) + ) + """ + Element ID of the Form Field + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/form_submission_trigger_payload_schema_item_field_type.py b/src/webflow/types/form_submission_trigger_payload_schema_item_field_type.py new file mode 100644 index 0000000..0ab97d1 --- /dev/null +++ b/src/webflow/types/form_submission_trigger_payload_schema_item_field_type.py @@ -0,0 +1,8 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +FormSubmissionTriggerPayloadSchemaItemFieldType = typing.Union[ + typing.Literal["FormTextInput", "FormTextarea", "FormCheckboxInput", "FormRadioInput", "FormFileUploadInput"], + typing.Any, +] diff --git a/src/webflow/types/image_node.py b/src/webflow/types/image_node.py index 2351cea..c4e7eac 100644 --- a/src/webflow/types/image_node.py +++ b/src/webflow/types/image_node.py @@ -1,9 +1,9 @@ # This file was auto-generated by Fern from our API Definition. from ..core.pydantic_utilities import UniversalBaseModel -import typing import pydantic from .image_node_image import ImageNodeImage +import typing from ..core.pydantic_utilities import IS_PYDANTIC_V2 @@ -12,12 +12,16 @@ class ImageNode(UniversalBaseModel): Represents an image within the DOM. It contains details about the image, such as its alternative text (alt) for accessibility and an asset identifier for fetching the actual image resource. Additional attributes can be associated with the image for styling or other purposes. """ - id: typing.Optional[str] = pydantic.Field(default=None) + id: str = pydantic.Field() """ Node UUID """ - image: typing.Optional[ImageNodeImage] = None + image: ImageNodeImage = pydantic.Field() + """ + The image details of the node + """ + attributes: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None) """ The custom attributes of the node diff --git a/src/webflow/types/image_node_image.py b/src/webflow/types/image_node_image.py index 2ef819f..f8d9379 100644 --- a/src/webflow/types/image_node_image.py +++ b/src/webflow/types/image_node_image.py @@ -9,6 +9,10 @@ class ImageNodeImage(UniversalBaseModel): + """ + The image details of the node + """ + alt: typing.Optional[str] = None asset_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="assetId")] = None diff --git a/src/webflow/types/items_list_items_live_request_last_published.py b/src/webflow/types/items_list_items_live_request_last_published.py new file mode 100644 index 0000000..31aab15 --- /dev/null +++ b/src/webflow/types/items_list_items_live_request_last_published.py @@ -0,0 +1,28 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +import datetime as dt +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class ItemsListItemsLiveRequestLastPublished(UniversalBaseModel): + lte: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Filter items last published before this date + """ + + gte: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Filter items last published after this date + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/items_list_items_request_last_published.py b/src/webflow/types/items_list_items_request_last_published.py new file mode 100644 index 0000000..bf4505d --- /dev/null +++ b/src/webflow/types/items_list_items_request_last_published.py @@ -0,0 +1,28 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +import datetime as dt +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class ItemsListItemsRequestLastPublished(UniversalBaseModel): + lte: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Filter items last published before this date + """ + + gte: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Filter items last published after this date + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/metadata.py b/src/webflow/types/metadata.py new file mode 100644 index 0000000..1c9caa7 --- /dev/null +++ b/src/webflow/types/metadata.py @@ -0,0 +1,27 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +from .metadata_options_item import MetadataOptionsItem +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class Metadata(UniversalBaseModel): + """ + The metadata for the Option field. + """ + + options: typing.List[MetadataOptionsItem] = pydantic.Field() + """ + The option values for the Option field. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/metadata_options_item.py b/src/webflow/types/metadata_options_item.py new file mode 100644 index 0000000..91eb360 --- /dev/null +++ b/src/webflow/types/metadata_options_item.py @@ -0,0 +1,31 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import pydantic +import typing +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class MetadataOptionsItem(UniversalBaseModel): + """ + A single option value for the Option field. + """ + + name: str = pydantic.Field() + """ + The name of the option + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the option + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/new_order.py b/src/webflow/types/new_order.py new file mode 100644 index 0000000..c156c65 --- /dev/null +++ b/src/webflow/types/new_order.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ..core.serialization import FieldMetadata +import pydantic +from .order import Order +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class NewOrder(UniversalBaseModel): + """ + The Webhook payload for when a new order is created + """ + + trigger_type: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="triggerType")] = ( + pydantic.Field(default=None) + ) + """ + The type of event that triggered the request + """ + + payload: typing.Optional[Order] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/node.py b/src/webflow/types/node.py index cd0942f..6ec64b9 100644 --- a/src/webflow/types/node.py +++ b/src/webflow/types/node.py @@ -10,6 +10,7 @@ import typing_extensions from ..core.serialization import FieldMetadata from .component_property import ComponentProperty +from .select_node_choices_item import SelectNodeChoicesItem class Node_Text(UniversalBaseModel): @@ -18,8 +19,8 @@ class Node_Text(UniversalBaseModel): """ type: typing.Literal["text"] = "text" - id: typing.Optional[str] = None - text: typing.Optional[TextNodeText] = None + id: str + text: TextNodeText attributes: typing.Optional[typing.Dict[str, str]] = None if IS_PYDANTIC_V2: @@ -38,8 +39,8 @@ class Node_Image(UniversalBaseModel): """ type: typing.Literal["image"] = "image" - id: typing.Optional[str] = None - image: typing.Optional[ImageNodeImage] = None + id: str + image: ImageNodeImage attributes: typing.Optional[typing.Dict[str, str]] = None if IS_PYDANTIC_V2: @@ -58,11 +59,11 @@ class Node_ComponentInstance(UniversalBaseModel): """ type: typing.Literal["component-instance"] = "component-instance" - id: typing.Optional[str] = None - component_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="componentId")] = None + id: str + component_id: typing_extensions.Annotated[str, FieldMetadata(alias="componentId")] property_overrides: typing_extensions.Annotated[ - typing.Optional[typing.List[ComponentProperty]], FieldMetadata(alias="propertyOverrides") - ] = None + typing.List[ComponentProperty], FieldMetadata(alias="propertyOverrides") + ] if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -74,4 +75,87 @@ class Config: extra = pydantic.Extra.allow -Node = typing.Union[Node_Text, Node_Image, Node_ComponentInstance] +class Node_TextInput(UniversalBaseModel): + """ + A generic representation of a content element within the Document Object Model (DOM). Each node has a unique identifier and a specific type that determines its content structure and attributes. + """ + + type: typing.Literal["text-input"] = "text-input" + id: str + placeholder: str + attributes: typing.Optional[typing.Dict[str, str]] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow + + +class Node_Select(UniversalBaseModel): + """ + A generic representation of a content element within the Document Object Model (DOM). Each node has a unique identifier and a specific type that determines its content structure and attributes. + """ + + type: typing.Literal["select"] = "select" + id: str + choices: typing.List[SelectNodeChoicesItem] + attributes: typing.Optional[typing.Dict[str, str]] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow + + +class Node_SubmitButton(UniversalBaseModel): + """ + A generic representation of a content element within the Document Object Model (DOM). Each node has a unique identifier and a specific type that determines its content structure and attributes. + """ + + type: typing.Literal["submit-button"] = "submit-button" + id: str + value: str + waiting_text: typing_extensions.Annotated[str, FieldMetadata(alias="waitingText")] + attributes: typing.Optional[typing.Dict[str, str]] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow + + +class Node_SearchButton(UniversalBaseModel): + """ + A generic representation of a content element within the Document Object Model (DOM). Each node has a unique identifier and a specific type that determines its content structure and attributes. + """ + + type: typing.Literal["search-button"] = "search-button" + id: str + value: str + attributes: typing.Optional[typing.Dict[str, str]] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow + + +Node = typing.Union[ + Node_Text, Node_Image, Node_ComponentInstance, Node_TextInput, Node_Select, Node_SubmitButton, Node_SearchButton +] diff --git a/src/webflow/types/option_field.py b/src/webflow/types/option_field.py new file mode 100644 index 0000000..7f7c6d5 --- /dev/null +++ b/src/webflow/types/option_field.py @@ -0,0 +1,58 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +import pydantic +import typing_extensions +from ..core.serialization import FieldMetadata +from .metadata import Metadata +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class OptionField(UniversalBaseModel): + id: typing.Optional[str] = pydantic.Field(default=None) + """ + Unique identifier for a Field + """ + + is_editable: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="isEditable")] = pydantic.Field( + default=None + ) + """ + Define whether the field is editable + """ + + is_required: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="isRequired")] = pydantic.Field( + default=None + ) + """ + define whether a field is required in a collection + """ + + type: typing.Literal["Option"] = pydantic.Field(default="Option") + """ + The [Option field type](/data/reference/field-types-item-values#option) + """ + + display_name: typing_extensions.Annotated[str, FieldMetadata(alias="displayName")] = pydantic.Field() + """ + The name of a field + """ + + help_text: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="helpText")] = pydantic.Field( + default=None + ) + """ + Additional text to help anyone filling out this field + """ + + metadata: Metadata + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/order.py b/src/webflow/types/order.py index d45b1de..2b2844c 100644 --- a/src/webflow/types/order.py +++ b/src/webflow/types/order.py @@ -10,6 +10,8 @@ from .order_dispute_last_status import OrderDisputeLastStatus from .order_price import OrderPrice from .order_address import OrderAddress +from .order_shipping_address import OrderShippingAddress +from .order_billing_address import OrderBillingAddress from .order_customer_info import OrderCustomerInfo from .order_purchased_item import OrderPurchasedItem from .stripe_details import StripeDetails @@ -119,14 +121,14 @@ class Order(UniversalBaseModel): """ shipping_address: typing_extensions.Annotated[ - typing.Optional[OrderAddress], FieldMetadata(alias="shippingAddress") + typing.Optional[OrderShippingAddress], FieldMetadata(alias="shippingAddress") ] = pydantic.Field(default=None) """ The shipping address """ billing_address: typing_extensions.Annotated[ - typing.Optional[OrderAddress], FieldMetadata(alias="billingAddress") + typing.Optional[OrderBillingAddress], FieldMetadata(alias="billingAddress") ] = pydantic.Field(default=None) """ The billing address diff --git a/src/webflow/types/order_billing_address.py b/src/webflow/types/order_billing_address.py new file mode 100644 index 0000000..75e87c6 --- /dev/null +++ b/src/webflow/types/order_billing_address.py @@ -0,0 +1,78 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +from .order_billing_address_type import OrderBillingAddressType +import pydantic +import typing_extensions +from .order_billing_address_japan_type import OrderBillingAddressJapanType +from ..core.serialization import FieldMetadata +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class OrderBillingAddress(UniversalBaseModel): + """ + The billing address + """ + + type: typing.Optional[OrderBillingAddressType] = pydantic.Field(default=None) + """ + The type of the order address (billing or shipping) + """ + + japan_type: typing_extensions.Annotated[ + typing.Optional[OrderBillingAddressJapanType], FieldMetadata(alias="japanType") + ] = pydantic.Field(default=None) + """ + Represents a Japan-only address format. This field will only appear on orders placed from Japan. + """ + + addressee: typing.Optional[str] = pydantic.Field(default=None) + """ + Display name on the address + """ + + line_1: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="line1")] = pydantic.Field( + default=None + ) + """ + The first line of the address + """ + + line_2: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="line2")] = pydantic.Field( + default=None + ) + """ + The second line of the address + """ + + city: typing.Optional[str] = pydantic.Field(default=None) + """ + The city of the address. + """ + + state: typing.Optional[str] = pydantic.Field(default=None) + """ + The state or province of the address + """ + + country: typing.Optional[str] = pydantic.Field(default=None) + """ + The country of the address + """ + + postal_code: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="postalCode")] = pydantic.Field( + default=None + ) + """ + The postal code of the address + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/order_billing_address_japan_type.py b/src/webflow/types/order_billing_address_japan_type.py new file mode 100644 index 0000000..8c983bb --- /dev/null +++ b/src/webflow/types/order_billing_address_japan_type.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +OrderBillingAddressJapanType = typing.Union[typing.Literal["kana", "kanji"], typing.Any] diff --git a/src/webflow/types/order_billing_address_type.py b/src/webflow/types/order_billing_address_type.py new file mode 100644 index 0000000..6b03d6e --- /dev/null +++ b/src/webflow/types/order_billing_address_type.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +OrderBillingAddressType = typing.Union[typing.Literal["shipping", "billing"], typing.Any] diff --git a/src/webflow/types/order_shipping_address.py b/src/webflow/types/order_shipping_address.py new file mode 100644 index 0000000..5c62f00 --- /dev/null +++ b/src/webflow/types/order_shipping_address.py @@ -0,0 +1,78 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +from .order_shipping_address_type import OrderShippingAddressType +import pydantic +import typing_extensions +from .order_shipping_address_japan_type import OrderShippingAddressJapanType +from ..core.serialization import FieldMetadata +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class OrderShippingAddress(UniversalBaseModel): + """ + The shipping address + """ + + type: typing.Optional[OrderShippingAddressType] = pydantic.Field(default=None) + """ + The type of the order address (billing or shipping) + """ + + japan_type: typing_extensions.Annotated[ + typing.Optional[OrderShippingAddressJapanType], FieldMetadata(alias="japanType") + ] = pydantic.Field(default=None) + """ + Represents a Japan-only address format. This field will only appear on orders placed from Japan. + """ + + addressee: typing.Optional[str] = pydantic.Field(default=None) + """ + Display name on the address + """ + + line_1: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="line1")] = pydantic.Field( + default=None + ) + """ + The first line of the address + """ + + line_2: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="line2")] = pydantic.Field( + default=None + ) + """ + The second line of the address + """ + + city: typing.Optional[str] = pydantic.Field(default=None) + """ + The city of the address. + """ + + state: typing.Optional[str] = pydantic.Field(default=None) + """ + The state or province of the address + """ + + country: typing.Optional[str] = pydantic.Field(default=None) + """ + The country of the address + """ + + postal_code: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="postalCode")] = pydantic.Field( + default=None + ) + """ + The postal code of the address + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/order_shipping_address_japan_type.py b/src/webflow/types/order_shipping_address_japan_type.py new file mode 100644 index 0000000..b5b548e --- /dev/null +++ b/src/webflow/types/order_shipping_address_japan_type.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +OrderShippingAddressJapanType = typing.Union[typing.Literal["kana", "kanji"], typing.Any] diff --git a/src/webflow/types/order_shipping_address_type.py b/src/webflow/types/order_shipping_address_type.py new file mode 100644 index 0000000..467ccbd --- /dev/null +++ b/src/webflow/types/order_shipping_address_type.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +OrderShippingAddressType = typing.Union[typing.Literal["shipping", "billing"], typing.Any] diff --git a/src/webflow/types/page.py b/src/webflow/types/page.py index 56b32d3..51346a0 100644 --- a/src/webflow/types/page.py +++ b/src/webflow/types/page.py @@ -80,7 +80,7 @@ class Page(UniversalBaseModel): default=None ) """ - Indicates whether the Page supports [Page Branching](https://university.webflow.com/lesson/page-branching) + Indicates whether the Page supports [Page Branching](https://university.webflow.com/lesson/page-branching). Pages that are already branches cannot be branched again. """ is_branch: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="isBranch")] = pydantic.Field( @@ -90,11 +90,11 @@ class Page(UniversalBaseModel): Indicates whether the Page is a Branch of another Page [Page Branching](https://university.webflow.com/lesson/page-branching) """ - is_members_only: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="isMembersOnly")] = ( - pydantic.Field(default=None) + branch_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="branchId")] = pydantic.Field( + default=None ) """ - Indicates whether the Page is restricted by [Memberships Controls](https://university.webflow.com/lesson/webflow-memberships-overview#how-to-manage-page-restrictions) + If the Page is a Branch of another Page, this is the ID of the Branch """ seo: typing.Optional[PageSeo] = pydantic.Field(default=None) diff --git a/src/webflow/types/page_created_webhook.py b/src/webflow/types/page_created_webhook.py new file mode 100644 index 0000000..60ef73e --- /dev/null +++ b/src/webflow/types/page_created_webhook.py @@ -0,0 +1,36 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ..core.serialization import FieldMetadata +import pydantic +from .page_created_webhook_payload import PageCreatedWebhookPayload +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class PageCreatedWebhook(UniversalBaseModel): + """ + The Webhook payload for when a Page is created + """ + + trigger_type: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="triggerType")] = ( + pydantic.Field(default=None) + ) + """ + The type of event that triggered the request + """ + + payload: typing.Optional[PageCreatedWebhookPayload] = pydantic.Field(default=None) + """ + The payload of data sent from Webflow + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/page_created_webhook_payload.py b/src/webflow/types/page_created_webhook_payload.py new file mode 100644 index 0000000..e986315 --- /dev/null +++ b/src/webflow/types/page_created_webhook_payload.py @@ -0,0 +1,30 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ..core.serialization import FieldMetadata +import datetime as dt +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class PageCreatedWebhookPayload(UniversalBaseModel): + """ + The payload of data sent from Webflow + """ + + site_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="siteId")] = None + page_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="pageId")] = None + page_title: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="pageTitle")] = None + created_on: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="createdOn")] = None + published_path: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="publishedPath")] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/page_deleted_webhook.py b/src/webflow/types/page_deleted_webhook.py new file mode 100644 index 0000000..5894078 --- /dev/null +++ b/src/webflow/types/page_deleted_webhook.py @@ -0,0 +1,36 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ..core.serialization import FieldMetadata +import pydantic +from .page_deleted_webhook_payload import PageDeletedWebhookPayload +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class PageDeletedWebhook(UniversalBaseModel): + """ + The Webhook payload for when a Page is deleted + """ + + trigger_type: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="triggerType")] = ( + pydantic.Field(default=None) + ) + """ + The type of event that triggered the request + """ + + payload: typing.Optional[PageDeletedWebhookPayload] = pydantic.Field(default=None) + """ + The payload of data sent from Webflow + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/page_deleted_webhook_payload.py b/src/webflow/types/page_deleted_webhook_payload.py new file mode 100644 index 0000000..5d09458 --- /dev/null +++ b/src/webflow/types/page_deleted_webhook_payload.py @@ -0,0 +1,30 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ..core.serialization import FieldMetadata +import datetime as dt +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class PageDeletedWebhookPayload(UniversalBaseModel): + """ + The payload of data sent from Webflow + """ + + site_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="siteId")] = None + page_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="pageId")] = None + page_title: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="pageTitle")] = None + deleted_on: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="deletedOn")] = None + published_path: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="publishedPath")] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/page_metadata_updated_webhook.py b/src/webflow/types/page_metadata_updated_webhook.py new file mode 100644 index 0000000..1bcb1e1 --- /dev/null +++ b/src/webflow/types/page_metadata_updated_webhook.py @@ -0,0 +1,36 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ..core.serialization import FieldMetadata +import pydantic +from .page_metadata_updated_webhook_payload import PageMetadataUpdatedWebhookPayload +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class PageMetadataUpdatedWebhook(UniversalBaseModel): + """ + The Webhook payload for when a Page's metadata is updated + """ + + trigger_type: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="triggerType")] = ( + pydantic.Field(default=None) + ) + """ + The type of event that triggered the request + """ + + payload: typing.Optional[PageMetadataUpdatedWebhookPayload] = pydantic.Field(default=None) + """ + The payload of data sent from Webflow + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/page_metadata_updated_webhook_payload.py b/src/webflow/types/page_metadata_updated_webhook_payload.py new file mode 100644 index 0000000..a75b703 --- /dev/null +++ b/src/webflow/types/page_metadata_updated_webhook_payload.py @@ -0,0 +1,30 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ..core.serialization import FieldMetadata +import datetime as dt +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class PageMetadataUpdatedWebhookPayload(UniversalBaseModel): + """ + The payload of data sent from Webflow + """ + + site_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="siteId")] = None + page_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="pageId")] = None + page_title: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="pageTitle")] = None + last_updated: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="lastUpdated")] = None + published_path: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="publishedPath")] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/payload.py b/src/webflow/types/payload.py new file mode 100644 index 0000000..a608741 --- /dev/null +++ b/src/webflow/types/payload.py @@ -0,0 +1,67 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +import pydantic +import typing_extensions +from ..core.serialization import FieldMetadata +import datetime as dt +from .payload_field_data import PayloadFieldData +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class Payload(UniversalBaseModel): + """ + The payload of data sent from Webflow + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + The ID of the collection item that was unpublished + """ + + site_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="siteId")] = pydantic.Field( + default=None + ) + """ + The ID of the site + """ + + workspace_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="workspaceId")] = ( + pydantic.Field(default=None) + ) + """ + The ID of the workspace + """ + + collection_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="collectionId")] = ( + pydantic.Field(default=None) + ) + """ + The ID of the collection + """ + + cms_locale_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="cmsLocaleId")] = ( + pydantic.Field(default=None) + ) + """ + Unique identifier of the CMS locale for this item + """ + + last_published: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="lastPublished")] = ( + None + ) + last_updated: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="lastUpdated")] = None + created_on: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="createdOn")] = None + is_archived: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="isArchived")] = None + is_draft: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="isDraft")] = None + field_data: typing_extensions.Annotated[typing.Optional[PayloadFieldData], FieldMetadata(alias="fieldData")] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/payload_field_data.py b/src/webflow/types/payload_field_data.py new file mode 100644 index 0000000..6fa4fc5 --- /dev/null +++ b/src/webflow/types/payload_field_data.py @@ -0,0 +1,20 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import typing +import pydantic + + +class PayloadFieldData(UniversalBaseModel): + name: str + slug: str + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/product_field_data.py b/src/webflow/types/product_field_data.py index e58b83d..e907159 100644 --- a/src/webflow/types/product_field_data.py +++ b/src/webflow/types/product_field_data.py @@ -43,9 +43,9 @@ class ProductFieldData(UniversalBaseModel): Variant types to include in SKUs """ - categories: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + category: typing.Optional[typing.List[str]] = pydantic.Field(default=None) """ - The categories your product belongs to. + The category your product belongs to. """ tax_category: typing_extensions.Annotated[ diff --git a/src/webflow/types/reference_field.py b/src/webflow/types/reference_field.py new file mode 100644 index 0000000..3c75552 --- /dev/null +++ b/src/webflow/types/reference_field.py @@ -0,0 +1,62 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +import pydantic +import typing_extensions +from ..core.serialization import FieldMetadata +from .reference_field_type import ReferenceFieldType +from .reference_field_metadata import ReferenceFieldMetadata +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class ReferenceField(UniversalBaseModel): + id: typing.Optional[str] = pydantic.Field(default=None) + """ + Unique identifier for a Field + """ + + is_editable: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="isEditable")] = pydantic.Field( + default=None + ) + """ + Define whether the field is editable + """ + + is_required: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="isRequired")] = pydantic.Field( + default=None + ) + """ + define whether a field is required in a collection + """ + + type: ReferenceFieldType = pydantic.Field() + """ + Choose these appropriate field type for your collection data + """ + + display_name: typing_extensions.Annotated[str, FieldMetadata(alias="displayName")] = pydantic.Field() + """ + The name of a field + """ + + help_text: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="helpText")] = pydantic.Field( + default=None + ) + """ + Additional text to help anyone filling out this field + """ + + metadata: ReferenceFieldMetadata = pydantic.Field() + """ + The collectionId for the referenced collection. Only applicable for Reference and MultiReference fields. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/reference_field_metadata.py b/src/webflow/types/reference_field_metadata.py new file mode 100644 index 0000000..164c4a6 --- /dev/null +++ b/src/webflow/types/reference_field_metadata.py @@ -0,0 +1,28 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +from ..core.serialization import FieldMetadata +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import typing + + +class ReferenceFieldMetadata(UniversalBaseModel): + """ + The collectionId for the referenced collection. Only applicable for Reference and MultiReference fields. + """ + + collection_id: typing_extensions.Annotated[str, FieldMetadata(alias="collectionId")] = pydantic.Field() + """ + The unique identifier of the collection + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/reference_field_type.py b/src/webflow/types/reference_field_type.py new file mode 100644 index 0000000..b80f3e1 --- /dev/null +++ b/src/webflow/types/reference_field_type.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +ReferenceFieldType = typing.Union[typing.Literal["MultiReference", "Reference"], typing.Any] diff --git a/src/webflow/types/registered_script_list.py b/src/webflow/types/registered_script_list.py index ddfff8d..e9d8a01 100644 --- a/src/webflow/types/registered_script_list.py +++ b/src/webflow/types/registered_script_list.py @@ -5,6 +5,7 @@ import typing from .custom_code_hosted_response import CustomCodeHostedResponse from ..core.serialization import FieldMetadata +from .pagination import Pagination from ..core.pydantic_utilities import IS_PYDANTIC_V2 import pydantic @@ -17,6 +18,7 @@ class RegisteredScriptList(UniversalBaseModel): registered_scripts: typing_extensions.Annotated[ typing.Optional[typing.List[CustomCodeHostedResponse]], FieldMetadata(alias="registeredScripts") ] = None + pagination: typing.Optional[Pagination] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/webflow/types/robots.py b/src/webflow/types/robots.py new file mode 100644 index 0000000..7489660 --- /dev/null +++ b/src/webflow/types/robots.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +from .robots_rules_item import RobotsRulesItem +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class Robots(UniversalBaseModel): + """ + The robots.txt file for a given site + """ + + rules: typing.Optional[typing.List[RobotsRulesItem]] = pydantic.Field(default=None) + """ + List of rules for user agents. + """ + + sitemap: typing.Optional[str] = pydantic.Field(default=None) + """ + URL to the sitemap. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/robots_rules_item.py b/src/webflow/types/robots_rules_item.py new file mode 100644 index 0000000..048f239 --- /dev/null +++ b/src/webflow/types/robots_rules_item.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +from ..core.serialization import FieldMetadata +import pydantic +import typing +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class RobotsRulesItem(UniversalBaseModel): + user_agent: typing_extensions.Annotated[str, FieldMetadata(alias="userAgent")] = pydantic.Field() + """ + The user agent the rules apply to. + """ + + allows: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + List of paths allowed for this user agent. + """ + + disallows: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + List of paths disallowed for this user agent. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/search_button_node.py b/src/webflow/types/search_button_node.py new file mode 100644 index 0000000..091b06c --- /dev/null +++ b/src/webflow/types/search_button_node.py @@ -0,0 +1,36 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import pydantic +import typing +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class SearchButtonNode(UniversalBaseModel): + """ + Represents search button elements within the DOM. It contains the text of the button. Additional attributes can be associated with the text for styling or other purposes. + """ + + id: str = pydantic.Field() + """ + Node UUID + """ + + value: str = pydantic.Field() + """ + The text content of the search button. + """ + + attributes: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None) + """ + The custom attributes of the node + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/search_button_node_write.py b/src/webflow/types/search_button_node_write.py new file mode 100644 index 0000000..15c5daf --- /dev/null +++ b/src/webflow/types/search_button_node_write.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +from ..core.serialization import FieldMetadata +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import typing + + +class SearchButtonNodeWrite(UniversalBaseModel): + """ + Update a search button node + """ + + node_id: typing_extensions.Annotated[str, FieldMetadata(alias="nodeId")] = pydantic.Field() + """ + Node UUID + """ + + value: str = pydantic.Field() + """ + The text content of the search button. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/select.py b/src/webflow/types/select.py new file mode 100644 index 0000000..7208091 --- /dev/null +++ b/src/webflow/types/select.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +from ..core.serialization import FieldMetadata +import pydantic +import typing +from .select_node_write_choices_item import SelectNodeWriteChoicesItem +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class Select(UniversalBaseModel): + """ + Update choices on a select node + """ + + node_id: typing_extensions.Annotated[str, FieldMetadata(alias="nodeId")] = pydantic.Field() + """ + Node UUID + """ + + choices: typing.List[SelectNodeWriteChoicesItem] = pydantic.Field() + """ + The list of choices to set on the select node. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/select_node.py b/src/webflow/types/select_node.py new file mode 100644 index 0000000..f8cc21f --- /dev/null +++ b/src/webflow/types/select_node.py @@ -0,0 +1,37 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import pydantic +import typing +from .select_node_choices_item import SelectNodeChoicesItem +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class SelectNode(UniversalBaseModel): + """ + Represents select elements within the DOM. It contains the list of choices in the select. Additional attributes can be associated with the text for styling or other purposes. + """ + + id: str = pydantic.Field() + """ + Node UUID + """ + + choices: typing.List[SelectNodeChoicesItem] = pydantic.Field() + """ + The list of choices in this select node. + """ + + attributes: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None) + """ + The custom attributes of the node + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/select_node_choices_item.py b/src/webflow/types/select_node_choices_item.py new file mode 100644 index 0000000..cd210b1 --- /dev/null +++ b/src/webflow/types/select_node_choices_item.py @@ -0,0 +1,27 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import typing + + +class SelectNodeChoicesItem(UniversalBaseModel): + value: str = pydantic.Field() + """ + The value of the choice when selected. + """ + + text: str = pydantic.Field() + """ + The text to display for the choice. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/select_node_write_choices_item.py b/src/webflow/types/select_node_write_choices_item.py new file mode 100644 index 0000000..4346fef --- /dev/null +++ b/src/webflow/types/select_node_write_choices_item.py @@ -0,0 +1,27 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import typing + + +class SelectNodeWriteChoicesItem(UniversalBaseModel): + value: str = pydantic.Field() + """ + The value of the choice when selected. + """ + + text: str = pydantic.Field() + """ + The text to display for the choice. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/single_locale_created_payload.py b/src/webflow/types/single_locale_created_payload.py new file mode 100644 index 0000000..9293d8c --- /dev/null +++ b/src/webflow/types/single_locale_created_payload.py @@ -0,0 +1,57 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import pydantic +import typing_extensions +from ..core.serialization import FieldMetadata +import typing +import datetime as dt +from .single_locale_created_payload_field_data import SingleLocaleCreatedPayloadFieldData +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class SingleLocaleCreatedPayload(UniversalBaseModel): + id: str = pydantic.Field() + """ + Unique identifier for the Item + """ + + workspace_id: typing_extensions.Annotated[str, FieldMetadata(alias="workspaceId")] = pydantic.Field() + """ + Unique identifier of the workspace + """ + + site_id: typing_extensions.Annotated[str, FieldMetadata(alias="siteId")] = pydantic.Field() + """ + Unique identifier of the site + """ + + collection_id: typing_extensions.Annotated[str, FieldMetadata(alias="collectionId")] = pydantic.Field() + """ + Unique identifier of the collection + """ + + cms_locale_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="cmsLocaleId")] = ( + pydantic.Field(default=None) + ) + """ + Unique identifier of the CMS locale for this item + """ + + last_published: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="lastPublished")] = ( + None + ) + last_updated: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="lastUpdated")] = None + created_on: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="createdOn")] = None + is_archived: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="isArchived")] = None + is_draft: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="isDraft")] = None + field_data: typing_extensions.Annotated[SingleLocaleCreatedPayloadFieldData, FieldMetadata(alias="fieldData")] + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/single_locale_created_payload_field_data.py b/src/webflow/types/single_locale_created_payload_field_data.py new file mode 100644 index 0000000..b412ef9 --- /dev/null +++ b/src/webflow/types/single_locale_created_payload_field_data.py @@ -0,0 +1,20 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import typing +import pydantic + + +class SingleLocaleCreatedPayloadFieldData(UniversalBaseModel): + name: str + slug: str + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/site_membership.py b/src/webflow/types/site_membership.py new file mode 100644 index 0000000..5ff933a --- /dev/null +++ b/src/webflow/types/site_membership.py @@ -0,0 +1,56 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +from .workspace_audit_log_item_payload_site_membership_site import WorkspaceAuditLogItemPayloadSiteMembershipSite +import typing_extensions +from .workspace_audit_log_item_payload_site_membership_target_user import ( + WorkspaceAuditLogItemPayloadSiteMembershipTargetUser, +) +from ..core.serialization import FieldMetadata +from .workspace_audit_log_item_payload_site_membership_method import WorkspaceAuditLogItemPayloadSiteMembershipMethod +from .workspace_audit_log_item_payload_site_membership_user_type import ( + WorkspaceAuditLogItemPayloadSiteMembershipUserType, +) +import pydantic +from .workspace_audit_log_item_payload_site_membership_granular_access import ( + WorkspaceAuditLogItemPayloadSiteMembershipGranularAccess, +) +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class SiteMembership(UniversalBaseModel): + site: typing.Optional[WorkspaceAuditLogItemPayloadSiteMembershipSite] = None + target_user: typing_extensions.Annotated[ + typing.Optional[WorkspaceAuditLogItemPayloadSiteMembershipTargetUser], FieldMetadata(alias="targetUser") + ] = None + method: typing.Optional[WorkspaceAuditLogItemPayloadSiteMembershipMethod] = None + user_type: typing_extensions.Annotated[ + typing.Optional[WorkspaceAuditLogItemPayloadSiteMembershipUserType], FieldMetadata(alias="userType") + ] = None + role_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="roleName")] = pydantic.Field( + default=None + ) + """ + The name of the role that was assigned to the user + """ + + previous_role_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="previousRoleName")] = ( + pydantic.Field(default=None) + ) + """ + The previous role that the user had + """ + + granular_access: typing_extensions.Annotated[ + typing.Optional[WorkspaceAuditLogItemPayloadSiteMembershipGranularAccess], FieldMetadata(alias="granularAccess") + ] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/site_membership_audit_log_item.py b/src/webflow/types/site_membership_audit_log_item.py new file mode 100644 index 0000000..d24ee9f --- /dev/null +++ b/src/webflow/types/site_membership_audit_log_item.py @@ -0,0 +1,26 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from .site_membership_audit_log_item_event_sub_type import SiteMembershipAuditLogItemEventSubType +from ..core.serialization import FieldMetadata +from .site_membership import SiteMembership +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class SiteMembershipAuditLogItem(UniversalBaseModel): + event_sub_type: typing_extensions.Annotated[ + typing.Optional[SiteMembershipAuditLogItemEventSubType], FieldMetadata(alias="eventSubType") + ] = None + payload: typing.Optional[SiteMembership] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/site_membership_audit_log_item_event_sub_type.py b/src/webflow/types/site_membership_audit_log_item_event_sub_type.py new file mode 100644 index 0000000..ff26017 --- /dev/null +++ b/src/webflow/types/site_membership_audit_log_item_event_sub_type.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +SiteMembershipAuditLogItemEventSubType = typing.Union[ + typing.Literal["user_added", "user_removed", "user_role_updated", "user_granular_access_updated"], typing.Any +] diff --git a/src/webflow/types/site_publish.py b/src/webflow/types/site_publish.py new file mode 100644 index 0000000..518178e --- /dev/null +++ b/src/webflow/types/site_publish.py @@ -0,0 +1,36 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ..core.serialization import FieldMetadata +import pydantic +from .site_publish_payload import SitePublishPayload +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class SitePublish(UniversalBaseModel): + """ + The Webhook payload for when a Site is published + """ + + trigger_type: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="triggerType")] = ( + pydantic.Field(default=None) + ) + """ + The type of event that triggered the request + """ + + payload: typing.Optional[SitePublishPayload] = pydantic.Field(default=None) + """ + The payload of data sent from Webflow + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/site_publish_payload.py b/src/webflow/types/site_publish_payload.py new file mode 100644 index 0000000..f44882e --- /dev/null +++ b/src/webflow/types/site_publish_payload.py @@ -0,0 +1,50 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ..core.serialization import FieldMetadata +import pydantic +import datetime as dt +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class SitePublishPayload(UniversalBaseModel): + """ + The payload of data sent from Webflow + """ + + site_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="siteId")] = pydantic.Field( + default=None + ) + """ + The ID of the site that was published + """ + + published_on: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="publishedOn")] = ( + pydantic.Field(default=None) + ) + """ + The timestamp of the publish event + """ + + domains: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + The domains that were published + """ + + published_by: typing_extensions.Annotated[ + typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]], FieldMetadata(alias="publishedBy") + ] = pydantic.Field(default=None) + """ + The name andID of the user who published the site + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/sku_field_data.py b/src/webflow/types/sku_field_data.py index e20efdb..c7540d8 100644 --- a/src/webflow/types/sku_field_data.py +++ b/src/webflow/types/sku_field_data.py @@ -10,6 +10,7 @@ from .sku_field_data_compare_at_price import SkuFieldDataCompareAtPrice from .sku_field_data_ec_sku_billing_method import SkuFieldDataEcSkuBillingMethod from .sku_field_data_ec_sku_subscription_plan import SkuFieldDataEcSkuSubscriptionPlan +from .sku_property_list import SkuPropertyList from ..core.pydantic_utilities import IS_PYDANTIC_V2 @@ -43,20 +44,35 @@ class SkuFieldData(UniversalBaseModel): ec_sku_billing_method: typing_extensions.Annotated[ typing.Optional[SkuFieldDataEcSkuBillingMethod], FieldMetadata(alias="ec-sku-billing-method") - ] = None + ] = pydantic.Field(default=None) + """ + [Billing method](https://help.webflow.com/hc/en-us/articles/33961432087955-Add-and-manage-products-and-categories#billing-methods)for the SKU + """ + ec_sku_subscription_plan: typing_extensions.Annotated[ typing.Optional[SkuFieldDataEcSkuSubscriptionPlan], FieldMetadata(alias="ec-sku-subscription-plan") - ] = None - track_inventory: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="track-inventory")] = ( - pydantic.Field(default=None) + ] = pydantic.Field(default=None) + """ + [Subscription plan](https://help.webflow.com/hc/en-us/articles/33961432087955-Add-and-manage-products-and-categories#subscription) for the SKU + """ + + main_image: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="main-image")] = pydantic.Field( + default=None ) """ - A boolean indicating whether inventory for this product should be tracked. + The URL for the main image of the SKU + """ + + sku: typing.Optional[str] = pydantic.Field(default=None) + """ + A unique identifier for the SKU """ - quantity: typing.Optional[float] = pydantic.Field(default=None) + sku_properties: typing_extensions.Annotated[ + typing.Optional[typing.List[SkuPropertyList]], FieldMetadata(alias="sku-properties") + ] = pydantic.Field(default=None) """ - Quantity of SKU that will be tracked as items are ordered. + The properties of the SKU """ if IS_PYDANTIC_V2: diff --git a/src/webflow/types/sku_field_data_ec_sku_subscription_plan.py b/src/webflow/types/sku_field_data_ec_sku_subscription_plan.py index 24c85a7..ed2e484 100644 --- a/src/webflow/types/sku_field_data_ec_sku_subscription_plan.py +++ b/src/webflow/types/sku_field_data_ec_sku_subscription_plan.py @@ -9,6 +9,10 @@ class SkuFieldDataEcSkuSubscriptionPlan(UniversalBaseModel): + """ + [Subscription plan](https://help.webflow.com/hc/en-us/articles/33961432087955-Add-and-manage-products-and-categories#subscription) for the SKU + """ + interval: typing.Optional[SkuFieldDataEcSkuSubscriptionPlanInterval] = pydantic.Field(default=None) """ Interval of subscription renewal diff --git a/src/webflow/types/sku_field_data_price.py b/src/webflow/types/sku_field_data_price.py index 45ff611..cb31f4a 100644 --- a/src/webflow/types/sku_field_data_price.py +++ b/src/webflow/types/sku_field_data_price.py @@ -21,6 +21,11 @@ class SkuFieldDataPrice(UniversalBaseModel): Currency of Item """ + currency: typing.Optional[str] = pydantic.Field(default=None) + """ + Currency of Item (alternative representation) + """ + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 else: diff --git a/src/webflow/types/static_field.py b/src/webflow/types/static_field.py new file mode 100644 index 0000000..c6e6162 --- /dev/null +++ b/src/webflow/types/static_field.py @@ -0,0 +1,56 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +import pydantic +import typing_extensions +from ..core.serialization import FieldMetadata +from .static_field_type import StaticFieldType +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class StaticField(UniversalBaseModel): + id: typing.Optional[str] = pydantic.Field(default=None) + """ + Unique identifier for a Field + """ + + is_editable: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="isEditable")] = pydantic.Field( + default=None + ) + """ + Define whether the field is editable + """ + + is_required: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="isRequired")] = pydantic.Field( + default=None + ) + """ + define whether a field is required in a collection + """ + + type: StaticFieldType = pydantic.Field() + """ + Choose these appropriate field type for your collection data + """ + + display_name: typing_extensions.Annotated[str, FieldMetadata(alias="displayName")] = pydantic.Field() + """ + The name of a field + """ + + help_text: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="helpText")] = pydantic.Field( + default=None + ) + """ + Additional text to help anyone filling out this field + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/resources/collections/resources/fields/types/field_create_type.py b/src/webflow/types/static_field_type.py similarity index 82% rename from src/webflow/resources/collections/resources/fields/types/field_create_type.py rename to src/webflow/types/static_field_type.py index c8ec44b..e7cadf0 100644 --- a/src/webflow/resources/collections/resources/fields/types/field_create_type.py +++ b/src/webflow/types/static_field_type.py @@ -2,12 +2,11 @@ import typing -FieldCreateType = typing.Union[ +StaticFieldType = typing.Union[ typing.Literal[ "Color", "DateTime", "Email", - "ExtFileRef", "File", "Image", "Link", @@ -17,7 +16,7 @@ "PlainText", "RichText", "Switch", - "Video", + "VideoLink", ], typing.Any, ] diff --git a/src/webflow/types/submit_button_node.py b/src/webflow/types/submit_button_node.py new file mode 100644 index 0000000..25ba646 --- /dev/null +++ b/src/webflow/types/submit_button_node.py @@ -0,0 +1,43 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import pydantic +import typing_extensions +from ..core.serialization import FieldMetadata +import typing +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class SubmitButtonNode(UniversalBaseModel): + """ + Represents submit button elements within the DOM. It contains the text and waiting text of the button. Additional attributes can be associated with the text for styling or other purposes. + """ + + id: str = pydantic.Field() + """ + Node UUID + """ + + value: str = pydantic.Field() + """ + The text content of the submit button. + """ + + waiting_text: typing_extensions.Annotated[str, FieldMetadata(alias="waitingText")] = pydantic.Field() + """ + The text to show while the form is submitting. + """ + + attributes: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None) + """ + The custom attributes of the node + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/submit_button_node_write.py b/src/webflow/types/submit_button_node_write.py new file mode 100644 index 0000000..6233215 --- /dev/null +++ b/src/webflow/types/submit_button_node_write.py @@ -0,0 +1,40 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +from ..core.serialization import FieldMetadata +import pydantic +import typing +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class SubmitButtonNodeWrite(UniversalBaseModel): + """ + Update a submit button node + """ + + node_id: typing_extensions.Annotated[str, FieldMetadata(alias="nodeId")] = pydantic.Field() + """ + Node UUID + """ + + value: typing.Optional[str] = pydantic.Field(default=None) + """ + The text content of the submit button. + """ + + waiting_text: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="waitingText")] = ( + pydantic.Field(default=None) + ) + """ + The text to show while the form is submitting. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/text.py b/src/webflow/types/text.py index 18f8501..913d5d1 100644 --- a/src/webflow/types/text.py +++ b/src/webflow/types/text.py @@ -7,6 +7,10 @@ class Text(UniversalBaseModel): + """ + The text content of the node + """ + html: typing.Optional[str] = pydantic.Field(default=None) """ The HTML content of the text node. diff --git a/src/webflow/types/text_input_node.py b/src/webflow/types/text_input_node.py new file mode 100644 index 0000000..7146e15 --- /dev/null +++ b/src/webflow/types/text_input_node.py @@ -0,0 +1,36 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import pydantic +import typing +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class TextInputNode(UniversalBaseModel): + """ + Represents text input and textarea elements within the DOM. It contains the placeholder text in the input. Additional attributes can be associated with the text for styling or other purposes. + """ + + id: str = pydantic.Field() + """ + Node UUID + """ + + placeholder: str = pydantic.Field() + """ + The placeholder text of the input node + """ + + attributes: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None) + """ + The custom attributes of the node + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/text_input_node_write.py b/src/webflow/types/text_input_node_write.py new file mode 100644 index 0000000..6ea8e98 --- /dev/null +++ b/src/webflow/types/text_input_node_write.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +from ..core.serialization import FieldMetadata +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import typing + + +class TextInputNodeWrite(UniversalBaseModel): + """ + Update placeholder text on a text input node + """ + + node_id: typing_extensions.Annotated[str, FieldMetadata(alias="nodeId")] = pydantic.Field() + """ + Node UUID + """ + + placeholder: str = pydantic.Field() + """ + The placeholder text of the input node + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/text_node.py b/src/webflow/types/text_node.py index 1e16717..aa15d4b 100644 --- a/src/webflow/types/text_node.py +++ b/src/webflow/types/text_node.py @@ -1,9 +1,9 @@ # This file was auto-generated by Fern from our API Definition. from ..core.pydantic_utilities import UniversalBaseModel -import typing import pydantic from .text_node_text import TextNodeText +import typing from ..core.pydantic_utilities import IS_PYDANTIC_V2 @@ -12,12 +12,16 @@ class TextNode(UniversalBaseModel): Represents text content within the DOM. It contains both the raw text and its HTML representation. Additional attributes can be associated with the text for styling or other purposes. """ - id: typing.Optional[str] = pydantic.Field(default=None) + id: str = pydantic.Field() """ Node UUID """ - text: typing.Optional[TextNodeText] = None + text: TextNodeText = pydantic.Field() + """ + The text content of the node + """ + attributes: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None) """ The custom attributes of the node diff --git a/src/webflow/types/text_node_text.py b/src/webflow/types/text_node_text.py index 895dc0b..5add2f0 100644 --- a/src/webflow/types/text_node_text.py +++ b/src/webflow/types/text_node_text.py @@ -7,6 +7,10 @@ class TextNodeText(UniversalBaseModel): + """ + The text content of the node + """ + html: typing.Optional[str] = pydantic.Field(default=None) """ The HTML content of the text node. diff --git a/src/webflow/types/trigger_type.py b/src/webflow/types/trigger_type.py index e12b650..6540e4b 100644 --- a/src/webflow/types/trigger_type.py +++ b/src/webflow/types/trigger_type.py @@ -18,7 +18,9 @@ "collection_item_created", "collection_item_changed", "collection_item_deleted", + "collection_item_published", "collection_item_unpublished", + "comment_created", ], typing.Any, ] diff --git a/src/webflow/types/updated_order.py b/src/webflow/types/updated_order.py new file mode 100644 index 0000000..a3fc241 --- /dev/null +++ b/src/webflow/types/updated_order.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ..core.serialization import FieldMetadata +import pydantic +from .order import Order +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class UpdatedOrder(UniversalBaseModel): + """ + The Webhook payload for when an order is updated + """ + + trigger_type: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="triggerType")] = ( + pydantic.Field(default=None) + ) + """ + The type of event that triggered the request + """ + + payload: typing.Optional[Order] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/user.py b/src/webflow/types/user.py index a27a063..d6c3ade 100644 --- a/src/webflow/types/user.py +++ b/src/webflow/types/user.py @@ -57,11 +57,7 @@ class User(UniversalBaseModel): The timestamp the user was logged in """ - status: typing.Optional[UserStatus] = pydantic.Field(default=None) - """ - The status of the user - """ - + status: typing.Optional[UserStatus] = None access_groups: typing_extensions.Annotated[ typing.Optional[typing.List[UserAccessGroupsItem]], FieldMetadata(alias="accessGroups") ] = pydantic.Field(default=None) diff --git a/src/webflow/types/user_access.py b/src/webflow/types/user_access.py new file mode 100644 index 0000000..7c869dd --- /dev/null +++ b/src/webflow/types/user_access.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +from .workspace_audit_log_item_payload_user_access_method import WorkspaceAuditLogItemPayloadUserAccessMethod +import pydantic +import typing_extensions +from ..core.serialization import FieldMetadata +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class UserAccess(UniversalBaseModel): + method: typing.Optional[WorkspaceAuditLogItemPayloadUserAccessMethod] = None + location: typing.Optional[str] = pydantic.Field(default=None) + """ + The geolocation based on the logged IP address + """ + + ip_address: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="ipAddress")] = pydantic.Field( + default=None + ) + """ + The captured IP address of the user + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/user_access_audit_log_item.py b/src/webflow/types/user_access_audit_log_item.py new file mode 100644 index 0000000..b94e6a7 --- /dev/null +++ b/src/webflow/types/user_access_audit_log_item.py @@ -0,0 +1,26 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from .user_access_audit_log_item_event_sub_type import UserAccessAuditLogItemEventSubType +from ..core.serialization import FieldMetadata +from .user_access import UserAccess +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class UserAccessAuditLogItem(UniversalBaseModel): + event_sub_type: typing_extensions.Annotated[ + typing.Optional[UserAccessAuditLogItemEventSubType], FieldMetadata(alias="eventSubType") + ] = None + payload: typing.Optional[UserAccess] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/user_access_audit_log_item_event_sub_type.py b/src/webflow/types/user_access_audit_log_item_event_sub_type.py new file mode 100644 index 0000000..382f247 --- /dev/null +++ b/src/webflow/types/user_access_audit_log_item_event_sub_type.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +UserAccessAuditLogItemEventSubType = typing.Union[typing.Literal["login", "logout"], typing.Any] diff --git a/src/webflow/types/webhook_list.py b/src/webflow/types/webhook_list.py index ea705c4..1740272 100644 --- a/src/webflow/types/webhook_list.py +++ b/src/webflow/types/webhook_list.py @@ -2,15 +2,15 @@ from ..core.pydantic_utilities import UniversalBaseModel import typing -from .pagination import Pagination from .webhook import Webhook +from .pagination import Pagination from ..core.pydantic_utilities import IS_PYDANTIC_V2 import pydantic class WebhookList(UniversalBaseModel): - pagination: typing.Optional[Pagination] = None webhooks: typing.Optional[typing.List[Webhook]] = None + pagination: typing.Optional[Pagination] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/webflow/types/workspace_audit_log_item.py b/src/webflow/types/workspace_audit_log_item.py new file mode 100644 index 0000000..4f95a56 --- /dev/null +++ b/src/webflow/types/workspace_audit_log_item.py @@ -0,0 +1,141 @@ +# This file was auto-generated by Fern from our API Definition. + +from __future__ import annotations +from ..core.pydantic_utilities import UniversalBaseModel +import typing +import datetime as dt +from .workspace_audit_log_item_actor import WorkspaceAuditLogItemActor +from .workspace_audit_log_item_workspace import WorkspaceAuditLogItemWorkspace +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic +import typing_extensions +from ..core.serialization import FieldMetadata +from .user_access_audit_log_item_event_sub_type import UserAccessAuditLogItemEventSubType +from .user_access import UserAccess +from .custom_role_audit_log_item_event_sub_type import CustomRoleAuditLogItemEventSubType +from .custom_role import CustomRole +from .workspace_membership_audit_log_item_event_sub_type import WorkspaceMembershipAuditLogItemEventSubType +from .workspace_membership import WorkspaceMembership +from .site_membership_audit_log_item_event_sub_type import SiteMembershipAuditLogItemEventSubType +from .site_membership import SiteMembership +from .workspace_invitation_audit_log_item_event_sub_type import WorkspaceInvitationAuditLogItemEventSubType +from .workspace_invitation import WorkspaceInvitation + + +class Base(UniversalBaseModel): + timestamp: typing.Optional[dt.datetime] = None + actor: typing.Optional[WorkspaceAuditLogItemActor] = None + workspace: typing.Optional[WorkspaceAuditLogItemWorkspace] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow + + +class WorkspaceAuditLogItem_UserAccess(Base): + event_type: typing_extensions.Annotated[typing.Literal["user_access"], FieldMetadata(alias="eventType")] = ( + "user_access" + ) + event_sub_type: typing_extensions.Annotated[ + typing.Optional[UserAccessAuditLogItemEventSubType], FieldMetadata(alias="eventSubType") + ] = None + payload: typing.Optional[UserAccess] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow + + +class WorkspaceAuditLogItem_CustomRole(Base): + event_type: typing_extensions.Annotated[typing.Literal["custom_role"], FieldMetadata(alias="eventType")] = ( + "custom_role" + ) + event_sub_type: typing_extensions.Annotated[ + typing.Optional[CustomRoleAuditLogItemEventSubType], FieldMetadata(alias="eventSubType") + ] = None + payload: typing.Optional[CustomRole] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow + + +class WorkspaceAuditLogItem_WorkspaceMembership(Base): + event_type: typing_extensions.Annotated[ + typing.Literal["workspace_membership"], FieldMetadata(alias="eventType") + ] = "workspace_membership" + event_sub_type: typing_extensions.Annotated[ + typing.Optional[WorkspaceMembershipAuditLogItemEventSubType], FieldMetadata(alias="eventSubType") + ] = None + payload: typing.Optional[WorkspaceMembership] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow + + +class WorkspaceAuditLogItem_SiteMembership(Base): + event_type: typing_extensions.Annotated[typing.Literal["site_membership"], FieldMetadata(alias="eventType")] = ( + "site_membership" + ) + event_sub_type: typing_extensions.Annotated[ + typing.Optional[SiteMembershipAuditLogItemEventSubType], FieldMetadata(alias="eventSubType") + ] = None + payload: typing.Optional[SiteMembership] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow + + +class WorkspaceAuditLogItem_WorkspaceInvitation(Base): + event_type: typing_extensions.Annotated[ + typing.Literal["workspace_invitation"], FieldMetadata(alias="eventType") + ] = "workspace_invitation" + event_sub_type: typing_extensions.Annotated[ + typing.Optional[WorkspaceInvitationAuditLogItemEventSubType], FieldMetadata(alias="eventSubType") + ] = None + payload: typing.Optional[WorkspaceInvitation] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow + + +WorkspaceAuditLogItem = typing.Union[ + WorkspaceAuditLogItem_UserAccess, + WorkspaceAuditLogItem_CustomRole, + WorkspaceAuditLogItem_WorkspaceMembership, + WorkspaceAuditLogItem_SiteMembership, + WorkspaceAuditLogItem_WorkspaceInvitation, +] diff --git a/src/webflow/types/workspace_audit_log_item_actor.py b/src/webflow/types/workspace_audit_log_item_actor.py new file mode 100644 index 0000000..7da609c --- /dev/null +++ b/src/webflow/types/workspace_audit_log_item_actor.py @@ -0,0 +1,20 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class WorkspaceAuditLogItemActor(UniversalBaseModel): + id: typing.Optional[str] = None + email: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/workspace_audit_log_item_payload_site_membership_granular_access.py b/src/webflow/types/workspace_audit_log_item_payload_site_membership_granular_access.py new file mode 100644 index 0000000..8d18539 --- /dev/null +++ b/src/webflow/types/workspace_audit_log_item_payload_site_membership_granular_access.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class WorkspaceAuditLogItemPayloadSiteMembershipGranularAccess(UniversalBaseModel): + id: typing.Optional[str] = None + name: typing.Optional[str] = None + type: typing.Optional[typing.Literal["cms"]] = None + restricted: typing.Optional[bool] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/workspace_audit_log_item_payload_site_membership_method.py b/src/webflow/types/workspace_audit_log_item_payload_site_membership_method.py new file mode 100644 index 0000000..a13fbae --- /dev/null +++ b/src/webflow/types/workspace_audit_log_item_payload_site_membership_method.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +WorkspaceAuditLogItemPayloadSiteMembershipMethod = typing.Union[ + typing.Literal["sso", "invite", "scim", "dashboard", "admin", "access_request"], typing.Any +] diff --git a/src/webflow/types/workspace_audit_log_item_payload_site_membership_site.py b/src/webflow/types/workspace_audit_log_item_payload_site_membership_site.py new file mode 100644 index 0000000..6d392bd --- /dev/null +++ b/src/webflow/types/workspace_audit_log_item_payload_site_membership_site.py @@ -0,0 +1,20 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class WorkspaceAuditLogItemPayloadSiteMembershipSite(UniversalBaseModel): + id: typing.Optional[str] = None + slug: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/workspace_audit_log_item_payload_site_membership_target_user.py b/src/webflow/types/workspace_audit_log_item_payload_site_membership_target_user.py new file mode 100644 index 0000000..bcfc37b --- /dev/null +++ b/src/webflow/types/workspace_audit_log_item_payload_site_membership_target_user.py @@ -0,0 +1,20 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class WorkspaceAuditLogItemPayloadSiteMembershipTargetUser(UniversalBaseModel): + id: typing.Optional[str] = None + email: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/workspace_audit_log_item_payload_site_membership_user_type.py b/src/webflow/types/workspace_audit_log_item_payload_site_membership_user_type.py new file mode 100644 index 0000000..47b5168 --- /dev/null +++ b/src/webflow/types/workspace_audit_log_item_payload_site_membership_user_type.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +WorkspaceAuditLogItemPayloadSiteMembershipUserType = typing.Union[ + typing.Literal["member", "guest", "reviewer", "client"], typing.Any +] diff --git a/src/webflow/types/workspace_audit_log_item_payload_user_access_method.py b/src/webflow/types/workspace_audit_log_item_payload_user_access_method.py new file mode 100644 index 0000000..5417cff --- /dev/null +++ b/src/webflow/types/workspace_audit_log_item_payload_user_access_method.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +WorkspaceAuditLogItemPayloadUserAccessMethod = typing.Union[ + typing.Literal["dashboard", "sso", "api", "google"], typing.Any +] diff --git a/src/webflow/types/workspace_audit_log_item_payload_workspace_invitation_method.py b/src/webflow/types/workspace_audit_log_item_payload_workspace_invitation_method.py new file mode 100644 index 0000000..79a3042 --- /dev/null +++ b/src/webflow/types/workspace_audit_log_item_payload_workspace_invitation_method.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +WorkspaceAuditLogItemPayloadWorkspaceInvitationMethod = typing.Union[ + typing.Literal["sso", "dashboard", "admin"], typing.Any +] diff --git a/src/webflow/types/workspace_audit_log_item_payload_workspace_invitation_target_user.py b/src/webflow/types/workspace_audit_log_item_payload_workspace_invitation_target_user.py new file mode 100644 index 0000000..1360978 --- /dev/null +++ b/src/webflow/types/workspace_audit_log_item_payload_workspace_invitation_target_user.py @@ -0,0 +1,20 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class WorkspaceAuditLogItemPayloadWorkspaceInvitationTargetUser(UniversalBaseModel): + id: typing.Optional[str] = None + email: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/workspace_audit_log_item_payload_workspace_invitation_target_users_item.py b/src/webflow/types/workspace_audit_log_item_payload_workspace_invitation_target_users_item.py new file mode 100644 index 0000000..1338b5f --- /dev/null +++ b/src/webflow/types/workspace_audit_log_item_payload_workspace_invitation_target_users_item.py @@ -0,0 +1,20 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class WorkspaceAuditLogItemPayloadWorkspaceInvitationTargetUsersItem(UniversalBaseModel): + id: typing.Optional[str] = None + email: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/workspace_audit_log_item_payload_workspace_invitation_user_type.py b/src/webflow/types/workspace_audit_log_item_payload_workspace_invitation_user_type.py new file mode 100644 index 0000000..980d3a9 --- /dev/null +++ b/src/webflow/types/workspace_audit_log_item_payload_workspace_invitation_user_type.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +WorkspaceAuditLogItemPayloadWorkspaceInvitationUserType = typing.Union[ + typing.Literal["member", "guest", "reviewer", "client"], typing.Any +] diff --git a/src/webflow/types/workspace_audit_log_item_payload_workspace_membership_method.py b/src/webflow/types/workspace_audit_log_item_payload_workspace_membership_method.py new file mode 100644 index 0000000..df8982f --- /dev/null +++ b/src/webflow/types/workspace_audit_log_item_payload_workspace_membership_method.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +WorkspaceAuditLogItemPayloadWorkspaceMembershipMethod = typing.Union[ + typing.Literal["sso", "dashboard", "admin", "access_request"], typing.Any +] diff --git a/src/webflow/types/workspace_audit_log_item_payload_workspace_membership_target_user.py b/src/webflow/types/workspace_audit_log_item_payload_workspace_membership_target_user.py new file mode 100644 index 0000000..6ce0f6a --- /dev/null +++ b/src/webflow/types/workspace_audit_log_item_payload_workspace_membership_target_user.py @@ -0,0 +1,20 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class WorkspaceAuditLogItemPayloadWorkspaceMembershipTargetUser(UniversalBaseModel): + id: typing.Optional[str] = None + email: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/workspace_audit_log_item_payload_workspace_membership_user_type.py b/src/webflow/types/workspace_audit_log_item_payload_workspace_membership_user_type.py new file mode 100644 index 0000000..dad636f --- /dev/null +++ b/src/webflow/types/workspace_audit_log_item_payload_workspace_membership_user_type.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +WorkspaceAuditLogItemPayloadWorkspaceMembershipUserType = typing.Union[ + typing.Literal["member", "guest", "reviewer", "client"], typing.Any +] diff --git a/src/webflow/types/workspace_audit_log_item_workspace.py b/src/webflow/types/workspace_audit_log_item_workspace.py new file mode 100644 index 0000000..6c13bf5 --- /dev/null +++ b/src/webflow/types/workspace_audit_log_item_workspace.py @@ -0,0 +1,20 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class WorkspaceAuditLogItemWorkspace(UniversalBaseModel): + id: typing.Optional[str] = None + slug: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/workspace_audit_log_response.py b/src/webflow/types/workspace_audit_log_response.py new file mode 100644 index 0000000..f6d0d13 --- /dev/null +++ b/src/webflow/types/workspace_audit_log_response.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing +from .workspace_audit_log_item import WorkspaceAuditLogItem +from .pagination import Pagination +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class WorkspaceAuditLogResponse(UniversalBaseModel): + items: typing.Optional[typing.List[WorkspaceAuditLogItem]] = None + pagination: typing.Optional[Pagination] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/workspace_invitation.py b/src/webflow/types/workspace_invitation.py new file mode 100644 index 0000000..a096af1 --- /dev/null +++ b/src/webflow/types/workspace_invitation.py @@ -0,0 +1,57 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from .workspace_audit_log_item_payload_workspace_invitation_target_user import ( + WorkspaceAuditLogItemPayloadWorkspaceInvitationTargetUser, +) +from ..core.serialization import FieldMetadata +from .workspace_audit_log_item_payload_workspace_invitation_method import ( + WorkspaceAuditLogItemPayloadWorkspaceInvitationMethod, +) +from .workspace_audit_log_item_payload_workspace_invitation_user_type import ( + WorkspaceAuditLogItemPayloadWorkspaceInvitationUserType, +) +import pydantic +from .workspace_audit_log_item_payload_workspace_invitation_target_users_item import ( + WorkspaceAuditLogItemPayloadWorkspaceInvitationTargetUsersItem, +) +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class WorkspaceInvitation(UniversalBaseModel): + target_user: typing_extensions.Annotated[ + typing.Optional[WorkspaceAuditLogItemPayloadWorkspaceInvitationTargetUser], FieldMetadata(alias="targetUser") + ] = None + method: typing.Optional[WorkspaceAuditLogItemPayloadWorkspaceInvitationMethod] = None + user_type: typing_extensions.Annotated[ + typing.Optional[WorkspaceAuditLogItemPayloadWorkspaceInvitationUserType], FieldMetadata(alias="userType") + ] = None + role_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="roleName")] = pydantic.Field( + default=None + ) + """ + The name of the role that was assigned to the user + """ + + previous_role_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="previousRoleName")] = ( + pydantic.Field(default=None) + ) + """ + The previous role that the user had + """ + + target_users: typing_extensions.Annotated[ + typing.Optional[typing.List[WorkspaceAuditLogItemPayloadWorkspaceInvitationTargetUsersItem]], + FieldMetadata(alias="targetUsers"), + ] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/workspace_invitation_audit_log_item.py b/src/webflow/types/workspace_invitation_audit_log_item.py new file mode 100644 index 0000000..e41f504 --- /dev/null +++ b/src/webflow/types/workspace_invitation_audit_log_item.py @@ -0,0 +1,26 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from .workspace_invitation_audit_log_item_event_sub_type import WorkspaceInvitationAuditLogItemEventSubType +from ..core.serialization import FieldMetadata +from .workspace_invitation import WorkspaceInvitation +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class WorkspaceInvitationAuditLogItem(UniversalBaseModel): + event_sub_type: typing_extensions.Annotated[ + typing.Optional[WorkspaceInvitationAuditLogItemEventSubType], FieldMetadata(alias="eventSubType") + ] = None + payload: typing.Optional[WorkspaceInvitation] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/workspace_invitation_audit_log_item_event_sub_type.py b/src/webflow/types/workspace_invitation_audit_log_item_event_sub_type.py new file mode 100644 index 0000000..07ccddb --- /dev/null +++ b/src/webflow/types/workspace_invitation_audit_log_item_event_sub_type.py @@ -0,0 +1,15 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +WorkspaceInvitationAuditLogItemEventSubType = typing.Union[ + typing.Literal[ + "invite_sent", + "invite_accepted", + "invite_updated", + "invite_canceled", + "invite_declined", + "access_request_accepted", + ], + typing.Any, +] diff --git a/src/webflow/types/workspace_membership.py b/src/webflow/types/workspace_membership.py new file mode 100644 index 0000000..1c369a2 --- /dev/null +++ b/src/webflow/types/workspace_membership.py @@ -0,0 +1,49 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from .workspace_audit_log_item_payload_workspace_membership_target_user import ( + WorkspaceAuditLogItemPayloadWorkspaceMembershipTargetUser, +) +from ..core.serialization import FieldMetadata +from .workspace_audit_log_item_payload_workspace_membership_method import ( + WorkspaceAuditLogItemPayloadWorkspaceMembershipMethod, +) +from .workspace_audit_log_item_payload_workspace_membership_user_type import ( + WorkspaceAuditLogItemPayloadWorkspaceMembershipUserType, +) +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class WorkspaceMembership(UniversalBaseModel): + target_user: typing_extensions.Annotated[ + typing.Optional[WorkspaceAuditLogItemPayloadWorkspaceMembershipTargetUser], FieldMetadata(alias="targetUser") + ] = None + method: typing.Optional[WorkspaceAuditLogItemPayloadWorkspaceMembershipMethod] = None + user_type: typing_extensions.Annotated[ + typing.Optional[WorkspaceAuditLogItemPayloadWorkspaceMembershipUserType], FieldMetadata(alias="userType") + ] = None + role_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="roleName")] = pydantic.Field( + default=None + ) + """ + The name of the role that was assigned to the user + """ + + previous_role_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="previousRoleName")] = ( + pydantic.Field(default=None) + ) + """ + The previous role that the user had + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/workspace_membership_audit_log_item.py b/src/webflow/types/workspace_membership_audit_log_item.py new file mode 100644 index 0000000..4ac92d7 --- /dev/null +++ b/src/webflow/types/workspace_membership_audit_log_item.py @@ -0,0 +1,26 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from .workspace_membership_audit_log_item_event_sub_type import WorkspaceMembershipAuditLogItemEventSubType +from ..core.serialization import FieldMetadata +from .workspace_membership import WorkspaceMembership +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class WorkspaceMembershipAuditLogItem(UniversalBaseModel): + event_sub_type: typing_extensions.Annotated[ + typing.Optional[WorkspaceMembershipAuditLogItemEventSubType], FieldMetadata(alias="eventSubType") + ] = None + payload: typing.Optional[WorkspaceMembership] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/workspace_membership_audit_log_item_event_sub_type.py b/src/webflow/types/workspace_membership_audit_log_item_event_sub_type.py new file mode 100644 index 0000000..4d90d7a --- /dev/null +++ b/src/webflow/types/workspace_membership_audit_log_item_event_sub_type.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +WorkspaceMembershipAuditLogItemEventSubType = typing.Union[ + typing.Literal["user_added", "user_removed", "user_role_updated"], typing.Any +] diff --git a/tests/collections/test_fields.py b/tests/collections/test_fields.py deleted file mode 100644 index f64c447..0000000 --- a/tests/collections/test_fields.py +++ /dev/null @@ -1,97 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from webflow import Webflow -from webflow import AsyncWebflow -import typing -from ..utilities import validate_response - - -async def test_create(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "75821f618da60c18383330bcc0ca488b", - "isRequired": False, - "isEditable": True, - "type": "RichText", - "slug": "post-body", - "displayName": "Post Body", - "helpText": "Add the body of your post here", - } - expected_types: typing.Any = { - "id": None, - "isRequired": None, - "isEditable": None, - "type": None, - "slug": None, - "displayName": None, - "helpText": None, - } - response = client.collections.fields.create( - collection_id="580e63fc8c9a982ac9b8b745", - is_required=False, - type="RichText", - display_name="Post Body", - help_text="Add the body of your post here", - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.collections.fields.create( - collection_id="580e63fc8c9a982ac9b8b745", - is_required=False, - type="RichText", - display_name="Post Body", - help_text="Add the body of your post here", - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_delete(client: Webflow, async_client: AsyncWebflow) -> None: - # Type ignore to avoid mypy complaining about the function not being meant to return a value - assert ( - client.collections.fields.delete(collection_id="580e63fc8c9a982ac9b8b745", field_id="580e63fc8c9a982ac9b8b745") # type: ignore[func-returns-value] - is None - ) - - assert ( - await async_client.collections.fields.delete( - collection_id="580e63fc8c9a982ac9b8b745", field_id="580e63fc8c9a982ac9b8b745" - ) # type: ignore[func-returns-value] - is None - ) - - -async def test_update(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "75821f618da60c18383330bcc0ca488b", - "isRequired": False, - "isEditable": True, - "type": "RichText", - "slug": "post-body", - "displayName": "Post Body", - "helpText": "Add the body of your post here", - } - expected_types: typing.Any = { - "id": None, - "isRequired": None, - "isEditable": None, - "type": None, - "slug": None, - "displayName": None, - "helpText": None, - } - response = client.collections.fields.update( - collection_id="580e63fc8c9a982ac9b8b745", - field_id="580e63fc8c9a982ac9b8b745", - is_required=False, - display_name="Post Body", - help_text="Add the body of your post here", - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.collections.fields.update( - collection_id="580e63fc8c9a982ac9b8b745", - field_id="580e63fc8c9a982ac9b8b745", - is_required=False, - display_name="Post Body", - help_text="Add the body of your post here", - ) - validate_response(async_response, expected_response, expected_types) diff --git a/tests/collections/test_items.py b/tests/collections/test_items.py deleted file mode 100644 index fc926a7..0000000 --- a/tests/collections/test_items.py +++ /dev/null @@ -1,810 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from webflow import Webflow -from webflow import AsyncWebflow -import typing -from ..utilities import validate_response -from webflow import CollectionItemPostSingle -from webflow import CollectionItemPostSingleFieldData -from webflow import CollectionItemWithIdInput -from webflow import CollectionItemWithIdInputFieldData -from webflow import CollectionItem -from webflow import CollectionItemFieldData -from webflow.resources.collections.resources.items import SingleCmsItem -from webflow import CollectionItemPatchSingleFieldData - - -async def test_list_items(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "items": [ - { - "id": "62b720ef280c7a7a3be8cabe", - "cmsLocaleId": "66f6e966c9e1dc700a857ca3", - "lastPublished": "2022-06-30T13:35:20.878Z", - "lastUpdated": "2022-06-25T14:51:27.809Z", - "createdOn": "2022-06-25T14:51:27.809Z", - "isArchived": False, - "isDraft": False, - "fieldData": { - "name": "Senior Data Analyst", - "slug": "senior-data-analyst", - "url": "https://boards.greenhouse.io/webflow/jobs/26567701", - "department": "Data", - }, - }, - { - "id": "62c880ef281c7b7b4cf9dabc", - "cmsLocaleId": "66f6e966c9e1dc700a857ca3", - "lastPublished": "2023-04-15T10:25:18.123Z", - "lastUpdated": "2023-04-10T11:45:30.567Z", - "createdOn": "2023-04-10T11:45:30.567Z", - "isArchived": False, - "isDraft": False, - "fieldData": { - "name": "Product Manager", - "slug": "product-manager", - "url": "https://boards.greenhouse.io/webflow/jobs/31234567", - "department": "Product", - }, - }, - ], - "pagination": {"limit": 25, "offset": 0, "total": 2}, - } - expected_types: typing.Any = { - "items": ( - "list", - { - 0: { - "id": None, - "cmsLocaleId": None, - "lastPublished": None, - "lastUpdated": None, - "createdOn": None, - "isArchived": None, - "isDraft": None, - "fieldData": {"name": None, "slug": None}, - }, - 1: { - "id": None, - "cmsLocaleId": None, - "lastPublished": None, - "lastUpdated": None, - "createdOn": None, - "isArchived": None, - "isDraft": None, - "fieldData": {"name": None, "slug": None}, - }, - }, - ), - "pagination": {"limit": None, "offset": None, "total": None}, - } - response = client.collections.items.list_items(collection_id="580e63fc8c9a982ac9b8b745") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.collections.items.list_items(collection_id="580e63fc8c9a982ac9b8b745") - validate_response(async_response, expected_response, expected_types) - - -async def test_create_item(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "42b720ef280c7a7a3be8cabe", - "cmsLocaleId": "653ad57de882f528b32e810e", - "lastPublished": "2022-11-29T16:22:43.159Z", - "lastUpdated": "2022-11-17T17:19:43.282Z", - "createdOn": "2022-11-17T17:11:57.148Z", - "isArchived": False, - "isDraft": False, - "fieldData": { - "name": "Pan Galactic Gargle Blaster Recipe", - "slug": "pan-galactic-gargle-blaster", - "color": "#db4b68", - "date": "2022-11-18T00:00:00.000Z", - "featured": True, - }, - } - expected_types: typing.Any = { - "id": None, - "cmsLocaleId": None, - "lastPublished": None, - "lastUpdated": None, - "createdOn": None, - "isArchived": None, - "isDraft": None, - "fieldData": {"name": None, "slug": None}, - } - response = client.collections.items.create_item( - collection_id="580e63fc8c9a982ac9b8b745", - request=CollectionItemPostSingle( - is_archived=False, - is_draft=False, - field_data=CollectionItemPostSingleFieldData( - name="Pan Galactic Gargle Blaster Recipe", slug="pan-galactic-gargle-blaster" - ), - ), - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.collections.items.create_item( - collection_id="580e63fc8c9a982ac9b8b745", - request=CollectionItemPostSingle( - is_archived=False, - is_draft=False, - field_data=CollectionItemPostSingleFieldData( - name="Pan Galactic Gargle Blaster Recipe", slug="pan-galactic-gargle-blaster" - ), - ), - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_delete_items(client: Webflow, async_client: AsyncWebflow) -> None: - # Type ignore to avoid mypy complaining about the function not being meant to return a value - assert ( - client.collections.items.delete_items(collection_id="580e63fc8c9a982ac9b8b745") # type: ignore[func-returns-value] - is None - ) - - assert ( - await async_client.collections.items.delete_items(collection_id="580e63fc8c9a982ac9b8b745") # type: ignore[func-returns-value] - is None - ) - - -async def test_update_items(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "id", - "cmsLocaleId": "653ad57de882f528b32e810e", - "lastPublished": "2023-03-17T18:47:35.560Z", - "lastUpdated": "2023-03-17T18:47:35.560Z", - "createdOn": "2023-03-17T18:47:35.560Z", - "isArchived": True, - "isDraft": True, - "fieldData": { - "name": "My new item", - "slug": "my-new-item", - "date": "2022-11-18T00:00:00.000Z", - "featured": False, - "color": "#db4b68", - }, - } - expected_types: typing.Any = { - "id": None, - "cmsLocaleId": None, - "lastPublished": None, - "lastUpdated": None, - "createdOn": None, - "isArchived": None, - "isDraft": None, - "fieldData": {"name": None, "slug": None}, - } - response = client.collections.items.update_items( - collection_id="580e63fc8c9a982ac9b8b745", - items=[ - CollectionItemWithIdInput( - id="66f6ed9576ddacf3149d5ea6", - cms_locale_id="66f6e966c9e1dc700a857ca5", - field_data=CollectionItemWithIdInputFieldData(name="Ne Paniquez Pas", slug="ne-paniquez-pas"), - ), - CollectionItemWithIdInput( - id="66f6ed9576ddacf3149d5ea6", - cms_locale_id="66f6e966c9e1dc700a857ca4", - field_data=CollectionItemWithIdInputFieldData(name="No Entrar en Pánico", slug="no-entrar-en-panico"), - ), - CollectionItemWithIdInput( - id="66f6ed9576ddacf3149d5eaa", - cms_locale_id="66f6e966c9e1dc700a857ca5", - field_data=CollectionItemWithIdInputFieldData( - name="Au Revoir et Merci pour Tous les Poissons", slug="au-revoir-et-merci" - ), - ), - CollectionItemWithIdInput( - id="66f6ed9576ddacf3149d5eaa", - cms_locale_id="66f6e966c9e1dc700a857ca4", - field_data=CollectionItemWithIdInputFieldData( - name="Hasta Luego y Gracias por Todo el Pescado", slug="hasta-luego-y-gracias" - ), - ), - ], - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.collections.items.update_items( - collection_id="580e63fc8c9a982ac9b8b745", - items=[ - CollectionItemWithIdInput( - id="66f6ed9576ddacf3149d5ea6", - cms_locale_id="66f6e966c9e1dc700a857ca5", - field_data=CollectionItemWithIdInputFieldData(name="Ne Paniquez Pas", slug="ne-paniquez-pas"), - ), - CollectionItemWithIdInput( - id="66f6ed9576ddacf3149d5ea6", - cms_locale_id="66f6e966c9e1dc700a857ca4", - field_data=CollectionItemWithIdInputFieldData(name="No Entrar en Pánico", slug="no-entrar-en-panico"), - ), - CollectionItemWithIdInput( - id="66f6ed9576ddacf3149d5eaa", - cms_locale_id="66f6e966c9e1dc700a857ca5", - field_data=CollectionItemWithIdInputFieldData( - name="Au Revoir et Merci pour Tous les Poissons", slug="au-revoir-et-merci" - ), - ), - CollectionItemWithIdInput( - id="66f6ed9576ddacf3149d5eaa", - cms_locale_id="66f6e966c9e1dc700a857ca4", - field_data=CollectionItemWithIdInputFieldData( - name="Hasta Luego y Gracias por Todo el Pescado", slug="hasta-luego-y-gracias" - ), - ), - ], - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_list_items_live(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "items": [ - { - "id": "62b720ef280c7a7a3be8cabe", - "cmsLocaleId": "66f6e966c9e1dc700a857ca3", - "lastPublished": "2022-06-30T13:35:20.878Z", - "lastUpdated": "2022-06-25T14:51:27.809Z", - "createdOn": "2022-06-25T14:51:27.809Z", - "isArchived": False, - "isDraft": False, - "fieldData": { - "name": "Senior Data Analyst", - "slug": "senior-data-analyst", - "url": "https://boards.greenhouse.io/webflow/jobs/26567701", - "department": "Data", - }, - }, - { - "id": "62c880ef281c7b7b4cf9dabc", - "cmsLocaleId": "66f6e966c9e1dc700a857ca3", - "lastPublished": "2023-04-15T10:25:18.123Z", - "lastUpdated": "2023-04-10T11:45:30.567Z", - "createdOn": "2023-04-10T11:45:30.567Z", - "isArchived": False, - "isDraft": False, - "fieldData": { - "name": "Product Manager", - "slug": "product-manager", - "url": "https://boards.greenhouse.io/webflow/jobs/31234567", - "department": "Product", - }, - }, - ], - "pagination": {"limit": 25, "offset": 0, "total": 2}, - } - expected_types: typing.Any = { - "items": ( - "list", - { - 0: { - "id": None, - "cmsLocaleId": None, - "lastPublished": None, - "lastUpdated": None, - "createdOn": None, - "isArchived": None, - "isDraft": None, - "fieldData": {"name": None, "slug": None}, - }, - 1: { - "id": None, - "cmsLocaleId": None, - "lastPublished": None, - "lastUpdated": None, - "createdOn": None, - "isArchived": None, - "isDraft": None, - "fieldData": {"name": None, "slug": None}, - }, - }, - ), - "pagination": {"limit": None, "offset": None, "total": None}, - } - response = client.collections.items.list_items_live(collection_id="580e63fc8c9a982ac9b8b745") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.collections.items.list_items_live(collection_id="580e63fc8c9a982ac9b8b745") - validate_response(async_response, expected_response, expected_types) - - -async def test_create_item_live(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "42b720ef280c7a7a3be8cabe", - "cmsLocaleId": "653ad57de882f528b32e810e", - "lastPublished": "2022-11-29T16:22:43.159Z", - "lastUpdated": "2022-11-17T17:19:43.282Z", - "createdOn": "2022-11-17T17:11:57.148Z", - "isArchived": False, - "isDraft": False, - "fieldData": { - "name": "Pan Galactic Gargle Blaster Recipe", - "slug": "pan-galactic-gargle-blaster", - "color": "#db4b68", - "date": "2022-11-18T00:00:00.000Z", - "featured": True, - }, - } - expected_types: typing.Any = { - "id": None, - "cmsLocaleId": None, - "lastPublished": None, - "lastUpdated": None, - "createdOn": None, - "isArchived": None, - "isDraft": None, - "fieldData": {"name": None, "slug": None}, - } - response = client.collections.items.create_item_live( - collection_id="580e63fc8c9a982ac9b8b745", - request=CollectionItem( - is_archived=False, - is_draft=False, - field_data=CollectionItemFieldData( - name="Pan Galactic Gargle Blaster Recipe", slug="pan-galactic-gargle-blaster" - ), - ), - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.collections.items.create_item_live( - collection_id="580e63fc8c9a982ac9b8b745", - request=CollectionItem( - is_archived=False, - is_draft=False, - field_data=CollectionItemFieldData( - name="Pan Galactic Gargle Blaster Recipe", slug="pan-galactic-gargle-blaster" - ), - ), - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_delete_items_live(client: Webflow, async_client: AsyncWebflow) -> None: - # Type ignore to avoid mypy complaining about the function not being meant to return a value - assert ( - client.collections.items.delete_items_live(collection_id="580e63fc8c9a982ac9b8b745") # type: ignore[func-returns-value] - is None - ) - - assert ( - await async_client.collections.items.delete_items_live(collection_id="580e63fc8c9a982ac9b8b745") # type: ignore[func-returns-value] - is None - ) - - -async def test_update_items_live(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "items": [ - { - "id": "66f6ed9576ddacf3149d5ea6", - "cmsLocaleId": "66f6e966c9e1dc700a857ca5", - "lastPublished": "2023-03-17T18:47:35.560Z", - "lastUpdated": "2024-09-27T17:38:29.066Z", - "createdOn": "2024-09-27T17:38:29.066Z", - "isArchived": True, - "isDraft": True, - "fieldData": {"name": "Ne Paniquez Pas", "slug": "ne-paniquez-pas", "featured": False}, - }, - { - "id": "66f6ed9576ddacf3149d5ea6", - "cmsLocaleId": "66f6e966c9e1dc700a857ca4", - "lastPublished": "2023-03-17T18:47:35.560Z", - "lastUpdated": "2024-09-27T17:38:29.066Z", - "createdOn": "2024-09-27T17:38:29.066Z", - "isArchived": True, - "isDraft": True, - "fieldData": {"name": "No Entrar en Pánico", "slug": "no-entrar-en-panico", "featured": False}, - }, - { - "id": "66f6ed9576ddacf3149d5eaa", - "cmsLocaleId": "66f6e966c9e1dc700a857ca5", - "lastPublished": "2023-03-17T18:47:35.560Z", - "lastUpdated": "2024-09-27T17:38:29.066Z", - "createdOn": "2024-09-27T17:38:29.066Z", - "isArchived": True, - "isDraft": True, - "fieldData": { - "name": "Au Revoir et Merci pour Tous les Poissons", - "slug": "au-revoir-et-merci", - "featured": False, - }, - }, - { - "id": "66f6ed9576ddacf3149d5eaa", - "cmsLocaleId": "66f6e966c9e1dc700a857ca4", - "lastPublished": "2023-03-17T18:47:35.560Z", - "lastUpdated": "2024-09-27T17:38:29.066Z", - "createdOn": "2024-09-27T17:38:29.066Z", - "isArchived": True, - "isDraft": True, - "fieldData": { - "name": "Hasta Luego y Gracias por Todo el Pescado", - "slug": "hasta-luego-y-gracias", - "featured": False, - }, - }, - ] - } - expected_types: typing.Any = { - "items": ( - "list", - { - 0: { - "id": None, - "cmsLocaleId": None, - "lastPublished": None, - "lastUpdated": None, - "createdOn": None, - "isArchived": None, - "isDraft": None, - "fieldData": {"name": None, "slug": None}, - }, - 1: { - "id": None, - "cmsLocaleId": None, - "lastPublished": None, - "lastUpdated": None, - "createdOn": None, - "isArchived": None, - "isDraft": None, - "fieldData": {"name": None, "slug": None}, - }, - 2: { - "id": None, - "cmsLocaleId": None, - "lastPublished": None, - "lastUpdated": None, - "createdOn": None, - "isArchived": None, - "isDraft": None, - "fieldData": {"name": None, "slug": None}, - }, - 3: { - "id": None, - "cmsLocaleId": None, - "lastPublished": None, - "lastUpdated": None, - "createdOn": None, - "isArchived": None, - "isDraft": None, - "fieldData": {"name": None, "slug": None}, - }, - }, - ) - } - response = client.collections.items.update_items_live( - collection_id="580e63fc8c9a982ac9b8b745", - items=[ - CollectionItemWithIdInput( - id="66f6ed9576ddacf3149d5ea6", - cms_locale_id="66f6e966c9e1dc700a857ca5", - field_data=CollectionItemWithIdInputFieldData(name="Ne Paniquez Pas", slug="ne-paniquez-pas"), - ), - CollectionItemWithIdInput( - id="66f6ed9576ddacf3149d5ea6", - cms_locale_id="66f6e966c9e1dc700a857ca4", - field_data=CollectionItemWithIdInputFieldData(name="No Entrar en Pánico", slug="no-entrar-en-panico"), - ), - CollectionItemWithIdInput( - id="66f6ed9576ddacf3149d5eaa", - cms_locale_id="66f6e966c9e1dc700a857ca5", - field_data=CollectionItemWithIdInputFieldData( - name="Au Revoir et Merci pour Tous les Poissons", slug="au-revoir-et-merci" - ), - ), - CollectionItemWithIdInput( - id="66f6ed9576ddacf3149d5eaa", - cms_locale_id="66f6e966c9e1dc700a857ca4", - field_data=CollectionItemWithIdInputFieldData( - name="Hasta Luego y Gracias por Todo el Pescado", slug="hasta-luego-y-gracias" - ), - ), - ], - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.collections.items.update_items_live( - collection_id="580e63fc8c9a982ac9b8b745", - items=[ - CollectionItemWithIdInput( - id="66f6ed9576ddacf3149d5ea6", - cms_locale_id="66f6e966c9e1dc700a857ca5", - field_data=CollectionItemWithIdInputFieldData(name="Ne Paniquez Pas", slug="ne-paniquez-pas"), - ), - CollectionItemWithIdInput( - id="66f6ed9576ddacf3149d5ea6", - cms_locale_id="66f6e966c9e1dc700a857ca4", - field_data=CollectionItemWithIdInputFieldData(name="No Entrar en Pánico", slug="no-entrar-en-panico"), - ), - CollectionItemWithIdInput( - id="66f6ed9576ddacf3149d5eaa", - cms_locale_id="66f6e966c9e1dc700a857ca5", - field_data=CollectionItemWithIdInputFieldData( - name="Au Revoir et Merci pour Tous les Poissons", slug="au-revoir-et-merci" - ), - ), - CollectionItemWithIdInput( - id="66f6ed9576ddacf3149d5eaa", - cms_locale_id="66f6e966c9e1dc700a857ca4", - field_data=CollectionItemWithIdInputFieldData( - name="Hasta Luego y Gracias por Todo el Pescado", slug="hasta-luego-y-gracias" - ), - ), - ], - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_create_items(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "580e64008c9a982ac9b8b754", - "cmsLocaleIds": ["653ad57de882f528b32e810e", "6514390aea353fc691d69827", "65143930ea353fc691d69cd8"], - "lastPublished": "2023-03-17T18:47:35.560Z", - "lastUpdated": "2023-03-17T18:47:35.560Z", - "createdOn": "2023-03-17T18:47:35.560Z", - "isArchived": True, - "isDraft": True, - "fieldData": { - "name": "My new item", - "slug": "my-new-item", - "date": "2022-11-18T00:00:00.000Z", - "featured": False, - "color": "#db4b68", - }, - } - expected_types: typing.Any = { - "id": None, - "cmsLocaleIds": ("list", {0: None, 1: None, 2: None}), - "lastPublished": None, - "lastUpdated": None, - "createdOn": None, - "isArchived": None, - "isDraft": None, - "fieldData": {"name": None, "slug": None}, - } - response = client.collections.items.create_items( - collection_id="580e63fc8c9a982ac9b8b745", - cms_locale_ids=["66f6e966c9e1dc700a857ca3", "66f6e966c9e1dc700a857ca4", "66f6e966c9e1dc700a857ca5"], - is_archived=False, - is_draft=False, - field_data=SingleCmsItem(name="Don’t Panic", slug="dont-panic"), - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.collections.items.create_items( - collection_id="580e63fc8c9a982ac9b8b745", - cms_locale_ids=["66f6e966c9e1dc700a857ca3", "66f6e966c9e1dc700a857ca4", "66f6e966c9e1dc700a857ca5"], - is_archived=False, - is_draft=False, - field_data=SingleCmsItem(name="Don’t Panic", slug="dont-panic"), - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_get_item(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "42b720ef280c7a7a3be8cabe", - "cmsLocaleId": "653ad57de882f528b32e810e", - "lastPublished": "2022-11-29T16:22:43.159Z", - "lastUpdated": "2022-11-17T17:19:43.282Z", - "createdOn": "2022-11-17T17:11:57.148Z", - "isArchived": False, - "isDraft": False, - "fieldData": { - "name": "Pan Galactic Gargle Blaster Recipe", - "slug": "pan-galactic-gargle-blaster", - "color": "#db4b68", - "date": "2022-11-18T00:00:00.000Z", - "featured": True, - }, - } - expected_types: typing.Any = { - "id": None, - "cmsLocaleId": None, - "lastPublished": None, - "lastUpdated": None, - "createdOn": None, - "isArchived": None, - "isDraft": None, - "fieldData": {"name": None, "slug": None}, - } - response = client.collections.items.get_item( - collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754" - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.collections.items.get_item( - collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754" - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_delete_item(client: Webflow, async_client: AsyncWebflow) -> None: - # Type ignore to avoid mypy complaining about the function not being meant to return a value - assert ( - client.collections.items.delete_item( - collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754" - ) # type: ignore[func-returns-value] - is None - ) - - assert ( - await async_client.collections.items.delete_item( - collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754" - ) # type: ignore[func-returns-value] - is None - ) - - -async def test_update_item(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "42b720ef280c7a7a3be8cabe", - "cmsLocaleId": "653ad57de882f528b32e810e", - "lastPublished": "2022-11-29T16:22:43.159Z", - "lastUpdated": "2022-11-17T17:19:43.282Z", - "createdOn": "2022-11-17T17:11:57.148Z", - "isArchived": False, - "isDraft": False, - "fieldData": { - "name": "Pan Galactic Gargle Blaster Recipe", - "slug": "pan-galactic-gargle-blaster", - "color": "#db4b68", - "date": "2022-11-18T00:00:00.000Z", - "featured": True, - }, - } - expected_types: typing.Any = { - "id": None, - "cmsLocaleId": None, - "lastPublished": None, - "lastUpdated": None, - "createdOn": None, - "isArchived": None, - "isDraft": None, - "fieldData": {"name": None, "slug": None}, - } - response = client.collections.items.update_item( - collection_id="580e63fc8c9a982ac9b8b745", - item_id="580e64008c9a982ac9b8b754", - is_archived=False, - is_draft=False, - field_data=CollectionItemPatchSingleFieldData( - name="Pan Galactic Gargle Blaster Recipe", slug="pan-galactic-gargle-blaster" - ), - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.collections.items.update_item( - collection_id="580e63fc8c9a982ac9b8b745", - item_id="580e64008c9a982ac9b8b754", - is_archived=False, - is_draft=False, - field_data=CollectionItemPatchSingleFieldData( - name="Pan Galactic Gargle Blaster Recipe", slug="pan-galactic-gargle-blaster" - ), - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_get_item_live(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "42b720ef280c7a7a3be8cabe", - "cmsLocaleId": "653ad57de882f528b32e810e", - "lastPublished": "2022-11-29T16:22:43.159Z", - "lastUpdated": "2022-11-17T17:19:43.282Z", - "createdOn": "2022-11-17T17:11:57.148Z", - "isArchived": False, - "isDraft": False, - "fieldData": { - "name": "Pan Galactic Gargle Blaster Recipe", - "slug": "pan-galactic-gargle-blaster", - "color": "#db4b68", - "date": "2022-11-18T00:00:00.000Z", - "featured": True, - }, - } - expected_types: typing.Any = { - "id": None, - "cmsLocaleId": None, - "lastPublished": None, - "lastUpdated": None, - "createdOn": None, - "isArchived": None, - "isDraft": None, - "fieldData": {"name": None, "slug": None}, - } - response = client.collections.items.get_item_live( - collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754" - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.collections.items.get_item_live( - collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754" - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_delete_item_live(client: Webflow, async_client: AsyncWebflow) -> None: - # Type ignore to avoid mypy complaining about the function not being meant to return a value - assert ( - client.collections.items.delete_item_live( - collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754" - ) # type: ignore[func-returns-value] - is None - ) - - assert ( - await async_client.collections.items.delete_item_live( - collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754" - ) # type: ignore[func-returns-value] - is None - ) - - -async def test_update_item_live(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "42b720ef280c7a7a3be8cabe", - "cmsLocaleId": "653ad57de882f528b32e810e", - "lastPublished": "2022-11-29T16:22:43.159Z", - "lastUpdated": "2022-11-17T17:19:43.282Z", - "createdOn": "2022-11-17T17:11:57.148Z", - "isArchived": False, - "isDraft": False, - "fieldData": { - "name": "Pan Galactic Gargle Blaster Recipe", - "slug": "pan-galactic-gargle-blaster", - "color": "#db4b68", - "date": "2022-11-18T00:00:00.000Z", - "featured": True, - }, - } - expected_types: typing.Any = { - "id": None, - "cmsLocaleId": None, - "lastPublished": None, - "lastUpdated": None, - "createdOn": None, - "isArchived": None, - "isDraft": None, - "fieldData": {"name": None, "slug": None}, - } - response = client.collections.items.update_item_live( - collection_id="580e63fc8c9a982ac9b8b745", - item_id="580e64008c9a982ac9b8b754", - is_archived=False, - is_draft=False, - field_data=CollectionItemPatchSingleFieldData( - name="Pan Galactic Gargle Blaster Recipe", slug="pan-galactic-gargle-blaster" - ), - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.collections.items.update_item_live( - collection_id="580e63fc8c9a982ac9b8b745", - item_id="580e64008c9a982ac9b8b754", - is_archived=False, - is_draft=False, - field_data=CollectionItemPatchSingleFieldData( - name="Pan Galactic Gargle Blaster Recipe", slug="pan-galactic-gargle-blaster" - ), - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_publish_item(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "publishedItemIds": ["643fd856d66b6528195ee2ca", "643fd856d66b6528195ee2cb"], - "errors": ["Staging item ID 643fd856d66b6528195ee2cf not found."], - } - expected_types: typing.Any = {"publishedItemIds": ("list", {0: None, 1: None}), "errors": ("list", {0: None})} - response = client.collections.items.publish_item(collection_id="580e63fc8c9a982ac9b8b745", item_ids=["itemIds"]) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.collections.items.publish_item( - collection_id="580e63fc8c9a982ac9b8b745", item_ids=["itemIds"] - ) - validate_response(async_response, expected_response, expected_types) diff --git a/tests/conftest.py b/tests/conftest.py deleted file mode 100644 index 019aab8..0000000 --- a/tests/conftest.py +++ /dev/null @@ -1,20 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from webflow import Webflow -import os -import pytest -from webflow import AsyncWebflow - - -@pytest.fixture -def client() -> Webflow: - return Webflow( - access_token=os.getenv("ENV_ACCESS_TOKEN", "access_token"), base_url=os.getenv("TESTS_BASE_URL", "base_url") - ) - - -@pytest.fixture -def async_client() -> AsyncWebflow: - return AsyncWebflow( - access_token=os.getenv("ENV_ACCESS_TOKEN", "access_token"), base_url=os.getenv("TESTS_BASE_URL", "base_url") - ) diff --git a/tests/pages/test_scripts.py b/tests/pages/test_scripts.py deleted file mode 100644 index 0e553d2..0000000 --- a/tests/pages/test_scripts.py +++ /dev/null @@ -1,85 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from webflow import Webflow -from webflow import AsyncWebflow -import typing -from ..utilities import validate_response -from webflow import ScriptApply - - -async def test_get_custom_code(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "scripts": [{"id": "id", "location": "header", "version": "version", "attributes": {"key": "value"}}], - "lastUpdated": "lastUpdated", - "createdOn": "createdOn", - } - expected_types: typing.Any = { - "scripts": ( - "list", - {0: {"id": None, "location": None, "version": None, "attributes": ("dict", {0: (None, None)})}}, - ), - "lastUpdated": None, - "createdOn": None, - } - response = client.pages.scripts.get_custom_code(page_id="63c720f9347c2139b248e552") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.pages.scripts.get_custom_code(page_id="63c720f9347c2139b248e552") - validate_response(async_response, expected_response, expected_types) - - -async def test_upsert_custom_code(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "scripts": [ - { - "id": "cms_slider", - "location": "header", - "version": "1.0.0", - "attributes": {"my-attribute": "some-value"}, - }, - {"id": "alert", "location": "header", "version": "0.0.1", "attributes": {"key": "value"}}, - ], - "lastUpdated": "2022-10-26T00:28:54.191Z", - "createdOn": "2022-10-26T00:28:54.191Z", - } - expected_types: typing.Any = { - "scripts": ( - "list", - { - 0: {"id": None, "location": None, "version": None, "attributes": ("dict", {0: (None, None)})}, - 1: {"id": None, "location": None, "version": None, "attributes": ("dict", {0: (None, None)})}, - }, - ), - "lastUpdated": None, - "createdOn": None, - } - response = client.pages.scripts.upsert_custom_code( - page_id="63c720f9347c2139b248e552", - scripts=[ - ScriptApply(id="cms_slider", location="header", version="1.0.0", attributes={"my-attribute": "some-value"}), - ScriptApply(id="alert", location="header", version="0.0.1"), - ], - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.pages.scripts.upsert_custom_code( - page_id="63c720f9347c2139b248e552", - scripts=[ - ScriptApply(id="cms_slider", location="header", version="1.0.0", attributes={"my-attribute": "some-value"}), - ScriptApply(id="alert", location="header", version="0.0.1"), - ], - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_delete_custom_code(client: Webflow, async_client: AsyncWebflow) -> None: - # Type ignore to avoid mypy complaining about the function not being meant to return a value - assert ( - client.pages.scripts.delete_custom_code(page_id="63c720f9347c2139b248e552") # type: ignore[func-returns-value] - is None - ) - - assert ( - await async_client.pages.scripts.delete_custom_code(page_id="63c720f9347c2139b248e552") # type: ignore[func-returns-value] - is None - ) diff --git a/tests/sites/__init__.py b/tests/sites/__init__.py deleted file mode 100644 index f3ea265..0000000 --- a/tests/sites/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - diff --git a/tests/sites/test_activity_logs.py b/tests/sites/test_activity_logs.py deleted file mode 100644 index f289464..0000000 --- a/tests/sites/test_activity_logs.py +++ /dev/null @@ -1,53 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from webflow import Webflow -from webflow import AsyncWebflow -import typing -from ..utilities import validate_response - - -async def test_list_(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "items": [ - { - "id": "654c16c7b229e56bcf26872d", - "createdOn": "2023-11-08T23:16:23Z", - "lastUpdated": "2023-11-08T23:16:23Z", - "event": "cms_collection", - "resourceOperation": "CREATED", - "user": {"id": "6509cd56e90eec668b009712", "displayName": "John Doe"}, - "resourceId": "654c16c7b229e56bcf26870c", - "resourceName": "foo-bar", - "newValue": "newValue", - "previousValue": "previousValue", - "payload": {"key": "value"}, - } - ], - "pagination": {"limit": 25, "offset": 0, "total": 1}, - } - expected_types: typing.Any = { - "items": ( - "list", - { - 0: { - "id": None, - "createdOn": "datetime", - "lastUpdated": "datetime", - "event": None, - "resourceOperation": None, - "user": {"id": None, "displayName": None}, - "resourceId": None, - "resourceName": None, - "newValue": None, - "previousValue": None, - "payload": ("dict", {0: (None, None)}), - } - }, - ), - "pagination": {"limit": None, "offset": None, "total": None}, - } - response = client.sites.activity_logs.list(site_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.sites.activity_logs.list(site_id="580e63e98c9a982ac9b8b741") - validate_response(async_response, expected_response, expected_types) diff --git a/tests/sites/test_plans.py b/tests/sites/test_plans.py deleted file mode 100644 index 01c304e..0000000 --- a/tests/sites/test_plans.py +++ /dev/null @@ -1,20 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from webflow import Webflow -from webflow import AsyncWebflow -import typing -from ..utilities import validate_response - - -async def test_get_site_plan(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "hosting-business-v4", - "name": "Business Hosting", - "pricingInfo": "https://webflow.com/pricing", - } - expected_types: typing.Any = {"id": None, "name": None, "pricingInfo": None} - response = client.sites.plans.get_site_plan(site_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.sites.plans.get_site_plan(site_id="580e63e98c9a982ac9b8b741") - validate_response(async_response, expected_response, expected_types) diff --git a/tests/sites/test_redirects.py b/tests/sites/test_redirects.py deleted file mode 100644 index e10b50e..0000000 --- a/tests/sites/test_redirects.py +++ /dev/null @@ -1,88 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from webflow import Webflow -from webflow import AsyncWebflow -import typing -from ..utilities import validate_response - - -async def test_list_(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "redirects": [ - {"id": "42e1a2b7aa1a13f768a0042a", "fromUrl": "/mostly-harmless", "toUrl": "/earth"}, - {"id": "6x9e7f8d9a4b1c2d3e4f5678", "fromUrl": "/babel-fish", "toUrl": "/translate"}, - ], - "pagination": {"limit": 100, "offset": 0, "total": 2}, - } - expected_types: typing.Any = { - "redirects": ( - "list", - {0: {"id": None, "fromUrl": None, "toUrl": None}, 1: {"id": None, "fromUrl": None, "toUrl": None}}, - ), - "pagination": {"limit": None, "offset": None, "total": None}, - } - response = client.sites.redirects.list(site_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.sites.redirects.list(site_id="580e63e98c9a982ac9b8b741") - validate_response(async_response, expected_response, expected_types) - - -async def test_create(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = {"id": "42e1a2b7aa1a13f768a0042a", "fromUrl": "/mostly-harmless", "toUrl": "/earth"} - expected_types: typing.Any = {"id": None, "fromUrl": None, "toUrl": None} - response = client.sites.redirects.create( - site_id="580e63e98c9a982ac9b8b741", id="42e1a2b7aa1a13f768a0042a", from_url="/mostly-harmless", to_url="/earth" - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.sites.redirects.create( - site_id="580e63e98c9a982ac9b8b741", id="42e1a2b7aa1a13f768a0042a", from_url="/mostly-harmless", to_url="/earth" - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_delete(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "redirects": [ - {"id": "42e1a2b7aa1a13f768a0042a", "fromUrl": "/mostly-harmless", "toUrl": "/earth"}, - {"id": "6x9e7f8d9a4b1c2d3e4f5678", "fromUrl": "/babel-fish", "toUrl": "/translate"}, - ], - "pagination": {"limit": 100, "offset": 0, "total": 2}, - } - expected_types: typing.Any = { - "redirects": ( - "list", - {0: {"id": None, "fromUrl": None, "toUrl": None}, 1: {"id": None, "fromUrl": None, "toUrl": None}}, - ), - "pagination": {"limit": None, "offset": None, "total": None}, - } - response = client.sites.redirects.delete(site_id="580e63e98c9a982ac9b8b741", redirect_id="66c4cb9a20cac35ed19500e6") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.sites.redirects.delete( - site_id="580e63e98c9a982ac9b8b741", redirect_id="66c4cb9a20cac35ed19500e6" - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_update(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = {"id": "42e1a2b7aa1a13f768a0042a", "fromUrl": "/mostly-harmless", "toUrl": "/earth"} - expected_types: typing.Any = {"id": None, "fromUrl": None, "toUrl": None} - response = client.sites.redirects.update( - site_id="580e63e98c9a982ac9b8b741", - redirect_id="66c4cb9a20cac35ed19500e6", - id="42e1a2b7aa1a13f768a0042a", - from_url="/mostly-harmless", - to_url="/earth", - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.sites.redirects.update( - site_id="580e63e98c9a982ac9b8b741", - redirect_id="66c4cb9a20cac35ed19500e6", - id="42e1a2b7aa1a13f768a0042a", - from_url="/mostly-harmless", - to_url="/earth", - ) - validate_response(async_response, expected_response, expected_types) diff --git a/tests/sites/test_scripts.py b/tests/sites/test_scripts.py deleted file mode 100644 index cc5d71c..0000000 --- a/tests/sites/test_scripts.py +++ /dev/null @@ -1,154 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from webflow import Webflow -from webflow import AsyncWebflow -import typing -from ..utilities import validate_response -from webflow import ScriptApply - - -async def test_get_custom_code(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "scripts": [ - { - "id": "cms_slider", - "location": "header", - "version": "1.0.0", - "attributes": {"my-attribute": "some-value"}, - }, - {"id": "alert", "location": "header", "version": "0.0.1", "attributes": {"key": "value"}}, - ], - "lastUpdated": "2022-10-26T00:28:54.191Z", - "createdOn": "2022-10-26T00:28:54.191Z", - } - expected_types: typing.Any = { - "scripts": ( - "list", - { - 0: {"id": None, "location": None, "version": None, "attributes": ("dict", {0: (None, None)})}, - 1: {"id": None, "location": None, "version": None, "attributes": ("dict", {0: (None, None)})}, - }, - ), - "lastUpdated": None, - "createdOn": None, - } - response = client.sites.scripts.get_custom_code(site_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.sites.scripts.get_custom_code(site_id="580e63e98c9a982ac9b8b741") - validate_response(async_response, expected_response, expected_types) - - -async def test_upsert_custom_code(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "scripts": [ - { - "id": "cms_slider", - "location": "header", - "version": "1.0.0", - "attributes": {"my-attribute": "some-value"}, - }, - {"id": "alert", "location": "header", "version": "0.0.1", "attributes": {"key": "value"}}, - ], - "lastUpdated": "lastUpdated", - "createdOn": "createdOn", - } - expected_types: typing.Any = { - "scripts": ( - "list", - { - 0: {"id": None, "location": None, "version": None, "attributes": ("dict", {0: (None, None)})}, - 1: {"id": None, "location": None, "version": None, "attributes": ("dict", {0: (None, None)})}, - }, - ), - "lastUpdated": None, - "createdOn": None, - } - response = client.sites.scripts.upsert_custom_code( - site_id="580e63e98c9a982ac9b8b741", - scripts=[ - ScriptApply(id="cms_slider", location="header", version="1.0.0", attributes={"my-attribute": "some-value"}), - ScriptApply(id="alert", location="header", version="0.0.1"), - ], - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.sites.scripts.upsert_custom_code( - site_id="580e63e98c9a982ac9b8b741", - scripts=[ - ScriptApply(id="cms_slider", location="header", version="1.0.0", attributes={"my-attribute": "some-value"}), - ScriptApply(id="alert", location="header", version="0.0.1"), - ], - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_delete_custom_code(client: Webflow, async_client: AsyncWebflow) -> None: - # Type ignore to avoid mypy complaining about the function not being meant to return a value - assert ( - client.sites.scripts.delete_custom_code(site_id="580e63e98c9a982ac9b8b741") # type: ignore[func-returns-value] - is None - ) - - assert ( - await async_client.sites.scripts.delete_custom_code(site_id="580e63e98c9a982ac9b8b741") # type: ignore[func-returns-value] - is None - ) - - -async def test_list_custom_code_blocks(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "blocks": [ - { - "siteId": "6258612d1ee792848f805dcf", - "pageId": "pageId", - "type": "site", - "scripts": [ - {"id": "chartjs", "location": "header", "version": "4.4.2", "attributes": {"key": "value"}} - ], - "createdOn": "2024-04-03T16:49:15Z", - "lastUpdated": "2024-04-03T16:49:15Z", - }, - { - "siteId": "6390c49674a71f84b51a08d8", - "pageId": "6419db964a9c43f6a3af6348", - "type": "page", - "scripts": [{"id": "id", "location": "header", "version": "version"}], - "createdOn": "2022-10-26T00:28:54Z", - "lastUpdated": "2022-10-26T00:28:54Z", - }, - ], - "pagination": {"limit": 10, "offset": 0, "total": 1}, - } - expected_types: typing.Any = { - "blocks": ( - "list", - { - 0: { - "siteId": None, - "pageId": None, - "type": None, - "scripts": ( - "list", - {0: {"id": None, "location": None, "version": None, "attributes": ("dict", {0: (None, None)})}}, - ), - "createdOn": "datetime", - "lastUpdated": "datetime", - }, - 1: { - "siteId": None, - "pageId": None, - "type": None, - "scripts": ("list", {0: {"id": None, "location": None, "version": None}}), - "createdOn": "datetime", - "lastUpdated": "datetime", - }, - }, - ), - "pagination": {"limit": None, "offset": None, "total": None}, - } - response = client.sites.scripts.list_custom_code_blocks(site_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.sites.scripts.list_custom_code_blocks(site_id="580e63e98c9a982ac9b8b741") - validate_response(async_response, expected_response, expected_types) diff --git a/tests/test_access_groups.py b/tests/test_access_groups.py deleted file mode 100644 index dfe7e19..0000000 --- a/tests/test_access_groups.py +++ /dev/null @@ -1,49 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from webflow import Webflow -from webflow import AsyncWebflow -import typing -from .utilities import validate_response - - -async def test_list_(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "count": 1, - "limit": 10, - "offset": 0, - "total": 1, - "accessGroups": [ - { - "id": "62be58d404be8a6cc900c081", - "name": "Research Team", - "shortId": "rt", - "slug": "hitchhikers-guide-research-team", - "createdOn": "2022-08-01T19:41:48Z", - }, - { - "id": "65a96161991e77bbb4a6c573", - "name": "Admin", - "shortId": "ad", - "slug": "admin", - "createdOn": "2022-08-01T19:41:48Z", - }, - ], - } - expected_types: typing.Any = { - "count": None, - "limit": None, - "offset": None, - "total": None, - "accessGroups": ( - "list", - { - 0: {"id": None, "name": None, "shortId": None, "slug": None, "createdOn": "datetime"}, - 1: {"id": None, "name": None, "shortId": None, "slug": None, "createdOn": "datetime"}, - }, - ), - } - response = client.access_groups.list(site_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.access_groups.list(site_id="580e63e98c9a982ac9b8b741") - validate_response(async_response, expected_response, expected_types) diff --git a/tests/test_assets.py b/tests/test_assets.py deleted file mode 100644 index af158ef..0000000 --- a/tests/test_assets.py +++ /dev/null @@ -1,358 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from webflow import Webflow -from webflow import AsyncWebflow -import typing -from .utilities import validate_response - - -async def test_list_(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "assets": [ - { - "id": "63e5889e7fe4eafa7384cea4", - "contentType": "image/png", - "size": 2212772, - "siteId": "63938b302ea6b0aa6f3d8745", - "hostedUrl": "https://s3.amazonaws.com/webflow-prod-assets/63938b302ea6b0aa6f3d8745/63e5889e7fe4eafa7384cea4_Vectors-Wrapper.svg", - "originalFileName": "Candy-Wrapper.svg", - "displayName": "63e5889e7fe4eafa7384cea4_Candy-Wrapper.png", - "lastUpdated": "2023-03-01T23:42:57Z", - "createdOn": "2023-02-09T23:58:22Z", - "variants": [ - { - "hostedUrl": "https://s3.amazonaws.com/webflow-prod-assets/6258612d1ee792848f805dcf/660d83ce30f3a599ddb0bdb3_Screenshot%202024-03-20%20at%209.03.24%E2%80%AFPM-p-500.png", - "originalFileName": "Screenshot%202024-03-20%20at%209.03.24%E2%80%AFPM-p-500.png", - "displayName": "660d83ce30f3a599ddb0bdb3_Screenshot%202024-03-20%20at%209.03.24%E2%80%AFPM-p-500.png", - "format": "png", - "width": 500, - "height": 900, - "quality": 100, - } - ], - "altText": "A red chair", - } - ] - } - expected_types: typing.Any = { - "assets": ( - "list", - { - 0: { - "id": None, - "contentType": None, - "size": "integer", - "siteId": None, - "hostedUrl": None, - "originalFileName": None, - "displayName": None, - "lastUpdated": "datetime", - "createdOn": "datetime", - "variants": ( - "list", - { - 0: { - "hostedUrl": None, - "originalFileName": None, - "displayName": None, - "format": None, - "width": "integer", - "height": "integer", - "quality": "integer", - } - }, - ), - "altText": None, - } - }, - ) - } - response = client.assets.list(site_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.assets.list(site_id="580e63e98c9a982ac9b8b741") - validate_response(async_response, expected_response, expected_types) - - -async def test_create(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "uploadDetails": { - "acl": "public-read", - "bucket": "webflow-bucket-name", - "X-Amz-Algorithm": "AWS4-HMAC-SHA256", - "X-Amz-Credential": "///s3/aws4_request", - "X-Amz-Date": "", - "key": "/_", - "Policy": "", - "X-Amz-Signature": "", - "success_action_status": "201", - "content-type": "image/png", - "Cache-Control": "max-age=31536000, must-revalidate", - }, - "contentType": "image/png", - "id": "64358b9544249dc43d37d2b7", - "parentFolder": "6436b1ce5281cace05b65aea", - "uploadUrl": "https://s3.amazonaws.com/webflow-dev-assets/643021114e290e0d3a0602b2/64358b9544249dc43d37d2b7_Screenshot%202023-04-11%20at%209.50.42%20AM.png", - "assetUrl": "https://s3.amazonaws.com/webflow-prod-assets/6258612d1ee792848f805dcf/660d907ab9e91e3e9f56385e_paranoidAndroid-2024.png", - "hostedUrl": "https://d1otoma47x30pg.cloudfront.net/643021114e290e0d3a0602b2/64358b9544249dc43d37d2b7_Screenshot%202023-04-11%20at%209.50.42%20AM.png", - "originalFileName": "file.png", - "createdOn": "2023-04-11T16:32:21Z", - "lastUpdated": "2023-04-12T20:31:03Z", - } - expected_types: typing.Any = { - "uploadDetails": { - "acl": None, - "bucket": None, - "X-Amz-Algorithm": None, - "X-Amz-Credential": None, - "X-Amz-Date": None, - "key": None, - "Policy": None, - "X-Amz-Signature": None, - "success_action_status": None, - "content-type": None, - "Cache-Control": None, - }, - "contentType": None, - "id": None, - "parentFolder": None, - "uploadUrl": None, - "assetUrl": None, - "hostedUrl": None, - "originalFileName": None, - "createdOn": "datetime", - "lastUpdated": "datetime", - } - response = client.assets.create( - site_id="580e63e98c9a982ac9b8b741", file_name="file.png", file_hash="3c7d87c9575702bc3b1e991f4d3c638e" - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.assets.create( - site_id="580e63e98c9a982ac9b8b741", file_name="file.png", file_hash="3c7d87c9575702bc3b1e991f4d3c638e" - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_get(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "55131cd036c09f7d07883dfc", - "contentType": "image/png", - "size": 1500, - "siteId": "62749158efef318abc8d5a0f", - "hostedUrl": "example.com/hostedimage.png", - "originalFileName": "image.png", - "displayName": "example-image-123.png", - "lastUpdated": "2016-09-06T21:12:22Z", - "createdOn": "2016-09-02T23:26:22Z", - "variants": [ - { - "hostedUrl": "example.com/hostedimage.png", - "originalFileName": "image.png", - "displayName": "A brown dog", - "format": "format", - "width": 1500, - "height": 900, - "quality": 1, - "error": "error", - } - ], - "altText": "A red chair", - } - expected_types: typing.Any = { - "id": None, - "contentType": None, - "size": "integer", - "siteId": None, - "hostedUrl": None, - "originalFileName": None, - "displayName": None, - "lastUpdated": "datetime", - "createdOn": "datetime", - "variants": ( - "list", - { - 0: { - "hostedUrl": None, - "originalFileName": None, - "displayName": None, - "format": None, - "width": "integer", - "height": "integer", - "quality": "integer", - "error": None, - } - }, - ), - "altText": None, - } - response = client.assets.get(asset_id="580e63fc8c9a982ac9b8b745") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.assets.get(asset_id="580e63fc8c9a982ac9b8b745") - validate_response(async_response, expected_response, expected_types) - - -async def test_delete(client: Webflow, async_client: AsyncWebflow) -> None: - # Type ignore to avoid mypy complaining about the function not being meant to return a value - assert ( - client.assets.delete(asset_id="580e63fc8c9a982ac9b8b745") # type: ignore[func-returns-value] - is None - ) - - assert ( - await async_client.assets.delete(asset_id="580e63fc8c9a982ac9b8b745") # type: ignore[func-returns-value] - is None - ) - - -async def test_update(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "55131cd036c09f7d07883dfc", - "contentType": "image/png", - "size": 1500, - "siteId": "62749158efef318abc8d5a0f", - "hostedUrl": "example.com/hostedimage.png", - "originalFileName": "image.png", - "displayName": "example-image-123.png", - "lastUpdated": "2016-09-06T21:12:22Z", - "createdOn": "2016-09-02T23:26:22Z", - "variants": [ - { - "hostedUrl": "example.com/hostedimage.png", - "originalFileName": "image.png", - "displayName": "A brown dog", - "format": "format", - "width": 1500, - "height": 900, - "quality": 1, - "error": "error", - } - ], - "altText": "A red chair", - } - expected_types: typing.Any = { - "id": None, - "contentType": None, - "size": "integer", - "siteId": None, - "hostedUrl": None, - "originalFileName": None, - "displayName": None, - "lastUpdated": "datetime", - "createdOn": "datetime", - "variants": ( - "list", - { - 0: { - "hostedUrl": None, - "originalFileName": None, - "displayName": None, - "format": None, - "width": "integer", - "height": "integer", - "quality": "integer", - "error": None, - } - }, - ), - "altText": None, - } - response = client.assets.update(asset_id="580e63fc8c9a982ac9b8b745") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.assets.update(asset_id="580e63fc8c9a982ac9b8b745") - validate_response(async_response, expected_response, expected_types) - - -async def test_list_folders(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "assetFolders": [ - { - "id": "6390c49774a71f0e3c1a08ee", - "displayName": "emoji icons", - "parentFolder": "6390c49774a71f99f21a08eb", - "assets": ["63e5889e7fe4eafa7384cea4", "659595234426a9fcbad57043"], - "siteId": "6390c49674a71f84b51a08d8", - "createdOn": "2018-10-14T21:55:49Z", - "lastUpdated": "2022-12-07T16:51:37Z", - } - ], - "pagination": {"limit": 1, "offset": 0, "total": 1}, - } - expected_types: typing.Any = { - "assetFolders": ( - "list", - { - 0: { - "id": None, - "displayName": None, - "parentFolder": None, - "assets": ("list", {0: None, 1: None}), - "siteId": None, - "createdOn": "datetime", - "lastUpdated": "datetime", - } - }, - ), - "pagination": {"limit": None, "offset": None, "total": None}, - } - response = client.assets.list_folders(site_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.assets.list_folders(site_id="580e63e98c9a982ac9b8b741") - validate_response(async_response, expected_response, expected_types) - - -async def test_create_folder(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "6390c49774a71f0e3c1a08ee", - "displayName": "emoji icons", - "parentFolder": "6390c49774a71f99f21a08eb", - "assets": ["63e5889e7fe4eafa7384cea4", "659595234426a9fcbad57043"], - "siteId": "6390c49674a71f84b51a08d8", - "createdOn": "2018-10-14T21:55:49Z", - "lastUpdated": "2022-12-07T16:51:37Z", - } - expected_types: typing.Any = { - "id": None, - "displayName": None, - "parentFolder": None, - "assets": ("list", {0: None, 1: None}), - "siteId": None, - "createdOn": "datetime", - "lastUpdated": "datetime", - } - response = client.assets.create_folder(site_id="580e63e98c9a982ac9b8b741", display_name="my asset folder") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.assets.create_folder( - site_id="580e63e98c9a982ac9b8b741", display_name="my asset folder" - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_get_folder(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "6390c49774a71f0e3c1a08ee", - "displayName": "emoji icons", - "parentFolder": "6390c49774a71f99f21a08eb", - "assets": ["63e5889e7fe4eafa7384cea4", "659595234426a9fcbad57043"], - "siteId": "6390c49674a71f84b51a08d8", - "createdOn": "2018-10-14T21:55:49Z", - "lastUpdated": "2022-12-07T16:51:37Z", - } - expected_types: typing.Any = { - "id": None, - "displayName": None, - "parentFolder": None, - "assets": ("list", {0: None, 1: None}), - "siteId": None, - "createdOn": "datetime", - "lastUpdated": "datetime", - } - response = client.assets.get_folder(asset_folder_id="6390c49774a71f0e3c1a08ee") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.assets.get_folder(asset_folder_id="6390c49774a71f0e3c1a08ee") - validate_response(async_response, expected_response, expected_types) diff --git a/tests/test_collections.py b/tests/test_collections.py deleted file mode 100644 index 1e76945..0000000 --- a/tests/test_collections.py +++ /dev/null @@ -1,188 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from webflow import Webflow -from webflow import AsyncWebflow -import typing -from .utilities import validate_response - - -async def test_list_(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "collections": [ - { - "id": "63692ab61fb2852f582ba8f5", - "displayName": "Products", - "singularName": "Product", - "slug": "product", - "createdOn": "2019-06-12T13:35:14Z", - "lastUpdated": "2022-11-17T15:08:50Z", - }, - { - "id": "63692ab61fb2856e6a2ba8f6", - "displayName": "Categories", - "singularName": "Category", - "slug": "category", - "createdOn": "2019-06-12T13:35:14Z", - "lastUpdated": "2022-11-17T15:08:50Z", - }, - { - "id": "63692ab61fb285a8562ba8f4", - "displayName": "SKUs", - "singularName": "SKU", - "slug": "sku", - "createdOn": "2019-06-12T13:35:14Z", - "lastUpdated": "2022-11-17T15:08:50Z", - }, - ] - } - expected_types: typing.Any = { - "collections": ( - "list", - { - 0: { - "id": None, - "displayName": None, - "singularName": None, - "slug": None, - "createdOn": "datetime", - "lastUpdated": "datetime", - }, - 1: { - "id": None, - "displayName": None, - "singularName": None, - "slug": None, - "createdOn": "datetime", - "lastUpdated": "datetime", - }, - 2: { - "id": None, - "displayName": None, - "singularName": None, - "slug": None, - "createdOn": "datetime", - "lastUpdated": "datetime", - }, - }, - ) - } - response = client.collections.list(site_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.collections.list(site_id="580e63e98c9a982ac9b8b741") - validate_response(async_response, expected_response, expected_types) - - -async def test_create(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "580e63fc8c9a982ac9b8b745", - "displayName": "Blog Posts", - "singularName": "Blog Post", - "slug": "post", - "createdOn": "2016-10-24T19:41:48Z", - "lastUpdated": "2016-10-24T19:42:38Z", - "fields": [ - { - "id": "23cc2d952d4e4631ffd4345d2743db4e", - "isRequired": True, - "isEditable": True, - "type": "PlainText", - "slug": "name", - "displayName": "Name", - "helpText": "helpText", - } - ], - } - expected_types: typing.Any = { - "id": None, - "displayName": None, - "singularName": None, - "slug": None, - "createdOn": "datetime", - "lastUpdated": "datetime", - "fields": ( - "list", - { - 0: { - "id": None, - "isRequired": None, - "isEditable": None, - "type": None, - "slug": None, - "displayName": None, - "helpText": None, - } - }, - ), - } - response = client.collections.create( - site_id="580e63e98c9a982ac9b8b741", display_name="Blog Posts", singular_name="Blog Post", slug="posts" - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.collections.create( - site_id="580e63e98c9a982ac9b8b741", display_name="Blog Posts", singular_name="Blog Post", slug="posts" - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_get(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "580e63fc8c9a982ac9b8b745", - "displayName": "Blog Posts", - "singularName": "Blog Post", - "slug": "post", - "createdOn": "2016-10-24T19:41:48Z", - "lastUpdated": "2016-10-24T19:42:38Z", - "fields": [ - { - "id": "23cc2d952d4e4631ffd4345d2743db4e", - "isRequired": True, - "isEditable": True, - "type": "PlainText", - "slug": "name", - "displayName": "Name", - "helpText": "helpText", - } - ], - } - expected_types: typing.Any = { - "id": None, - "displayName": None, - "singularName": None, - "slug": None, - "createdOn": "datetime", - "lastUpdated": "datetime", - "fields": ( - "list", - { - 0: { - "id": None, - "isRequired": None, - "isEditable": None, - "type": None, - "slug": None, - "displayName": None, - "helpText": None, - } - }, - ), - } - response = client.collections.get(collection_id="580e63fc8c9a982ac9b8b745") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.collections.get(collection_id="580e63fc8c9a982ac9b8b745") - validate_response(async_response, expected_response, expected_types) - - -async def test_delete(client: Webflow, async_client: AsyncWebflow) -> None: - # Type ignore to avoid mypy complaining about the function not being meant to return a value - assert ( - client.collections.delete(collection_id="580e63fc8c9a982ac9b8b745") # type: ignore[func-returns-value] - is None - ) - - assert ( - await async_client.collections.delete(collection_id="580e63fc8c9a982ac9b8b745") # type: ignore[func-returns-value] - is None - ) diff --git a/tests/test_components.py b/tests/test_components.py deleted file mode 100644 index 2f5a42d..0000000 --- a/tests/test_components.py +++ /dev/null @@ -1,266 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from webflow import Webflow -from webflow import AsyncWebflow -import typing -from .utilities import validate_response -from webflow import TextNodeWrite -from webflow import ComponentInstanceNodePropertyOverridesWrite -from webflow import ComponentInstanceNodePropertyOverridesWritePropertyOverridesItem -from webflow.resources.components import ComponentPropertiesWritePropertiesItem - - -async def test_list_(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "components": [ - { - "id": "6596da6045e56dee495bcbba", - "name": "Primary Button", - "group": "Buttons", - "description": "A default button component that can be used across the site", - "readonly": True, - }, - { - "id": "658205daa3e8206a523b5ad4", - "name": "Secondary Button", - "group": "Buttons", - "description": "A secondary button component that can be used across the site", - "readonly": True, - }, - { - "id": "6258612d1ee792848f805dcf", - "name": "Card", - "group": "Buttons", - "description": "A button component that can be used across the site", - "readonly": True, - }, - { - "id": "68a2b1d1ee792848f805dcf", - "name": "Nav", - "group": "Buttons", - "description": "A button component that can be used across the site", - "readonly": True, - }, - ], - "pagination": {"limit": 20, "offset": 0, "total": 4}, - } - expected_types: typing.Any = { - "components": ( - "list", - { - 0: {"id": None, "name": None, "group": None, "description": None, "readonly": None}, - 1: {"id": None, "name": None, "group": None, "description": None, "readonly": None}, - 2: {"id": None, "name": None, "group": None, "description": None, "readonly": None}, - 3: {"id": None, "name": None, "group": None, "description": None, "readonly": None}, - }, - ), - "pagination": {"limit": None, "offset": None, "total": None}, - } - response = client.components.list(site_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.components.list(site_id="580e63e98c9a982ac9b8b741") - validate_response(async_response, expected_response, expected_types) - - -async def test_get_content(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "componentId": "69118560-d0bc-15fc-bbf8-b8fe5f6535b5", - "nodes": [ - { - "type": "component-instance", - "id": "a245c12d-995b-55ee-5ec7-aa36a6cad623", - "componentId": "nodes", - "propertyOverrides": [{"propertyId": "7dd14c08-2e96-8d3d-2b19-b5c03642a0f0"}], - }, - { - "type": "component-instance", - "id": "a245c12d-995b-55ee-5ec7-aa36a6cad627", - "componentId": "nodes", - "propertyOverrides": [{"propertyId": "7dd14c08-2e96-8d3d-2b19-b5c03642a0f0"}], - }, - { - "type": "component-instance", - "id": "a245c12d-995b-55ee-5ec7-aa36a6cad629", - "componentId": "nodes", - "propertyOverrides": [{"propertyId": "7dd14c08-2e96-8d3d-2b19-b5c03642a0f0"}], - }, - { - "type": "component-instance", - "id": "a245c12d-995b-55ee-5ec7-aa36a6cad631", - "componentId": "6258612d1ee792848f805dcf", - "propertyOverrides": [ - { - "propertyId": "a245c12d-995b-55ee-5ec7-aa36a6cad633", - "type": "Plain Text", - "text": {"text": "Don't Panic!"}, - }, - { - "propertyId": "a245c12d-995b-55ee-5ec7-aa36a6cad635", - "type": "Rich Text", - "text": {"html": "

Always know where your towel is.

"}, - }, - ], - }, - ], - "pagination": {"limit": 4, "offset": 0, "total": 4}, - } - expected_types: typing.Any = { - "componentId": None, - "nodes": ("list", {0: "no_validate", 1: "no_validate", 2: "no_validate", 3: "no_validate"}), - "pagination": {"limit": None, "offset": None, "total": None}, - } - response = client.components.get_content( - site_id="580e63e98c9a982ac9b8b741", - component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", - locale_id="65427cf400e02b306eaa04a0", - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.components.get_content( - site_id="580e63e98c9a982ac9b8b741", - component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", - locale_id="65427cf400e02b306eaa04a0", - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_update_content(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = {"errors": ["errors"]} - expected_types: typing.Any = {"errors": ("list", {0: None})} - response = client.components.update_content( - site_id="580e63e98c9a982ac9b8b741", - component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", - locale_id="65427cf400e02b306eaa04a0", - nodes=[ - TextNodeWrite( - node_id="a245c12d-995b-55ee-5ec7-aa36a6cad623", text="

The Hitchhiker's Guide to the Galaxy

" - ), - TextNodeWrite( - node_id="a245c12d-995b-55ee-5ec7-aa36a6cad627", - text="

Don't Panic!

Always know where your towel is.

", - ), - ComponentInstanceNodePropertyOverridesWrite( - node_id="a245c12d-995b-55ee-5ec7-aa36a6cad629", - property_overrides=[ - ComponentInstanceNodePropertyOverridesWritePropertyOverridesItem( - property_id="7dd14c08-2e96-8d3d-2b19-b5c03642a0f0", - text="

Time is an illusion

", - ), - ComponentInstanceNodePropertyOverridesWritePropertyOverridesItem( - property_id="7dd14c08-2e96-8d3d-2b19-b5c03642a0f1", text="Life, the Universe and Everything" - ), - ], - ), - ], - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.components.update_content( - site_id="580e63e98c9a982ac9b8b741", - component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", - locale_id="65427cf400e02b306eaa04a0", - nodes=[ - TextNodeWrite( - node_id="a245c12d-995b-55ee-5ec7-aa36a6cad623", text="

The Hitchhiker's Guide to the Galaxy

" - ), - TextNodeWrite( - node_id="a245c12d-995b-55ee-5ec7-aa36a6cad627", - text="

Don't Panic!

Always know where your towel is.

", - ), - ComponentInstanceNodePropertyOverridesWrite( - node_id="a245c12d-995b-55ee-5ec7-aa36a6cad629", - property_overrides=[ - ComponentInstanceNodePropertyOverridesWritePropertyOverridesItem( - property_id="7dd14c08-2e96-8d3d-2b19-b5c03642a0f0", - text="

Time is an illusion

", - ), - ComponentInstanceNodePropertyOverridesWritePropertyOverridesItem( - property_id="7dd14c08-2e96-8d3d-2b19-b5c03642a0f1", text="Life, the Universe and Everything" - ), - ], - ), - ], - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_get_properties(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "componentId": "658205daa3e8206a523b5ad4", - "properties": [ - { - "propertyId": "a245c12d-995b-55ee-5ec7-aa36a6cad623", - "type": "Plain Text", - "label": "Title", - "text": {"text": "The Hitchhiker's Guide to the Galaxy"}, - }, - { - "propertyId": "a245c12d-995b-55ee-5ec7-aa36a6cad627", - "type": "Rich Text", - "label": "Content", - "text": {"html": "

Don't Panic!

Always know where your towel is.

"}, - }, - ], - "pagination": {"limit": 2, "offset": 0, "total": 2}, - } - expected_types: typing.Any = { - "componentId": None, - "properties": ( - "list", - { - 0: {"propertyId": None, "type": None, "label": None, "text": {"text": None}}, - 1: {"propertyId": None, "type": None, "label": None, "text": {"html": None}}, - }, - ), - "pagination": {"limit": None, "offset": None, "total": None}, - } - response = client.components.get_properties( - site_id="580e63e98c9a982ac9b8b741", - component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", - locale_id="65427cf400e02b306eaa04a0", - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.components.get_properties( - site_id="580e63e98c9a982ac9b8b741", - component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", - locale_id="65427cf400e02b306eaa04a0", - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_update_properties(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = {"errors": ["errors"]} - expected_types: typing.Any = {"errors": ("list", {0: None})} - response = client.components.update_properties( - site_id="580e63e98c9a982ac9b8b741", - component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", - locale_id="65427cf400e02b306eaa04a0", - properties=[ - ComponentPropertiesWritePropertiesItem( - property_id="a245c12d-995b-55ee-5ec7-aa36a6cad623", text="The Hitchhiker’s Guide to the Galaxy" - ), - ComponentPropertiesWritePropertiesItem( - property_id="a245c12d-995b-55ee-5ec7-aa36a6cad627", - text="

Dont Panic!

Always know where your towel is.

", - ), - ], - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.components.update_properties( - site_id="580e63e98c9a982ac9b8b741", - component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", - locale_id="65427cf400e02b306eaa04a0", - properties=[ - ComponentPropertiesWritePropertiesItem( - property_id="a245c12d-995b-55ee-5ec7-aa36a6cad623", text="The Hitchhiker’s Guide to the Galaxy" - ), - ComponentPropertiesWritePropertiesItem( - property_id="a245c12d-995b-55ee-5ec7-aa36a6cad627", - text="

Dont Panic!

Always know where your towel is.

", - ), - ], - ) - validate_response(async_response, expected_response, expected_types) diff --git a/tests/test_ecommerce.py b/tests/test_ecommerce.py deleted file mode 100644 index b33a06f..0000000 --- a/tests/test_ecommerce.py +++ /dev/null @@ -1,20 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from webflow import Webflow -from webflow import AsyncWebflow -import typing -from .utilities import validate_response - - -async def test_get_settings(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "siteId": "5eb0b5583bf24e2d3a488969", - "createdOn": "2018-10-04T15:21:02Z", - "defaultCurrency": "USD", - } - expected_types: typing.Any = {"siteId": None, "createdOn": "datetime", "defaultCurrency": None} - response = client.ecommerce.get_settings(site_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.ecommerce.get_settings(site_id="580e63e98c9a982ac9b8b741") - validate_response(async_response, expected_response, expected_types) diff --git a/tests/test_forms.py b/tests/test_forms.py deleted file mode 100644 index ee88977..0000000 --- a/tests/test_forms.py +++ /dev/null @@ -1,266 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from webflow import Webflow -from webflow import AsyncWebflow -import typing -from .utilities import validate_response - - -async def test_list_(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "forms": [ - { - "displayName": "Email Form", - "createdOn": "2016-10-24T19:41:29Z", - "lastUpdated": "2016-10-24T19:43:17Z", - "fields": { - "0": {"displayName": "Email", "userVisible": True}, - "1": {"displayName": "Email", "userVisible": True}, - }, - "responseSettings": { - "redirectUrl": "https://example.com", - "redirectMethod": "GET", - "sendEmailConfirmation": True, - }, - "id": "589a331aa51e760df7ccb89e", - "siteId": "580e63e98c9a982ac9b8b741", - "siteDomainId": "6419db964a9c436a4baf6248", - "pageId": "6419db964a9c43f6a3af6348", - "pageName": "Home", - "formElementId": "4e038d2c-6a1e-4953-7be9-a59a2b453177", - "workspaceId": "580e63fc8c9a982ac9b8b744", - }, - { - "displayName": "Name Form", - "createdOn": "2016-10-24T19:41:29Z", - "lastUpdated": "2016-10-24T19:43:17Z", - "fields": {"0": {"displayName": "Email", "userVisible": True}}, - "responseSettings": { - "redirectUrl": "https://example.com", - "redirectMethod": "GET", - "sendEmailConfirmation": False, - }, - "id": "580ff8d7ba3e45ba9fe588e9", - "siteId": "580e63e98c9a982ac9b8b741", - "siteDomainId": "6419db964a9c436a4baf6248", - "pageId": "6419db964a9c43f6a3af6348", - "pageName": "Home", - "formElementId": "4e038d2c-6a1e-4953-7be9-a59a2b453177", - "workspaceId": "580e63fc8c9a982ac9b8b744", - }, - ], - "pagination": {"limit": 25, "offset": 0, "total": 2}, - } - expected_types: typing.Any = { - "forms": ( - "list", - { - 0: { - "displayName": None, - "createdOn": "datetime", - "lastUpdated": "datetime", - "fields": ( - "dict", - { - 0: (None, {"displayName": None, "userVisible": None}), - 1: (None, {"displayName": None, "userVisible": None}), - }, - ), - "responseSettings": {"redirectUrl": None, "redirectMethod": None, "sendEmailConfirmation": None}, - "id": None, - "siteId": None, - "siteDomainId": None, - "pageId": None, - "pageName": None, - "formElementId": None, - "workspaceId": None, - }, - 1: { - "displayName": None, - "createdOn": "datetime", - "lastUpdated": "datetime", - "fields": ("dict", {0: (None, {"displayName": None, "userVisible": None})}), - "responseSettings": {"redirectUrl": None, "redirectMethod": None, "sendEmailConfirmation": None}, - "id": None, - "siteId": None, - "siteDomainId": None, - "pageId": None, - "pageName": None, - "formElementId": None, - "workspaceId": None, - }, - }, - ), - "pagination": {"limit": None, "offset": None, "total": None}, - } - response = client.forms.list(site_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.forms.list(site_id="580e63e98c9a982ac9b8b741") - validate_response(async_response, expected_response, expected_types) - - -async def test_get(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "displayName": "Email Form", - "createdOn": "2016-10-24T19:41:29Z", - "lastUpdated": "2016-10-24T19:43:17Z", - "fields": { - "660d5bcc9c0772150459dfb1": { - "displayName": "Name", - "type": "Plain", - "placeholder": "Enter your email", - "userVisible": True, - }, - "589a331aa51e760df7ccb89d": { - "displayName": "Email", - "type": "Email", - "placeholder": "Enter your email", - "userVisible": True, - }, - }, - "responseSettings": { - "redirectUrl": "https://example.com", - "redirectMethod": "GET", - "redirectAction": "POST https://example.com", - "sendEmailConfirmation": True, - }, - "id": "589a331aa51e760df7ccb89e", - "siteId": "580e63e98c9a982ac9b8b741", - "siteDomainId": "6419db964a9c436a4baf6248", - "pageId": "6419db964a9c43f6a3af6348", - "pageName": "Home", - "formElementId": "4e038d2c-6a1e-4953-7be9-a59a2b453177", - "workspaceId": "580e63fc8c9a982ac9b8b744", - } - expected_types: typing.Any = { - "displayName": None, - "createdOn": "datetime", - "lastUpdated": "datetime", - "fields": ( - "dict", - { - 0: (None, {"displayName": None, "type": None, "placeholder": None, "userVisible": None}), - 1: (None, {"displayName": None, "type": None, "placeholder": None, "userVisible": None}), - }, - ), - "responseSettings": { - "redirectUrl": None, - "redirectMethod": None, - "redirectAction": None, - "sendEmailConfirmation": None, - }, - "id": None, - "siteId": None, - "siteDomainId": None, - "pageId": None, - "pageName": None, - "formElementId": None, - "workspaceId": None, - } - response = client.forms.get(form_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.forms.get(form_id="580e63e98c9a982ac9b8b741") - validate_response(async_response, expected_response, expected_types) - - -async def test_list_submissions(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "formSubmissions": [ - { - "id": "6321ca84df3949bfc6752327", - "displayName": "Sample Form", - "siteId": "62749158efef318abc8d5a0f", - "workspaceId": "62749158efef318abc8d5a0f", - "dateSubmitted": "2022-09-14T12:35:16Z", - "formResponse": {"First Name": "Arthur", "Last Name": "Dent"}, - }, - { - "id": "660d64fabf6e0a0d4edab981", - "displayName": "Sample Form", - "siteId": "62749158efef318abc8d5a0f", - "workspaceId": "62749158efef318abc8d5a0f", - "dateSubmitted": "2022-09-14T12:35:16Z", - "formResponse": {"First Name": "Ford", "Last Name": "Prefect"}, - }, - ], - "pagination": {"limit": 25, "offset": 0, "total": 2}, - } - expected_types: typing.Any = { - "formSubmissions": ( - "list", - { - 0: { - "id": None, - "displayName": None, - "siteId": None, - "workspaceId": None, - "dateSubmitted": "datetime", - "formResponse": ("dict", {0: (None, None), 1: (None, None)}), - }, - 1: { - "id": None, - "displayName": None, - "siteId": None, - "workspaceId": None, - "dateSubmitted": "datetime", - "formResponse": ("dict", {0: (None, None), 1: (None, None)}), - }, - }, - ), - "pagination": {"limit": None, "offset": None, "total": None}, - } - response = client.forms.list_submissions(form_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.forms.list_submissions(form_id="580e63e98c9a982ac9b8b741") - validate_response(async_response, expected_response, expected_types) - - -async def test_get_submission(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "6321ca84df3949bfc6752327", - "displayName": "Sample Form", - "siteId": "62749158efef318abc8d5a0f", - "workspaceId": "62749158efef318abc8d5a0f", - "dateSubmitted": "2022-09-14T12:35:16Z", - "formResponse": {"First Name": "Arthur", "Last Name": "Dent"}, - } - expected_types: typing.Any = { - "id": None, - "displayName": None, - "siteId": None, - "workspaceId": None, - "dateSubmitted": "datetime", - "formResponse": ("dict", {0: (None, None), 1: (None, None)}), - } - response = client.forms.get_submission(form_submission_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.forms.get_submission(form_submission_id="580e63e98c9a982ac9b8b741") - validate_response(async_response, expected_response, expected_types) - - -async def test_update_submission(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "6321ca84df3949bfc6752327", - "displayName": "Sample Form", - "siteId": "62749158efef318abc8d5a0f", - "workspaceId": "62749158efef318abc8d5a0f", - "dateSubmitted": "2022-09-14T12:35:16Z", - "formResponse": {"First Name": "Arthur", "Last Name": "Dent"}, - } - expected_types: typing.Any = { - "id": None, - "displayName": None, - "siteId": None, - "workspaceId": None, - "dateSubmitted": "datetime", - "formResponse": ("dict", {0: (None, None), 1: (None, None)}), - } - response = client.forms.update_submission(form_submission_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.forms.update_submission(form_submission_id="580e63e98c9a982ac9b8b741") - validate_response(async_response, expected_response, expected_types) diff --git a/tests/test_inventory.py b/tests/test_inventory.py deleted file mode 100644 index a4f1518..0000000 --- a/tests/test_inventory.py +++ /dev/null @@ -1,32 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from webflow import Webflow -from webflow import AsyncWebflow -import typing -from .utilities import validate_response - - -async def test_list_(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = {"id": "5bfedb42bab0ad90fa7dad39", "quantity": 100, "inventoryType": "finite"} - expected_types: typing.Any = {"id": None, "quantity": None, "inventoryType": None} - response = client.inventory.list(collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.inventory.list( - collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754" - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_update(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = {"id": "5bfedb42bab0ad90fa7dad39", "quantity": 100, "inventoryType": "finite"} - expected_types: typing.Any = {"id": None, "quantity": None, "inventoryType": None} - response = client.inventory.update( - collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", inventory_type="infinite" - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.inventory.update( - collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", inventory_type="infinite" - ) - validate_response(async_response, expected_response, expected_types) diff --git a/tests/test_orders.py b/tests/test_orders.py deleted file mode 100644 index a874784..0000000 --- a/tests/test_orders.py +++ /dev/null @@ -1,2327 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from webflow import Webflow -from webflow import AsyncWebflow -import typing -from .utilities import validate_response - - -async def test_list_(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "orders": [ - { - "orderId": "7c1-9fd", - "status": "unfulfilled", - "comment": "Customer requested gift wrapping and a personalized note saying: Happy Birthday, Ford! 🎉 Please ensure the item is packed with extra bubble wrap for safe transit.", - "orderComment": 'Please gift wrap with a personal note saying "Happy Birthday, Ford! 🎉', - "acceptedOn": "2024-04-10T13:16:21Z", - "fulfilledOn": "2018-12-03T22:06:15Z", - "refundedOn": "2018-12-03T22:06:15Z", - "disputedOn": "2018-12-03T22:06:15Z", - "disputeUpdatedOn": "2018-12-03T22:06:15Z", - "disputeLastStatus": "warning_needs_response", - "customerPaid": {"unit": "USD", "value": "5892", "string": " 211.55 USD"}, - "netAmount": {"unit": "USD", "value": "5892", "string": " 200.89 USD"}, - "applicationFee": {"unit": "USD", "value": "5892", "string": " 4.23 USD"}, - "allAddresses": [ - { - "type": "billing", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - { - "type": "shipping", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - ], - "shippingAddress": { - "type": "shipping", - "japanType": "kanji", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - "billingAddress": { - "type": "billing", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - "shippingProvider": "Shipping Company, Co.", - "shippingTracking": "tr00000000002", - "shippingTrackingURL": "https://www.shippingcompany.com/tracking/tr00000000002", - "customerInfo": {"fullName": "Arthur Dent", "email": "arthur.dent@example.com"}, - "purchasedItems": [ - { - "count": 2, - "rowTotal": {"unit": "USD", "value": "5892", "string": " 111.22 USD"}, - "productId": "66072fb61b89448912e26791", - "productName": "Luxurious Fresh Ball", - "productSlug": "luxurious-fresh-ball", - "variantId": "66072fb71b89448912e2683f", - "variantName": "Luxurious Fresh Ball Generic: Bronze, Practical: Plastic", - "variantSlug": "luxurious-fresh-ball-generic-bronze-practical-plastic", - "variantSKU": "luxurious-fresh-ball-generic-bronze-practical-plastic", - "variantImage": { - "url": "https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg" - }, - "variantPrice": {"unit": "USD", "value": "5892", "string": " 55.61 USD"}, - "weight": 11, - "width": 82, - "height": 70, - "length": 9, - }, - { - "count": 1, - "rowTotal": {"unit": "USD", "value": "5892", "string": " 83.09 USD"}, - "productId": "66072fb61b89448912e2678b", - "productName": "Incredible Bronze Towels", - "productSlug": "incredible-bronze-towels", - "variantId": "66072fb71b89448912e2681e", - "variantName": "Incredible Bronze Towels Sleek: Frozen, Incredible: Metal", - "variantSlug": "incredible-bronze-towels-sleek-frozen-incredible-metal", - "variantSKU": "incredible-bronze-towels-sleek-frozen-incredible-metal", - "variantImage": { - "url": "https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e26729_image16.jpeg" - }, - "variantPrice": {"unit": "USD", "value": "5892", "string": " 83.09 USD"}, - "width": 19, - "height": 72, - "length": 18, - }, - ], - "purchasedItemsCount": 3, - "stripeDetails": { - "paymentMethod": "pm_1P410gJYFi4lcbXWbeKghqjK", - "paymentIntentId": "pi_3P410iJYFi4lcbXW0EKKgcVg", - "customerId": "cus_Ptod8KJBiiPgnH", - "chargeId": "ch_3P410iJYFi4lcbXW0DxUkzCH", - }, - "stripeCard": { - "last4": "4242", - "brand": "Visa", - "ownerName": "Arthur Dent", - "expires": {"year": 2025, "month": 4}, - }, - "paypalDetails": { - "orderId": "1a2b3c4d5e6f7g8h9i0j", - "payerId": "9k8j7i6h5g4f3e2d1c0b", - "captureId": "qwe123rty456uio789p", - "refundId": "abcde12345fghij67890", - "refundReason": "Customer requested refund", - "disputeId": "zxcvbnm987poiuytrewq", - }, - "customData": [{"key": "value"}], - "metadata": {"isBuyNow": False}, - "isCustomerDeleted": False, - "isShippingRequired": False, - "hasDownloads": False, - "paymentProcessor": "stripe", - "totals": { - "extras": [ - { - "type": "tax", - "name": "State Taxes", - "description": "CA Taxes (6.25%)", - "price": {"unit": "USD", "value": "5892", "string": "3.44"}, - } - ] - }, - "downloadFiles": [ - { - "id": "5e9a5eba75e0ac242e1b6f64", - "name": "The modern web design process - Webflow Ebook.pdf", - "url": "https://webflow.com/dashboard/download-digital-product?payload=5d93ba5e38c6b0160ab711d3;e7634a;5eb1aac72912ec06f561278c;5e9a5eba75e0ac242e1b6f63:ka2nehxy:4a1ee0a632feaab94294350087215ed89533f2f530903e3b933b638940e921aa", - } - ], - }, - { - "orderId": "fc7-128", - "status": "refunded", - "comment": "Example comment to myself", - "orderComment": "", - "acceptedOn": "2024-03-29T21:29:21Z", - "fulfilledOn": "2018-12-03T22:06:15Z", - "refundedOn": "2024-04-08T18:25:04Z", - "disputedOn": "2018-12-03T22:06:15Z", - "disputeUpdatedOn": "2018-12-03T22:06:15Z", - "disputeLastStatus": "warning_needs_response", - "customerPaid": {"unit": "USD", "value": "5892", "string": " 118.73 USD"}, - "netAmount": {"unit": "USD", "value": "5892", "string": " 112.62 USD"}, - "applicationFee": {"unit": "USD", "value": "5892", "string": " 2.37 USD"}, - "allAddresses": [ - { - "type": "billing", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - { - "type": "shipping", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - ], - "shippingAddress": { - "type": "shipping", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - "billingAddress": { - "type": "billing", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - "shippingProvider": "Shipping Company, Co.", - "shippingTracking": "tr00000000001", - "shippingTrackingURL": "https://www.shippingcompany.com/tracking/tr00000000001", - "customerInfo": {"fullName": "Arthur Dent", "email": "arthur.dent@example.com"}, - "purchasedItems": [ - { - "count": 1, - "rowTotal": {"unit": "USD", "value": "5892", "string": " 55.61 USD"}, - "productId": "66072fb61b89448912e26791", - "productName": "Luxurious Fresh Ball", - "productSlug": "luxurious-fresh-ball", - "variantId": "66072fb71b89448912e2683f", - "variantName": "Luxurious Fresh Ball Generic: Bronze, Practical: Plastic", - "variantSlug": "luxurious-fresh-ball-generic-bronze-practical-plastic", - "variantSKU": "luxurious-fresh-ball-generic-bronze-practical-plastic", - "variantImage": { - "url": "https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg" - }, - "variantPrice": {"unit": "USD", "value": "5892", "string": " 55.61 USD"}, - "weight": 11, - "width": 82, - "height": 70, - "length": 9, - }, - { - "count": 1, - "rowTotal": {"unit": "USD", "value": "5892", "string": " 53.44 USD"}, - "productId": "66072fb61b89448912e26799", - "productName": "Recycled Steel Gloves", - "productSlug": "recycled-steel-gloves", - "variantId": "66072fb91b89448912e26ab9", - "variantName": "Recycled Steel Gloves Electronic: Granite, Handcrafted: grey", - "variantSlug": "recycled-steel-gloves-electronic-granite-handcrafted-grey", - "variantSKU": "recycled-steel-gloves-electronic-granite-handcrafted-grey", - "variantImage": { - "url": "https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2671e_image2.jpeg" - }, - "variantPrice": {"unit": "USD", "value": "5892", "string": " 53.44 USD"}, - "weight": 38, - "width": 76, - "height": 85, - "length": 40, - }, - ], - "purchasedItemsCount": 2, - "stripeDetails": { - "paymentMethod": "pm_1OzmzBJYFi4lcbXWHKNdXU7j", - "paymentIntentId": "pi_3OzmzDJYFi4lcbXW1hTBW6ft", - "customerId": "cus_PpRsNHwWdUoRKR", - "chargeId": "ch_3OzmzDJYFi4lcbXW1ndkkrH2", - "refundId": "re_3OzmzDJYFi4lcbXW1kFAmlBk", - "refundReason": "fraudulent", - }, - "stripeCard": { - "last4": "4242", - "brand": "Visa", - "ownerName": "Arthur Dent", - "expires": {"year": 2024, "month": 4}, - }, - "paypalDetails": { - "orderId": "1a2b3c4d5e6f7g8h9i0j", - "payerId": "9k8j7i6h5g4f3e2d1c0b", - "captureId": "qwe123rty456uio789p", - "refundId": "abcde12345fghij67890", - "refundReason": "Customer requested refund", - "disputeId": "zxcvbnm987poiuytrewq", - }, - "customData": [{"key": "value"}], - "metadata": {"isBuyNow": False}, - "isCustomerDeleted": False, - "isShippingRequired": True, - "hasDownloads": False, - "paymentProcessor": "stripe", - "totals": { - "subtotal": {"unit": "USD", "value": "5892", "string": " 109.05 USD"}, - "extras": [ - { - "type": "tax", - "name": "State Taxes", - "description": "NY Taxes (4.00%)", - "price": {"unit": "USD", "value": "5892", "string": " 4.36 USD"}, - }, - { - "type": "tax", - "name": "City Taxes", - "description": "NEW YORK Taxes (4.88%)", - "price": {"unit": "USD", "value": "5892", "string": " 5.32 USD"}, - }, - { - "type": "shipping", - "name": "Flat", - "description": "", - "price": {"unit": "USD", "value": "5892", "string": " 0.00 USD"}, - }, - ], - "total": {"unit": "USD", "value": "5892", "string": " 118.73 USD"}, - }, - "downloadFiles": [ - { - "id": "5e9a5eba75e0ac242e1b6f64", - "name": "New product guide", - "url": "https://webflow.com/dashboard/download-digital-product?payload=5d93ba5e38c6b0160ab711d3;e7634a;5eb1aac72912ec06f561278c;5e9a5eba75e0ac242e1b6f63:ka2nehxy:4a1ee0a632feaab94294350087215ed89533f2f530903e3b933b638940e921aa", - } - ], - }, - ], - "pagination": {"limit": 100, "offset": 0, "total": 2}, - } - expected_types: typing.Any = { - "orders": ( - "list", - { - 0: { - "orderId": None, - "status": None, - "comment": None, - "orderComment": None, - "acceptedOn": "datetime", - "fulfilledOn": "datetime", - "refundedOn": "datetime", - "disputedOn": "datetime", - "disputeUpdatedOn": "datetime", - "disputeLastStatus": None, - "customerPaid": {"unit": None, "value": None, "string": None}, - "netAmount": {"unit": None, "value": None, "string": None}, - "applicationFee": {"unit": None, "value": None, "string": None}, - "allAddresses": ( - "list", - { - 0: { - "type": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - 1: { - "type": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - }, - ), - "shippingAddress": { - "type": None, - "japanType": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - "billingAddress": { - "type": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - "shippingProvider": None, - "shippingTracking": None, - "shippingTrackingURL": None, - "customerInfo": {"fullName": None, "email": None}, - "purchasedItems": ( - "list", - { - 0: { - "count": None, - "rowTotal": {"unit": None, "value": None, "string": None}, - "productId": None, - "productName": None, - "productSlug": None, - "variantId": None, - "variantName": None, - "variantSlug": None, - "variantSKU": None, - "variantImage": {"url": None}, - "variantPrice": {"unit": None, "value": None, "string": None}, - "weight": None, - "width": None, - "height": None, - "length": None, - }, - 1: { - "count": None, - "rowTotal": {"unit": None, "value": None, "string": None}, - "productId": None, - "productName": None, - "productSlug": None, - "variantId": None, - "variantName": None, - "variantSlug": None, - "variantSKU": None, - "variantImage": {"url": None}, - "variantPrice": {"unit": None, "value": None, "string": None}, - "width": None, - "height": None, - "length": None, - }, - }, - ), - "purchasedItemsCount": None, - "stripeDetails": { - "paymentMethod": None, - "paymentIntentId": None, - "customerId": None, - "chargeId": None, - }, - "stripeCard": { - "last4": None, - "brand": None, - "ownerName": None, - "expires": {"year": None, "month": None}, - }, - "paypalDetails": { - "orderId": None, - "payerId": None, - "captureId": None, - "refundId": None, - "refundReason": None, - "disputeId": None, - }, - "customData": ("list", {0: ("dict", {0: (None, None)})}), - "metadata": {"isBuyNow": None}, - "isCustomerDeleted": None, - "isShippingRequired": None, - "hasDownloads": None, - "paymentProcessor": None, - "totals": { - "extras": ( - "list", - { - 0: { - "type": None, - "name": None, - "description": None, - "price": {"unit": None, "value": None, "string": None}, - } - }, - ) - }, - "downloadFiles": ("list", {0: {"id": None, "name": None, "url": None}}), - }, - 1: { - "orderId": None, - "status": None, - "comment": None, - "orderComment": None, - "acceptedOn": "datetime", - "fulfilledOn": "datetime", - "refundedOn": "datetime", - "disputedOn": "datetime", - "disputeUpdatedOn": "datetime", - "disputeLastStatus": None, - "customerPaid": {"unit": None, "value": None, "string": None}, - "netAmount": {"unit": None, "value": None, "string": None}, - "applicationFee": {"unit": None, "value": None, "string": None}, - "allAddresses": ( - "list", - { - 0: { - "type": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - 1: { - "type": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - }, - ), - "shippingAddress": { - "type": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - "billingAddress": { - "type": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - "shippingProvider": None, - "shippingTracking": None, - "shippingTrackingURL": None, - "customerInfo": {"fullName": None, "email": None}, - "purchasedItems": ( - "list", - { - 0: { - "count": None, - "rowTotal": {"unit": None, "value": None, "string": None}, - "productId": None, - "productName": None, - "productSlug": None, - "variantId": None, - "variantName": None, - "variantSlug": None, - "variantSKU": None, - "variantImage": {"url": None}, - "variantPrice": {"unit": None, "value": None, "string": None}, - "weight": None, - "width": None, - "height": None, - "length": None, - }, - 1: { - "count": None, - "rowTotal": {"unit": None, "value": None, "string": None}, - "productId": None, - "productName": None, - "productSlug": None, - "variantId": None, - "variantName": None, - "variantSlug": None, - "variantSKU": None, - "variantImage": {"url": None}, - "variantPrice": {"unit": None, "value": None, "string": None}, - "weight": None, - "width": None, - "height": None, - "length": None, - }, - }, - ), - "purchasedItemsCount": None, - "stripeDetails": { - "paymentMethod": None, - "paymentIntentId": None, - "customerId": None, - "chargeId": None, - "refundId": None, - "refundReason": None, - }, - "stripeCard": { - "last4": None, - "brand": None, - "ownerName": None, - "expires": {"year": None, "month": None}, - }, - "paypalDetails": { - "orderId": None, - "payerId": None, - "captureId": None, - "refundId": None, - "refundReason": None, - "disputeId": None, - }, - "customData": ("list", {0: ("dict", {0: (None, None)})}), - "metadata": {"isBuyNow": None}, - "isCustomerDeleted": None, - "isShippingRequired": None, - "hasDownloads": None, - "paymentProcessor": None, - "totals": { - "subtotal": {"unit": None, "value": None, "string": None}, - "extras": ( - "list", - { - 0: { - "type": None, - "name": None, - "description": None, - "price": {"unit": None, "value": None, "string": None}, - }, - 1: { - "type": None, - "name": None, - "description": None, - "price": {"unit": None, "value": None, "string": None}, - }, - 2: { - "type": None, - "name": None, - "description": None, - "price": {"unit": None, "value": None, "string": None}, - }, - }, - ), - "total": {"unit": None, "value": None, "string": None}, - }, - "downloadFiles": ("list", {0: {"id": None, "name": None, "url": None}}), - }, - }, - ), - "pagination": {"limit": None, "offset": None, "total": None}, - } - response = client.orders.list(site_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.orders.list(site_id="580e63e98c9a982ac9b8b741") - validate_response(async_response, expected_response, expected_types) - - -async def test_get(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "orderId": "fc7-128", - "status": "refunded", - "comment": "Customer requested gift wrapping and a personalized note saying: Happy Birthday, Ford! 🎉 Please ensure the item is packed with extra bubble wrap for safe transit.", - "orderComment": 'Please gift wrap with a personal note saying "Happy Birthday, Ford! 🎉', - "acceptedOn": "2024-03-29T21:29:21Z", - "fulfilledOn": "2024-03-29T21:29:21Z", - "refundedOn": "2024-04-08T18:25:04Z", - "disputedOn": "2024-03-29T21:29:21Z", - "disputeUpdatedOn": "2024-03-29T21:29:21Z", - "disputeLastStatus": "charge_refunded", - "customerPaid": {"unit": "USD", "value": "5892", "string": " 118.73 USD"}, - "netAmount": {"unit": "USD", "value": "5892", "string": " 112.62 USD"}, - "applicationFee": {"unit": "USD", "value": "5892", "string": " 2.37 USD"}, - "allAddresses": [ - { - "type": "billing", - "japanType": "kana", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - { - "type": "shipping", - "japanType": "kana", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - ], - "shippingAddress": { - "type": "shipping", - "japanType": "kanji", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - "billingAddress": { - "type": "billing", - "japanType": "kana", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - "shippingProvider": "Shipping Company, Co.", - "shippingTracking": "tr00000000001", - "shippingTrackingURL": "https://www.shippingcompany.com/tracking/tr00000000001", - "customerInfo": {"fullName": "Arthur Dent", "email": "arthur.dent@example.com"}, - "purchasedItems": [ - { - "count": 1, - "rowTotal": {"unit": "USD", "value": "5892", "string": " 55.61 USD"}, - "productId": "66072fb61b89448912e26791", - "productName": "Luxurious Fresh Ball", - "productSlug": "luxurious-fresh-ball", - "variantId": "66072fb71b89448912e2683f", - "variantName": "Luxurious Fresh Ball Generic: Bronze, Practical: Plastic", - "variantSlug": "luxurious-fresh-ball-generic-bronze-practical-plastic", - "variantSKU": "luxurious-fresh-ball-generic-bronze-practical-plastic", - "variantImage": { - "url": "https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg" - }, - "variantPrice": {"unit": "USD", "value": "5892", "string": " 55.61 USD"}, - "weight": 11, - "width": 82, - "height": 70, - "length": 9, - }, - { - "count": 1, - "rowTotal": {"unit": "USD", "value": "5892", "string": " 53.44 USD"}, - "productId": "66072fb61b89448912e26799", - "productName": "Recycled Steel Gloves", - "productSlug": "recycled-steel-gloves", - "variantId": "66072fb91b89448912e26ab9", - "variantName": "Recycled Steel Gloves Electronic: Granite, Handcrafted: grey", - "variantSlug": "recycled-steel-gloves-electronic-granite-handcrafted-grey", - "variantSKU": "recycled-steel-gloves-electronic-granite-handcrafted-grey", - "variantImage": { - "url": "https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2671e_image2.jpeg" - }, - "variantPrice": {"unit": "USD", "value": "5892", "string": " 53.44 USD"}, - "weight": 38, - "width": 76, - "height": 85, - "length": 40, - }, - ], - "purchasedItemsCount": 2, - "stripeDetails": { - "subscriptionId": "sub_1J6xwG2eZvKYlo2CXu9Zt0Tn", - "paymentMethod": "pm_1OzmzBJYFi4lcbXWHKNdXU7j", - "paymentIntentId": "pi_3OzmzDJYFi4lcbXW1hTBW6ft", - "customerId": "cus_PpRsNHwWdUoRKR", - "chargeId": "ch_3OzmzDJYFi4lcbXW1ndkkrH2", - "disputeId": "disputeId", - "refundId": "re_3OzmzDJYFi4lcbXW1kFAmlBk", - "refundReason": "fraudulent", - }, - "stripeCard": { - "last4": "4242", - "brand": "Visa", - "ownerName": "Arthur Dent", - "expires": {"year": 2024, "month": 4}, - }, - "paypalDetails": { - "orderId": "1a2b3c4d5e6f7g8h9i0j", - "payerId": "9k8j7i6h5g4f3e2d1c0b", - "captureId": "qwe123rty456uio789p", - "refundId": "abcde12345fghij67890", - "refundReason": "Customer requested refund", - "disputeId": "zxcvbnm987poiuytrewq", - }, - "customData": [{"key": "value"}], - "metadata": {"isBuyNow": False}, - "isCustomerDeleted": False, - "isShippingRequired": True, - "hasDownloads": False, - "paymentProcessor": "stripe", - "totals": { - "subtotal": {"unit": "USD", "value": "5892", "string": " 109.05 USD"}, - "extras": [ - { - "type": "tax", - "name": "State Taxes", - "description": "NY Taxes (4.00%)", - "price": {"unit": "USD", "value": "5892", "string": " 4.36 USD"}, - }, - { - "type": "tax", - "name": "City Taxes", - "description": "NEW YORK Taxes (4.88%)", - "price": {"unit": "USD", "value": "5892", "string": " 5.32 USD"}, - }, - { - "type": "shipping", - "name": "Flat", - "description": "", - "price": {"unit": "USD", "value": "5892", "string": " 0.00 USD"}, - }, - ], - "total": {"unit": "USD", "value": "5892", "string": " 118.73 USD"}, - }, - "downloadFiles": [ - { - "id": "5e9a5eba75e0ac242e1b6f64", - "name": "New product guide", - "url": "https://webflow.com/dashboard/download-digital-product?payload=5d93ba5e38c6b0160ab711d3;e7634a;5eb1aac72912ec06f561278c;5e9a5eba75e0ac242e1b6f63:ka2nehxy:4a1ee0a632feaab94294350087215ed89533f2f530903e3b933b638940e921aa", - } - ], - } - expected_types: typing.Any = { - "orderId": None, - "status": None, - "comment": None, - "orderComment": None, - "acceptedOn": "datetime", - "fulfilledOn": "datetime", - "refundedOn": "datetime", - "disputedOn": "datetime", - "disputeUpdatedOn": "datetime", - "disputeLastStatus": None, - "customerPaid": {"unit": None, "value": None, "string": None}, - "netAmount": {"unit": None, "value": None, "string": None}, - "applicationFee": {"unit": None, "value": None, "string": None}, - "allAddresses": ( - "list", - { - 0: { - "type": None, - "japanType": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - 1: { - "type": None, - "japanType": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - }, - ), - "shippingAddress": { - "type": None, - "japanType": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - "billingAddress": { - "type": None, - "japanType": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - "shippingProvider": None, - "shippingTracking": None, - "shippingTrackingURL": None, - "customerInfo": {"fullName": None, "email": None}, - "purchasedItems": ( - "list", - { - 0: { - "count": None, - "rowTotal": {"unit": None, "value": None, "string": None}, - "productId": None, - "productName": None, - "productSlug": None, - "variantId": None, - "variantName": None, - "variantSlug": None, - "variantSKU": None, - "variantImage": {"url": None}, - "variantPrice": {"unit": None, "value": None, "string": None}, - "weight": None, - "width": None, - "height": None, - "length": None, - }, - 1: { - "count": None, - "rowTotal": {"unit": None, "value": None, "string": None}, - "productId": None, - "productName": None, - "productSlug": None, - "variantId": None, - "variantName": None, - "variantSlug": None, - "variantSKU": None, - "variantImage": {"url": None}, - "variantPrice": {"unit": None, "value": None, "string": None}, - "weight": None, - "width": None, - "height": None, - "length": None, - }, - }, - ), - "purchasedItemsCount": None, - "stripeDetails": { - "subscriptionId": None, - "paymentMethod": None, - "paymentIntentId": None, - "customerId": None, - "chargeId": None, - "disputeId": None, - "refundId": None, - "refundReason": None, - }, - "stripeCard": {"last4": None, "brand": None, "ownerName": None, "expires": {"year": None, "month": None}}, - "paypalDetails": { - "orderId": None, - "payerId": None, - "captureId": None, - "refundId": None, - "refundReason": None, - "disputeId": None, - }, - "customData": ("list", {0: ("dict", {0: (None, None)})}), - "metadata": {"isBuyNow": None}, - "isCustomerDeleted": None, - "isShippingRequired": None, - "hasDownloads": None, - "paymentProcessor": None, - "totals": { - "subtotal": {"unit": None, "value": None, "string": None}, - "extras": ( - "list", - { - 0: { - "type": None, - "name": None, - "description": None, - "price": {"unit": None, "value": None, "string": None}, - }, - 1: { - "type": None, - "name": None, - "description": None, - "price": {"unit": None, "value": None, "string": None}, - }, - 2: { - "type": None, - "name": None, - "description": None, - "price": {"unit": None, "value": None, "string": None}, - }, - }, - ), - "total": {"unit": None, "value": None, "string": None}, - }, - "downloadFiles": ("list", {0: {"id": None, "name": None, "url": None}}), - } - response = client.orders.get(site_id="580e63e98c9a982ac9b8b741", order_id="5e8518516e147040726cc415") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.orders.get( - site_id="580e63e98c9a982ac9b8b741", order_id="5e8518516e147040726cc415" - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_update(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "orderId": "fc7-128", - "status": "refunded", - "comment": "Customer requested gift wrapping and a personalized note saying: Happy Birthday, Ford! 🎉 Please ensure the item is packed with extra bubble wrap for safe transit.", - "orderComment": 'Please gift wrap with a personal note saying "Happy Birthday, Ford! 🎉', - "acceptedOn": "2024-03-29T21:29:21Z", - "fulfilledOn": "2024-03-29T21:29:21Z", - "refundedOn": "2024-04-08T18:25:04Z", - "disputedOn": "2024-03-29T21:29:21Z", - "disputeUpdatedOn": "2024-03-29T21:29:21Z", - "disputeLastStatus": "charge_refunded", - "customerPaid": {"unit": "USD", "value": "5892", "string": " 118.73 USD"}, - "netAmount": {"unit": "USD", "value": "5892", "string": " 112.62 USD"}, - "applicationFee": {"unit": "USD", "value": "5892", "string": " 2.37 USD"}, - "allAddresses": [ - { - "type": "billing", - "japanType": "kana", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - { - "type": "shipping", - "japanType": "kana", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - ], - "shippingAddress": { - "type": "shipping", - "japanType": "kanji", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - "billingAddress": { - "type": "billing", - "japanType": "kana", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - "shippingProvider": "Shipping Company, Co.", - "shippingTracking": "tr00000000001", - "shippingTrackingURL": "https://www.shippingcompany.com/tracking/tr00000000001", - "customerInfo": {"fullName": "Arthur Dent", "email": "arthur.dent@example.com"}, - "purchasedItems": [ - { - "count": 1, - "rowTotal": {"unit": "USD", "value": "5892", "string": " 55.61 USD"}, - "productId": "66072fb61b89448912e26791", - "productName": "Luxurious Fresh Ball", - "productSlug": "luxurious-fresh-ball", - "variantId": "66072fb71b89448912e2683f", - "variantName": "Luxurious Fresh Ball Generic: Bronze, Practical: Plastic", - "variantSlug": "luxurious-fresh-ball-generic-bronze-practical-plastic", - "variantSKU": "luxurious-fresh-ball-generic-bronze-practical-plastic", - "variantImage": { - "url": "https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg" - }, - "variantPrice": {"unit": "USD", "value": "5892", "string": " 55.61 USD"}, - "weight": 11, - "width": 82, - "height": 70, - "length": 9, - }, - { - "count": 1, - "rowTotal": {"unit": "USD", "value": "5892", "string": " 53.44 USD"}, - "productId": "66072fb61b89448912e26799", - "productName": "Recycled Steel Gloves", - "productSlug": "recycled-steel-gloves", - "variantId": "66072fb91b89448912e26ab9", - "variantName": "Recycled Steel Gloves Electronic: Granite, Handcrafted: grey", - "variantSlug": "recycled-steel-gloves-electronic-granite-handcrafted-grey", - "variantSKU": "recycled-steel-gloves-electronic-granite-handcrafted-grey", - "variantImage": { - "url": "https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2671e_image2.jpeg" - }, - "variantPrice": {"unit": "USD", "value": "5892", "string": " 53.44 USD"}, - "weight": 38, - "width": 76, - "height": 85, - "length": 40, - }, - ], - "purchasedItemsCount": 2, - "stripeDetails": { - "subscriptionId": "sub_1J6xwG2eZvKYlo2CXu9Zt0Tn", - "paymentMethod": "pm_1OzmzBJYFi4lcbXWHKNdXU7j", - "paymentIntentId": "pi_3OzmzDJYFi4lcbXW1hTBW6ft", - "customerId": "cus_PpRsNHwWdUoRKR", - "chargeId": "ch_3OzmzDJYFi4lcbXW1ndkkrH2", - "disputeId": "disputeId", - "refundId": "re_3OzmzDJYFi4lcbXW1kFAmlBk", - "refundReason": "fraudulent", - }, - "stripeCard": { - "last4": "4242", - "brand": "Visa", - "ownerName": "Arthur Dent", - "expires": {"year": 2024, "month": 4}, - }, - "paypalDetails": { - "orderId": "1a2b3c4d5e6f7g8h9i0j", - "payerId": "9k8j7i6h5g4f3e2d1c0b", - "captureId": "qwe123rty456uio789p", - "refundId": "abcde12345fghij67890", - "refundReason": "Customer requested refund", - "disputeId": "zxcvbnm987poiuytrewq", - }, - "customData": [{"key": "value"}], - "metadata": {"isBuyNow": False}, - "isCustomerDeleted": False, - "isShippingRequired": True, - "hasDownloads": False, - "paymentProcessor": "stripe", - "totals": { - "subtotal": {"unit": "USD", "value": "5892", "string": " 109.05 USD"}, - "extras": [ - { - "type": "tax", - "name": "State Taxes", - "description": "NY Taxes (4.00%)", - "price": {"unit": "USD", "value": "5892", "string": " 4.36 USD"}, - }, - { - "type": "tax", - "name": "City Taxes", - "description": "NEW YORK Taxes (4.88%)", - "price": {"unit": "USD", "value": "5892", "string": " 5.32 USD"}, - }, - { - "type": "shipping", - "name": "Flat", - "description": "", - "price": {"unit": "USD", "value": "5892", "string": " 0.00 USD"}, - }, - ], - "total": {"unit": "USD", "value": "5892", "string": " 118.73 USD"}, - }, - "downloadFiles": [ - { - "id": "5e9a5eba75e0ac242e1b6f64", - "name": "New product guide", - "url": "https://webflow.com/dashboard/download-digital-product?payload=5d93ba5e38c6b0160ab711d3;e7634a;5eb1aac72912ec06f561278c;5e9a5eba75e0ac242e1b6f63:ka2nehxy:4a1ee0a632feaab94294350087215ed89533f2f530903e3b933b638940e921aa", - } - ], - } - expected_types: typing.Any = { - "orderId": None, - "status": None, - "comment": None, - "orderComment": None, - "acceptedOn": "datetime", - "fulfilledOn": "datetime", - "refundedOn": "datetime", - "disputedOn": "datetime", - "disputeUpdatedOn": "datetime", - "disputeLastStatus": None, - "customerPaid": {"unit": None, "value": None, "string": None}, - "netAmount": {"unit": None, "value": None, "string": None}, - "applicationFee": {"unit": None, "value": None, "string": None}, - "allAddresses": ( - "list", - { - 0: { - "type": None, - "japanType": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - 1: { - "type": None, - "japanType": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - }, - ), - "shippingAddress": { - "type": None, - "japanType": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - "billingAddress": { - "type": None, - "japanType": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - "shippingProvider": None, - "shippingTracking": None, - "shippingTrackingURL": None, - "customerInfo": {"fullName": None, "email": None}, - "purchasedItems": ( - "list", - { - 0: { - "count": None, - "rowTotal": {"unit": None, "value": None, "string": None}, - "productId": None, - "productName": None, - "productSlug": None, - "variantId": None, - "variantName": None, - "variantSlug": None, - "variantSKU": None, - "variantImage": {"url": None}, - "variantPrice": {"unit": None, "value": None, "string": None}, - "weight": None, - "width": None, - "height": None, - "length": None, - }, - 1: { - "count": None, - "rowTotal": {"unit": None, "value": None, "string": None}, - "productId": None, - "productName": None, - "productSlug": None, - "variantId": None, - "variantName": None, - "variantSlug": None, - "variantSKU": None, - "variantImage": {"url": None}, - "variantPrice": {"unit": None, "value": None, "string": None}, - "weight": None, - "width": None, - "height": None, - "length": None, - }, - }, - ), - "purchasedItemsCount": None, - "stripeDetails": { - "subscriptionId": None, - "paymentMethod": None, - "paymentIntentId": None, - "customerId": None, - "chargeId": None, - "disputeId": None, - "refundId": None, - "refundReason": None, - }, - "stripeCard": {"last4": None, "brand": None, "ownerName": None, "expires": {"year": None, "month": None}}, - "paypalDetails": { - "orderId": None, - "payerId": None, - "captureId": None, - "refundId": None, - "refundReason": None, - "disputeId": None, - }, - "customData": ("list", {0: ("dict", {0: (None, None)})}), - "metadata": {"isBuyNow": None}, - "isCustomerDeleted": None, - "isShippingRequired": None, - "hasDownloads": None, - "paymentProcessor": None, - "totals": { - "subtotal": {"unit": None, "value": None, "string": None}, - "extras": ( - "list", - { - 0: { - "type": None, - "name": None, - "description": None, - "price": {"unit": None, "value": None, "string": None}, - }, - 1: { - "type": None, - "name": None, - "description": None, - "price": {"unit": None, "value": None, "string": None}, - }, - 2: { - "type": None, - "name": None, - "description": None, - "price": {"unit": None, "value": None, "string": None}, - }, - }, - ), - "total": {"unit": None, "value": None, "string": None}, - }, - "downloadFiles": ("list", {0: {"id": None, "name": None, "url": None}}), - } - response = client.orders.update(site_id="580e63e98c9a982ac9b8b741", order_id="5e8518516e147040726cc415") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.orders.update( - site_id="580e63e98c9a982ac9b8b741", order_id="5e8518516e147040726cc415" - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_update_fulfill(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "orderId": "fc7-128", - "status": "refunded", - "comment": "Customer requested gift wrapping and a personalized note saying: Happy Birthday, Ford! 🎉 Please ensure the item is packed with extra bubble wrap for safe transit.", - "orderComment": 'Please gift wrap with a personal note saying "Happy Birthday, Ford! 🎉', - "acceptedOn": "2024-03-29T21:29:21Z", - "fulfilledOn": "2024-03-29T21:29:21Z", - "refundedOn": "2024-04-08T18:25:04Z", - "disputedOn": "2024-03-29T21:29:21Z", - "disputeUpdatedOn": "2024-03-29T21:29:21Z", - "disputeLastStatus": "charge_refunded", - "customerPaid": {"unit": "USD", "value": "5892", "string": " 118.73 USD"}, - "netAmount": {"unit": "USD", "value": "5892", "string": " 112.62 USD"}, - "applicationFee": {"unit": "USD", "value": "5892", "string": " 2.37 USD"}, - "allAddresses": [ - { - "type": "billing", - "japanType": "kana", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - { - "type": "shipping", - "japanType": "kana", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - ], - "shippingAddress": { - "type": "shipping", - "japanType": "kanji", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - "billingAddress": { - "type": "billing", - "japanType": "kana", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - "shippingProvider": "Shipping Company, Co.", - "shippingTracking": "tr00000000001", - "shippingTrackingURL": "https://www.shippingcompany.com/tracking/tr00000000001", - "customerInfo": {"fullName": "Arthur Dent", "email": "arthur.dent@example.com"}, - "purchasedItems": [ - { - "count": 1, - "rowTotal": {"unit": "USD", "value": "5892", "string": " 55.61 USD"}, - "productId": "66072fb61b89448912e26791", - "productName": "Luxurious Fresh Ball", - "productSlug": "luxurious-fresh-ball", - "variantId": "66072fb71b89448912e2683f", - "variantName": "Luxurious Fresh Ball Generic: Bronze, Practical: Plastic", - "variantSlug": "luxurious-fresh-ball-generic-bronze-practical-plastic", - "variantSKU": "luxurious-fresh-ball-generic-bronze-practical-plastic", - "variantImage": { - "url": "https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg" - }, - "variantPrice": {"unit": "USD", "value": "5892", "string": " 55.61 USD"}, - "weight": 11, - "width": 82, - "height": 70, - "length": 9, - }, - { - "count": 1, - "rowTotal": {"unit": "USD", "value": "5892", "string": " 53.44 USD"}, - "productId": "66072fb61b89448912e26799", - "productName": "Recycled Steel Gloves", - "productSlug": "recycled-steel-gloves", - "variantId": "66072fb91b89448912e26ab9", - "variantName": "Recycled Steel Gloves Electronic: Granite, Handcrafted: grey", - "variantSlug": "recycled-steel-gloves-electronic-granite-handcrafted-grey", - "variantSKU": "recycled-steel-gloves-electronic-granite-handcrafted-grey", - "variantImage": { - "url": "https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2671e_image2.jpeg" - }, - "variantPrice": {"unit": "USD", "value": "5892", "string": " 53.44 USD"}, - "weight": 38, - "width": 76, - "height": 85, - "length": 40, - }, - ], - "purchasedItemsCount": 2, - "stripeDetails": { - "subscriptionId": "sub_1J6xwG2eZvKYlo2CXu9Zt0Tn", - "paymentMethod": "pm_1OzmzBJYFi4lcbXWHKNdXU7j", - "paymentIntentId": "pi_3OzmzDJYFi4lcbXW1hTBW6ft", - "customerId": "cus_PpRsNHwWdUoRKR", - "chargeId": "ch_3OzmzDJYFi4lcbXW1ndkkrH2", - "disputeId": "disputeId", - "refundId": "re_3OzmzDJYFi4lcbXW1kFAmlBk", - "refundReason": "fraudulent", - }, - "stripeCard": { - "last4": "4242", - "brand": "Visa", - "ownerName": "Arthur Dent", - "expires": {"year": 2024, "month": 4}, - }, - "paypalDetails": { - "orderId": "1a2b3c4d5e6f7g8h9i0j", - "payerId": "9k8j7i6h5g4f3e2d1c0b", - "captureId": "qwe123rty456uio789p", - "refundId": "abcde12345fghij67890", - "refundReason": "Customer requested refund", - "disputeId": "zxcvbnm987poiuytrewq", - }, - "customData": [{"key": "value"}], - "metadata": {"isBuyNow": False}, - "isCustomerDeleted": False, - "isShippingRequired": True, - "hasDownloads": False, - "paymentProcessor": "stripe", - "totals": { - "subtotal": {"unit": "USD", "value": "5892", "string": " 109.05 USD"}, - "extras": [ - { - "type": "tax", - "name": "State Taxes", - "description": "NY Taxes (4.00%)", - "price": {"unit": "USD", "value": "5892", "string": " 4.36 USD"}, - }, - { - "type": "tax", - "name": "City Taxes", - "description": "NEW YORK Taxes (4.88%)", - "price": {"unit": "USD", "value": "5892", "string": " 5.32 USD"}, - }, - { - "type": "shipping", - "name": "Flat", - "description": "", - "price": {"unit": "USD", "value": "5892", "string": " 0.00 USD"}, - }, - ], - "total": {"unit": "USD", "value": "5892", "string": " 118.73 USD"}, - }, - "downloadFiles": [ - { - "id": "5e9a5eba75e0ac242e1b6f64", - "name": "New product guide", - "url": "https://webflow.com/dashboard/download-digital-product?payload=5d93ba5e38c6b0160ab711d3;e7634a;5eb1aac72912ec06f561278c;5e9a5eba75e0ac242e1b6f63:ka2nehxy:4a1ee0a632feaab94294350087215ed89533f2f530903e3b933b638940e921aa", - } - ], - } - expected_types: typing.Any = { - "orderId": None, - "status": None, - "comment": None, - "orderComment": None, - "acceptedOn": "datetime", - "fulfilledOn": "datetime", - "refundedOn": "datetime", - "disputedOn": "datetime", - "disputeUpdatedOn": "datetime", - "disputeLastStatus": None, - "customerPaid": {"unit": None, "value": None, "string": None}, - "netAmount": {"unit": None, "value": None, "string": None}, - "applicationFee": {"unit": None, "value": None, "string": None}, - "allAddresses": ( - "list", - { - 0: { - "type": None, - "japanType": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - 1: { - "type": None, - "japanType": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - }, - ), - "shippingAddress": { - "type": None, - "japanType": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - "billingAddress": { - "type": None, - "japanType": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - "shippingProvider": None, - "shippingTracking": None, - "shippingTrackingURL": None, - "customerInfo": {"fullName": None, "email": None}, - "purchasedItems": ( - "list", - { - 0: { - "count": None, - "rowTotal": {"unit": None, "value": None, "string": None}, - "productId": None, - "productName": None, - "productSlug": None, - "variantId": None, - "variantName": None, - "variantSlug": None, - "variantSKU": None, - "variantImage": {"url": None}, - "variantPrice": {"unit": None, "value": None, "string": None}, - "weight": None, - "width": None, - "height": None, - "length": None, - }, - 1: { - "count": None, - "rowTotal": {"unit": None, "value": None, "string": None}, - "productId": None, - "productName": None, - "productSlug": None, - "variantId": None, - "variantName": None, - "variantSlug": None, - "variantSKU": None, - "variantImage": {"url": None}, - "variantPrice": {"unit": None, "value": None, "string": None}, - "weight": None, - "width": None, - "height": None, - "length": None, - }, - }, - ), - "purchasedItemsCount": None, - "stripeDetails": { - "subscriptionId": None, - "paymentMethod": None, - "paymentIntentId": None, - "customerId": None, - "chargeId": None, - "disputeId": None, - "refundId": None, - "refundReason": None, - }, - "stripeCard": {"last4": None, "brand": None, "ownerName": None, "expires": {"year": None, "month": None}}, - "paypalDetails": { - "orderId": None, - "payerId": None, - "captureId": None, - "refundId": None, - "refundReason": None, - "disputeId": None, - }, - "customData": ("list", {0: ("dict", {0: (None, None)})}), - "metadata": {"isBuyNow": None}, - "isCustomerDeleted": None, - "isShippingRequired": None, - "hasDownloads": None, - "paymentProcessor": None, - "totals": { - "subtotal": {"unit": None, "value": None, "string": None}, - "extras": ( - "list", - { - 0: { - "type": None, - "name": None, - "description": None, - "price": {"unit": None, "value": None, "string": None}, - }, - 1: { - "type": None, - "name": None, - "description": None, - "price": {"unit": None, "value": None, "string": None}, - }, - 2: { - "type": None, - "name": None, - "description": None, - "price": {"unit": None, "value": None, "string": None}, - }, - }, - ), - "total": {"unit": None, "value": None, "string": None}, - }, - "downloadFiles": ("list", {0: {"id": None, "name": None, "url": None}}), - } - response = client.orders.update_fulfill(site_id="580e63e98c9a982ac9b8b741", order_id="5e8518516e147040726cc415") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.orders.update_fulfill( - site_id="580e63e98c9a982ac9b8b741", order_id="5e8518516e147040726cc415" - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_update_unfulfill(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "orderId": "fc7-128", - "status": "refunded", - "comment": "Customer requested gift wrapping and a personalized note saying: Happy Birthday, Ford! 🎉 Please ensure the item is packed with extra bubble wrap for safe transit.", - "orderComment": 'Please gift wrap with a personal note saying "Happy Birthday, Ford! 🎉', - "acceptedOn": "2024-03-29T21:29:21Z", - "fulfilledOn": "2024-03-29T21:29:21Z", - "refundedOn": "2024-04-08T18:25:04Z", - "disputedOn": "2024-03-29T21:29:21Z", - "disputeUpdatedOn": "2024-03-29T21:29:21Z", - "disputeLastStatus": "charge_refunded", - "customerPaid": {"unit": "USD", "value": "5892", "string": " 118.73 USD"}, - "netAmount": {"unit": "USD", "value": "5892", "string": " 112.62 USD"}, - "applicationFee": {"unit": "USD", "value": "5892", "string": " 2.37 USD"}, - "allAddresses": [ - { - "type": "billing", - "japanType": "kana", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - { - "type": "shipping", - "japanType": "kana", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - ], - "shippingAddress": { - "type": "shipping", - "japanType": "kanji", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - "billingAddress": { - "type": "billing", - "japanType": "kana", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - "shippingProvider": "Shipping Company, Co.", - "shippingTracking": "tr00000000001", - "shippingTrackingURL": "https://www.shippingcompany.com/tracking/tr00000000001", - "customerInfo": {"fullName": "Arthur Dent", "email": "arthur.dent@example.com"}, - "purchasedItems": [ - { - "count": 1, - "rowTotal": {"unit": "USD", "value": "5892", "string": " 55.61 USD"}, - "productId": "66072fb61b89448912e26791", - "productName": "Luxurious Fresh Ball", - "productSlug": "luxurious-fresh-ball", - "variantId": "66072fb71b89448912e2683f", - "variantName": "Luxurious Fresh Ball Generic: Bronze, Practical: Plastic", - "variantSlug": "luxurious-fresh-ball-generic-bronze-practical-plastic", - "variantSKU": "luxurious-fresh-ball-generic-bronze-practical-plastic", - "variantImage": { - "url": "https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg" - }, - "variantPrice": {"unit": "USD", "value": "5892", "string": " 55.61 USD"}, - "weight": 11, - "width": 82, - "height": 70, - "length": 9, - }, - { - "count": 1, - "rowTotal": {"unit": "USD", "value": "5892", "string": " 53.44 USD"}, - "productId": "66072fb61b89448912e26799", - "productName": "Recycled Steel Gloves", - "productSlug": "recycled-steel-gloves", - "variantId": "66072fb91b89448912e26ab9", - "variantName": "Recycled Steel Gloves Electronic: Granite, Handcrafted: grey", - "variantSlug": "recycled-steel-gloves-electronic-granite-handcrafted-grey", - "variantSKU": "recycled-steel-gloves-electronic-granite-handcrafted-grey", - "variantImage": { - "url": "https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2671e_image2.jpeg" - }, - "variantPrice": {"unit": "USD", "value": "5892", "string": " 53.44 USD"}, - "weight": 38, - "width": 76, - "height": 85, - "length": 40, - }, - ], - "purchasedItemsCount": 2, - "stripeDetails": { - "subscriptionId": "sub_1J6xwG2eZvKYlo2CXu9Zt0Tn", - "paymentMethod": "pm_1OzmzBJYFi4lcbXWHKNdXU7j", - "paymentIntentId": "pi_3OzmzDJYFi4lcbXW1hTBW6ft", - "customerId": "cus_PpRsNHwWdUoRKR", - "chargeId": "ch_3OzmzDJYFi4lcbXW1ndkkrH2", - "disputeId": "disputeId", - "refundId": "re_3OzmzDJYFi4lcbXW1kFAmlBk", - "refundReason": "fraudulent", - }, - "stripeCard": { - "last4": "4242", - "brand": "Visa", - "ownerName": "Arthur Dent", - "expires": {"year": 2024, "month": 4}, - }, - "paypalDetails": { - "orderId": "1a2b3c4d5e6f7g8h9i0j", - "payerId": "9k8j7i6h5g4f3e2d1c0b", - "captureId": "qwe123rty456uio789p", - "refundId": "abcde12345fghij67890", - "refundReason": "Customer requested refund", - "disputeId": "zxcvbnm987poiuytrewq", - }, - "customData": [{"key": "value"}], - "metadata": {"isBuyNow": False}, - "isCustomerDeleted": False, - "isShippingRequired": True, - "hasDownloads": False, - "paymentProcessor": "stripe", - "totals": { - "subtotal": {"unit": "USD", "value": "5892", "string": " 109.05 USD"}, - "extras": [ - { - "type": "tax", - "name": "State Taxes", - "description": "NY Taxes (4.00%)", - "price": {"unit": "USD", "value": "5892", "string": " 4.36 USD"}, - }, - { - "type": "tax", - "name": "City Taxes", - "description": "NEW YORK Taxes (4.88%)", - "price": {"unit": "USD", "value": "5892", "string": " 5.32 USD"}, - }, - { - "type": "shipping", - "name": "Flat", - "description": "", - "price": {"unit": "USD", "value": "5892", "string": " 0.00 USD"}, - }, - ], - "total": {"unit": "USD", "value": "5892", "string": " 118.73 USD"}, - }, - "downloadFiles": [ - { - "id": "5e9a5eba75e0ac242e1b6f64", - "name": "New product guide", - "url": "https://webflow.com/dashboard/download-digital-product?payload=5d93ba5e38c6b0160ab711d3;e7634a;5eb1aac72912ec06f561278c;5e9a5eba75e0ac242e1b6f63:ka2nehxy:4a1ee0a632feaab94294350087215ed89533f2f530903e3b933b638940e921aa", - } - ], - } - expected_types: typing.Any = { - "orderId": None, - "status": None, - "comment": None, - "orderComment": None, - "acceptedOn": "datetime", - "fulfilledOn": "datetime", - "refundedOn": "datetime", - "disputedOn": "datetime", - "disputeUpdatedOn": "datetime", - "disputeLastStatus": None, - "customerPaid": {"unit": None, "value": None, "string": None}, - "netAmount": {"unit": None, "value": None, "string": None}, - "applicationFee": {"unit": None, "value": None, "string": None}, - "allAddresses": ( - "list", - { - 0: { - "type": None, - "japanType": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - 1: { - "type": None, - "japanType": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - }, - ), - "shippingAddress": { - "type": None, - "japanType": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - "billingAddress": { - "type": None, - "japanType": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - "shippingProvider": None, - "shippingTracking": None, - "shippingTrackingURL": None, - "customerInfo": {"fullName": None, "email": None}, - "purchasedItems": ( - "list", - { - 0: { - "count": None, - "rowTotal": {"unit": None, "value": None, "string": None}, - "productId": None, - "productName": None, - "productSlug": None, - "variantId": None, - "variantName": None, - "variantSlug": None, - "variantSKU": None, - "variantImage": {"url": None}, - "variantPrice": {"unit": None, "value": None, "string": None}, - "weight": None, - "width": None, - "height": None, - "length": None, - }, - 1: { - "count": None, - "rowTotal": {"unit": None, "value": None, "string": None}, - "productId": None, - "productName": None, - "productSlug": None, - "variantId": None, - "variantName": None, - "variantSlug": None, - "variantSKU": None, - "variantImage": {"url": None}, - "variantPrice": {"unit": None, "value": None, "string": None}, - "weight": None, - "width": None, - "height": None, - "length": None, - }, - }, - ), - "purchasedItemsCount": None, - "stripeDetails": { - "subscriptionId": None, - "paymentMethod": None, - "paymentIntentId": None, - "customerId": None, - "chargeId": None, - "disputeId": None, - "refundId": None, - "refundReason": None, - }, - "stripeCard": {"last4": None, "brand": None, "ownerName": None, "expires": {"year": None, "month": None}}, - "paypalDetails": { - "orderId": None, - "payerId": None, - "captureId": None, - "refundId": None, - "refundReason": None, - "disputeId": None, - }, - "customData": ("list", {0: ("dict", {0: (None, None)})}), - "metadata": {"isBuyNow": None}, - "isCustomerDeleted": None, - "isShippingRequired": None, - "hasDownloads": None, - "paymentProcessor": None, - "totals": { - "subtotal": {"unit": None, "value": None, "string": None}, - "extras": ( - "list", - { - 0: { - "type": None, - "name": None, - "description": None, - "price": {"unit": None, "value": None, "string": None}, - }, - 1: { - "type": None, - "name": None, - "description": None, - "price": {"unit": None, "value": None, "string": None}, - }, - 2: { - "type": None, - "name": None, - "description": None, - "price": {"unit": None, "value": None, "string": None}, - }, - }, - ), - "total": {"unit": None, "value": None, "string": None}, - }, - "downloadFiles": ("list", {0: {"id": None, "name": None, "url": None}}), - } - response = client.orders.update_unfulfill(site_id="580e63e98c9a982ac9b8b741", order_id="5e8518516e147040726cc415") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.orders.update_unfulfill( - site_id="580e63e98c9a982ac9b8b741", order_id="5e8518516e147040726cc415" - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_refund(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "orderId": "fc7-128", - "status": "refunded", - "comment": "Customer requested gift wrapping and a personalized note saying: Happy Birthday, Ford! 🎉 Please ensure the item is packed with extra bubble wrap for safe transit.", - "orderComment": 'Please gift wrap with a personal note saying "Happy Birthday, Ford! 🎉', - "acceptedOn": "2024-03-29T21:29:21Z", - "fulfilledOn": "2024-03-29T21:29:21Z", - "refundedOn": "2024-04-08T18:25:04Z", - "disputedOn": "2024-03-29T21:29:21Z", - "disputeUpdatedOn": "2024-03-29T21:29:21Z", - "disputeLastStatus": "charge_refunded", - "customerPaid": {"unit": "USD", "value": "5892", "string": " 118.73 USD"}, - "netAmount": {"unit": "USD", "value": "5892", "string": " 112.62 USD"}, - "applicationFee": {"unit": "USD", "value": "5892", "string": " 2.37 USD"}, - "allAddresses": [ - { - "type": "billing", - "japanType": "kana", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - { - "type": "shipping", - "japanType": "kana", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - ], - "shippingAddress": { - "type": "shipping", - "japanType": "kanji", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - "billingAddress": { - "type": "billing", - "japanType": "kana", - "addressee": "Arthur Dent", - "line1": "20 W 34th St", - "line2": "Empire State Building", - "city": "New York", - "state": "New York", - "country": "US", - "postalCode": "10118", - }, - "shippingProvider": "Shipping Company, Co.", - "shippingTracking": "tr00000000001", - "shippingTrackingURL": "https://www.shippingcompany.com/tracking/tr00000000001", - "customerInfo": {"fullName": "Arthur Dent", "email": "arthur.dent@example.com"}, - "purchasedItems": [ - { - "count": 1, - "rowTotal": {"unit": "USD", "value": "5892", "string": " 55.61 USD"}, - "productId": "66072fb61b89448912e26791", - "productName": "Luxurious Fresh Ball", - "productSlug": "luxurious-fresh-ball", - "variantId": "66072fb71b89448912e2683f", - "variantName": "Luxurious Fresh Ball Generic: Bronze, Practical: Plastic", - "variantSlug": "luxurious-fresh-ball-generic-bronze-practical-plastic", - "variantSKU": "luxurious-fresh-ball-generic-bronze-practical-plastic", - "variantImage": { - "url": "https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg" - }, - "variantPrice": {"unit": "USD", "value": "5892", "string": " 55.61 USD"}, - "weight": 11, - "width": 82, - "height": 70, - "length": 9, - }, - { - "count": 1, - "rowTotal": {"unit": "USD", "value": "5892", "string": " 53.44 USD"}, - "productId": "66072fb61b89448912e26799", - "productName": "Recycled Steel Gloves", - "productSlug": "recycled-steel-gloves", - "variantId": "66072fb91b89448912e26ab9", - "variantName": "Recycled Steel Gloves Electronic: Granite, Handcrafted: grey", - "variantSlug": "recycled-steel-gloves-electronic-granite-handcrafted-grey", - "variantSKU": "recycled-steel-gloves-electronic-granite-handcrafted-grey", - "variantImage": { - "url": "https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2671e_image2.jpeg" - }, - "variantPrice": {"unit": "USD", "value": "5892", "string": " 53.44 USD"}, - "weight": 38, - "width": 76, - "height": 85, - "length": 40, - }, - ], - "purchasedItemsCount": 2, - "stripeDetails": { - "subscriptionId": "sub_1J6xwG2eZvKYlo2CXu9Zt0Tn", - "paymentMethod": "pm_1OzmzBJYFi4lcbXWHKNdXU7j", - "paymentIntentId": "pi_3OzmzDJYFi4lcbXW1hTBW6ft", - "customerId": "cus_PpRsNHwWdUoRKR", - "chargeId": "ch_3OzmzDJYFi4lcbXW1ndkkrH2", - "disputeId": "disputeId", - "refundId": "re_3OzmzDJYFi4lcbXW1kFAmlBk", - "refundReason": "fraudulent", - }, - "stripeCard": { - "last4": "4242", - "brand": "Visa", - "ownerName": "Arthur Dent", - "expires": {"year": 2024, "month": 4}, - }, - "paypalDetails": { - "orderId": "1a2b3c4d5e6f7g8h9i0j", - "payerId": "9k8j7i6h5g4f3e2d1c0b", - "captureId": "qwe123rty456uio789p", - "refundId": "abcde12345fghij67890", - "refundReason": "Customer requested refund", - "disputeId": "zxcvbnm987poiuytrewq", - }, - "customData": [{"key": "value"}], - "metadata": {"isBuyNow": False}, - "isCustomerDeleted": False, - "isShippingRequired": True, - "hasDownloads": False, - "paymentProcessor": "stripe", - "totals": { - "subtotal": {"unit": "USD", "value": "5892", "string": " 109.05 USD"}, - "extras": [ - { - "type": "tax", - "name": "State Taxes", - "description": "NY Taxes (4.00%)", - "price": {"unit": "USD", "value": "5892", "string": " 4.36 USD"}, - }, - { - "type": "tax", - "name": "City Taxes", - "description": "NEW YORK Taxes (4.88%)", - "price": {"unit": "USD", "value": "5892", "string": " 5.32 USD"}, - }, - { - "type": "shipping", - "name": "Flat", - "description": "", - "price": {"unit": "USD", "value": "5892", "string": " 0.00 USD"}, - }, - ], - "total": {"unit": "USD", "value": "5892", "string": " 118.73 USD"}, - }, - "downloadFiles": [ - { - "id": "5e9a5eba75e0ac242e1b6f64", - "name": "New product guide", - "url": "https://webflow.com/dashboard/download-digital-product?payload=5d93ba5e38c6b0160ab711d3;e7634a;5eb1aac72912ec06f561278c;5e9a5eba75e0ac242e1b6f63:ka2nehxy:4a1ee0a632feaab94294350087215ed89533f2f530903e3b933b638940e921aa", - } - ], - } - expected_types: typing.Any = { - "orderId": None, - "status": None, - "comment": None, - "orderComment": None, - "acceptedOn": "datetime", - "fulfilledOn": "datetime", - "refundedOn": "datetime", - "disputedOn": "datetime", - "disputeUpdatedOn": "datetime", - "disputeLastStatus": None, - "customerPaid": {"unit": None, "value": None, "string": None}, - "netAmount": {"unit": None, "value": None, "string": None}, - "applicationFee": {"unit": None, "value": None, "string": None}, - "allAddresses": ( - "list", - { - 0: { - "type": None, - "japanType": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - 1: { - "type": None, - "japanType": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - }, - ), - "shippingAddress": { - "type": None, - "japanType": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - "billingAddress": { - "type": None, - "japanType": None, - "addressee": None, - "line1": None, - "line2": None, - "city": None, - "state": None, - "country": None, - "postalCode": None, - }, - "shippingProvider": None, - "shippingTracking": None, - "shippingTrackingURL": None, - "customerInfo": {"fullName": None, "email": None}, - "purchasedItems": ( - "list", - { - 0: { - "count": None, - "rowTotal": {"unit": None, "value": None, "string": None}, - "productId": None, - "productName": None, - "productSlug": None, - "variantId": None, - "variantName": None, - "variantSlug": None, - "variantSKU": None, - "variantImage": {"url": None}, - "variantPrice": {"unit": None, "value": None, "string": None}, - "weight": None, - "width": None, - "height": None, - "length": None, - }, - 1: { - "count": None, - "rowTotal": {"unit": None, "value": None, "string": None}, - "productId": None, - "productName": None, - "productSlug": None, - "variantId": None, - "variantName": None, - "variantSlug": None, - "variantSKU": None, - "variantImage": {"url": None}, - "variantPrice": {"unit": None, "value": None, "string": None}, - "weight": None, - "width": None, - "height": None, - "length": None, - }, - }, - ), - "purchasedItemsCount": None, - "stripeDetails": { - "subscriptionId": None, - "paymentMethod": None, - "paymentIntentId": None, - "customerId": None, - "chargeId": None, - "disputeId": None, - "refundId": None, - "refundReason": None, - }, - "stripeCard": {"last4": None, "brand": None, "ownerName": None, "expires": {"year": None, "month": None}}, - "paypalDetails": { - "orderId": None, - "payerId": None, - "captureId": None, - "refundId": None, - "refundReason": None, - "disputeId": None, - }, - "customData": ("list", {0: ("dict", {0: (None, None)})}), - "metadata": {"isBuyNow": None}, - "isCustomerDeleted": None, - "isShippingRequired": None, - "hasDownloads": None, - "paymentProcessor": None, - "totals": { - "subtotal": {"unit": None, "value": None, "string": None}, - "extras": ( - "list", - { - 0: { - "type": None, - "name": None, - "description": None, - "price": {"unit": None, "value": None, "string": None}, - }, - 1: { - "type": None, - "name": None, - "description": None, - "price": {"unit": None, "value": None, "string": None}, - }, - 2: { - "type": None, - "name": None, - "description": None, - "price": {"unit": None, "value": None, "string": None}, - }, - }, - ), - "total": {"unit": None, "value": None, "string": None}, - }, - "downloadFiles": ("list", {0: {"id": None, "name": None, "url": None}}), - } - response = client.orders.refund(site_id="580e63e98c9a982ac9b8b741", order_id="5e8518516e147040726cc415") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.orders.refund( - site_id="580e63e98c9a982ac9b8b741", order_id="5e8518516e147040726cc415" - ) - validate_response(async_response, expected_response, expected_types) diff --git a/tests/test_pages.py b/tests/test_pages.py deleted file mode 100644 index 716c201..0000000 --- a/tests/test_pages.py +++ /dev/null @@ -1,403 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from webflow import Webflow -from webflow import AsyncWebflow -import typing -from .utilities import validate_response -import datetime -from webflow import PageSeo -from webflow import PageOpenGraph -from webflow import TextNodeWrite -from webflow import ComponentInstanceNodePropertyOverridesWrite -from webflow import ComponentInstanceNodePropertyOverridesWritePropertyOverridesItem - - -async def test_list_(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "pages": [ - { - "id": "6596da6045e56dee495bcbba", - "siteId": "6258612d1ee792848f805dcf", - "title": "Guide to the Galaxy", - "slug": "guide-to-the-galaxy", - "parentId": "6419db964a9c435aa3af6251", - "collectionId": "6390c49774a71f12831a08e3", - "createdOn": "2024-03-11T10:42:00Z", - "lastUpdated": "2024-03-11T10:42:42Z", - "archived": False, - "draft": False, - "canBranch": True, - "isBranch": False, - "isMembersOnly": False, - "seo": { - "title": "The Ultimate Hitchhiker's Guide to the Galaxy", - "description": "Everything you need to know about the galaxy, from avoiding Vogon poetry to the importance of towels.", - }, - "openGraph": { - "title": "Explore the Cosmos with The Ultimate Guide", - "titleCopied": False, - "description": "Dive deep into the mysteries of the universe with your guide to everything galactic.", - "descriptionCopied": False, - }, - "localeId": "653fd9af6a07fc9cfd7a5e57", - "publishedPath": "/en-us/guide-to-the-galaxy", - }, - { - "id": "6596da6045e56dee495bcbad", - "siteId": "6258612d1ee792848f805dcf", - "title": "Towel Day Celebrations", - "slug": "towel-day", - "parentId": "6419db964a9c435aa3af6251", - "collectionId": "6390c49774a71f12831a08e3", - "createdOn": "2024-05-25T09:00:00Z", - "lastUpdated": "2024-05-25T09:42:00Z", - "archived": False, - "draft": False, - "canBranch": True, - "isBranch": False, - "isMembersOnly": False, - "seo": { - "title": "Celebrate Towel Day - The Hitchhiker's Guide to the Galaxy", - "description": "A guide to celebrating Towel Day, in honor of the most massively useful thing an interstellar hitchhiker can have.", - }, - "openGraph": { - "title": "Towel Day - Don't Panic", - "titleCopied": False, - "description": "Join the galaxy in celebrating Towel Day, the day dedicated to carrying towels everywhere in memory of Douglas Adams.", - "descriptionCopied": False, - }, - "localeId": "653fd9af6a07fc9cfd7a5e57", - "publishedPath": "/en-us/towel-day", - }, - ], - "pagination": {"limit": 20, "offset": 0, "total": 2}, - } - expected_types: typing.Any = { - "pages": ( - "list", - { - 0: { - "id": None, - "siteId": None, - "title": None, - "slug": None, - "parentId": None, - "collectionId": None, - "createdOn": "datetime", - "lastUpdated": "datetime", - "archived": None, - "draft": None, - "canBranch": None, - "isBranch": None, - "isMembersOnly": None, - "seo": {"title": None, "description": None}, - "openGraph": {"title": None, "titleCopied": None, "description": None, "descriptionCopied": None}, - "localeId": None, - "publishedPath": None, - }, - 1: { - "id": None, - "siteId": None, - "title": None, - "slug": None, - "parentId": None, - "collectionId": None, - "createdOn": "datetime", - "lastUpdated": "datetime", - "archived": None, - "draft": None, - "canBranch": None, - "isBranch": None, - "isMembersOnly": None, - "seo": {"title": None, "description": None}, - "openGraph": {"title": None, "titleCopied": None, "description": None, "descriptionCopied": None}, - "localeId": None, - "publishedPath": None, - }, - }, - ), - "pagination": {"limit": None, "offset": None, "total": None}, - } - response = client.pages.list(site_id="580e63e98c9a982ac9b8b741", locale_id="65427cf400e02b306eaa04a0") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.pages.list( - site_id="580e63e98c9a982ac9b8b741", locale_id="65427cf400e02b306eaa04a0" - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_get_metadata(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "6596da6045e56dee495bcbba", - "siteId": "6258612d1ee792848f805dcf", - "title": "Guide to the Galaxy", - "slug": "guide-to-the-galaxy", - "parentId": "6419db964a9c435aa3af6251", - "collectionId": "6390c49774a71f12831a08e3", - "createdOn": "2024-03-11T10:42:00Z", - "lastUpdated": "2024-03-11T10:42:42Z", - "archived": False, - "draft": False, - "canBranch": True, - "isBranch": False, - "isMembersOnly": False, - "seo": { - "title": "The Ultimate Hitchhiker's Guide to the Galaxy", - "description": "Everything you need to know about the galaxy, from avoiding Vogon poetry to the importance of towels.", - }, - "openGraph": { - "title": "Explore the Cosmos with The Ultimate Guide", - "titleCopied": False, - "description": "Dive deep into the mysteries of the universe with your guide to everything galactic.", - "descriptionCopied": False, - }, - "localeId": "653fd9af6a07fc9cfd7a5e57", - "publishedPath": "/en-us/guide-to-the-galaxy", - } - expected_types: typing.Any = { - "id": None, - "siteId": None, - "title": None, - "slug": None, - "parentId": None, - "collectionId": None, - "createdOn": "datetime", - "lastUpdated": "datetime", - "archived": None, - "draft": None, - "canBranch": None, - "isBranch": None, - "isMembersOnly": None, - "seo": {"title": None, "description": None}, - "openGraph": {"title": None, "titleCopied": None, "description": None, "descriptionCopied": None}, - "localeId": None, - "publishedPath": None, - } - response = client.pages.get_metadata(page_id="63c720f9347c2139b248e552", locale_id="65427cf400e02b306eaa04a0") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.pages.get_metadata( - page_id="63c720f9347c2139b248e552", locale_id="65427cf400e02b306eaa04a0" - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_update_page_settings(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "6596da6045e56dee495bcbba", - "siteId": "6258612d1ee792848f805dcf", - "title": "Guide to the Galaxy", - "slug": "guide-to-the-galaxy", - "parentId": "6419db964a9c435aa3af6251", - "collectionId": "6390c49774a71f12831a08e3", - "createdOn": "2024-03-11T10:42:00Z", - "lastUpdated": "2024-03-11T10:42:42Z", - "archived": False, - "draft": False, - "canBranch": True, - "isBranch": False, - "isMembersOnly": False, - "seo": { - "title": "The Ultimate Hitchhiker's Guide to the Galaxy", - "description": "Everything you need to know about the galaxy, from avoiding Vogon poetry to the importance of towels.", - }, - "openGraph": { - "title": "Explore the Cosmos with The Ultimate Guide", - "titleCopied": False, - "description": "Dive deep into the mysteries of the universe with your guide to everything galactic.", - "descriptionCopied": False, - }, - "localeId": "653fd9af6a07fc9cfd7a5e57", - "publishedPath": "/en-us/guide-to-the-galaxy", - } - expected_types: typing.Any = { - "id": None, - "siteId": None, - "title": None, - "slug": None, - "parentId": None, - "collectionId": None, - "createdOn": "datetime", - "lastUpdated": "datetime", - "archived": None, - "draft": None, - "canBranch": None, - "isBranch": None, - "isMembersOnly": None, - "seo": {"title": None, "description": None}, - "openGraph": {"title": None, "titleCopied": None, "description": None, "descriptionCopied": None}, - "localeId": None, - "publishedPath": None, - } - response = client.pages.update_page_settings( - page_id="63c720f9347c2139b248e552", - locale_id="65427cf400e02b306eaa04a0", - id="6596da6045e56dee495bcbba", - site_id="6258612d1ee792848f805dcf", - title="Guide to the Galaxy", - slug="guide-to-the-galaxy", - created_on=datetime.datetime.fromisoformat("2024-03-11 10:42:00+00:00"), - last_updated=datetime.datetime.fromisoformat("2024-03-11 10:42:42+00:00"), - archived=False, - draft=False, - can_branch=True, - is_branch=False, - seo=PageSeo( - title="The Ultimate Hitchhiker's Guide to the Galaxy", - description="Everything you need to know about the galaxy, from avoiding Vogon poetry to the importance of towels.", - ), - open_graph=PageOpenGraph( - title="Explore the Cosmos with The Ultimate Guide", - title_copied=False, - description="Dive deep into the mysteries of the universe with your guide to everything galactic.", - description_copied=False, - ), - page_locale_id="653fd9af6a07fc9cfd7a5e57", - published_path="/en-us/guide-to-the-galaxy", - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.pages.update_page_settings( - page_id="63c720f9347c2139b248e552", - locale_id="65427cf400e02b306eaa04a0", - id="6596da6045e56dee495bcbba", - site_id="6258612d1ee792848f805dcf", - title="Guide to the Galaxy", - slug="guide-to-the-galaxy", - created_on=datetime.datetime.fromisoformat("2024-03-11 10:42:00+00:00"), - last_updated=datetime.datetime.fromisoformat("2024-03-11 10:42:42+00:00"), - archived=False, - draft=False, - can_branch=True, - is_branch=False, - seo=PageSeo( - title="The Ultimate Hitchhiker's Guide to the Galaxy", - description="Everything you need to know about the galaxy, from avoiding Vogon poetry to the importance of towels.", - ), - open_graph=PageOpenGraph( - title="Explore the Cosmos with The Ultimate Guide", - title_copied=False, - description="Dive deep into the mysteries of the universe with your guide to everything galactic.", - description_copied=False, - ), - page_locale_id="653fd9af6a07fc9cfd7a5e57", - published_path="/en-us/guide-to-the-galaxy", - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_get_content(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "pageId": "658205daa3e8206a523b5ad4", - "nodes": [ - { - "type": "component-instance", - "id": "a245c12d-995b-55ee-5ec7-aa36a6cad623", - "componentId": "nodes", - "propertyOverrides": [{"propertyId": "7dd14c08-2e96-8d3d-2b19-b5c03642a0f0"}], - }, - { - "type": "component-instance", - "id": "a245c12d-995b-55ee-5ec7-aa36a6cad627", - "componentId": "nodes", - "propertyOverrides": [{"propertyId": "7dd14c08-2e96-8d3d-2b19-b5c03642a0f0"}], - }, - { - "type": "component-instance", - "id": "a245c12d-995b-55ee-5ec7-aa36a6cad629", - "componentId": "nodes", - "propertyOverrides": [{"propertyId": "7dd14c08-2e96-8d3d-2b19-b5c03642a0f0"}], - }, - { - "type": "component-instance", - "id": "a245c12d-995b-55ee-5ec7-aa36a6cad631", - "componentId": "6258612d1ee792848f805dcf", - "propertyOverrides": [ - { - "propertyId": "a245c12d-995b-55ee-5ec7-aa36a6cad633", - "type": "Plain Text", - "label": "Catchphrase", - "text": {"text": "Don't Panic!"}, - }, - { - "propertyId": "a245c12d-995b-55ee-5ec7-aa36a6cad635", - "type": "Rich Text", - "label": "Tagline", - "text": {"html": "

Always know where your towel is.

"}, - }, - ], - }, - ], - "pagination": {"limit": 4, "offset": 0, "total": 4}, - } - expected_types: typing.Any = { - "pageId": None, - "nodes": ("list", {0: "no_validate", 1: "no_validate", 2: "no_validate", 3: "no_validate"}), - "pagination": {"limit": None, "offset": None, "total": None}, - } - response = client.pages.get_content(page_id="63c720f9347c2139b248e552", locale_id="65427cf400e02b306eaa04a0") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.pages.get_content( - page_id="63c720f9347c2139b248e552", locale_id="65427cf400e02b306eaa04a0" - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_update_static_content(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = {"errors": ["errors"]} - expected_types: typing.Any = {"errors": ("list", {0: None})} - response = client.pages.update_static_content( - page_id="63c720f9347c2139b248e552", - locale_id="localeId", - nodes=[ - TextNodeWrite( - node_id="a245c12d-995b-55ee-5ec7-aa36a6cad623", text="

The Hitchhiker's Guide to the Galaxy

" - ), - TextNodeWrite( - node_id="a245c12d-995b-55ee-5ec7-aa36a6cad627", - text="

Don't Panic!

Always know where your towel is.

", - ), - ComponentInstanceNodePropertyOverridesWrite( - node_id="a245c12d-995b-55ee-5ec7-aa36a6cad629", - property_overrides=[ - ComponentInstanceNodePropertyOverridesWritePropertyOverridesItem( - property_id="7dd14c08-2e96-8d3d-2b19-b5c03642a0f0", - text="

Time is an illusion

", - ), - ComponentInstanceNodePropertyOverridesWritePropertyOverridesItem( - property_id="7dd14c08-2e96-8d3d-2b19-b5c03642a0f1", text="Life, the Universe and Everything" - ), - ], - ), - ], - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.pages.update_static_content( - page_id="63c720f9347c2139b248e552", - locale_id="localeId", - nodes=[ - TextNodeWrite( - node_id="a245c12d-995b-55ee-5ec7-aa36a6cad623", text="

The Hitchhiker's Guide to the Galaxy

" - ), - TextNodeWrite( - node_id="a245c12d-995b-55ee-5ec7-aa36a6cad627", - text="

Don't Panic!

Always know where your towel is.

", - ), - ComponentInstanceNodePropertyOverridesWrite( - node_id="a245c12d-995b-55ee-5ec7-aa36a6cad629", - property_overrides=[ - ComponentInstanceNodePropertyOverridesWritePropertyOverridesItem( - property_id="7dd14c08-2e96-8d3d-2b19-b5c03642a0f0", - text="

Time is an illusion

", - ), - ComponentInstanceNodePropertyOverridesWritePropertyOverridesItem( - property_id="7dd14c08-2e96-8d3d-2b19-b5c03642a0f1", text="Life, the Universe and Everything" - ), - ], - ), - ], - ) - validate_response(async_response, expected_response, expected_types) diff --git a/tests/test_products.py b/tests/test_products.py deleted file mode 100644 index 03d28db..0000000 --- a/tests/test_products.py +++ /dev/null @@ -1,465 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from webflow import Webflow -from webflow import AsyncWebflow -import typing -from .utilities import validate_response -from webflow import Sku - - -async def test_list_(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "items": [ - { - "product": { - "id": "660eb7a486d1d6e0412292d7", - "cmsLocaleId": "653ad57de882f528b32e810e", - "lastPublished": "2024-04-04T14:24:19Z", - "lastUpdated": "2024-04-04T14:30:19Z", - "createdOn": "2024-04-04T14:22:28Z", - "isArchived": False, - "isDraft": False, - "fieldData": { - "name": "T-Shirt", - "slug": "t-shirt", - "description": "A plain cotton t-shirt.", - "shippable": True, - "sku-properties": [ - { - "id": "Color", - "name": "Color", - "enum": [{"id": "id", "name": "Royal Blue", "slug": "royal-blue"}], - } - ], - }, - }, - "skus": [ - { - "id": "580e63fc8c9a982ac9b8b745", - "cmsLocaleId": "653ad57de882f528b32e810e", - "lastPublished": "2023-03-17T18:47:35Z", - "lastUpdated": "2023-03-17T18:47:35Z", - "createdOn": "2023-03-17T18:47:35Z", - "fieldData": { - "sku-values": {"ff42fee0113744f693a764e3431a9cc2": "64a74715c456e36762fc39a1"}, - "name": "Blue T-shirt", - "slug": "t-shirt-blue", - "price": {"value": 100, "unit": "USD"}, - "quantity": 10, - }, - } - ], - } - ], - "pagination": {"limit": 100, "offset": 0, "total": 100}, - } - expected_types: typing.Any = { - "items": ( - "list", - { - 0: { - "product": { - "id": None, - "cmsLocaleId": None, - "lastPublished": "datetime", - "lastUpdated": "datetime", - "createdOn": "datetime", - "isArchived": None, - "isDraft": None, - "fieldData": { - "name": None, - "slug": None, - "description": None, - "shippable": None, - "sku-properties": ( - "list", - { - 0: { - "id": None, - "name": None, - "enum": ("list", {0: {"id": None, "name": None, "slug": None}}), - } - }, - ), - }, - }, - "skus": ( - "list", - { - 0: { - "id": None, - "cmsLocaleId": None, - "lastPublished": "datetime", - "lastUpdated": "datetime", - "createdOn": "datetime", - "fieldData": { - "sku-values": ("dict", {0: (None, None)}), - "name": None, - "slug": None, - "price": {"value": None, "unit": None}, - "quantity": None, - }, - } - }, - ), - } - }, - ), - "pagination": {"limit": None, "offset": None, "total": None}, - } - response = client.products.list(site_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.products.list(site_id="580e63e98c9a982ac9b8b741") - validate_response(async_response, expected_response, expected_types) - - -async def test_create(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "product": { - "id": "660eb7a486d1d6e0412292d7", - "cmsLocaleId": "653ad57de882f528b32e810e", - "lastPublished": "2024-04-04T14:24:19Z", - "lastUpdated": "2024-04-04T14:30:19Z", - "createdOn": "2024-04-04T14:22:28Z", - "isArchived": False, - "isDraft": False, - "fieldData": { - "name": "T-Shirt", - "slug": "t-shirt", - "description": "A plain cotton t-shirt.", - "shippable": True, - "sku-properties": [ - {"id": "Color", "name": "Color", "enum": [{"id": "id", "name": "Royal Blue", "slug": "royal-blue"}]} - ], - "categories": ["categories"], - "tax-category": "standard-taxable", - "default-sku": "default-sku", - "ec-product-type": "ff42fee0113744f693a764e3431a9cc2", - }, - }, - "skus": [ - { - "id": "580e63fc8c9a982ac9b8b745", - "cmsLocaleId": "653ad57de882f528b32e810e", - "lastPublished": "2023-03-17T18:47:35Z", - "lastUpdated": "2023-03-17T18:47:35Z", - "createdOn": "2023-03-17T18:47:35Z", - "fieldData": { - "sku-values": {"ff42fee0113744f693a764e3431a9cc2": "64a74715c456e36762fc39a1"}, - "name": "Blue T-shirt", - "slug": "t-shirt-blue", - "price": {"value": 100, "unit": "USD"}, - "quantity": 10, - }, - } - ], - } - expected_types: typing.Any = { - "product": { - "id": None, - "cmsLocaleId": None, - "lastPublished": "datetime", - "lastUpdated": "datetime", - "createdOn": "datetime", - "isArchived": None, - "isDraft": None, - "fieldData": { - "name": None, - "slug": None, - "description": None, - "shippable": None, - "sku-properties": ( - "list", - {0: {"id": None, "name": None, "enum": ("list", {0: {"id": None, "name": None, "slug": None}})}}, - ), - "categories": ("list", {0: None}), - "tax-category": None, - "default-sku": None, - "ec-product-type": None, - }, - }, - "skus": ( - "list", - { - 0: { - "id": None, - "cmsLocaleId": None, - "lastPublished": "datetime", - "lastUpdated": "datetime", - "createdOn": "datetime", - "fieldData": { - "sku-values": ("dict", {0: (None, None)}), - "name": None, - "slug": None, - "price": {"value": None, "unit": None}, - "quantity": None, - }, - } - }, - ), - } - response = client.products.create(site_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.products.create(site_id="580e63e98c9a982ac9b8b741") - validate_response(async_response, expected_response, expected_types) - - -async def test_get(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "product": { - "id": "660eb7a486d1d6e0412292d7", - "cmsLocaleId": "653ad57de882f528b32e810e", - "lastPublished": "2024-04-04T14:24:19Z", - "lastUpdated": "2024-04-04T14:30:19Z", - "createdOn": "2024-04-04T14:22:28Z", - "isArchived": False, - "isDraft": False, - "fieldData": { - "name": "T-Shirt", - "slug": "t-shirt", - "description": "A plain cotton t-shirt.", - "shippable": True, - "sku-properties": [ - {"id": "Color", "name": "Color", "enum": [{"id": "id", "name": "Royal Blue", "slug": "royal-blue"}]} - ], - "categories": ["categories"], - "tax-category": "standard-taxable", - "default-sku": "default-sku", - "ec-product-type": "ff42fee0113744f693a764e3431a9cc2", - }, - }, - "skus": [ - { - "id": "580e63fc8c9a982ac9b8b745", - "cmsLocaleId": "653ad57de882f528b32e810e", - "lastPublished": "2023-03-17T18:47:35Z", - "lastUpdated": "2023-03-17T18:47:35Z", - "createdOn": "2023-03-17T18:47:35Z", - "fieldData": { - "sku-values": {"ff42fee0113744f693a764e3431a9cc2": "64a74715c456e36762fc39a1"}, - "name": "Blue T-shirt", - "slug": "t-shirt-blue", - "price": {"value": 100, "unit": "USD"}, - "quantity": 10, - }, - } - ], - } - expected_types: typing.Any = { - "product": { - "id": None, - "cmsLocaleId": None, - "lastPublished": "datetime", - "lastUpdated": "datetime", - "createdOn": "datetime", - "isArchived": None, - "isDraft": None, - "fieldData": { - "name": None, - "slug": None, - "description": None, - "shippable": None, - "sku-properties": ( - "list", - {0: {"id": None, "name": None, "enum": ("list", {0: {"id": None, "name": None, "slug": None}})}}, - ), - "categories": ("list", {0: None}), - "tax-category": None, - "default-sku": None, - "ec-product-type": None, - }, - }, - "skus": ( - "list", - { - 0: { - "id": None, - "cmsLocaleId": None, - "lastPublished": "datetime", - "lastUpdated": "datetime", - "createdOn": "datetime", - "fieldData": { - "sku-values": ("dict", {0: (None, None)}), - "name": None, - "slug": None, - "price": {"value": None, "unit": None}, - "quantity": None, - }, - } - }, - ), - } - response = client.products.get(site_id="580e63e98c9a982ac9b8b741", product_id="580e63fc8c9a982ac9b8b745") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.products.get( - site_id="580e63e98c9a982ac9b8b741", product_id="580e63fc8c9a982ac9b8b745" - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_update(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "660eb7a486d1d6e0412292d7", - "cmsLocaleId": "653ad57de882f528b32e810e", - "lastPublished": "2024-04-04T14:24:19Z", - "lastUpdated": "2024-04-04T14:30:19Z", - "createdOn": "2024-04-04T14:22:28Z", - "isArchived": False, - "isDraft": False, - "fieldData": { - "name": "T-Shirt", - "slug": "t-shirt", - "description": "A plain cotton t-shirt.", - "shippable": True, - "sku-properties": [ - {"id": "Color", "name": "Color", "enum": [{"id": "id", "name": "Royal Blue", "slug": "royal-blue"}]} - ], - "categories": ["categories"], - "tax-category": "standard-taxable", - "default-sku": "default-sku", - "ec-product-type": "ff42fee0113744f693a764e3431a9cc2", - }, - } - expected_types: typing.Any = { - "id": None, - "cmsLocaleId": None, - "lastPublished": "datetime", - "lastUpdated": "datetime", - "createdOn": "datetime", - "isArchived": None, - "isDraft": None, - "fieldData": { - "name": None, - "slug": None, - "description": None, - "shippable": None, - "sku-properties": ( - "list", - {0: {"id": None, "name": None, "enum": ("list", {0: {"id": None, "name": None, "slug": None}})}}, - ), - "categories": ("list", {0: None}), - "tax-category": None, - "default-sku": None, - "ec-product-type": None, - }, - } - response = client.products.update(site_id="580e63e98c9a982ac9b8b741", product_id="580e63fc8c9a982ac9b8b745") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.products.update( - site_id="580e63e98c9a982ac9b8b741", product_id="580e63fc8c9a982ac9b8b745" - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_create_sku(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "skus": [ - { - "id": "580e63fc8c9a982ac9b8b745", - "cmsLocaleId": "653ad57de882f528b32e810e", - "lastPublished": "2023-03-17T18:47:35Z", - "lastUpdated": "2023-03-17T18:47:35Z", - "createdOn": "2023-03-17T18:47:35Z", - "fieldData": { - "sku-values": {"ff42fee0113744f693a764e3431a9cc2": "64a74715c456e36762fc39a1"}, - "name": "Blue T-shirt", - "slug": "t-shirt-blue", - "price": {"value": 100, "unit": "USD"}, - "quantity": 10, - }, - } - ] - } - expected_types: typing.Any = { - "skus": ( - "list", - { - 0: { - "id": None, - "cmsLocaleId": None, - "lastPublished": "datetime", - "lastUpdated": "datetime", - "createdOn": "datetime", - "fieldData": { - "sku-values": ("dict", {0: (None, None)}), - "name": None, - "slug": None, - "price": {"value": None, "unit": None}, - "quantity": None, - }, - } - }, - ) - } - response = client.products.create_sku( - site_id="580e63e98c9a982ac9b8b741", product_id="580e63fc8c9a982ac9b8b745", skus=[Sku()] - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.products.create_sku( - site_id="580e63e98c9a982ac9b8b741", product_id="580e63fc8c9a982ac9b8b745", skus=[Sku()] - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_update_sku(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "580e63fc8c9a982ac9b8b745", - "cmsLocaleId": "653ad57de882f528b32e810e", - "lastPublished": "2023-03-17T18:47:35Z", - "lastUpdated": "2023-03-17T18:47:35Z", - "createdOn": "2023-03-17T18:47:35Z", - "fieldData": { - "sku-values": {"ff42fee0113744f693a764e3431a9cc2": "64a74715c456e36762fc39a1"}, - "name": "Blue T-shirt", - "slug": "t-shirt-blue", - "price": {"value": 100, "unit": "USD"}, - "compare-at-price": {"value": 100, "unit": "USD"}, - "ec-sku-billing-method": "one-time", - "ec-sku-subscription-plan": {"interval": "day", "frequency": 1, "trial": 7, "plans": [{}]}, - "track-inventory": True, - "quantity": 10, - }, - } - expected_types: typing.Any = { - "id": None, - "cmsLocaleId": None, - "lastPublished": "datetime", - "lastUpdated": "datetime", - "createdOn": "datetime", - "fieldData": { - "sku-values": ("dict", {0: (None, None)}), - "name": None, - "slug": None, - "price": {"value": None, "unit": None}, - "compare-at-price": {"value": None, "unit": None}, - "ec-sku-billing-method": None, - "ec-sku-subscription-plan": { - "interval": None, - "frequency": None, - "trial": None, - "plans": ("list", {0: {}}), - }, - "track-inventory": None, - "quantity": None, - }, - } - response = client.products.update_sku( - site_id="580e63e98c9a982ac9b8b741", - product_id="580e63fc8c9a982ac9b8b745", - sku_id="5e8518516e147040726cc415", - sku=Sku(), - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.products.update_sku( - site_id="580e63e98c9a982ac9b8b741", - product_id="580e63fc8c9a982ac9b8b745", - sku_id="5e8518516e147040726cc415", - sku=Sku(), - ) - validate_response(async_response, expected_response, expected_types) diff --git a/tests/test_scripts.py b/tests/test_scripts.py deleted file mode 100644 index 6432530..0000000 --- a/tests/test_scripts.py +++ /dev/null @@ -1,157 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from webflow import Webflow -from webflow import AsyncWebflow -import typing -from .utilities import validate_response - - -async def test_list_(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "registeredScripts": [ - { - "id": "alert", - "canCopy": False, - "displayName": "Alert", - "hostedLocation": "https://cdn.webflow.io/.../alert-0.0.1.js", - "integrityHash": "integrityHash", - "createdOn": "2022-10-26T00:28:54.191Z", - "lastUpdated": "lastUpdated", - "version": "0.0.1", - }, - { - "id": "alert", - "canCopy": False, - "displayName": "Alert", - "hostedLocation": "https://cdn.webflow.io/.../alert-0.0.2.js", - "integrityHash": "integrityHash", - "createdOn": "2022-10-26T00:28:54.191Z", - "lastUpdated": "lastUpdated", - "version": "0.0.2", - }, - { - "id": "cms_slider", - "canCopy": True, - "displayName": "CMS Slider", - "hostedLocation": "https://cdn.jsdelivr.net/.../cms_slider.js", - "integrityHash": "sha384-J+YlJ8v0gpaRoKH7SbFbEmxOZlAxLiwNjfSsBhDooGa5roXlPPpXbEevck4J7YZ+", - "createdOn": "2022-10-26T00:28:54.191Z", - "lastUpdated": "lastUpdated", - "version": "1.0.0", - }, - ] - } - expected_types: typing.Any = { - "registeredScripts": ( - "list", - { - 0: { - "id": None, - "canCopy": None, - "displayName": None, - "hostedLocation": None, - "integrityHash": None, - "createdOn": None, - "lastUpdated": None, - "version": None, - }, - 1: { - "id": None, - "canCopy": None, - "displayName": None, - "hostedLocation": None, - "integrityHash": None, - "createdOn": None, - "lastUpdated": None, - "version": None, - }, - 2: { - "id": None, - "canCopy": None, - "displayName": None, - "hostedLocation": None, - "integrityHash": None, - "createdOn": None, - "lastUpdated": None, - "version": None, - }, - }, - ) - } - response = client.scripts.list(site_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.scripts.list(site_id="580e63e98c9a982ac9b8b741") - validate_response(async_response, expected_response, expected_types) - - -async def test_register_hosted(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "cms_slider", - "canCopy": True, - "displayName": "CMS Slider", - "hostedLocation": "https://cdn.jsdelivr.net/.../cmsslider.js", - "integrityHash": "sha384-J+YlJ8v0gpaRoKH7SbFbEmxOZlAxLiwNjfSsBhDooGa5roXlPPpXbEevck4J7YZ+", - "createdOn": "2022-10-26T00:28:54.191Z", - "lastUpdated": "lastUpdated", - "version": "1.0.0", - } - expected_types: typing.Any = { - "id": None, - "canCopy": None, - "displayName": None, - "hostedLocation": None, - "integrityHash": None, - "createdOn": None, - "lastUpdated": None, - "version": None, - } - response = client.scripts.register_hosted( - site_id="580e63e98c9a982ac9b8b741", - hosted_location="hostedLocation", - integrity_hash="integrityHash", - version="version", - display_name="displayName", - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.scripts.register_hosted( - site_id="580e63e98c9a982ac9b8b741", - hosted_location="hostedLocation", - integrity_hash="integrityHash", - version="version", - display_name="displayName", - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_register_inline(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "alert", - "canCopy": False, - "displayName": "Alert", - "hostedLocation": "https://uploads-ssl.webflow.com/6258612d1ee792848f805dcf%2F64b6c769ff52ba6c3d904a91%2F660d6e15b3d1696f2d2b1447%2Falert-0.0.1.js", - "integrityHash": "integrityHash", - "createdOn": "2022-10-26T00:28:54.191Z", - "lastUpdated": "lastUpdated", - "version": "0.0.1", - } - expected_types: typing.Any = { - "id": None, - "canCopy": None, - "displayName": None, - "hostedLocation": None, - "integrityHash": None, - "createdOn": None, - "lastUpdated": None, - "version": None, - } - response = client.scripts.register_inline( - site_id="580e63e98c9a982ac9b8b741", source_code="alert('hello world');", version="0.0.1", display_name="Alert" - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.scripts.register_inline( - site_id="580e63e98c9a982ac9b8b741", source_code="alert('hello world');", version="0.0.1", display_name="Alert" - ) - validate_response(async_response, expected_response, expected_types) diff --git a/tests/test_sites.py b/tests/test_sites.py deleted file mode 100644 index 6e9dd9b..0000000 --- a/tests/test_sites.py +++ /dev/null @@ -1,637 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from webflow import Webflow -from webflow import AsyncWebflow -import typing -from .utilities import validate_response - - -async def test_create(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "670ecf86817e3cc7a510eb6a", - "workspaceId": "625860a7a6c16d624927122f", - "createdOn": "2024-10-15T20:24:38Z", - "displayName": "The Hitchiker‘s Guide", - "shortName": "hitchikers-guide", - "lastPublished": "2016-10-24T19:43:17Z", - "lastUpdated": "2024-10-15T20:24:38Z", - "previewUrl": "https://d1otoma47x30pg.cloudfront.net/580e63e98c9a982ac9b8b741/201610241243.png", - "timeZone": "America/Los_Angeles", - "parentFolderId": "670ece123598db72d9648be1", - "customDomains": [ - {"id": "589a331aa51e760df7ccb89d", "url": "test-api-domain.com", "lastPublished": "2022-12-07T16:51:37Z"} - ], - "locales": { - "primary": { - "id": "653fd9af6a07fc9cfd7a5e57", - "cmsLocaleId": "653ad57de882f528b32e810e", - "enabled": False, - "displayName": "English (United States)", - "displayImageId": "displayImageId", - "redirect": True, - "subdirectory": "", - "tag": "en-US", - }, - "secondary": [ - { - "id": "653fd9af6a07fc9cfd7a5e57", - "cmsLocaleId": "653ad57de882f528b32e810e", - "enabled": False, - "displayName": "English (United States)", - "redirect": True, - "subdirectory": "", - "tag": "en-US", - } - ], - }, - "dataCollectionEnabled": False, - "dataCollectionType": "always", - } - expected_types: typing.Any = { - "id": None, - "workspaceId": None, - "createdOn": "datetime", - "displayName": None, - "shortName": None, - "lastPublished": "datetime", - "lastUpdated": "datetime", - "previewUrl": None, - "timeZone": None, - "parentFolderId": None, - "customDomains": ("list", {0: {"id": None, "url": None, "lastPublished": "datetime"}}), - "locales": { - "primary": { - "id": None, - "cmsLocaleId": None, - "enabled": None, - "displayName": None, - "displayImageId": None, - "redirect": None, - "subdirectory": None, - "tag": None, - }, - "secondary": ( - "list", - { - 0: { - "id": None, - "cmsLocaleId": None, - "enabled": None, - "displayName": None, - "redirect": None, - "subdirectory": None, - "tag": None, - } - }, - ), - }, - "dataCollectionEnabled": None, - "dataCollectionType": None, - } - response = client.sites.create(workspace_id="580e63e98c9a982ac9b8b741", name="The Hitchhiker's Guide to the Galaxy") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.sites.create( - workspace_id="580e63e98c9a982ac9b8b741", name="The Hitchhiker's Guide to the Galaxy" - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_list_(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "sites": [ - { - "id": "42e63e98c9a982ac9b8b741", - "workspaceId": "42e63fc8c9a982ac9b8b744", - "createdOn": "1979-10-12T12:00:00Z", - "displayName": "Heart of Gold Spaceship", - "shortName": "heart-of-gold", - "lastPublished": "2023-04-02T12:42:00Z", - "lastUpdated": "2016-10-24T19:43:17Z", - "previewUrl": "https://d1otoma47x30pg.cloudfront.net/42e63e98c9a982ac9b8b741/197910121200.png", - "timeZone": "DeepSpace/InfiniteImprobability", - "parentFolderId": "1as2d3f4g5h6j7k8l9z0x1c2v3b4n5m6", - "customDomains": [ - { - "id": "589a331aa51e760df7ccb89e", - "url": "heartofgold.galaxy", - "lastPublished": "2022-12-07T16:51:37Z", - } - ], - "locales": { - "primary": { - "id": "653fd9af6a07fc9cfd7a5e57", - "cmsLocaleId": "653ad57de882f528b32e810e", - "enabled": True, - "displayName": "English - Heart of Gold Standard", - "redirect": False, - "subdirectory": "/en", - "tag": "The Ultimate Answer", - }, - "secondary": [ - { - "id": "653fd9af6a07fc9cfd7a5e58", - "cmsLocaleId": "653ad57de882f528b32e810g", - "enabled": True, - "displayName": "Betelgeusian - Vogon Liaison", - "redirect": True, - "subdirectory": "/bet", - "tag": "Vogon", - }, - { - "id": "653fd9af6a07fc9cfd7a5e59", - "cmsLocaleId": "653ad57de882f528b32e810h", - "enabled": False, - "displayName": "Magrathean - Custom Planet Designs", - "redirect": True, - "subdirectory": "/mg", - "tag": "Magrathean", - }, - ], - }, - "dataCollectionEnabled": True, - "dataCollectionType": "always", - }, - { - "id": "42e63e98c9a982ac9b8b742", - "workspaceId": "42e63fc8c9a982ac9b8b745", - "createdOn": "1981-10-12T12:00:00Z", - "displayName": "Marvin's Personal Blog", - "shortName": "paranoid-android", - "lastPublished": "2023-04-02T12:45:00Z", - "lastUpdated": "2016-10-24T19:43:17Z", - "previewUrl": "https://d1otoma47x30pg.cloudfront.net/42e63e98c9a982ac9b8b742/198110121200.png", - "timeZone": "DeepSpace/Depression", - "parentFolderId": "1as2d3f4g5h6j7k8l9z0x1c2v3b4n5m6", - "customDomains": [ - {"id": "589a331aa51e760df7ccb89f", "url": "marvin.blog", "lastPublished": "2022-12-07T16:51:37Z"} - ], - "locales": { - "primary": { - "id": "653fd9af6a07fc9cfd7a5e57", - "cmsLocaleId": "653ad57de882f528b32e810e", - "enabled": True, - "displayName": "English - Marvin's Musings", - "redirect": False, - "subdirectory": "/en", - "tag": "English", - }, - "secondary": [ - { - "id": "653fd9af6a07fc9cfd7a5e56", - "cmsLocaleId": "653ad57de882f528b32e810f", - "enabled": True, - "displayName": "Squornshellous - Mattress Speak", - "redirect": True, - "subdirectory": "/sr", - "tag": "Squornshellous", - } - ], - }, - "dataCollectionEnabled": True, - "dataCollectionType": "always", - }, - { - "id": "42e63e98c9a982ac9b8b743", - "workspaceId": "42e63fc8c9a982ac9b8b746", - "createdOn": "1982-10-12T12:00:00Z", - "displayName": "Vogon Poetry Archive", - "shortName": "vogon-poetry", - "lastPublished": "2023-04-02T12:50:00Z", - "lastUpdated": "2016-10-24T19:43:17Z", - "previewUrl": "https://d1otoma47x30pg.cloudfront.net/42e63e98c9a982ac9b8b743/198210121200.png", - "timeZone": "Vogsphere/PoetryHall", - "parentFolderId": "1as2d3f4g5h6j7k8l9z0x1c2v3b4n5m6", - "customDomains": [ - { - "id": "589a331aa51e760df7ccb8a0", - "url": "vogonpoetry.galaxy", - "lastPublished": "2022-12-07T16:51:37Z", - } - ], - "locales": { - "primary": { - "id": "653fd9af6a07fc9cfd7a5e55", - "cmsLocaleId": "653ad57de882f528b32e810d", - "enabled": True, - "displayName": "English - Vogon Verse", - "redirect": False, - "subdirectory": "/en", - "tag": "Third Worst Poetry", - }, - "secondary": [ - { - "id": "653fd9af6a07fc9cfd7a5e54", - "cmsLocaleId": "653ad57de882f528b32e810c", - "enabled": True, - "displayName": "Galactic - Universal Language", - "redirect": True, - "subdirectory": "/gl", - "tag": "Pan-Galactic Gargle Blaster", - } - ], - }, - "dataCollectionEnabled": True, - "dataCollectionType": "always", - }, - ] - } - expected_types: typing.Any = { - "sites": ( - "list", - { - 0: { - "id": None, - "workspaceId": None, - "createdOn": "datetime", - "displayName": None, - "shortName": None, - "lastPublished": "datetime", - "lastUpdated": "datetime", - "previewUrl": None, - "timeZone": None, - "parentFolderId": None, - "customDomains": ("list", {0: {"id": None, "url": None, "lastPublished": "datetime"}}), - "locales": { - "primary": { - "id": None, - "cmsLocaleId": None, - "enabled": None, - "displayName": None, - "redirect": None, - "subdirectory": None, - "tag": None, - }, - "secondary": ( - "list", - { - 0: { - "id": None, - "cmsLocaleId": None, - "enabled": None, - "displayName": None, - "redirect": None, - "subdirectory": None, - "tag": None, - }, - 1: { - "id": None, - "cmsLocaleId": None, - "enabled": None, - "displayName": None, - "redirect": None, - "subdirectory": None, - "tag": None, - }, - }, - ), - }, - "dataCollectionEnabled": None, - "dataCollectionType": None, - }, - 1: { - "id": None, - "workspaceId": None, - "createdOn": "datetime", - "displayName": None, - "shortName": None, - "lastPublished": "datetime", - "lastUpdated": "datetime", - "previewUrl": None, - "timeZone": None, - "parentFolderId": None, - "customDomains": ("list", {0: {"id": None, "url": None, "lastPublished": "datetime"}}), - "locales": { - "primary": { - "id": None, - "cmsLocaleId": None, - "enabled": None, - "displayName": None, - "redirect": None, - "subdirectory": None, - "tag": None, - }, - "secondary": ( - "list", - { - 0: { - "id": None, - "cmsLocaleId": None, - "enabled": None, - "displayName": None, - "redirect": None, - "subdirectory": None, - "tag": None, - } - }, - ), - }, - "dataCollectionEnabled": None, - "dataCollectionType": None, - }, - 2: { - "id": None, - "workspaceId": None, - "createdOn": "datetime", - "displayName": None, - "shortName": None, - "lastPublished": "datetime", - "lastUpdated": "datetime", - "previewUrl": None, - "timeZone": None, - "parentFolderId": None, - "customDomains": ("list", {0: {"id": None, "url": None, "lastPublished": "datetime"}}), - "locales": { - "primary": { - "id": None, - "cmsLocaleId": None, - "enabled": None, - "displayName": None, - "redirect": None, - "subdirectory": None, - "tag": None, - }, - "secondary": ( - "list", - { - 0: { - "id": None, - "cmsLocaleId": None, - "enabled": None, - "displayName": None, - "redirect": None, - "subdirectory": None, - "tag": None, - } - }, - ), - }, - "dataCollectionEnabled": None, - "dataCollectionType": None, - }, - }, - ) - } - response = client.sites.list() - validate_response(response, expected_response, expected_types) - - async_response = await async_client.sites.list() - validate_response(async_response, expected_response, expected_types) - - -async def test_get(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "42e98c9a982ac9b8b742", - "workspaceId": "42e63e98c9a982ac9b8b742", - "createdOn": "1979-10-12T12:00:00Z", - "displayName": "The Hitchhiker's Guide to the Galaxy", - "shortName": "hitchhikers-guide", - "lastPublished": "2023-04-02T12:42:00Z", - "lastUpdated": "2023-04-02T12:42:00Z", - "previewUrl": "https://screenshots.webflow.com/sites/6258612d1ee792848f805dcf/20231219211811_d5990556c743f33b7071300a03bf67e6.png", - "timeZone": "Magrathea/FactoryFloor", - "parentFolderId": "1as2d3f4g5h6j7k8l9z0x1c2v3b4n5m6", - "customDomains": [ - { - "id": "589a331aa51e760df7ccb89d", - "url": "hitchhikersguide.galaxy", - "lastPublished": "2022-12-07T16:51:37Z", - }, - {"id": "589a331aa51e760df7ccb89e", "url": "heartofgold.spaceship", "lastPublished": "2022-12-07T16:51:37Z"}, - ], - "locales": { - "primary": { - "id": "653fd9af6a07fc9cfd7a5e57", - "cmsLocaleId": "653ad57de882f528b32e810e", - "enabled": False, - "displayName": "English (United States)", - "displayImageId": "displayImageId", - "redirect": True, - "subdirectory": "", - "tag": "en-US", - }, - "secondary": [ - { - "id": "653fd9af6a07fc9cfd7a5e57", - "cmsLocaleId": "653ad57de882f528b32e810e", - "enabled": False, - "displayName": "English (United States)", - "redirect": True, - "subdirectory": "", - "tag": "en-US", - } - ], - }, - "dataCollectionEnabled": True, - "dataCollectionType": "always", - } - expected_types: typing.Any = { - "id": None, - "workspaceId": None, - "createdOn": "datetime", - "displayName": None, - "shortName": None, - "lastPublished": "datetime", - "lastUpdated": "datetime", - "previewUrl": None, - "timeZone": None, - "parentFolderId": None, - "customDomains": ( - "list", - { - 0: {"id": None, "url": None, "lastPublished": "datetime"}, - 1: {"id": None, "url": None, "lastPublished": "datetime"}, - }, - ), - "locales": { - "primary": { - "id": None, - "cmsLocaleId": None, - "enabled": None, - "displayName": None, - "displayImageId": None, - "redirect": None, - "subdirectory": None, - "tag": None, - }, - "secondary": ( - "list", - { - 0: { - "id": None, - "cmsLocaleId": None, - "enabled": None, - "displayName": None, - "redirect": None, - "subdirectory": None, - "tag": None, - } - }, - ), - }, - "dataCollectionEnabled": None, - "dataCollectionType": None, - } - response = client.sites.get(site_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.sites.get(site_id="580e63e98c9a982ac9b8b741") - validate_response(async_response, expected_response, expected_types) - - -async def test_delete(client: Webflow, async_client: AsyncWebflow) -> None: - # Type ignore to avoid mypy complaining about the function not being meant to return a value - assert ( - client.sites.delete(site_id="580e63e98c9a982ac9b8b741") # type: ignore[func-returns-value] - is None - ) - - assert ( - await async_client.sites.delete(site_id="580e63e98c9a982ac9b8b741") # type: ignore[func-returns-value] - is None - ) - - -async def test_update(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "42e98c9a982ac9b8b742", - "workspaceId": "42e63e98c9a982ac9b8b742", - "createdOn": "1979-10-12T12:00:00Z", - "displayName": "The Hitchhiker's Guide to the Galaxy", - "shortName": "hitchhikers-guide", - "lastPublished": "2023-04-02T12:42:00Z", - "lastUpdated": "2023-04-02T12:42:00Z", - "previewUrl": "https://screenshots.webflow.com/sites/6258612d1ee792848f805dcf/20231219211811_d5990556c743f33b7071300a03bf67e6.png", - "timeZone": "Magrathea/FactoryFloor", - "parentFolderId": "1as2d3f4g5h6j7k8l9z0x1c2v3b4n5m6", - "customDomains": [ - { - "id": "589a331aa51e760df7ccb89d", - "url": "hitchhikersguide.galaxy", - "lastPublished": "2022-12-07T16:51:37Z", - }, - {"id": "589a331aa51e760df7ccb89e", "url": "heartofgold.spaceship", "lastPublished": "2022-12-07T16:51:37Z"}, - ], - "locales": { - "primary": { - "id": "653fd9af6a07fc9cfd7a5e57", - "cmsLocaleId": "653ad57de882f528b32e810e", - "enabled": False, - "displayName": "English (United States)", - "displayImageId": "displayImageId", - "redirect": True, - "subdirectory": "", - "tag": "en-US", - }, - "secondary": [ - { - "id": "653fd9af6a07fc9cfd7a5e57", - "cmsLocaleId": "653ad57de882f528b32e810e", - "enabled": False, - "displayName": "English (United States)", - "redirect": True, - "subdirectory": "", - "tag": "en-US", - } - ], - }, - "dataCollectionEnabled": True, - "dataCollectionType": "always", - } - expected_types: typing.Any = { - "id": None, - "workspaceId": None, - "createdOn": "datetime", - "displayName": None, - "shortName": None, - "lastPublished": "datetime", - "lastUpdated": "datetime", - "previewUrl": None, - "timeZone": None, - "parentFolderId": None, - "customDomains": ( - "list", - { - 0: {"id": None, "url": None, "lastPublished": "datetime"}, - 1: {"id": None, "url": None, "lastPublished": "datetime"}, - }, - ), - "locales": { - "primary": { - "id": None, - "cmsLocaleId": None, - "enabled": None, - "displayName": None, - "displayImageId": None, - "redirect": None, - "subdirectory": None, - "tag": None, - }, - "secondary": ( - "list", - { - 0: { - "id": None, - "cmsLocaleId": None, - "enabled": None, - "displayName": None, - "redirect": None, - "subdirectory": None, - "tag": None, - } - }, - ), - }, - "dataCollectionEnabled": None, - "dataCollectionType": None, - } - response = client.sites.update(site_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.sites.update(site_id="580e63e98c9a982ac9b8b741") - validate_response(async_response, expected_response, expected_types) - - -async def test_get_custom_domain(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "customDomains": [ - { - "id": "589a331aa51e760df7ccb89d", - "url": "hitchhikersguide.galaxy", - "lastPublished": "2022-12-07T16:51:37Z", - }, - {"id": "589a331aa51e760df7ccb89e", "url": "heartofgold.spaceship", "lastPublished": "2022-12-07T16:51:37Z"}, - ] - } - expected_types: typing.Any = { - "customDomains": ( - "list", - { - 0: {"id": None, "url": None, "lastPublished": "datetime"}, - 1: {"id": None, "url": None, "lastPublished": "datetime"}, - }, - ) - } - response = client.sites.get_custom_domain(site_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.sites.get_custom_domain(site_id="580e63e98c9a982ac9b8b741") - validate_response(async_response, expected_response, expected_types) - - -async def test_publish(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "customDomains": [ - {"id": "589a331aa51e760df7ccb89d", "url": "test-api-domain.com", "lastPublished": "2022-12-07T16:51:37Z"} - ], - "publishToWebflowSubdomain": True, - } - expected_types: typing.Any = { - "customDomains": ("list", {0: {"id": None, "url": None, "lastPublished": "datetime"}}), - "publishToWebflowSubdomain": None, - } - response = client.sites.publish(site_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.sites.publish(site_id="580e63e98c9a982ac9b8b741") - validate_response(async_response, expected_response, expected_types) diff --git a/tests/test_token.py b/tests/test_token.py deleted file mode 100644 index d57ee3b..0000000 --- a/tests/test_token.py +++ /dev/null @@ -1,66 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from webflow import Webflow -from webflow import AsyncWebflow -import typing -from .utilities import validate_response - - -async def test_authorized_by(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "545bbecb7bdd6769632504a7", - "email": "some@email.com", - "firstName": "Some", - "lastName": "One", - } - expected_types: typing.Any = {"id": None, "email": None, "firstName": None, "lastName": None} - response = client.token.authorized_by() - validate_response(response, expected_response, expected_types) - - async_response = await async_client.token.authorized_by() - validate_response(async_response, expected_response, expected_types) - - -async def test_introspect(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "authorization": { - "id": "55818d58616600637b9a5786", - "createdOn": "2016-10-03T23:12:00Z", - "lastUsed": "2016-10-10T21:41:12Z", - "grantType": "authorization_code", - "rateLimit": 60, - "scope": "assets:read,assets:write", - "authorizedTo": { - "siteIds": ["62f3b1f7eafac55d0c64ef91"], - "workspaceIds": ["52f3b1f7eafac55d0c64ef91"], - "userIds": ["545bbecb7bdd6769632504a7"], - }, - }, - "application": { - "id": "55131cd036c09f7d07883dfc", - "description": "My Amazing App", - "homepage": "https://webflow.com", - "displayName": "My Amazing App", - }, - } - expected_types: typing.Any = { - "authorization": { - "id": None, - "createdOn": "datetime", - "lastUsed": "datetime", - "grantType": None, - "rateLimit": "integer", - "scope": None, - "authorizedTo": { - "siteIds": ("list", {0: None}), - "workspaceIds": ("list", {0: None}), - "userIds": ("list", {0: None}), - }, - }, - "application": None, - } - response = client.token.introspect() - validate_response(response, expected_response, expected_types) - - async_response = await async_client.token.introspect() - validate_response(async_response, expected_response, expected_types) diff --git a/tests/test_users.py b/tests/test_users.py deleted file mode 100644 index abcbfd6..0000000 --- a/tests/test_users.py +++ /dev/null @@ -1,301 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from webflow import Webflow -from webflow import AsyncWebflow -import typing -from .utilities import validate_response -from webflow.resources.users import UsersUpdateRequestData - - -async def test_list_(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "count": 5, - "limit": 5, - "offset": 0, - "total": 201, - "users": [ - { - "id": "6287ec36a841b25637c663df", - "isEmailVerified": False, - "lastUpdated": "2022-05-20T13:46:12Z", - "invitedOn": "2016-10-24T19:41:29Z", - "createdOn": "2022-05-20T13:46:12Z", - "lastLogin": "2016-10-24T19:41:29Z", - "status": "unverified", - "accessGroups": [{"slug": "vogon-construction-crew", "type": "admin"}], - }, - { - "id": "6287ec36a841b25637c663f0", - "isEmailVerified": False, - "lastUpdated": "2022-05-19T05:32:04Z", - "invitedOn": "2016-10-24T19:41:29Z", - "createdOn": "2022-05-19T05:32:04Z", - "lastLogin": "2016-10-24T19:41:29Z", - "status": "unverified", - "accessGroups": [{"slug": "improbability-drive-test-subjects", "type": "admin"}], - }, - { - "id": "6287ec36a841b25637c663d9", - "isEmailVerified": True, - "lastUpdated": "2022-05-17T03:34:06Z", - "invitedOn": "2016-10-24T19:41:29Z", - "createdOn": "2022-05-17T03:34:06Z", - "lastLogin": "2016-10-24T19:41:29Z", - "status": "verified", - "accessGroups": [{"slug": "heart-of-gold-crew", "type": "admin"}], - }, - { - "id": "6287ec37a841b25637c6641b", - "isEmailVerified": False, - "lastUpdated": "2022-05-15T03:46:09Z", - "invitedOn": "2016-10-24T19:41:29Z", - "createdOn": "2022-05-15T03:46:09Z", - "lastLogin": "2016-10-24T19:41:29Z", - "status": "unverified", - "accessGroups": [{"slug": "hitchhikers-guide-research-team", "type": "admin"}], - }, - { - "id": "6287ec37a841b25637c66449", - "isEmailVerified": True, - "lastUpdated": "2022-05-15T02:55:38Z", - "invitedOn": "2016-10-24T19:41:29Z", - "createdOn": "2022-05-15T02:55:38Z", - "lastLogin": "2016-10-24T19:41:29Z", - "status": "verified", - "accessGroups": [{"slug": "milliways-reservationists", "type": "admin"}], - }, - ], - } - expected_types: typing.Any = { - "count": None, - "limit": None, - "offset": None, - "total": None, - "users": ( - "list", - { - 0: { - "id": None, - "isEmailVerified": None, - "lastUpdated": "datetime", - "invitedOn": "datetime", - "createdOn": "datetime", - "lastLogin": "datetime", - "status": None, - "accessGroups": ("list", {0: {"slug": None, "type": None}}), - }, - 1: { - "id": None, - "isEmailVerified": None, - "lastUpdated": "datetime", - "invitedOn": "datetime", - "createdOn": "datetime", - "lastLogin": "datetime", - "status": None, - "accessGroups": ("list", {0: {"slug": None, "type": None}}), - }, - 2: { - "id": None, - "isEmailVerified": None, - "lastUpdated": "datetime", - "invitedOn": "datetime", - "createdOn": "datetime", - "lastLogin": "datetime", - "status": None, - "accessGroups": ("list", {0: {"slug": None, "type": None}}), - }, - 3: { - "id": None, - "isEmailVerified": None, - "lastUpdated": "datetime", - "invitedOn": "datetime", - "createdOn": "datetime", - "lastLogin": "datetime", - "status": None, - "accessGroups": ("list", {0: {"slug": None, "type": None}}), - }, - 4: { - "id": None, - "isEmailVerified": None, - "lastUpdated": "datetime", - "invitedOn": "datetime", - "createdOn": "datetime", - "lastLogin": "datetime", - "status": None, - "accessGroups": ("list", {0: {"slug": None, "type": None}}), - }, - }, - ), - } - response = client.users.list(site_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.users.list(site_id="580e63e98c9a982ac9b8b741") - validate_response(async_response, expected_response, expected_types) - - -async def test_get(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "6287ec36a841b25637c663df", - "isEmailVerified": True, - "lastUpdated": "2022-05-20T13:46:12Z", - "invitedOn": "2022-05-20T13:46:12Z", - "createdOn": "2022-05-20T13:46:12Z", - "lastLogin": "2022-05-20T13:46:12Z", - "status": "verified", - "accessGroups": [{"slug": "webflowers", "type": "admin"}], - "data": { - "data": { - "name": "name", - "email": "email", - "accept-privacy": True, - "accept-communications": True, - "additionalProperties": "additionalProperties", - } - }, - } - expected_types: typing.Any = { - "id": None, - "isEmailVerified": None, - "lastUpdated": "datetime", - "invitedOn": "datetime", - "createdOn": "datetime", - "lastLogin": "datetime", - "status": None, - "accessGroups": ("list", {0: {"slug": None, "type": None}}), - "data": { - "data": { - "name": None, - "email": None, - "accept-privacy": None, - "accept-communications": None, - "additionalProperties": None, - } - }, - } - response = client.users.get(site_id="580e63e98c9a982ac9b8b741", user_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.users.get( - site_id="580e63e98c9a982ac9b8b741", user_id="580e63e98c9a982ac9b8b741" - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_delete(client: Webflow, async_client: AsyncWebflow) -> None: - # Type ignore to avoid mypy complaining about the function not being meant to return a value - assert ( - client.users.delete(site_id="580e63e98c9a982ac9b8b741", user_id="580e63e98c9a982ac9b8b741") # type: ignore[func-returns-value] - is None - ) - - assert ( - await async_client.users.delete(site_id="580e63e98c9a982ac9b8b741", user_id="580e63e98c9a982ac9b8b741") # type: ignore[func-returns-value] - is None - ) - - -async def test_update(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "6287ec36a841b25637c663df", - "isEmailVerified": True, - "lastUpdated": "2022-05-20T13:46:12Z", - "invitedOn": "2022-05-20T13:46:12Z", - "createdOn": "2022-05-20T13:46:12Z", - "lastLogin": "2022-05-20T13:46:12Z", - "status": "verified", - "accessGroups": [{"slug": "webflowers", "type": "admin"}], - "data": { - "data": { - "name": "name", - "email": "email", - "accept-privacy": True, - "accept-communications": True, - "additionalProperties": "additionalProperties", - } - }, - } - expected_types: typing.Any = { - "id": None, - "isEmailVerified": None, - "lastUpdated": "datetime", - "invitedOn": "datetime", - "createdOn": "datetime", - "lastLogin": "datetime", - "status": None, - "accessGroups": ("list", {0: {"slug": None, "type": None}}), - "data": { - "data": { - "name": None, - "email": None, - "accept-privacy": None, - "accept-communications": None, - "additionalProperties": None, - } - }, - } - response = client.users.update( - site_id="580e63e98c9a982ac9b8b741", - user_id="580e63e98c9a982ac9b8b741", - data=UsersUpdateRequestData(name="Some One", accept_privacy=False, accept_communications=False), - access_groups=["webflowers", "platinum", "free-tier"], - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.users.update( - site_id="580e63e98c9a982ac9b8b741", - user_id="580e63e98c9a982ac9b8b741", - data=UsersUpdateRequestData(name="Some One", accept_privacy=False, accept_communications=False), - access_groups=["webflowers", "platinum", "free-tier"], - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_invite(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "6287ec36a841b25637c663df", - "isEmailVerified": True, - "lastUpdated": "2022-05-20T13:46:12Z", - "invitedOn": "2022-05-20T13:46:12Z", - "createdOn": "2022-05-20T13:46:12Z", - "lastLogin": "2022-05-20T13:46:12Z", - "status": "verified", - "accessGroups": [{"slug": "webflowers", "type": "admin"}], - "data": { - "data": { - "name": "name", - "email": "email", - "accept-privacy": True, - "accept-communications": True, - "additionalProperties": "additionalProperties", - } - }, - } - expected_types: typing.Any = { - "id": None, - "isEmailVerified": None, - "lastUpdated": "datetime", - "invitedOn": "datetime", - "createdOn": "datetime", - "lastLogin": "datetime", - "status": None, - "accessGroups": ("list", {0: {"slug": None, "type": None}}), - "data": { - "data": { - "name": None, - "email": None, - "accept-privacy": None, - "accept-communications": None, - "additionalProperties": None, - } - }, - } - response = client.users.invite( - site_id="580e63e98c9a982ac9b8b741", email="some.one@home.com", access_groups=["webflowers"] - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.users.invite( - site_id="580e63e98c9a982ac9b8b741", email="some.one@home.com", access_groups=["webflowers"] - ) - validate_response(async_response, expected_response, expected_types) diff --git a/tests/test_webhooks.py b/tests/test_webhooks.py deleted file mode 100644 index 4c19188..0000000 --- a/tests/test_webhooks.py +++ /dev/null @@ -1,175 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from webflow import Webflow -from webflow import AsyncWebflow -import typing -from .utilities import validate_response -import datetime - - -async def test_list_(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "pagination": {"limit": 100, "offset": 0, "total": 100}, - "webhooks": [ - { - "id": "57ca0a9e418c504a6e1acbb6", - "triggerType": "form_submission", - "url": "https://webhook.site/7f7f7f7f-7f7f-7f7f-7f7f-7f7f7f7f7f7f", - "workspaceId": "4f4e46fd476ea8c507000001", - "siteId": "562ac0395358780a1f5e6fbd", - "filter": {"name": "Email Form"}, - "lastTriggered": "2023-02-08T23:59:28Z", - "createdOn": "2016-09-02T23:26:22Z", - }, - { - "id": "578d85cce0c47cd2865f4cf2", - "triggerType": "form_submission", - "url": "https://webhook.site/7f7f7f7f-7f7f-7f7f-7f7f-7f7f7f7f7f7f", - "workspaceId": "4f4e46fd476ea8c507000001", - "siteId": "562ac0395358780a1f5e6fbd", - "filter": {"name": "Email Form"}, - "lastTriggered": "2023-02-08T23:59:28Z", - "createdOn": "2016-07-19T01:43:40Z", - }, - { - "id": "578d85cce0c47cd2865f4cf3", - "triggerType": "form_submission", - "url": "https://webhook.site/7f7f7f7f-7f7f-7f7f-7f7f-7f7f7f7f7f7f", - "workspaceId": "4f4e46fd476ea8c507000001", - "siteId": "562ac0395358780a1f5e6fbd", - "filter": {"name": "Email Form"}, - "lastTriggered": "2023-02-08T23:59:28Z", - "createdOn": "2016-07-19T01:43:40Z", - }, - ], - } - expected_types: typing.Any = { - "pagination": {"limit": None, "offset": None, "total": None}, - "webhooks": ( - "list", - { - 0: { - "id": None, - "triggerType": None, - "url": None, - "workspaceId": None, - "siteId": None, - "filter": {"name": None}, - "lastTriggered": "datetime", - "createdOn": "datetime", - }, - 1: { - "id": None, - "triggerType": None, - "url": None, - "workspaceId": None, - "siteId": None, - "filter": {"name": None}, - "lastTriggered": "datetime", - "createdOn": "datetime", - }, - 2: { - "id": None, - "triggerType": None, - "url": None, - "workspaceId": None, - "siteId": None, - "filter": {"name": None}, - "lastTriggered": "datetime", - "createdOn": "datetime", - }, - }, - ), - } - response = client.webhooks.list(site_id="580e63e98c9a982ac9b8b741") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.webhooks.list(site_id="580e63e98c9a982ac9b8b741") - validate_response(async_response, expected_response, expected_types) - - -async def test_create(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "582266e0cd48de0f0e3c6d8b", - "triggerType": "form_submission", - "url": "https://webhook.site/7f7f7f7f-7f7f-7f7f-7f7f-7f7f7f7f7f7f", - "workspaceId": "4f4e46fd476ea8c507000001", - "siteId": "562ac0395358780a1f5e6fbd", - "filter": {"name": "My Form"}, - "lastTriggered": "2023-02-08T23:59:28Z", - "createdOn": "2022-11-08T23:59:28Z", - } - expected_types: typing.Any = { - "id": None, - "triggerType": None, - "url": None, - "workspaceId": None, - "siteId": None, - "filter": {"name": None}, - "lastTriggered": "datetime", - "createdOn": "datetime", - } - response = client.webhooks.create( - site_id_="580e63e98c9a982ac9b8b741", - id="582266e0cd48de0f0e3c6d8b", - trigger_type="form_submission", - url="https://webhook.site/7f7f7f7f-7f7f-7f7f-7f7f-7f7f7f7f7f7f", - workspace_id="4f4e46fd476ea8c507000001", - site_id="562ac0395358780a1f5e6fbd", - last_triggered=datetime.datetime.fromisoformat("2023-02-08 23:59:28+00:00"), - created_on=datetime.datetime.fromisoformat("2022-11-08 23:59:28+00:00"), - ) - validate_response(response, expected_response, expected_types) - - async_response = await async_client.webhooks.create( - site_id_="580e63e98c9a982ac9b8b741", - id="582266e0cd48de0f0e3c6d8b", - trigger_type="form_submission", - url="https://webhook.site/7f7f7f7f-7f7f-7f7f-7f7f-7f7f7f7f7f7f", - workspace_id="4f4e46fd476ea8c507000001", - site_id="562ac0395358780a1f5e6fbd", - last_triggered=datetime.datetime.fromisoformat("2023-02-08 23:59:28+00:00"), - created_on=datetime.datetime.fromisoformat("2022-11-08 23:59:28+00:00"), - ) - validate_response(async_response, expected_response, expected_types) - - -async def test_get(client: Webflow, async_client: AsyncWebflow) -> None: - expected_response: typing.Any = { - "id": "582266e0cd48de0f0e3c6d8b", - "triggerType": "form_submission", - "url": "https://webhook.site/7f7f7f7f-7f7f-7f7f-7f7f-7f7f7f7f7f7f", - "workspaceId": "4f4e46fd476ea8c507000001", - "siteId": "562ac0395358780a1f5e6fbd", - "filter": {"name": "My Form"}, - "lastTriggered": "2023-02-08T23:59:28Z", - "createdOn": "2022-11-08T23:59:28Z", - } - expected_types: typing.Any = { - "id": None, - "triggerType": None, - "url": None, - "workspaceId": None, - "siteId": None, - "filter": {"name": None}, - "lastTriggered": "datetime", - "createdOn": "datetime", - } - response = client.webhooks.get(webhook_id="580e64008c9a982ac9b8b754") - validate_response(response, expected_response, expected_types) - - async_response = await async_client.webhooks.get(webhook_id="580e64008c9a982ac9b8b754") - validate_response(async_response, expected_response, expected_types) - - -async def test_delete(client: Webflow, async_client: AsyncWebflow) -> None: - # Type ignore to avoid mypy complaining about the function not being meant to return a value - assert ( - client.webhooks.delete(webhook_id="580e64008c9a982ac9b8b754") # type: ignore[func-returns-value] - is None - ) - - assert ( - await async_client.webhooks.delete(webhook_id="580e64008c9a982ac9b8b754") # type: ignore[func-returns-value] - is None - ) diff --git a/tests/utilities.py b/tests/utilities.py deleted file mode 100644 index 3d22880..0000000 --- a/tests/utilities.py +++ /dev/null @@ -1,162 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing -import uuid - -from dateutil import parser - -import pydantic - - -def cast_field(json_expectation: typing.Any, type_expectation: typing.Any) -> typing.Any: - # Cast these specific types which come through as string and expect our - # models to cast to the correct type. - if type_expectation == "uuid": - return uuid.UUID(json_expectation) - elif type_expectation == "date": - return parser.parse(json_expectation).date() - elif type_expectation == "datetime": - return parser.parse(json_expectation) - elif type_expectation == "set": - return set(json_expectation) - elif type_expectation == "integer": - # Necessary as we allow numeric keys, but JSON makes them strings - return int(json_expectation) - - return json_expectation - - -def validate_field(response: typing.Any, json_expectation: typing.Any, type_expectation: typing.Any) -> None: - # Allow for an escape hatch if the object cannot be validated - if type_expectation == "no_validate": - return - - is_container_of_complex_type = False - # Parse types in containers, note that dicts are handled within `validate_response` - if isinstance(json_expectation, list): - if isinstance(type_expectation, tuple): - container_expectation = type_expectation[0] - contents_expectation = type_expectation[1] - - cast_json_expectation = [] - for idx, ex in enumerate(json_expectation): - if isinstance(contents_expectation, dict): - entry_expectation = contents_expectation.get(idx) - if isinstance(entry_expectation, dict): - is_container_of_complex_type = True - validate_response( - response=response[idx], - json_expectation=ex, - type_expectations=entry_expectation, - ) - else: - cast_json_expectation.append(cast_field(ex, entry_expectation)) - else: - cast_json_expectation.append(ex) - json_expectation = cast_json_expectation - - # Note that we explicitly do not allow for sets of pydantic models as they are not hashable, so - # if any of the values of the set have a type_expectation of a dict, we're assuming it's a pydantic - # model and keeping it a list. - if container_expectation != "set" or not any( - map( - lambda value: isinstance(value, dict), - list(contents_expectation.values()), - ) - ): - json_expectation = cast_field(json_expectation, container_expectation) - elif isinstance(type_expectation, tuple): - container_expectation = type_expectation[0] - contents_expectation = type_expectation[1] - if isinstance(contents_expectation, dict): - json_expectation = { - cast_field( - key, - contents_expectation.get(idx)[0] # type: ignore - if contents_expectation.get(idx) is not None - else None, - ): cast_field( - value, - contents_expectation.get(idx)[1] # type: ignore - if contents_expectation.get(idx) is not None - else None, - ) - for idx, (key, value) in enumerate(json_expectation.items()) - } - else: - json_expectation = cast_field(json_expectation, container_expectation) - elif type_expectation is not None: - json_expectation = cast_field(json_expectation, type_expectation) - - # When dealing with containers of models, etc. we're validating them implicitly, so no need to check the resultant list - if not is_container_of_complex_type: - assert ( - json_expectation == response - ), "Primitives found, expected: {0} (type: {1}), Actual: {2} (type: {3})".format( - json_expectation, type(json_expectation), response, type(response) - ) - - -# Arg type_expectations is a deeply nested structure that matches the response, but with the values replaced with the expected types -def validate_response(response: typing.Any, json_expectation: typing.Any, type_expectations: typing.Any) -> None: - # Allow for an escape hatch if the object cannot be validated - if type_expectations == "no_validate": - return - - if ( - not isinstance(response, list) - and not isinstance(response, dict) - and not issubclass(type(response), pydantic.BaseModel) - ): - validate_field( - response=response, - json_expectation=json_expectation, - type_expectation=type_expectations, - ) - return - - if isinstance(response, list): - assert len(response) == len(json_expectation), "Length mismatch, expected: {0}, Actual: {1}".format( - len(response), len(json_expectation) - ) - content_expectation = type_expectations - if isinstance(type_expectations, tuple): - content_expectation = type_expectations[1] - for idx, item in enumerate(response): - validate_response( - response=item, - json_expectation=json_expectation[idx], - type_expectations=content_expectation[idx], - ) - else: - response_json = response - if issubclass(type(response), pydantic.BaseModel): - response_json = response.dict(by_alias=True) - - for key, value in json_expectation.items(): - assert key in response_json, "Field {0} not found within the response object: {1}".format( - key, response_json - ) - - type_expectation = None - if type_expectations is not None and isinstance(type_expectations, dict): - type_expectation = type_expectations.get(key) - - # If your type_expectation is a tuple then you have a container field, process it as such - # Otherwise, we're just validating a single field that's a pydantic model. - if isinstance(value, dict) and not isinstance(type_expectation, tuple): - validate_response( - response=response_json[key], - json_expectation=value, - type_expectations=type_expectation, - ) - else: - validate_field( - response=response_json[key], - json_expectation=value, - type_expectation=type_expectation, - ) - - # Ensure there are no additional fields here either - del response_json[key] - assert len(response_json) == 0, "Additional fields found, expected None: {0}".format(response_json)