Skip to main content

AI-powered 3D scene assembly from natural language using OpenUSD

Project description

BowerBot

BowerBot

AI agent for OpenUSD.

From empty scene to a production-ready OpenUSD stage.

License Python OpenUSD YouTube Built by Binary Core LLC PRs Welcome


🐦 Meet BowerBot

In the rainforests of Australia and New Guinea lives one of nature's most remarkable architects: the bowerbird.

Instead of relying on appearance, the bowerbird collects, curates, and arranges objects from its environment into a carefully constructed 3D composition. Every object is chosen. Every placement is intentional.

BowerBot brings that same idea to OpenUSD.

BowerBot is an AI agent for OpenUSD, a conversational interface that helps any team using OpenUSD go from an empty scene to a production-ready stage by:

  • finding assets from any connected source (Sketchfab, local disk, company DAM, or any custom provider)
  • placing them with spatial awareness
  • authoring materials inline in ASWF-compliant asset folders
  • setting up native USD lighting (sun, dome, point, area, disk, tube)
  • validating technical correctness (units, hierarchy, references, bindings)
  • packaging the result for any USD-compatible runtime

🎯 What BowerBot Is (and Is Not)

BowerBot is:

  • A USD authoring agent for any OpenUSD pipeline: VFX, AEC, simulation, spatial computing, digital twins, robotics, e-commerce 3D
  • A conversational interface for the full authoring surface: assets, lighting, materials, validation, packaging
  • A fast way to go from 0 → production-ready scene
  • A pipeline assistant that handles technical correctness (units, hierarchy, references, bindings)
  • A pipeline guardian that catches asset issues before they reach production
  • Extensible by design: new asset sources, DCCs, and domains plug in as skills

BowerBot is NOT:

  • A final scene generator
  • A replacement for DCC tools like Maya or Omniverse
  • A system that produces perfect composition or artistic layouts

Scenes generated by BowerBot are meant to be opened, reviewed, and refined in your DCC.

Think of it as:

"Block out the scene instantly, then refine like a pro."

Pipeline Quality Built In

BowerBot enforces ASWF USD standards at every step, not just placing assets. Fixable mismatches (non-canonical folder names, external dependencies) are auto-normalized on intake so the project copy is always self-contained. Production-required invariants are validated at intake too: assets with non-identity root transforms (Maya pivot dance, unfrozen DCC exports) are refused with a clear message and the option to bake transforms into vertex data on the project copy without touching the source. Unfixable violations (wrong root prim type, missing defaultPrim, incorrect metersPerUnit, circular references, missing dependencies) are caught at assembly time with a clear message about what's wrong and how to fix it.

"The cheapest bug to fix is the one you catch before it enters the pipeline."


✨ What It Does

Watch BowerBot build real scenes end-to-end on the demo playlist on YouTube. Each video walks through a project across asset discovery, placement, materials, lighting, validation, and packaging.

Open the resulting .usda in Maya, usdview, Omniverse, Isaac Sim, or any USD-compatible tool to refine composition, lighting, materials, or downstream pipeline steps.

Projects are persistent. Close the session, come back later, and continue where you left off.


✨ Features

  • 📦 OpenUSD native: references, defaultPrim, metersPerUnit, upAxis, all correct out of the box
  • 🏗️ ASWF-compliant asset folders: geometry, materials, and lighting split into a root + layer files, per the USD Working Group guidelines
  • 🧳 Self-contained intake: non-canonical source folders are detected via USD composition, canonicalized (root.usd<folder>.usda), and external dependencies (textures, sublayers) are localized into the asset folder so the project copy is always portable
  • 🎨 Material binding: apply MaterialX or existing .usda materials to specific mesh parts
  • 💡 Native USD lighting: sun, dome, point, area, disk, and tube lights at scene or asset level
  • 🧩 Automatic unit handling: assets in cm, mm, or inches are scaled correctly at reference time
  • 📐 Geometry-aware placement: bounding-box resolved positions for surface, above, below, or nested placements
  • 🔌 Pluggable skills: connect any asset source (Sketchfab, PolyHaven, company DAM, or build your own)
  • 🧠 Multi-LLM support: OpenAI, Anthropic, and any provider via litellm
  • 📁 Project-based workflow: one folder per scene, resumable across sessions
  • Scene validation: defaultPrim, units, up-axis, reference resolution, and material binding checks
  • 📦 USDZ packaging: export for Apple Vision Pro, Omniverse, or any USD viewer
  • 🏗️ Onboarding wizard: zero-config setup in 60 seconds

Built on OpenUSD, the ASWF USD Working Group standards, and the Alliance for OpenUSD (AOUSD) core spec driven by Pixar, Apple, NVIDIA, and others.


🚀 Quick Start

Install

There are two paths for end users (pick whichever fits your environment), plus a separate path for contributors who want to modify BowerBot itself.

End users, Option A: uv (recommended)

uv manages Python and isolated tool environments for you, so you do not need to install or pin Python yourself.

uv tool install bowerbot

End users, Option B: pip

If you already maintain a Python 3.12+ environment, plain pip works:

pip install bowerbot

Contributors: developer install

To modify BowerBot itself, clone the repo and let uv manage the dev environment:

git clone https://github.com/binary-core-llc/bowerbot.git
cd bowerbot
uv sync
uv run bowerbot onboard

First-time setup

bowerbot onboard

The wizard asks for your LLM API key, your asset library directory, and your projects directory, then writes ~/.bowerbot/config.json. One file, one place, no .env.

Create a project and start building

bowerbot new "Coffee Shop"
bowerbot open coffee_shop

To plug in asset providers like Sketchfab, see Skills below.


📺 Tutorials

New to BowerBot? Watch the tutorial playlist on YouTube for setup walkthroughs, scene building demos, and tips for working with USD pipelines.


🩹 Troubleshooting

Stuck on something? See docs/TROUBLESHOOTING.md for common issues: working alongside a DCC, skill installation, CLI rendering on Windows, and LLM tool-calling pitfalls.


🛠️ CLI Commands

Command Description
bowerbot new "name" Create a new project
bowerbot open name Open a project and start chatting
bowerbot list Show all projects
bowerbot chat Auto-detect project in current directory
bowerbot build "prompt" Single-shot build (auto-creates project)
bowerbot skills List scene builder tools and enabled skills
bowerbot info Show current configuration
bowerbot onboard First-time setup wizard

📁 Projects

Each project is a self-contained folder with metadata, scene, assets, and packaged output in one place:

scenes/coffee_shop/
  project.json    # Metadata: name, created_at, updated_at, scene_file
  scene.usda      # The USD stage (references only, clean and readable)
  scene.usdz      # Packaged output (Apple Vision Pro, Omniverse, etc.)
  assets/         # ASWF folders + self-contained USDZs used by this scene
  textures/       # Scene-level textures (HDRI maps for DomeLights, etc.)

Projects are resumable. Close the session, come back later, and continue where you left off:

$ bowerbot open coffee_shop
# Project: Coffee Shop
# Scene: scene.usda (5 object(s))

You: Show me the scene structure
BowerBot: Scene has 5 objects...

You: Remove Table_03
BowerBot: Removed /Scene/Furniture/Table_03

🔄 How It Works

BowerBot is conversational: you tell it what you want and it uses the right tools to build your scene. Behind the scenes, it manages asset discovery, USD composition, materials, lighting, and more.

Asset Discovery

BowerBot searches for assets across all connected sources, prioritizing what's already available:

  1. Local assets first: BowerBot checks your local asset directory (assets_dir in config.json) for USD files (.usd, .usda, .usdc, .usdz). This includes anything you've exported from Maya, Houdini, Blender, or any DCC tool, as well as assets previously downloaded from cloud providers.

  2. Cloud providers if needed: If the asset isn't found locally, BowerBot searches connected providers (any installed skill, e.g. Sketchfab) and downloads the asset to your local directory.

  3. All downloads are cached locally: Once an asset is downloaded from any source, it lives in your assets_dir and is available for all future projects without re-downloading.

Scene Assembly

When you ask BowerBot to place an asset, it routes by what the source looks like and always produces a self-contained ASWF folder in the project:

  • Folder with a detectable root (canonical wall/wall.usda, or non-canonical wall/root.usd + wall/geo.usd + wall/mtl.usd): the root is identified via USD composition (the file no sibling depends on), the folder is copied into the project, the root is canonicalized to <folder>.usda, sibling references are rewritten, and any externally-referenced textures or layers are localized into the folder so the output is portable.
  • Loose USD geometry (.usd, .usda, .usdc from your DCC exports): wrapped in a fresh ASWF folder named after the file stem, producing <stem>/<stem>.usda + geo.usda.
  • USDZ files (from Sketchfab, DAMs, etc.): placed as-is since they're already self-contained.

When an asset can't be safely intaken (missing external dependencies, or a folder with multiple independent USDs and no clear root), BowerBot refuses with a message naming the conflict instead of guessing.

Material Workflow

When you apply materials to an asset, BowerBot writes them into the asset folder's mtl.usda, not the scene file. The scene stays clean with only references:

You: Apply wood material to the table top
BowerBot: [searches local assets for "wood" materials]
         [discovers mesh parts: table top, legs, frame]
         [writes material definition + binding into assets/table/mtl.usda]
         Bound /table/mtl/wood_varnished to table top

The result is a production-ready asset folder:

assets/single_table/
  single_table.usda   <- root (references geo + mtl)
  geo.usda            <- geometry (untouched from source)
  mtl.usda            <- materials inline + bindings

Scene Output

The scene file (scene.usda) contains only references and lights: no material data, no geometry copies, no sublayers. Clean and readable:

def Xform "Scene" (kind = "assembly") {
    def Xform "Furniture" {
        def Xform "Table_01" {
            xformOp:translate = (5, 0, 4)
            xformOp:scale = (0.01, 0.01, 0.01)
            def Xform "asset" (
                references = @assets/single_table/single_table.usda@
            ) { }
        }
    }
    def Xform "Lighting" {
        def DistantLight "Sun_01" { ... }
        def DomeLight "Environment_01" { ... }
    }
}

Open it in Maya, usdview, Omniverse, Isaac Sim, or any USD-compatible tool to refine.


🔌 Skills

Skills extend BowerBot with external asset providers, DCC connectors, and simulation runtimes. Each skill is a separate Python package, discovered at runtime through Python entry points (bowerbot.skills). The skill SDK lives in bowerbot.skills; skills themselves ship and version on their own. See Installing a skill below for the walkthrough.

Scene Builder Tools

BowerBot's core tools for building USD scenes:

Tool Description
create_stage Initialize a new USD scene with standard hierarchy
place_asset Add an asset (auto-creates ASWF folder for loose geometry)
place_asset_inside Nest an asset inside an ASWF container's contents.usda
move_asset Reposition an existing object without creating duplicates
compute_grid_layout Calculate evenly spaced positions
list_scene Show current scene with positions and bounding boxes
rename_prim Move/rename objects in the hierarchy
remove_prim Delete objects from the scene
create_light Add native USD lights (sun, dome, point, area, disk, tube)
update_light Modify an existing light's properties
remove_light Delete a light from the scene or asset
create_material Author a procedural MaterialX material and bind it to a prim
bind_material Apply a material to a specific mesh part (writes into asset mtl.usda)
remove_material Clear material binding from a prim
list_materials Show all materials and their bindings
cleanup_unused_materials Prune material definitions no prim binds to (per asset or project-wide)
cleanup_unused_contents Prune empty contents.usda scopes left after removing nested assets
freeze_asset Bake non-identity root transforms (Maya/Houdini unfrozen exports) into vertex data, per asset or project-wide
list_prim_children Discover mesh parts inside a referenced asset
list_project_assets Show asset folders with scene usage status
delete_project_asset Remove an asset folder (checks references first)
delete_project_texture Remove a texture file (checks references first)
search_assets Find USD assets in the user's library by keyword (geo, mtl, package)
list_assets List every USD asset in the user's library, classified by category
search_textures Find HDRIs and material maps in the asset library by keyword
list_textures List every HDRI and material map in the asset library
validate_scene Check for USD errors
package_scene Bundle as .usdz

Extension Skills

First-party skills

Maintained by Binary Core LLC alongside the BowerBot core.

Skill Install What it does
bowerbot-skill-sketchfab pip install bowerbot-skill-sketchfab Searches and downloads models from your own Sketchfab account in USDZ format.

Community skills

Built by external contributors, published to PyPI under each author's namespace, and listed here for discoverability. To add yours, open a PR on this README adding a row to the table below. The skill must be open source, installable via pip from public PyPI, and follow the contract in CONTRIBUTING.md.

Skill Author Install What it does
be the first

When this list grows large enough to warrant tooling, it becomes the BowerHub skill registry.

Installing a skill

Three steps. Sketchfab as the worked example.

1. Install the skill alongside BowerBot. With uv, add it to the same tool environment:

uv tool install bowerbot --with bowerbot-skill-sketchfab

To add more skills later, rerun with every --with you want and --reinstall:

uv tool install bowerbot --with bowerbot-skill-sketchfab --with bowerbot-skill-polyhaven --reinstall

If you used plain pip to install BowerBot, install the skill in the same Python environment:

pip install bowerbot-skill-sketchfab

2. Get any credentials the skill needs. Sketchfab requires an API token from https://sketchfab.com/settings/password. Each skill's README documents what credentials (if any) it needs.

3. Add the skill's config block to ~/.bowerbot/config.json:

"skills": {
  "sketchfab": {
    "enabled": true,
    "config": { "token": "your-sketchfab-token" }
  }
}

That's it. BowerBot auto-discovers the skill via Python entry points the next time you run it. The exact shape of config is per-skill; consult the skill's README.

Verifying a skill is installed

Three commands, in increasing depth. All work on Windows, macOS, and Linux.

1. Ask BowerBot what it sees:

bowerbot skills

Lists the core scene-builder tools plus every extension skill the registry has loaded successfully. If your skill shows under "Extension skills" with its tools, you are done.

2. If it does not appear, check the package is installed:

pip show bowerbot-skill-sketchfab

If the package is installed, this prints its name, version, and location. If not, it prints Package(s) not found and exits non-zero. Install it (see Installing a skill above). Replace bowerbot-skill-sketchfab with whichever skill you are checking.

3. If the package is installed but BowerBot still does not see it, inspect the entry-point registration directly:

python -c "from importlib.metadata import entry_points; print('\n'.join(f'{ep.name} -> {ep.value}' for ep in entry_points(group='bowerbot.skills')))"

If your skill does not appear in this output despite being pip-installed, the skill's pyproject.toml is missing or broken. File an issue on the skill's repo. If the skill does appear here but bowerbot skills still does not show it, the gap is in your ~/.bowerbot/config.json: the skill's block is missing, enabled: false, or the credentials fail validate_config().

Private and in-house skills

Skills do not have to be public. Install from a private PyPI index, a git URL, or a local path:

# Private PyPI
pip install bowerbot-skill-acme --index-url https://pypi.acme.internal/

# Direct git URL (any host)
pip install git+ssh://git@github.com/acme/bowerbot-skill-acme.git

# Local path during development
pip install -e /path/to/skill

Entry-point discovery works the same in all three cases.

Trust

A skill's SKILL.md is injected into the LLM's system prompt, and its tools run with the same access as core tools. Only install skills you trust. Open-source skills are auditable; closed-source skills should come from a vendor you have a relationship with. The first-party table above is the only set Binary Core has audited end-to-end.


⚙️ Configuration

All settings live in ~/.bowerbot/config.json. The skills block holds the config for any skill packages you've installed; the example below shows what it looks like once you've installed bowerbot-skill-sketchfab (see Skills). A fresh install starts with "skills": {}.

{
  "llm": {
    "model": "gpt-4.1",
    "api_key": "sk-...",
    "temperature": 0.1,
    "max_tokens": 4096,
    "context_window": null,
    "summarization_threshold": 0.75,
    "num_retries": 3,
    "request_timeout": 120.0,
    "max_tool_rounds": 25
  },
  "scene_defaults": {
    "meters_per_unit": 1.0,
    "up_axis": "Y",
    "default_room_bounds": [10.0, 3.0, 8.0]
  },
  "skills": {
    "sketchfab": {
      "enabled": true,
      "config": { "token": "your-sketchfab-token" }
    }
  },
  "assets_dir": "./assets",
  "projects_dir": "./scenes"
}

Switch models by changing one line:

{ "model": "gpt-4.1" }
{ "model": "anthropic/claude-sonnet-4-6" }
{ "model": "deepseek/deepseek-chat" }

Tested Models

Model Tool Calling Instruction Following Recommended
gpt-4.1 Excellent Excellent Yes (default)
gpt-4.1-mini Good Good Yes (budget)
gpt-4o Poor Poor No (skips tool calls, ignores SKILL.md)
anthropic/claude-sonnet-4-6 Excellent Excellent Yes

BowerBot relies heavily on tool calling and SKILL.md instructions. Models that don't follow tool-calling patterns reliably will produce poor results.

Token Management

BowerBot automatically manages conversation context to stay within model limits. Two settings control this:

Setting Default Description
context_window null Context window size in tokens. null = auto-detect from the model.
summarization_threshold 0.75 Fraction of context budget that triggers history summarization.

Additional tuning options (usually don't need changing):

Setting Default Description
tool_result_age_threshold 2 User turns before old tool results are compressed.
min_keep_recent 6 Minimum recent messages always kept verbatim.
summary_max_tokens 512 Max tokens for the summarization LLM call.

Tool-Calling Loop

BowerBot runs a loop where the LLM requests tool calls, BowerBot executes them, and the results are fed back. Complex requests (e.g. binding materials to many mesh parts at once) can require many rounds.

Setting Default Description
max_tool_rounds 25 Maximum LLM ↔ tool exchange rounds per request. Increase if BowerBot stops with "Reached maximum tool-calling rounds" on legitimate workflows.

Error Recovery

BowerBot automatically handles transient API errors:

Setting Default Description
num_retries 3 Retries for rate limits and transient errors (429, 500, 503).
request_timeout 120.0 Seconds before a request times out.
  • Rate limits and transient errors are retried automatically with exponential backoff.
  • Validation errors are fed back to the LLM so it can auto-fix issues and re-validate.
  • Permanent errors (bad API key, unknown model) show a clear message without crashing.

🏗️ Architecture

BowerBot is organized FastAPI-style:

  • schemas/ describe data (pydantic models + enums)
  • utils/ are pure-function primitives (no SceneState, no orchestration)
  • services/ are state-aware orchestrators, one function per tool, signature (state, params), calls utils and other services freely, raises on errors
  • tools/ are the LLM-facing surface, thin adapters that guard preconditions, call ONE service, wrap the result in ToolResult

Adding a feature is the same three-file change every time: schema, service, tool.

src/bowerbot/
  agent.py            # LLM tool-calling loop and prompt assembly
  cli.py              # Click CLI
  config.py           # Settings from ~/.bowerbot/config.json
  project.py          # Project lifecycle (create / load / resume)
  state.py            # SceneState: the context threaded through every tool handler
  dispatcher.py       # Aggregates tool defs + routes tool calls to handlers
  token_manager.py    # Conversation compression and summarization

  prompts/            # LLM instructions as markdown (editable without code changes)
    core.md
    scene_building.md

  schemas/            # Pydantic models and enums, grouped by domain
    assets.py         #   Asset formats, categories, ASWF layer names, metadata
    transforms.py     #   TransformParams, PositionMode, PlacementCategory, SceneObject
    lights.py         #   LightType, LightParams
    materials.py      #   MaterialXShaders, ProceduralMaterialParams
    textures.py       #   HDRI / image / texture-category enums
    validation.py     #   Severity, ValidationIssue, ValidationResult

  services/           # State-aware orchestrators, one per tools module
    stage_service.py       #   create_stage, list_scene, rename_prim, move_asset, ...
    asset_service.py       #   place_asset, place_asset_inside, list/delete_project_*
    library_service.py     #   list_assets, search_assets, find_package_for
    light_service.py       #   create_light, update_light, remove_light
    material_service.py    #   create_material, bind_material, list/remove/cleanup
    texture_service.py     #   list_textures, search_textures
    validation_service.py  #   validate_scene, package_scene

  tools/              # LLM-facing API layer (tool defs + thin handlers)
    _helpers.py            #   Precondition guards (require_stage / project / library)
    stage_tools.py         #   create_stage, list_scene, rename_prim, move_asset, ...
    asset_tools.py         #   place_asset, place_asset_inside, list/delete_project_*
    library_tools.py       #   search_assets, list_assets
    light_tools.py         #   create_light, update_light, remove_light
    material_tools.py      #   create_material, bind_material, list/remove_material
    texture_tools.py       #   search_textures, list_textures
    validation_tools.py    #   validate_scene, package_scene

  skills/             # Skill SDK. The contract every skill implements.
                      # Skills themselves ship as separate pip packages.
    base.py                #   Skill, SkillContext, SkillConfigError,
                           #   SkillCategory, Tool, ToolResult
    registry.py            #   Entry-point discovery and tool routing

  utils/              # Pure-function primitives shared by services
    stage_utils.py           #   Stage create/open/save, references, transforms, prims,
                             #   ref-path scanning, LIGHT_CLASSES
    asset_intake_utils.py    #   intake_folder, intake_usdz, create_asset_folder, ASWF
    asset_folder_utils.py    #   ASWF folder primitives (detect root, layer scopes,
                             #   resolve_asset_dir_for_prim)
    library_utils.py         #   scan_library, find_package_for
    light_utils.py           #   light_in_folder primitives, HDRI staging
    material_utils.py        #   material_in_folder primitives, find_first_material
    texture_utils.py         #   find_textures, copy_texture_to_project
    validation_utils.py      #   validate_stage, package_to_usdz
    geometry_utils.py        #   Bounds, unit conversion, layout math
    dependency_utils.py      #   USD dependency tree walker
    naming_utils.py          #   Name sanitization for files, prims, projects
  gateway/            # Future: FastAPI + MCP server

Design principles

  • One tools module, one service: every service module backs exactly one tool surface, with one orchestrator per tool. Shared primitives live in utils/, called freely by any service.
  • Functions only in tools / services / utils: classes live in schemas/ (pydantic models, enums) and a small set of state objects (SceneState, Project).
  • Tools are thin: guard preconditions, call ONE service, wrap in ToolResult. No business logic, no util calls, no cross-service routing.
  • Services own orchestration: take (state, params), do the cross-service and multi-util work, mutate state, raise on errors.
  • Utils are pure primitives: no SceneState, no other services. Composable building blocks.
  • State lives in one place: SceneState holds the open stage, the project binding, the asset library path, and the object counter; tool handlers thread it into service calls.
  • All pxr is in services/ and utils/: the rest of the codebase never imports pxr directly.
  • Prompts are content: editable .md files, not Python constants.
  • Skills are external integrations: new asset providers ship as Python packages discovered via entry points.
  • One config file: ~/.bowerbot/config.json, no .env.

📐 USD Compliance

Every scene follows OpenUSD best practices and the ASWF asset structure guidelines:

Scene level

  • metersPerUnit = 1.0, upAxis = "Y", defaultPrim always set
  • Standard hierarchy: /Scene/Architecture, /Scene/Furniture, /Scene/Products, /Scene/Lighting, /Scene/Props
  • References only: no inline geometry, no scattered material sublayers
  • Wrapper-prim pattern isolates scene-level transforms from asset-internal ones, so DCC export transforms (Maya pivots, rotations) stay untouched
  • Pre-packaging validator checks defaultPrim, units, up-axis, reference resolution, and material bindings

Asset level

  • References (not sublayers) per ASWF guidelines, for predictable opinion strength
  • Materials inline in mtl.usda, lights inline in lgt.usda, nested references in contents.usda
  • Automatic metersPerUnit conversion across composition boundaries
  • Identity root transforms enforced on intake: pivot dances, baked rotations, and other unfrozen DCC export ops are rejected (or baked into vertex data with explicit user consent), so nested placements compose predictably
  • Nested placements mirror the scene-level wrapper convention (a wrapper Xform holds the per-instance transform, an inner /asset child holds the reference arc), and move_asset / remove_prim on a nested path route writes to contents.usda instead of authoring per-instance overrides at scene level

🗺️ Roadmap

What's next for BowerBot. Contributions welcome:

  • USD Variant Sets: ASWF-compliant variants on asset root prims (materials, geometry, lighting, configurations, and more)
  • Scene templates: JSON-driven scene assembly with asset resolution
  • DCC exporter: Maya/Houdini tool to export scene layout as BowerBot JSON
  • More asset providers: Fab, PolyHaven, Objaverse, CGTrader skills
  • MCP Gateway: FastAPI server for web UI and external AI clients
  • Web UI: chat panel + live 3D viewport
  • BowerHub: community skill registry

🤝 Contributing

BowerBot is open source and welcomes contributions. The best way to start is writing a new skill for an asset provider, DCC, or simulation runtime you use. Skills ship as separate pip packages discovered through the bowerbot.skills entry-point group.

Read CONTRIBUTING.md for the skill contract, the required FastAPI internal layout, and a worked pyproject.toml example for a stand-alone skill package.

For a complete reference, see bowerbot-skill-sketchfab: a real first-party skill on PyPI, with the production layout, entry-point registration, validation, and release pipeline you can mirror for your own.


📄 License

Copyright 2026 Binary Core LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Built with 🐦 by Binary Core LLC

"The bowerbird doesn't have the flashiest feathers. It just builds the most compelling world."

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bowerbot-1.6.0.tar.gz (91.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bowerbot-1.6.0-py3-none-any.whl (111.0 kB view details)

Uploaded Python 3

File details

Details for the file bowerbot-1.6.0.tar.gz.

File metadata

  • Download URL: bowerbot-1.6.0.tar.gz
  • Upload date:
  • Size: 91.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for bowerbot-1.6.0.tar.gz
Algorithm Hash digest
SHA256 b473745580477c0ed0ce17b19c082e74feda45b931b342576c32dae45a1fa19f
MD5 aafefaf84790063ab7fffb9d1909733d
BLAKE2b-256 c7e8bf8fe69c21b6aeaa31d27defbc6eb57970a72058c143d24ba8dabe6aa055

See more details on using hashes here.

Provenance

The following attestation bundles were made for bowerbot-1.6.0.tar.gz:

Publisher: release-please.yml on binary-core-llc/bowerbot

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file bowerbot-1.6.0-py3-none-any.whl.

File metadata

  • Download URL: bowerbot-1.6.0-py3-none-any.whl
  • Upload date:
  • Size: 111.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for bowerbot-1.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1917d657fc8f013e6b9f5e103a72f9b8559adc466779ed4e8333567fb93122ca
MD5 64cad642413f21600fda4113b8f2fab1
BLAKE2b-256 0b4177c084f7446494bc911f178357d1173aff8c3bd824cd85a0973583c9819b

See more details on using hashes here.

Provenance

The following attestation bundles were made for bowerbot-1.6.0-py3-none-any.whl:

Publisher: release-please.yml on binary-core-llc/bowerbot

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page