Metadata-Version: 2.5
Name: vendor-fabric
Version: 2.3.0
Summary: Extended Data-native vendor connectors and sync capabilities
Project-URL: Documentation, https://jonbogaty.com/vendor-fabric/
Project-URL: Issues, https://github.com/jbcom/vendor-fabric/issues
Project-URL: Source, https://github.com/jbcom/vendor-fabric
Project-URL: Changelog, https://github.com/jbcom/vendor-fabric/blob/main/packages/vendor-fabric/CHANGELOG.md
Author-email: Jon Bogaty <jon@jonbogaty.com>
Maintainer-email: Jon Bogaty <jon@jonbogaty.com>
License: MIT
Keywords: aws,connectors,gcp,github,meshy,secrets,slack,vault,zoom
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: extended-data<9.0.0,>=8.4.0
Requires-Dist: httpx>=0.28.1
Requires-Dist: more-itertools>=11.0.2
Requires-Dist: pydantic<3.0.0,>=2.13.4
Requires-Dist: pyyaml>=6.0.3
Requires-Dist: requests>=2.33.1
Requires-Dist: tenacity<10.0.0,>=8.4.1
Provides-Extra: all
Requires-Dist: anthropic>=0.96.0; extra == 'all'
Requires-Dist: boto3>=1.42.92; extra == 'all'
Requires-Dist: fastapi>=0.136.0; extra == 'all'
Requires-Dist: filelock>=3.29.0; extra == 'all'
Requires-Dist: google-api-python-client>=2.194.0; extra == 'all'
Requires-Dist: google-cloud-billing>=1.19.0; extra == 'all'
Requires-Dist: google-cloud-resource-manager>=1.17.0; extra == 'all'
Requires-Dist: hvac>=2.4.0; extra == 'all'
Requires-Dist: numpy>=2.2.6; extra == 'all'
Requires-Dist: pygithub>=2.9.1; extra == 'all'
Requires-Dist: pyngrok>=8.0.0; extra == 'all'
Requires-Dist: python-graphql-client>=0.4.3; extra == 'all'
Requires-Dist: rich<16.0.0,>=13.7.0; extra == 'all'
Requires-Dist: slack-sdk>=3.41.0; extra == 'all'
Requires-Dist: sqlite-vec>=0.1.9; extra == 'all'
Requires-Dist: starlette>=1.3.1; extra == 'all'
Requires-Dist: uvicorn>=0.45.0; extra == 'all'
Requires-Dist: validators>=0.35.0; extra == 'all'
Provides-Extra: anthropic
Requires-Dist: anthropic>=0.96.0; extra == 'anthropic'
Provides-Extra: aws
Requires-Dist: boto3>=1.42.92; extra == 'aws'
Provides-Extra: cursor
Provides-Extra: dev
Requires-Dist: coverage[toml]>=7.6.0; extra == 'dev'
Requires-Dist: hypothesis>=6.100.2; extra == 'dev'
Requires-Dist: mypy>=1.20.1; extra == 'dev'
Requires-Dist: pytest-asyncio>=1.3.0; extra == 'dev'
Requires-Dist: pytest-cov>=7.1.0; extra == 'dev'
Requires-Dist: pytest-mock>=3.15.1; extra == 'dev'
Requires-Dist: pytest-timeout>=2.4.0; extra == 'dev'
Requires-Dist: pytest-xdist>=3.6.1; extra == 'dev'
Requires-Dist: pytest>=9.0.3; extra == 'dev'
Requires-Dist: ruff>=0.16.0; extra == 'dev'
Requires-Dist: types-pyyaml>=6.0.12.20240724; extra == 'dev'
Requires-Dist: types-requests>=2.33.0.20260408; extra == 'dev'
Provides-Extra: docs
Requires-Dist: furo>=2025.12.19; extra == 'docs'
Requires-Dist: myst-parser<6.0.0,>=4.0.1; extra == 'docs'
Requires-Dist: sphinx-autodoc2>=0.5.0; extra == 'docs'
Requires-Dist: sphinx-copybutton>=0.5.2; extra == 'docs'
Requires-Dist: sphinx<10.0.0,>=8.2.3; extra == 'docs'
Provides-Extra: github
Requires-Dist: pygithub>=2.9.1; extra == 'github'
Requires-Dist: python-graphql-client>=0.4.3; extra == 'github'
Provides-Extra: google
Requires-Dist: google-api-python-client>=2.194.0; extra == 'google'
Requires-Dist: google-cloud-billing>=1.19.0; extra == 'google'
Requires-Dist: google-cloud-resource-manager>=1.17.0; extra == 'google'
Provides-Extra: meshy
Requires-Dist: filelock>=3.29.0; extra == 'meshy'
Requires-Dist: numpy>=2.2.6; extra == 'meshy'
Requires-Dist: rich<16.0.0,>=13.7.0; extra == 'meshy'
Requires-Dist: validators>=0.35.0; extra == 'meshy'
Provides-Extra: secrets-sync
Requires-Dist: boto3>=1.42.92; extra == 'secrets-sync'
Requires-Dist: hvac>=2.4.0; extra == 'secrets-sync'
Provides-Extra: slack
Requires-Dist: slack-sdk>=3.41.0; extra == 'slack'
Provides-Extra: tests
Requires-Dist: coverage[toml]>=7.6.0; extra == 'tests'
Requires-Dist: hypothesis>=6.100.2; extra == 'tests'
Requires-Dist: pytest-asyncio>=1.3.0; extra == 'tests'
Requires-Dist: pytest-cov>=7.1.0; extra == 'tests'
Requires-Dist: pytest-mock>=3.15.1; extra == 'tests'
Requires-Dist: pytest-timeout>=2.4.0; extra == 'tests'
Requires-Dist: pytest-xdist>=3.6.1; extra == 'tests'
Requires-Dist: pytest>=9.0.3; extra == 'tests'
Provides-Extra: typing
Requires-Dist: mypy>=1.20.1; extra == 'typing'
Requires-Dist: types-pyyaml>=6.0.12.20240724; extra == 'typing'
Requires-Dist: types-requests>=2.33.0.20260408; extra == 'typing'
Provides-Extra: vault
Requires-Dist: hvac>=2.4.0; extra == 'vault'
Provides-Extra: vector
Requires-Dist: sqlite-vec>=0.1.9; extra == 'vector'
Provides-Extra: webhooks
Requires-Dist: fastapi>=0.136.0; extra == 'webhooks'
Requires-Dist: pyngrok>=8.0.0; extra == 'webhooks'
Requires-Dist: starlette>=1.3.1; extra == 'webhooks'
Requires-Dist: uvicorn>=0.45.0; extra == 'webhooks'
Provides-Extra: zoom
Description-Content-Type: text/markdown

# Vendor Fabric

`vendor-fabric` is the optional vendor integration layer for the
Extended Data Python stack. It depends on `extended-data>=8.4.0` for the
polymorphic `ExtendedData` root, concrete containers, local file sync, inputs,
logging, and workflow utilities, then adds
adapter-registered API clients and vendor-backed sync capabilities.

Documentation: [jonbogaty.com/vendor-fabric](https://jonbogaty.com/vendor-fabric/)

```bash
pip install vendor-fabric
pip install "vendor-fabric[github,slack]"
pip install "vendor-fabric[aws,google,vault,secrets-sync]"
pip install secrets-sync-python-binding
pip install pytest-vendor-fabric
```

The base install keeps vendor SDKs out of the environment. Connector metadata
is available even when an optional SDK is absent:

```python
from vendor_fabric import get_connector_info, list_connector_info

print(get_connector_info("github")["available"])
print(list_connector_info(include_unavailable=True))
```

Construct connectors through the registry or `ConnectorFabric`:

```python
from vendor_fabric import ConnectorFabric

fabric = ConnectorFabric(inputs={"GITHUB_TOKEN": "..."})
github = fabric.get_connector("github")
```

Unavailable features report install guidance instead of requiring callers to
wrap their own imports.

## Command-line interface

The `vendor-fabric` command exposes the same Extended Data-returning connector
surface as the Python registry. Connector credentials come from environment
variables, the AWS default credential chain, or SecretSync configuration; the
CLI has no credential flags.

```bash
# Discover connectors and their callable data surface.
vendor-fabric list
vendor-fabric list --category cloud --available-only
vendor-fabric info github
vendor-fabric methods github
vendor-fabric methods github --json
vendor-fabric credentials
vendor-fabric credentials github --json

# Provider commands use the connector method name and --name value arguments.
vendor-fabric github list_repositories --type-filter public
vendor-fabric meshy text3d_generate --prompt "a low-poly observatory" --wait false

# The generic spelling remains available for scripts that select a provider.
vendor-fabric call github list_repositories --type-filter public --json

# SecretSync is also routed through the unified command.
vendor-fabric secrets-sync validate --config pipeline.yaml
vendor-fabric secrets-sync info --config pipeline.yaml
vendor-fabric secrets-sync pipeline --config pipeline.yaml --dry-run --diff
```

`methods` prints each callable signature, including required and optional
arguments. Argument names accept either underscores or hyphens. Values are
decoded as JSON first, then as booleans, integers, floats, or strings. Use JSON
for structured arguments:

```bash
vendor-fabric anthropic create_message \
  --model claude-sonnet-4-20250514 \
  --max-tokens 1024 \
  --messages '[{"role":"user","content":"Summarize this change"}]'
```

Sensitive method inputs are never accepted as literal command-line values.
Use the generated `--<name>-env`, `--<name>-file`, or `--<name>-stdin` form so
the value does not land in shell history. These source forms also work for
non-sensitive structured or multiline inputs. File and environment contents
receive the same JSON-first decoding as ordinary arguments.

```bash
# APP_SECRET contains the value; only its variable name appears in history.
vendor-fabric aws create_secret --name app/api --secret-value-env APP_SECRET

# Read a Google Workspace initial password from standard input.
security find-generic-password -w -s workspace-bootstrap \
  | vendor-fabric google create_user \
      --primary-email new.user@example.com \
      --given-name New \
      --family-name User \
      --password-stdin

# Keep a large request payload in a permission-controlled file.
vendor-fabric anthropic create_message \
  --model claude-sonnet-4-20250514 \
  --max-tokens 1024 \
  --messages-file request-messages.json
```

### Credential sources

`vendor-fabric credentials [connector]` reports these names without reading or
printing their values. Optional SDK extras remain discoverable even when they
are not installed.

| Connector | Credential and configuration sources |
|---|---|
| `anthropic` | `ANTHROPIC_API_KEY` |
| `aws` | Standard boto3 credential/config chain; optional `EXECUTION_ROLE_ARN` and `ROLE_SESSION_NAME` |
| `cursor` | `CURSOR_API_KEY` |
| `github` | `GITHUB_TOKEN`, `GITHUB_OWNER`; optional `GITHUB_REPO` and `GITHUB_BRANCH` |
| `google` | `GOOGLE_SERVICE_ACCOUNT` (service-account JSON) |
| `jules` | `JULES_API_KEY` |
| `meshy` | `MESHY_API_KEY` |
| `slack` | `SLACK_TOKEN`, `SLACK_BOT_TOKEN` |
| `vault` | `VAULT_ADDR`; `VAULT_TOKEN` or `VAULT_ROLE_ID` plus `VAULT_SECRET_ID`; optional `VAULT_NAMESPACE` and `VAULT_APPROLE_PATH` |
| `zoom` | `ZOOM_CLIENT_ID`, `ZOOM_CLIENT_SECRET`, `ZOOM_ACCOUNT_ID` |

### Connector commands

Every command below is available through both
`vendor-fabric <connector> <method>` and
`vendor-fabric call <connector> <method>`. Run
`vendor-fabric methods <connector>` for its argument signature.

| Connector | Commands |
|---|---|
| `anthropic` | `create_message`, `get_available_models`, `get_model`, `list_models` |
| `aws` | `add_user_to_group`, `classify_accounts`, `classify_aws_accounts`, `copy_object`, `copy_secrets_to_s3`, `create_account_assignment`, `create_bucket`, `create_secret`, `create_sso_group`, `create_sso_user`, `delete_account_assignment`, `delete_object`, `delete_secret`, `delete_secrets_matching`, `find_buckets_by_name`, `get_accounts`, `get_bucket_features`, `get_bucket_location`, `get_bucket_sizes`, `get_bucket_tags`, `get_caller_account_id`, `get_controltower_accounts`, `get_identity_store_id`, `get_json_object`, `get_object`, `get_organization_accounts`, `get_organization_units`, `get_secret`, `get_sso_instance_arn`, `get_sso_user`, `label_aws_account`, `label_aws_accounts`, `list_account_assignments`, `list_objects`, `list_permission_sets`, `list_s3_buckets`, `list_secrets`, `list_sso_groups`, `list_sso_users`, `load_secrets_by_prefix`, `preprocess_aws_organization`, `preprocess_organization`, `put_json_object`, `put_object`, `update_secret` |
| `cursor` | `get_agent_conversation`, `get_agent_status`, `launch_agent`, `list_agents`, `list_models`, `list_repositories` |
| `github` | `build_workflow`, `build_workflow_job`, `build_workflow_step`, `create_python_ci_workflow`, `execute_graphql`, `get_org_member`, `get_repository`, `get_repository_file`, `get_team`, `get_users_with_verified_emails`, `list_org_members`, `list_repositories`, `list_teams` |
| `google` | `add_group_member`, `add_iam_binding`, `batch_enable_services`, `create_group`, `create_kms_key`, `create_kms_keyring`, `create_or_update_group`, `create_or_update_user`, `create_project`, `create_service_account`, `create_user`, `delete_project`, `disable_project_billing`, `disable_service`, `enable_service`, `find_inactive_projects`, `get_bigquery_billing_dataset`, `get_billing_account`, `get_billing_account_iam_policy`, `get_gke_cluster`, `get_group`, `get_iam_policy`, `get_license_summary`, `get_org_policy`, `get_organization`, `get_organization_id`, `get_project`, `get_project_billing_info`, `get_project_iam_users`, `get_pubsub_resources_for_project`, `get_user`, `list_available_licenses`, `list_billing_account_projects`, `list_billing_accounts`, `list_compute_instances`, `list_enabled_services`, `list_folders`, `list_gke_clusters`, `list_group_members`, `list_groups`, `list_kms_keyrings`, `list_org_units`, `list_projects`, `list_pubsub_subscriptions`, `list_pubsub_topics`, `list_service_accounts`, `list_sql_instances`, `list_storage_buckets`, `list_users`, `list_workspace_groups`, `list_workspace_users`, `move_project`, `set_billing_account_iam_policy`, `set_iam_policy`, `set_org_policy`, `setup_billing_export`, `update_project_billing_info`, `update_user` |
| `jules` | `add_user_response`, `approve_plan`, `create_session`, `get_session`, `list_sessions`, `list_sources`, `resume_session` |
| `meshy` | `apply_animation`, `image2image_generate`, `image3d_generate`, `multiimage3d_generate`, `remesh_model`, `retexture_model`, `rig_model`, `text2image_generate`, `text3d_generate` |
| `slack` | `get_bot_channels`, `list_conversations`, `list_usergroups`, `list_users`, `send_message` |
| `vault` | `generate_aws_credentials`, `get_aws_iam_role`, `get_secret`, `list_aws_iam_roles`, `list_secrets`, `read_secret` |
| `zoom` | `get_meeting`, `get_user`, `list_meetings`, `list_users` |

The CLI deliberately does not expose raw HTTP/SDK clients, sessions,
resources, authentication helpers, connector lifecycle methods, duplicate
agent-tool wrappers, Meshy persistence/webhook internals, SecretSync's
transitional Python helpers, or connector methods whose public return contract
is a raw `bool`, `str`, `None`, or SDK object. Those APIs either bypass the
Extended Data serialization/redaction boundary, duplicate a command above, or
need an application lifecycle rather than a one-shot shell command.

SecretSync access is exposed through a binding-backed facade:

```python
from vendor_fabric.secrets_sync import ProviderSession, SyncOptions, get_targets, run_pipeline

result = run_pipeline("pipeline.yaml", SyncOptions(dry_run=True))
targets = get_targets("pipeline.yaml")

print(result["success"])
print(targets["targets"])

session = ProviderSession(
    vault_address="https://vault.example.com",
    vault_token=vault_token,
    aws_region="us-east-1",
    aws_access_key_id=aws_credentials.access_key,
    aws_secret_access_key=aws_credentials.secret_key,
    aws_session_token=aws_credentials.token,
)
run_pipeline("pipeline.yaml", SyncOptions(dry_run=True), provider_session=session)
```

`vendor-fabric` consumes the `secrets_sync` import from
`secrets-sync-python-binding` and shapes those payloads into Extended Data
values. The canonical SecretSync runtime, CLI, pipeline semantics, and gopy
binding source live in `jbcom/secrets-sync`.

Connector and sync payloads are `ExtendedData` values at the boundary. Dict,
list, string, tuple, and set payloads are concrete extended subclasses, so code
can use normal container operations and extended-data methods without import
juggling.

Testing support lives in the separately published `pytest-vendor-fabric`
package. It provides connector fixtures, E2E controls, and credential guards
without forcing test-only dependencies into the runtime package.
