stackos-connectors 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- stackos_connectors/__init__.py +99 -0
- stackos_connectors/catalog/index.json +54 -0
- stackos_connectors/catalog/schema.json +80 -0
- stackos_connectors/catalog.py +160 -0
- stackos_connectors/connectors/__init__.py +1 -0
- stackos_connectors/connectors/ahrefs/__init__.py +1 -0
- stackos_connectors/connectors/ahrefs/actions.py +107 -0
- stackos_connectors/connectors/ahrefs/assets/icon.png +0 -0
- stackos_connectors/connectors/ahrefs/catalog.json +186 -0
- stackos_connectors/connectors/ahrefs/integration.py +184 -0
- stackos_connectors/connectors/aignc/__init__.py +1 -0
- stackos_connectors/connectors/aignc/actions.py +82 -0
- stackos_connectors/connectors/aignc/catalog.json +662 -0
- stackos_connectors/connectors/aignc/contract.py +31 -0
- stackos_connectors/connectors/aignc/docs/aignc.md +33 -0
- stackos_connectors/connectors/aignc/integration.py +572 -0
- stackos_connectors/connectors/alibaba_wan/__init__.py +1 -0
- stackos_connectors/connectors/alibaba_wan/actions.py +85 -0
- stackos_connectors/connectors/alibaba_wan/assets/icon.png +0 -0
- stackos_connectors/connectors/alibaba_wan/catalog.json +221 -0
- stackos_connectors/connectors/alibaba_wan/integration.py +392 -0
- stackos_connectors/connectors/apollo/__init__.py +1 -0
- stackos_connectors/connectors/apollo/actions.py +213 -0
- stackos_connectors/connectors/apollo/assets/icon.png +0 -0
- stackos_connectors/connectors/apollo/catalog.json +313 -0
- stackos_connectors/connectors/apollo/docs/protocol.md +19 -0
- stackos_connectors/connectors/aws_s3/__init__.py +1 -0
- stackos_connectors/connectors/aws_s3/actions.py +3082 -0
- stackos_connectors/connectors/aws_s3/assets/icon.png +0 -0
- stackos_connectors/connectors/aws_s3/catalog.json +1048 -0
- stackos_connectors/connectors/aws_s3/contract.py +89 -0
- stackos_connectors/connectors/aws_s3/docs/s3.md +49 -0
- stackos_connectors/connectors/aws_s3/integration.py +369 -0
- stackos_connectors/connectors/byteplus_seedance/__init__.py +1 -0
- stackos_connectors/connectors/byteplus_seedance/actions.py +85 -0
- stackos_connectors/connectors/byteplus_seedance/catalog.json +246 -0
- stackos_connectors/connectors/byteplus_seedream/__init__.py +1 -0
- stackos_connectors/connectors/byteplus_seedream/actions.py +88 -0
- stackos_connectors/connectors/byteplus_seedream/catalog.json +292 -0
- stackos_connectors/connectors/clay/__init__.py +1 -0
- stackos_connectors/connectors/clay/actions.py +100 -0
- stackos_connectors/connectors/clay/assets/icon.png +0 -0
- stackos_connectors/connectors/clay/catalog.json +139 -0
- stackos_connectors/connectors/clay/docs/protocol.md +16 -0
- stackos_connectors/connectors/cloudflare/__init__.py +1 -0
- stackos_connectors/connectors/cloudflare/actions.py +705 -0
- stackos_connectors/connectors/cloudflare/assets/icon.png +0 -0
- stackos_connectors/connectors/cloudflare/catalog.json +6381 -0
- stackos_connectors/connectors/cloudflare/docs/cloudflare-dns.md +37 -0
- stackos_connectors/connectors/cloudflare/integration.py +397 -0
- stackos_connectors/connectors/dataforseo/__init__.py +1 -0
- stackos_connectors/connectors/dataforseo/actions.py +147 -0
- stackos_connectors/connectors/dataforseo/assets/icon.jpeg +0 -0
- stackos_connectors/connectors/dataforseo/catalog.json +1275 -0
- stackos_connectors/connectors/dataforseo/integration.py +252 -0
- stackos_connectors/connectors/firecrawl/__init__.py +1 -0
- stackos_connectors/connectors/firecrawl/actions.py +100 -0
- stackos_connectors/connectors/firecrawl/assets/icon.png +0 -0
- stackos_connectors/connectors/firecrawl/catalog.json +189 -0
- stackos_connectors/connectors/firecrawl/integration.py +168 -0
- stackos_connectors/connectors/ftp/__init__.py +1 -0
- stackos_connectors/connectors/ftp/actions.py +1190 -0
- stackos_connectors/connectors/ftp/assets/icon.svg +7 -0
- stackos_connectors/connectors/ftp/catalog.json +1091 -0
- stackos_connectors/connectors/ftp/docs/ftp.md +40 -0
- stackos_connectors/connectors/ftp/integration.py +271 -0
- stackos_connectors/connectors/ftp/remote_tree.py +342 -0
- stackos_connectors/connectors/ghost/__init__.py +1 -0
- stackos_connectors/connectors/ghost/actions.py +80 -0
- stackos_connectors/connectors/ghost/assets/icon.png +0 -0
- stackos_connectors/connectors/ghost/catalog.json +214 -0
- stackos_connectors/connectors/ghost/integration.py +159 -0
- stackos_connectors/connectors/google_ads/__init__.py +1 -0
- stackos_connectors/connectors/google_ads/actions.py +279 -0
- stackos_connectors/connectors/google_ads/assets/icon.png +0 -0
- stackos_connectors/connectors/google_ads/catalog.json +797 -0
- stackos_connectors/connectors/google_ads/docs/protocol.md +22 -0
- stackos_connectors/connectors/google_analytics/__init__.py +1 -0
- stackos_connectors/connectors/google_analytics/actions.py +224 -0
- stackos_connectors/connectors/google_analytics/assets/icon.png +0 -0
- stackos_connectors/connectors/google_analytics/catalog.json +442 -0
- stackos_connectors/connectors/google_analytics/integration.py +112 -0
- stackos_connectors/connectors/google_gemini_image/__init__.py +1 -0
- stackos_connectors/connectors/google_gemini_image/actions.py +90 -0
- stackos_connectors/connectors/google_gemini_image/assets/icon.webp +0 -0
- stackos_connectors/connectors/google_gemini_image/catalog.json +275 -0
- stackos_connectors/connectors/google_gemini_image/integration.py +420 -0
- stackos_connectors/connectors/google_indexing/__init__.py +1 -0
- stackos_connectors/connectors/google_indexing/actions.py +148 -0
- stackos_connectors/connectors/google_indexing/catalog.json +224 -0
- stackos_connectors/connectors/google_indexing/docs/google-indexing.md +38 -0
- stackos_connectors/connectors/google_indexing/integration.py +261 -0
- stackos_connectors/connectors/google_search_console/__init__.py +1 -0
- stackos_connectors/connectors/google_search_console/actions.py +486 -0
- stackos_connectors/connectors/google_search_console/assets/icon.png +0 -0
- stackos_connectors/connectors/google_search_console/catalog.json +714 -0
- stackos_connectors/connectors/google_search_console/docs/google-search-console.md +37 -0
- stackos_connectors/connectors/google_search_console/integration.py +367 -0
- stackos_connectors/connectors/google_tag_manager/__init__.py +1 -0
- stackos_connectors/connectors/google_tag_manager/actions.py +241 -0
- stackos_connectors/connectors/google_tag_manager/assets/icon.png +0 -0
- stackos_connectors/connectors/google_tag_manager/catalog.json +477 -0
- stackos_connectors/connectors/google_tag_manager/integration.py +133 -0
- stackos_connectors/connectors/google_veo/__init__.py +1 -0
- stackos_connectors/connectors/google_veo/actions.py +85 -0
- stackos_connectors/connectors/google_veo/assets/icon.png +0 -0
- stackos_connectors/connectors/google_veo/catalog.json +211 -0
- stackos_connectors/connectors/google_veo/integration.py +337 -0
- stackos_connectors/connectors/google_workspace/__init__.py +1 -0
- stackos_connectors/connectors/google_workspace/actions.py +148 -0
- stackos_connectors/connectors/google_workspace/assets/icon.png +0 -0
- stackos_connectors/connectors/google_workspace/catalog.json +302 -0
- stackos_connectors/connectors/google_workspace/docs/protocol.md +19 -0
- stackos_connectors/connectors/http/__init__.py +1 -0
- stackos_connectors/connectors/http/actions.py +280 -0
- stackos_connectors/connectors/http/catalog.json +100 -0
- stackos_connectors/connectors/hubspot/__init__.py +1 -0
- stackos_connectors/connectors/hubspot/actions.py +144 -0
- stackos_connectors/connectors/hubspot/assets/icon.png +0 -0
- stackos_connectors/connectors/hubspot/catalog.json +4959 -0
- stackos_connectors/connectors/hubspot/contract.py +534 -0
- stackos_connectors/connectors/hubspot/docs/hubspot.md +41 -0
- stackos_connectors/connectors/hubspot/integration.py +209 -0
- stackos_connectors/connectors/ideogram/__init__.py +1 -0
- stackos_connectors/connectors/ideogram/actions.py +88 -0
- stackos_connectors/connectors/ideogram/assets/icon.png +0 -0
- stackos_connectors/connectors/ideogram/catalog.json +282 -0
- stackos_connectors/connectors/ideogram/integration.py +310 -0
- stackos_connectors/connectors/imap/__init__.py +1 -0
- stackos_connectors/connectors/imap/actions.py +1186 -0
- stackos_connectors/connectors/imap/assets/icon.svg +7 -0
- stackos_connectors/connectors/imap/catalog.json +520 -0
- stackos_connectors/connectors/imap/docs/protocol.md +19 -0
- stackos_connectors/connectors/imap/integration.py +300 -0
- stackos_connectors/connectors/jina/__init__.py +1 -0
- stackos_connectors/connectors/jina/actions.py +57 -0
- stackos_connectors/connectors/jina/assets/icon.png +0 -0
- stackos_connectors/connectors/jina/catalog.json +102 -0
- stackos_connectors/connectors/jina/integration.py +63 -0
- stackos_connectors/connectors/kling_video/__init__.py +1 -0
- stackos_connectors/connectors/kling_video/actions.py +86 -0
- stackos_connectors/connectors/kling_video/assets/icon.png +0 -0
- stackos_connectors/connectors/kling_video/catalog.json +232 -0
- stackos_connectors/connectors/kling_video/integration.py +413 -0
- stackos_connectors/connectors/linear/__init__.py +1 -0
- stackos_connectors/connectors/linear/actions.py +103 -0
- stackos_connectors/connectors/linear/assets/graphql/auth/viewer-organization.graphql +10 -0
- stackos_connectors/connectors/linear/assets/graphql/comments/create.graphql +25 -0
- stackos_connectors/connectors/linear/assets/graphql/comments/delete.graphql +6 -0
- stackos_connectors/connectors/linear/assets/graphql/comments/get.graphql +25 -0
- stackos_connectors/connectors/linear/assets/graphql/comments/list.graphql +45 -0
- stackos_connectors/connectors/linear/assets/graphql/comments/resolve.graphql +11 -0
- stackos_connectors/connectors/linear/assets/graphql/comments/unresolve.graphql +11 -0
- stackos_connectors/connectors/linear/assets/graphql/comments/update.graphql +14 -0
- stackos_connectors/connectors/linear/assets/graphql/cycles/get.graphql +17 -0
- stackos_connectors/connectors/linear/assets/graphql/cycles/list.graphql +37 -0
- stackos_connectors/connectors/linear/assets/graphql/issue-labels/get.graphql +15 -0
- stackos_connectors/connectors/linear/assets/graphql/issue-labels/list.graphql +35 -0
- stackos_connectors/connectors/linear/assets/graphql/issue-relations/create.graphql +21 -0
- stackos_connectors/connectors/linear/assets/graphql/issue-relations/delete.graphql +6 -0
- stackos_connectors/connectors/linear/assets/graphql/issue-relations/get.graphql +19 -0
- stackos_connectors/connectors/linear/assets/graphql/issue-relations/list.graphql +42 -0
- stackos_connectors/connectors/linear/assets/graphql/issue-relations/update.graphql +21 -0
- stackos_connectors/connectors/linear/assets/graphql/issues/add-label.graphql +17 -0
- stackos_connectors/connectors/linear/assets/graphql/issues/archive.graphql +11 -0
- stackos_connectors/connectors/linear/assets/graphql/issues/create.graphql +27 -0
- stackos_connectors/connectors/linear/assets/graphql/issues/get.graphql +51 -0
- stackos_connectors/connectors/linear/assets/graphql/issues/list.graphql +71 -0
- stackos_connectors/connectors/linear/assets/graphql/issues/remove-label.graphql +17 -0
- stackos_connectors/connectors/linear/assets/graphql/issues/search.graphql +62 -0
- stackos_connectors/connectors/linear/assets/graphql/issues/unarchive.graphql +11 -0
- stackos_connectors/connectors/linear/assets/graphql/issues/update.graphql +23 -0
- stackos_connectors/connectors/linear/assets/graphql/projects/get.graphql +18 -0
- stackos_connectors/connectors/linear/assets/graphql/projects/list.graphql +38 -0
- stackos_connectors/connectors/linear/assets/graphql/teams/get.graphql +12 -0
- stackos_connectors/connectors/linear/assets/graphql/teams/list.graphql +30 -0
- stackos_connectors/connectors/linear/assets/graphql/users/get.graphql +10 -0
- stackos_connectors/connectors/linear/assets/graphql/users/list.graphql +30 -0
- stackos_connectors/connectors/linear/assets/graphql/viewer/get.graphql +14 -0
- stackos_connectors/connectors/linear/assets/graphql/workflow-states/get.graphql +16 -0
- stackos_connectors/connectors/linear/assets/graphql/workflow-states/list.graphql +36 -0
- stackos_connectors/connectors/linear/assets/icon.png +0 -0
- stackos_connectors/connectors/linear/catalog.json +2794 -0
- stackos_connectors/connectors/linear/contract.py +101 -0
- stackos_connectors/connectors/linear/docs/linear.md +35 -0
- stackos_connectors/connectors/linear/integration.py +518 -0
- stackos_connectors/connectors/linear/schemas/introspection-2026-07-23.json +1 -0
- stackos_connectors/connectors/linear/schemas/introspection-2026-07-23.metadata.json +18 -0
- stackos_connectors/connectors/linear/schemas/root-policy-2026-07-23.json +552 -0
- stackos_connectors/connectors/meta_ads/__init__.py +1 -0
- stackos_connectors/connectors/meta_ads/actions.py +357 -0
- stackos_connectors/connectors/meta_ads/assets/icon.png +0 -0
- stackos_connectors/connectors/meta_ads/catalog.json +977 -0
- stackos_connectors/connectors/microsoft_365/__init__.py +1 -0
- stackos_connectors/connectors/microsoft_365/actions.py +121 -0
- stackos_connectors/connectors/microsoft_365/assets/icon.png +0 -0
- stackos_connectors/connectors/microsoft_365/catalog.json +261 -0
- stackos_connectors/connectors/microsoft_365/docs/protocol.md +17 -0
- stackos_connectors/connectors/openai_images/__init__.py +1 -0
- stackos_connectors/connectors/openai_images/actions.py +85 -0
- stackos_connectors/connectors/openai_images/assets/icon.webp +0 -0
- stackos_connectors/connectors/openai_images/catalog.json +282 -0
- stackos_connectors/connectors/openai_images/integration.py +327 -0
- stackos_connectors/connectors/openrouter/__init__.py +1 -0
- stackos_connectors/connectors/openrouter/assets/icon.png +0 -0
- stackos_connectors/connectors/openrouter/catalog.json +114 -0
- stackos_connectors/connectors/openrouter/integration.py +69 -0
- stackos_connectors/connectors/outreach/__init__.py +1 -0
- stackos_connectors/connectors/outreach/actions.py +107 -0
- stackos_connectors/connectors/outreach/assets/icon.png +0 -0
- stackos_connectors/connectors/outreach/catalog.json +197 -0
- stackos_connectors/connectors/outreach/docs/protocol.md +18 -0
- stackos_connectors/connectors/pipedrive/__init__.py +1 -0
- stackos_connectors/connectors/pipedrive/actions.py +173 -0
- stackos_connectors/connectors/pipedrive/assets/icon.png +0 -0
- stackos_connectors/connectors/pipedrive/catalog.json +449 -0
- stackos_connectors/connectors/pipedrive/docs/protocol.md +22 -0
- stackos_connectors/connectors/pipedrive/integration.py +160 -0
- stackos_connectors/connectors/reddit/__init__.py +1 -0
- stackos_connectors/connectors/reddit/actions.py +85 -0
- stackos_connectors/connectors/reddit/assets/icon.png +0 -0
- stackos_connectors/connectors/reddit/catalog.json +173 -0
- stackos_connectors/connectors/reddit/integration.py +117 -0
- stackos_connectors/connectors/reve/__init__.py +1 -0
- stackos_connectors/connectors/reve/actions.py +89 -0
- stackos_connectors/connectors/reve/assets/icon.png +0 -0
- stackos_connectors/connectors/reve/catalog.json +354 -0
- stackos_connectors/connectors/reve/integration.py +463 -0
- stackos_connectors/connectors/salesforce/__init__.py +1 -0
- stackos_connectors/connectors/salesforce/actions.py +173 -0
- stackos_connectors/connectors/salesforce/assets/icon.png +0 -0
- stackos_connectors/connectors/salesforce/catalog.json +490 -0
- stackos_connectors/connectors/salesforce/docs/protocol.md +17 -0
- stackos_connectors/connectors/salesloft/__init__.py +1 -0
- stackos_connectors/connectors/salesloft/actions.py +96 -0
- stackos_connectors/connectors/salesloft/assets/icon.jpeg +0 -0
- stackos_connectors/connectors/salesloft/catalog.json +239 -0
- stackos_connectors/connectors/salesloft/docs/protocol.md +17 -0
- stackos_connectors/connectors/salesloft/integration.py +119 -0
- stackos_connectors/connectors/serper/__init__.py +1 -0
- stackos_connectors/connectors/serper/actions.py +71 -0
- stackos_connectors/connectors/serper/assets/icon.svg +6 -0
- stackos_connectors/connectors/serper/catalog.json +124 -0
- stackos_connectors/connectors/serper/integration.py +83 -0
- stackos_connectors/connectors/shopify/__init__.py +1 -0
- stackos_connectors/connectors/shopify/actions.py +430 -0
- stackos_connectors/connectors/shopify/assets/graphql/customers/add-customer-tag.graphql +11 -0
- stackos_connectors/connectors/shopify/assets/graphql/customers/create-customer.graphql +24 -0
- stackos_connectors/connectors/shopify/assets/graphql/customers/get-customer-lifetime-value.graphql +30 -0
- stackos_connectors/connectors/shopify/assets/graphql/customers/get-customer-orders.graphql +27 -0
- stackos_connectors/connectors/shopify/assets/graphql/customers/get-customer.graphql +45 -0
- stackos_connectors/connectors/shopify/assets/graphql/customers/list-customers.graphql +29 -0
- stackos_connectors/connectors/shopify/assets/graphql/customers/remove-customer-tag.graphql +11 -0
- stackos_connectors/connectors/shopify/assets/graphql/customers/search-customers.graphql +29 -0
- stackos_connectors/connectors/shopify/assets/graphql/customers/update-customer.graphql +24 -0
- stackos_connectors/connectors/shopify/assets/graphql/inventory/adjust-inventory.graphql +25 -0
- stackos_connectors/connectors/shopify/assets/graphql/inventory/get-inventory-by-sku.graphql +28 -0
- stackos_connectors/connectors/shopify/assets/graphql/inventory/get-inventory-item.graphql +26 -0
- stackos_connectors/connectors/shopify/assets/graphql/inventory/get-location-inventory.graphql +26 -0
- stackos_connectors/connectors/shopify/assets/graphql/inventory/list-inventory-item-availability.graphql +40 -0
- stackos_connectors/connectors/shopify/assets/graphql/inventory/list-inventory-levels.graphql +30 -0
- stackos_connectors/connectors/shopify/assets/graphql/inventory/list-product-variant-inventory.graphql +20 -0
- stackos_connectors/connectors/shopify/assets/graphql/inventory/set-inventory-level.graphql +25 -0
- stackos_connectors/connectors/shopify/assets/graphql/orders/add-order-note.graphql +13 -0
- stackos_connectors/connectors/shopify/assets/graphql/orders/add-order-tag.graphql +11 -0
- stackos_connectors/connectors/shopify/assets/graphql/orders/create-draft-order.graphql +67 -0
- stackos_connectors/connectors/shopify/assets/graphql/orders/get-order-by-name.graphql +91 -0
- stackos_connectors/connectors/shopify/assets/graphql/orders/get-order-fulfillment-status.graphql +17 -0
- stackos_connectors/connectors/shopify/assets/graphql/orders/get-order-timeline.graphql +15 -0
- stackos_connectors/connectors/shopify/assets/graphql/orders/get-order.graphql +87 -0
- stackos_connectors/connectors/shopify/assets/graphql/orders/list-order-variant-quantities.graphql +18 -0
- stackos_connectors/connectors/shopify/assets/graphql/orders/list-orders.graphql +54 -0
- stackos_connectors/connectors/shopify/assets/graphql/orders/mark-order-paid.graphql +13 -0
- stackos_connectors/connectors/shopify/assets/graphql/orders/search-orders.graphql +54 -0
- stackos_connectors/connectors/shopify/assets/graphql/orders/update-order-note.graphql +13 -0
- stackos_connectors/connectors/shopify/assets/graphql/orders/update-order-tags.graphql +13 -0
- stackos_connectors/connectors/shopify/assets/graphql/products/create-collection.graphql +17 -0
- stackos_connectors/connectors/shopify/assets/graphql/products/create-product-variant.graphql +20 -0
- stackos_connectors/connectors/shopify/assets/graphql/products/create-product.graphql +29 -0
- stackos_connectors/connectors/shopify/assets/graphql/products/get-collection.graphql +41 -0
- stackos_connectors/connectors/shopify/assets/graphql/products/get-product-by-handle.graphql +61 -0
- stackos_connectors/connectors/shopify/assets/graphql/products/get-product-variant.graphql +31 -0
- stackos_connectors/connectors/shopify/assets/graphql/products/get-product.graphql +61 -0
- stackos_connectors/connectors/shopify/assets/graphql/products/list-collections.graphql +24 -0
- stackos_connectors/connectors/shopify/assets/graphql/products/list-product-variants.graphql +27 -0
- stackos_connectors/connectors/shopify/assets/graphql/products/list-products.graphql +38 -0
- stackos_connectors/connectors/shopify/assets/graphql/products/search-products.graphql +38 -0
- stackos_connectors/connectors/shopify/assets/graphql/products/update-product-status.graphql +14 -0
- stackos_connectors/connectors/shopify/assets/graphql/products/update-product-variant.graphql +20 -0
- stackos_connectors/connectors/shopify/assets/graphql/products/update-product.graphql +19 -0
- stackos_connectors/connectors/shopify/assets/graphql/shopifyql.graphql +13 -0
- stackos_connectors/connectors/shopify/assets/icon.png +0 -0
- stackos_connectors/connectors/shopify/catalog.json +3178 -0
- stackos_connectors/connectors/shopify/docs/shopify.md +51 -0
- stackos_connectors/connectors/shopify/integration.py +228 -0
- stackos_connectors/connectors/shopify/payloads.py +592 -0
- stackos_connectors/connectors/sitemap/__init__.py +1 -0
- stackos_connectors/connectors/sitemap/actions.py +88 -0
- stackos_connectors/connectors/sitemap/catalog.json +72 -0
- stackos_connectors/connectors/sitemap/integration.py +324 -0
- stackos_connectors/connectors/slack_bot/__init__.py +1 -0
- stackos_connectors/connectors/slack_bot/actions.py +47 -0
- stackos_connectors/connectors/slack_bot/assets/icon.png +0 -0
- stackos_connectors/connectors/slack_bot/catalog.json +557 -0
- stackos_connectors/connectors/slack_bot/constants.py +14 -0
- stackos_connectors/connectors/slack_bot/docs/protocol.md +20 -0
- stackos_connectors/connectors/slack_bot/files.py +111 -0
- stackos_connectors/connectors/slack_bot/http.py +163 -0
- stackos_connectors/connectors/slack_bot/integration.py +87 -0
- stackos_connectors/connectors/slack_bot/payloads.py +38 -0
- stackos_connectors/connectors/slack_bot/results.py +30 -0
- stackos_connectors/connectors/slack_bot/validation.py +145 -0
- stackos_connectors/connectors/smtp/__init__.py +1 -0
- stackos_connectors/connectors/smtp/actions.py +324 -0
- stackos_connectors/connectors/smtp/assets/icon.svg +7 -0
- stackos_connectors/connectors/smtp/catalog.json +238 -0
- stackos_connectors/connectors/smtp/docs/protocol.md +13 -0
- stackos_connectors/connectors/smtp/integration.py +104 -0
- stackos_connectors/connectors/stripe/__init__.py +1 -0
- stackos_connectors/connectors/stripe/actions.py +265 -0
- stackos_connectors/connectors/stripe/assets/icon.jpeg +0 -0
- stackos_connectors/connectors/stripe/catalog.json +2315 -0
- stackos_connectors/connectors/stripe/contract.py +92 -0
- stackos_connectors/connectors/stripe/docs/stripe.md +58 -0
- stackos_connectors/connectors/stripe/integration.py +668 -0
- stackos_connectors/connectors/taboola/__init__.py +1 -0
- stackos_connectors/connectors/taboola/actions.py +286 -0
- stackos_connectors/connectors/taboola/assets/icon.svg +18 -0
- stackos_connectors/connectors/taboola/catalog.json +593 -0
- stackos_connectors/connectors/telegram/__init__.py +1 -0
- stackos_connectors/connectors/telegram/actions.py +291 -0
- stackos_connectors/connectors/telegram/assets/icon.png +0 -0
- stackos_connectors/connectors/telegram/catalog.json +2121 -0
- stackos_connectors/connectors/telegram/docs/protocol.md +20 -0
- stackos_connectors/connectors/telegram/payloads.py +278 -0
- stackos_connectors/connectors/telegram/schema.py +35 -0
- stackos_connectors/connectors/telegram/tdlib/__init__.py +1 -0
- stackos_connectors/connectors/telegram/tdlib/native.py +513 -0
- stackos_connectors/connectors/telegram/tdlib/proxy.py +347 -0
- stackos_connectors/connectors/telegram/tdlib/sessions.py +256 -0
- stackos_connectors/connectors/trackbooth/__init__.py +5 -0
- stackos_connectors/connectors/trackbooth/actions.py +220 -0
- stackos_connectors/connectors/trackbooth/assets/agent-api/catalog.json +53858 -0
- stackos_connectors/connectors/trackbooth/assets/agent-api/openapi.json +25942 -0
- stackos_connectors/connectors/trackbooth/assets/agent-api/stackos-tools.json +17122 -0
- stackos_connectors/connectors/trackbooth/assets/icon.png +0 -0
- stackos_connectors/connectors/trackbooth/assets.py +279 -0
- stackos_connectors/connectors/trackbooth/catalog.json +168 -0
- stackos_connectors/connectors/trackbooth/contract.py +8 -0
- stackos_connectors/connectors/trackbooth/docs/agent-api/README.md +17 -0
- stackos_connectors/connectors/trackbooth/docs/trackbooth.md +33 -0
- stackos_connectors/connectors/trackbooth/integration.py +202 -0
- stackos_connectors/connectors/trackbooth/schema.py +78 -0
- stackos_connectors/connectors/trackbooth/transport.py +107 -0
- stackos_connectors/connectors/wordpress/__init__.py +1 -0
- stackos_connectors/connectors/wordpress/actions.py +69 -0
- stackos_connectors/connectors/wordpress/assets/icon.png +0 -0
- stackos_connectors/connectors/wordpress/catalog.json +183 -0
- stackos_connectors/connectors/wordpress/integration.py +121 -0
- stackos_connectors/connectors/xai_imagine/__init__.py +1 -0
- stackos_connectors/connectors/xai_imagine/actions.py +89 -0
- stackos_connectors/connectors/xai_imagine/assets/icon.png +0 -0
- stackos_connectors/connectors/xai_imagine/catalog.json +402 -0
- stackos_connectors/connectors/xai_imagine/integration.py +420 -0
- stackos_connectors/contracts.py +177 -0
- stackos_connectors/errors.py +63 -0
- stackos_connectors/probe.py +26 -0
- stackos_connectors/py.typed +0 -0
- stackos_connectors/redaction.py +140 -0
- stackos_connectors/registry.py +419 -0
- stackos_connectors/shared/__init__.py +1 -0
- stackos_connectors/shared/base.py +380 -0
- stackos_connectors/shared/byteplus/__init__.py +1 -0
- stackos_connectors/shared/byteplus/ark.py +794 -0
- stackos_connectors/shared/byteplus/media.py +178 -0
- stackos_connectors/shared/google/__init__.py +1 -0
- stackos_connectors/shared/google/batch.py +219 -0
- stackos_connectors/shared/google/oauth.py +51 -0
- stackos_connectors/shared/icons/integration.svg +8 -0
- stackos_connectors/shared/media.py +263 -0
- stackos_connectors/shared/provider_utils.py +350 -0
- stackos_connectors/shared/rate_limit.py +72 -0
- stackos_connectors/shared/vendor_utils.py +182 -0
- stackos_connectors/validation.py +25 -0
- stackos_connectors-0.1.0.dist-info/METADATA +160 -0
- stackos_connectors-0.1.0.dist-info/RECORD +388 -0
- stackos_connectors-0.1.0.dist-info/WHEEL +4 -0
- stackos_connectors-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"""Execute a named connector action using plain data and resolved authentication."""
|
|
2
|
+
|
|
3
|
+
from collections.abc import Mapping
|
|
4
|
+
from functools import lru_cache
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from .contracts import (
|
|
8
|
+
ActionDefinition,
|
|
9
|
+
AuthMethodDefinition,
|
|
10
|
+
CallOptions,
|
|
11
|
+
Connector,
|
|
12
|
+
ConnectorAuth,
|
|
13
|
+
ConnectorFile,
|
|
14
|
+
ConnectorRequest,
|
|
15
|
+
ConnectorResult,
|
|
16
|
+
NativeSession,
|
|
17
|
+
RateLimiter,
|
|
18
|
+
ValidationIssue,
|
|
19
|
+
)
|
|
20
|
+
from .errors import ConnectorError, IntegrationDownError, RateLimitedError, ValidationError
|
|
21
|
+
from .registry import ConnectorClient, ConnectorRegistry
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@lru_cache(maxsize=1)
|
|
25
|
+
def get_default_client() -> ConnectorClient:
|
|
26
|
+
"""Load reviewed builtin descriptions on first use, without provider imports."""
|
|
27
|
+
from .catalog import default_registry
|
|
28
|
+
|
|
29
|
+
return ConnectorClient(registry=default_registry())
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
async def execute(
|
|
33
|
+
connector: str,
|
|
34
|
+
action: str,
|
|
35
|
+
data: Mapping[str, Any],
|
|
36
|
+
auth: ConnectorAuth | Mapping[str, Any] | None = None,
|
|
37
|
+
options: CallOptions | None = None,
|
|
38
|
+
) -> ConnectorResult:
|
|
39
|
+
return await get_default_client().execute(connector, action, data, auth, options)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def validate(
|
|
43
|
+
connector: str,
|
|
44
|
+
action: str,
|
|
45
|
+
data: Mapping[str, Any],
|
|
46
|
+
auth: ConnectorAuth | Mapping[str, Any] | None = None,
|
|
47
|
+
options: CallOptions | None = None,
|
|
48
|
+
) -> list[ValidationIssue]:
|
|
49
|
+
return get_default_client().validate(connector, action, data, auth, options)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def validate_data(connector: str, action: str, data: Mapping[str, Any]) -> list[ValidationIssue]:
|
|
53
|
+
return get_default_client().validate_data(connector, action, data)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def estimate_cost(
|
|
57
|
+
connector: str,
|
|
58
|
+
action: str,
|
|
59
|
+
data: Mapping[str, Any],
|
|
60
|
+
auth: ConnectorAuth | Mapping[str, Any] | None = None,
|
|
61
|
+
options: CallOptions | None = None,
|
|
62
|
+
) -> int:
|
|
63
|
+
return get_default_client().estimate_cost(connector, action, data, auth, options)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def list_connectors() -> list[str]:
|
|
67
|
+
return get_default_client().list_connectors()
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def describe(connector: str, action: str | None = None) -> dict[str, Any]:
|
|
71
|
+
return get_default_client().describe(connector, action)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
__all__ = [
|
|
75
|
+
"ActionDefinition",
|
|
76
|
+
"AuthMethodDefinition",
|
|
77
|
+
"CallOptions",
|
|
78
|
+
"Connector",
|
|
79
|
+
"ConnectorAuth",
|
|
80
|
+
"ConnectorClient",
|
|
81
|
+
"ConnectorError",
|
|
82
|
+
"ConnectorFile",
|
|
83
|
+
"ConnectorRegistry",
|
|
84
|
+
"ConnectorRequest",
|
|
85
|
+
"ConnectorResult",
|
|
86
|
+
"IntegrationDownError",
|
|
87
|
+
"NativeSession",
|
|
88
|
+
"RateLimitedError",
|
|
89
|
+
"RateLimiter",
|
|
90
|
+
"ValidationError",
|
|
91
|
+
"ValidationIssue",
|
|
92
|
+
"describe",
|
|
93
|
+
"estimate_cost",
|
|
94
|
+
"execute",
|
|
95
|
+
"get_default_client",
|
|
96
|
+
"list_connectors",
|
|
97
|
+
"validate",
|
|
98
|
+
"validate_data",
|
|
99
|
+
]
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": "stackos.connectors.index.v1",
|
|
3
|
+
"connectors": [
|
|
4
|
+
"connectors/ahrefs/catalog.json",
|
|
5
|
+
"connectors/aignc/catalog.json",
|
|
6
|
+
"connectors/alibaba_wan/catalog.json",
|
|
7
|
+
"connectors/apollo/catalog.json",
|
|
8
|
+
"connectors/aws_s3/catalog.json",
|
|
9
|
+
"connectors/byteplus_seedance/catalog.json",
|
|
10
|
+
"connectors/byteplus_seedream/catalog.json",
|
|
11
|
+
"connectors/clay/catalog.json",
|
|
12
|
+
"connectors/cloudflare/catalog.json",
|
|
13
|
+
"connectors/dataforseo/catalog.json",
|
|
14
|
+
"connectors/firecrawl/catalog.json",
|
|
15
|
+
"connectors/ftp/catalog.json",
|
|
16
|
+
"connectors/ghost/catalog.json",
|
|
17
|
+
"connectors/google_ads/catalog.json",
|
|
18
|
+
"connectors/google_analytics/catalog.json",
|
|
19
|
+
"connectors/google_gemini_image/catalog.json",
|
|
20
|
+
"connectors/google_indexing/catalog.json",
|
|
21
|
+
"connectors/google_search_console/catalog.json",
|
|
22
|
+
"connectors/google_tag_manager/catalog.json",
|
|
23
|
+
"connectors/google_veo/catalog.json",
|
|
24
|
+
"connectors/google_workspace/catalog.json",
|
|
25
|
+
"connectors/http/catalog.json",
|
|
26
|
+
"connectors/hubspot/catalog.json",
|
|
27
|
+
"connectors/ideogram/catalog.json",
|
|
28
|
+
"connectors/imap/catalog.json",
|
|
29
|
+
"connectors/jina/catalog.json",
|
|
30
|
+
"connectors/kling_video/catalog.json",
|
|
31
|
+
"connectors/linear/catalog.json",
|
|
32
|
+
"connectors/meta_ads/catalog.json",
|
|
33
|
+
"connectors/microsoft_365/catalog.json",
|
|
34
|
+
"connectors/openai_images/catalog.json",
|
|
35
|
+
"connectors/openrouter/catalog.json",
|
|
36
|
+
"connectors/outreach/catalog.json",
|
|
37
|
+
"connectors/pipedrive/catalog.json",
|
|
38
|
+
"connectors/reddit/catalog.json",
|
|
39
|
+
"connectors/reve/catalog.json",
|
|
40
|
+
"connectors/salesforce/catalog.json",
|
|
41
|
+
"connectors/salesloft/catalog.json",
|
|
42
|
+
"connectors/serper/catalog.json",
|
|
43
|
+
"connectors/shopify/catalog.json",
|
|
44
|
+
"connectors/sitemap/catalog.json",
|
|
45
|
+
"connectors/slack_bot/catalog.json",
|
|
46
|
+
"connectors/smtp/catalog.json",
|
|
47
|
+
"connectors/stripe/catalog.json",
|
|
48
|
+
"connectors/taboola/catalog.json",
|
|
49
|
+
"connectors/telegram/catalog.json",
|
|
50
|
+
"connectors/trackbooth/catalog.json",
|
|
51
|
+
"connectors/wordpress/catalog.json",
|
|
52
|
+
"connectors/xai_imagine/catalog.json"
|
|
53
|
+
]
|
|
54
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$defs": {
|
|
4
|
+
"icon": {
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["path", "media_type", "kind"],
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"path": {"type": "string", "pattern": "^(?:[A-Za-z0-9_][A-Za-z0-9_-]*/)*[A-Za-z0-9_][A-Za-z0-9_-]*\\.(?:svg|png|jpg|jpeg|webp)$", "not": {"pattern": "[\\r\\n]"}},
|
|
10
|
+
"media_type": {"enum": ["image/svg+xml", "image/png", "image/jpeg", "image/webp"]},
|
|
11
|
+
"kind": {"enum": ["icon", "wordmark", "wordmark-dark", "wordmark-inverse", "fallback"]}
|
|
12
|
+
},
|
|
13
|
+
"allOf": [
|
|
14
|
+
{"if": {"properties": {"path": {"pattern": "\\.svg$"}}}, "then": {"properties": {"media_type": {"const": "image/svg+xml"}}}},
|
|
15
|
+
{"if": {"properties": {"path": {"pattern": "\\.png$"}}}, "then": {"properties": {"media_type": {"const": "image/png"}}}},
|
|
16
|
+
{"if": {"properties": {"path": {"pattern": "\\.jpe?g$"}}}, "then": {"properties": {"media_type": {"const": "image/jpeg"}}}},
|
|
17
|
+
{"if": {"properties": {"path": {"pattern": "\\.webp$"}}}, "then": {"properties": {"media_type": {"const": "image/webp"}}}}
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
"presentation_metadata": {
|
|
21
|
+
"type": "object",
|
|
22
|
+
"properties": {"icon": {"$ref": "#/$defs/icon"}}
|
|
23
|
+
},
|
|
24
|
+
"index": {
|
|
25
|
+
"type": "object",
|
|
26
|
+
"required": ["schema_version", "connectors"],
|
|
27
|
+
"additionalProperties": false,
|
|
28
|
+
"properties": {
|
|
29
|
+
"schema_version": {"const": "stackos.connectors.index.v1"},
|
|
30
|
+
"connectors": {"type": "array", "uniqueItems": true, "items": {"type": "string", "pattern": "^(?:[a-z0-9][a-z0-9_-]*/)*[a-z0-9][a-z0-9_-]*\\.json$"}}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"auth_method": {
|
|
34
|
+
"type": "object",
|
|
35
|
+
"required": ["key", "fields_schema"],
|
|
36
|
+
"properties": {
|
|
37
|
+
"key": {"type": "string", "minLength": 1},
|
|
38
|
+
"description": {"type": "string"},
|
|
39
|
+
"payload_format": {"enum": ["raw", "json", "none"]},
|
|
40
|
+
"payload_field": {"type": "string", "minLength": 1},
|
|
41
|
+
"fields_schema": {"type": "object"},
|
|
42
|
+
"config_schema": {"type": "object"}
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"action": {
|
|
46
|
+
"type": "object",
|
|
47
|
+
"required": ["key", "operation", "input_schema", "auth_methods", "config"],
|
|
48
|
+
"properties": {
|
|
49
|
+
"key": {"type": "string", "minLength": 1},
|
|
50
|
+
"operation": {"type": "string", "minLength": 1},
|
|
51
|
+
"description": {"type": "string"},
|
|
52
|
+
"guidance": {"type": "string"},
|
|
53
|
+
"icon": {"$ref": "#/$defs/icon"},
|
|
54
|
+
"input_schema": {"type": "object"},
|
|
55
|
+
"output_schema": {"type": "object"},
|
|
56
|
+
"auth_methods": {"type": "array", "uniqueItems": true, "items": {"type": "string", "minLength": 1}},
|
|
57
|
+
"auth_optional": {"type": "boolean"},
|
|
58
|
+
"config": {"type": "object"},
|
|
59
|
+
"examples": {"type": "array", "items": {"type": "object"}},
|
|
60
|
+
"metadata": {"$ref": "#/$defs/presentation_metadata"}
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"connector": {
|
|
64
|
+
"type": "object",
|
|
65
|
+
"required": ["schema_version", "connector", "name", "description", "auth_methods", "actions"],
|
|
66
|
+
"properties": {
|
|
67
|
+
"schema_version": {"const": "stackos.connector.v1"},
|
|
68
|
+
"connector": {"type": "string", "pattern": "^[a-z0-9][a-z0-9_-]*$"},
|
|
69
|
+
"name": {"type": "string", "minLength": 1},
|
|
70
|
+
"description": {"type": "string"},
|
|
71
|
+
"icon": {"$ref": "#/$defs/icon"},
|
|
72
|
+
"implementation": {"type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_.]*:[A-Za-z_][A-Za-z0-9_]*$"},
|
|
73
|
+
"auth_methods": {"type": "array", "items": {"$ref": "#/$defs/auth_method"}},
|
|
74
|
+
"actions": {"type": "array", "items": {"$ref": "#/$defs/action"}},
|
|
75
|
+
"metadata": {"$ref": "#/$defs/presentation_metadata"}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
"$ref": "#/$defs/connector"
|
|
80
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"""Load portable connector descriptions and lazy bindings from packaged JSON.
|
|
2
|
+
|
|
3
|
+
Provider packages use ``load_registry("connectors/provider/catalog.json")``;
|
|
4
|
+
the default registry reads the reviewed resource list in ``catalog/index.json``.
|
|
5
|
+
Execution auth schemas describe resolved credentials, while setup metadata is
|
|
6
|
+
retained separately for discovery and never used as an execution schema.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import json
|
|
12
|
+
import re
|
|
13
|
+
from collections.abc import Iterable, Mapping
|
|
14
|
+
from importlib.resources import files
|
|
15
|
+
from importlib.resources.abc import Traversable
|
|
16
|
+
from typing import Any
|
|
17
|
+
|
|
18
|
+
from jsonschema import Draft202012Validator
|
|
19
|
+
from jsonschema.exceptions import SchemaError
|
|
20
|
+
|
|
21
|
+
from .contracts import ActionDefinition, AuthMethodDefinition, freeze, thaw
|
|
22
|
+
from .registry import ConnectorRegistry
|
|
23
|
+
|
|
24
|
+
_RESOURCE_PATH = re.compile(r"(?:[a-z0-9][a-z0-9_-]*/)*[a-z0-9][a-z0-9_-]*\.json\Z")
|
|
25
|
+
_ACTION_FIELDS = {
|
|
26
|
+
"key",
|
|
27
|
+
"operation",
|
|
28
|
+
"input_schema",
|
|
29
|
+
"output_schema",
|
|
30
|
+
"auth_methods",
|
|
31
|
+
"config",
|
|
32
|
+
"description",
|
|
33
|
+
"guidance",
|
|
34
|
+
"examples",
|
|
35
|
+
"metadata",
|
|
36
|
+
"auth_optional",
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _read(resource: Traversable) -> Any:
|
|
41
|
+
try:
|
|
42
|
+
return json.loads(resource.read_text(encoding="utf-8"))
|
|
43
|
+
except (OSError, ValueError) as exc:
|
|
44
|
+
raise ValueError(f"could not read connector catalog resource: {resource.name}") from exc
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _validate(document: Any, definition: str) -> None:
|
|
48
|
+
schema = _read(files("stackos_connectors").joinpath("catalog", "schema.json"))
|
|
49
|
+
validator = Draft202012Validator({"$ref": f"#/$defs/{definition}", "$defs": schema["$defs"]})
|
|
50
|
+
error = next(validator.iter_errors(document), None)
|
|
51
|
+
if error is not None:
|
|
52
|
+
path = ".".join(str(item) for item in error.absolute_path) or "$"
|
|
53
|
+
raise ValueError(f"invalid connector catalog {definition} at {path}")
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def registry_from_documents(documents: Iterable[Mapping[str, Any]]) -> ConnectorRegistry:
|
|
57
|
+
"""Build one immutable registry without importing any provider implementation."""
|
|
58
|
+
actions: list[ActionDefinition] = []
|
|
59
|
+
implementations: dict[str, str] = {}
|
|
60
|
+
metadata: dict[str, dict[str, Any]] = {}
|
|
61
|
+
for original in documents:
|
|
62
|
+
document = thaw(freeze(original))
|
|
63
|
+
_validate(document, "connector")
|
|
64
|
+
key = document["connector"]
|
|
65
|
+
if key in metadata:
|
|
66
|
+
raise ValueError(f"duplicate connector registration: {key}")
|
|
67
|
+
methods: dict[str, AuthMethodDefinition] = {}
|
|
68
|
+
for method in document["auth_methods"]:
|
|
69
|
+
if method["key"] in methods:
|
|
70
|
+
raise ValueError(f"duplicate auth method registration: {key}/{method['key']}")
|
|
71
|
+
methods[method["key"]] = AuthMethodDefinition(
|
|
72
|
+
key=method["key"],
|
|
73
|
+
fields_schema=method["fields_schema"],
|
|
74
|
+
config_schema=method.get("config_schema", {"type": "object"}),
|
|
75
|
+
description=method.get("description", ""),
|
|
76
|
+
)
|
|
77
|
+
try:
|
|
78
|
+
Draft202012Validator.check_schema(method["fields_schema"])
|
|
79
|
+
Draft202012Validator.check_schema(method.get("config_schema", {"type": "object"}))
|
|
80
|
+
except SchemaError as exc:
|
|
81
|
+
raise ValueError("invalid connector auth schema") from exc
|
|
82
|
+
metadata[key] = {
|
|
83
|
+
**document.get("metadata", {}),
|
|
84
|
+
**{
|
|
85
|
+
name: value
|
|
86
|
+
for name, value in document.items()
|
|
87
|
+
if name not in {"connector", "implementation", "actions", "metadata"}
|
|
88
|
+
},
|
|
89
|
+
}
|
|
90
|
+
if binding := document.get("implementation"):
|
|
91
|
+
implementations[key] = binding
|
|
92
|
+
for action in document["actions"]:
|
|
93
|
+
unknown = set(action["auth_methods"]) - methods.keys()
|
|
94
|
+
if unknown:
|
|
95
|
+
raise ValueError(f"action selects an unknown auth method: {key}/{action['key']}")
|
|
96
|
+
extra = {
|
|
97
|
+
**action.get("metadata", {}),
|
|
98
|
+
**{name: value for name, value in action.items() if name not in _ACTION_FIELDS},
|
|
99
|
+
}
|
|
100
|
+
actions.append(
|
|
101
|
+
ActionDefinition(
|
|
102
|
+
connector=key,
|
|
103
|
+
key=action["key"],
|
|
104
|
+
operation=action["operation"],
|
|
105
|
+
input_schema=action["input_schema"],
|
|
106
|
+
output_schema=action.get("output_schema", {}),
|
|
107
|
+
auth_methods=tuple(methods[name] for name in action["auth_methods"]),
|
|
108
|
+
config=action["config"],
|
|
109
|
+
description=action.get("description", ""),
|
|
110
|
+
guidance=action.get("guidance", ""),
|
|
111
|
+
examples=tuple(action.get("examples", [])),
|
|
112
|
+
metadata=extra,
|
|
113
|
+
auth_optional=action.get("auth_optional", False),
|
|
114
|
+
)
|
|
115
|
+
)
|
|
116
|
+
try:
|
|
117
|
+
return ConnectorRegistry(
|
|
118
|
+
actions=actions,
|
|
119
|
+
implementations=implementations,
|
|
120
|
+
connector_metadata=metadata,
|
|
121
|
+
)
|
|
122
|
+
except SchemaError as exc:
|
|
123
|
+
raise ValueError("invalid connector action schema") from exc
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def load_registry(*resource_names: str, root: Traversable | None = None) -> ConnectorRegistry:
|
|
127
|
+
"""Read explicit provider resources, or the index when none are named.
|
|
128
|
+
|
|
129
|
+
``root`` is an explicit local resource root, useful for a consumer's declared
|
|
130
|
+
catalog and for deterministic tests. Resource names are package-relative JSON
|
|
131
|
+
paths; absolute paths, empty segments and traversal are rejected.
|
|
132
|
+
"""
|
|
133
|
+
source = root if root is not None else files("stackos_connectors")
|
|
134
|
+
if not resource_names:
|
|
135
|
+
index = _read(source.joinpath("catalog", "index.json"))
|
|
136
|
+
_validate(index, "index")
|
|
137
|
+
resource_names = tuple(index["connectors"])
|
|
138
|
+
for name in resource_names:
|
|
139
|
+
if not _RESOURCE_PATH.fullmatch(name) or name.rsplit("/", 1)[-1] in {
|
|
140
|
+
"index.json",
|
|
141
|
+
"schema.json",
|
|
142
|
+
}:
|
|
143
|
+
raise ValueError("invalid connector catalog resource name")
|
|
144
|
+
if len(set(resource_names)) != len(resource_names):
|
|
145
|
+
raise ValueError("duplicate connector catalog resource name")
|
|
146
|
+
registry = registry_from_documents(
|
|
147
|
+
_read(source.joinpath(*name.split("/"))) for name in resource_names
|
|
148
|
+
)
|
|
149
|
+
presentations = [*registry.connector_metadata.values()]
|
|
150
|
+
presentations.extend(action.metadata for action in registry.actions.values())
|
|
151
|
+
for metadata in presentations:
|
|
152
|
+
if (icon := metadata.get("icon")) and not source.joinpath(
|
|
153
|
+
*icon["path"].split("/")
|
|
154
|
+
).is_file():
|
|
155
|
+
raise ValueError(f"missing connector icon resource: {icon['path']}")
|
|
156
|
+
return registry
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def default_registry() -> ConnectorRegistry:
|
|
160
|
+
return load_registry()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""connectors components."""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""connectors ahrefs components."""
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"""Named native Ahrefs API requests; admission decisions belong to the caller."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from contextlib import nullcontext
|
|
6
|
+
|
|
7
|
+
import httpx
|
|
8
|
+
|
|
9
|
+
from stackos_connectors.connectors.ahrefs.integration import AhrefsIntegration
|
|
10
|
+
from stackos_connectors.contracts import ConnectorRequest, ConnectorResult, ValidationIssue
|
|
11
|
+
from stackos_connectors.errors import ValidationError
|
|
12
|
+
from stackos_connectors.shared.provider_utils import credential_value
|
|
13
|
+
from stackos_connectors.shared.vendor_utils import (
|
|
14
|
+
issue,
|
|
15
|
+
optional_str,
|
|
16
|
+
required_str,
|
|
17
|
+
unknown_operation,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
AHREFS_DEFAULT_ROWS = 100
|
|
21
|
+
AHREFS_MODE_VALUES = ("exact", "prefix", "domain", "subdomains")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _positive_limit(payload, issues):
|
|
25
|
+
value = payload.get("limit")
|
|
26
|
+
if value is not None and (not isinstance(value, int) or isinstance(value, bool) or value < 1):
|
|
27
|
+
issues.append(issue("$.limit", "limit must be a positive integer", "range"))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class AhrefsActionConnector:
|
|
31
|
+
key = "ahrefs"
|
|
32
|
+
|
|
33
|
+
def validate(self, request: ConnectorRequest) -> list[ValidationIssue]:
|
|
34
|
+
payload = request.input_json
|
|
35
|
+
issues = []
|
|
36
|
+
match request.operation:
|
|
37
|
+
case "limits_and_usage":
|
|
38
|
+
pass
|
|
39
|
+
case "competitor.keywords" | "keywords_for_site":
|
|
40
|
+
required_str(payload, "target", issues)
|
|
41
|
+
optional_str(payload, "country", issues)
|
|
42
|
+
optional_str(payload, "date", issues)
|
|
43
|
+
_positive_limit(payload, issues)
|
|
44
|
+
case "backlink.research" | "top_backlinks":
|
|
45
|
+
required_str(payload, "target", issues)
|
|
46
|
+
optional_str(payload, "mode", issues)
|
|
47
|
+
if (
|
|
48
|
+
isinstance(payload.get("mode"), str)
|
|
49
|
+
and payload["mode"] not in AHREFS_MODE_VALUES
|
|
50
|
+
):
|
|
51
|
+
issues.append(
|
|
52
|
+
issue(
|
|
53
|
+
"$.mode",
|
|
54
|
+
"mode must be one of exact, prefix, domain, subdomains",
|
|
55
|
+
"enum_mismatch",
|
|
56
|
+
)
|
|
57
|
+
)
|
|
58
|
+
_positive_limit(payload, issues)
|
|
59
|
+
case _:
|
|
60
|
+
issues.extend(unknown_operation(request))
|
|
61
|
+
return issues
|
|
62
|
+
|
|
63
|
+
def estimate_cost_cents(self, _request: ConnectorRequest) -> int:
|
|
64
|
+
return 0
|
|
65
|
+
|
|
66
|
+
async def execute(self, request: ConnectorRequest) -> ConnectorResult:
|
|
67
|
+
payload = request.input_json
|
|
68
|
+
async with (
|
|
69
|
+
nullcontext(request.options.http)
|
|
70
|
+
if request.options.http is not None
|
|
71
|
+
else httpx.AsyncClient(
|
|
72
|
+
timeout=request.options.timeout if request.options.timeout is not None else 60.0
|
|
73
|
+
)
|
|
74
|
+
) as http:
|
|
75
|
+
client = AhrefsIntegration(
|
|
76
|
+
payload=credential_value(request, "api_key").encode(),
|
|
77
|
+
http=http,
|
|
78
|
+
rate_limiter=request.options.rate_limiter,
|
|
79
|
+
timeout=request.options.timeout,
|
|
80
|
+
)
|
|
81
|
+
match request.operation:
|
|
82
|
+
case "limits_and_usage":
|
|
83
|
+
result = await client.limits_and_usage()
|
|
84
|
+
case "competitor.keywords" | "keywords_for_site":
|
|
85
|
+
result = await client.keywords_for_site(
|
|
86
|
+
target=str(payload["target"]),
|
|
87
|
+
country=str(payload.get("country", "us")),
|
|
88
|
+
limit=int(payload.get("limit", AHREFS_DEFAULT_ROWS)),
|
|
89
|
+
date_=payload.get("date"),
|
|
90
|
+
)
|
|
91
|
+
case "backlink.research" | "top_backlinks":
|
|
92
|
+
result = await client.top_backlinks(
|
|
93
|
+
target=str(payload["target"]),
|
|
94
|
+
mode=str(payload.get("mode", "domain")),
|
|
95
|
+
limit=int(payload.get("limit", AHREFS_DEFAULT_ROWS)),
|
|
96
|
+
)
|
|
97
|
+
case _:
|
|
98
|
+
raise ValidationError(f"unsupported Ahrefs operation {request.operation!r}")
|
|
99
|
+
return ConnectorResult(
|
|
100
|
+
output_json=result.data if isinstance(result.data, dict) else {"data": result.data},
|
|
101
|
+
metadata_json={
|
|
102
|
+
"vendor": "ahrefs",
|
|
103
|
+
"operation": request.operation,
|
|
104
|
+
**(result.metadata or {}),
|
|
105
|
+
},
|
|
106
|
+
cost_cents=0,
|
|
107
|
+
)
|
|
Binary file
|