AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Speckle Core Transport

skill-impertio-studio-speckle-claude-skill-package-speckle-core-transport · by Impertio-Studio

>

No reviews yet
0 installs
18 views
0.0% view→install

Install

$ agentstack add skill-impertio-studio-speckle-claude-skill-package-speckle-core-transport

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-impertio-studio-speckle-claude-skill-package-speckle-core-transport)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
4mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Speckle Core Transport? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

speckle-core-transport

Quick Reference

Transport Comparison Table

| Transport | Storage | Persistent | Network | Use Case | |-----------|---------|-----------|---------|----------| | ServerTransport | Speckle Server (HTTP) | Yes (remote) | Yes | Collaborative send/receive to shared projects | | SQLiteTransport | Local SQLite database | Yes (local) | No | Default local cache, offline access | | MemoryTransport | In-memory dictionary | No | No | Testing, temporary pipelines, benchmarking | | DiskTransport | Individual files on disk | Yes (local) | No | Project-local storage, git-tracked objects (C# only) |

Decision Tree: Choosing the Right Transport

Need to share data with others?
├── YES → ServerTransport (+ SQLiteTransport as cache)
└── NO
    ├── Need persistence across restarts?
    │   ├── YES
    │   │   ├── Need git-trackable individual files? → DiskTransport (C# only)
    │   │   └── Need fast bulk read/write? → SQLiteTransport
    │   └── NO
    │       ├── Testing or benchmarking? → MemoryTransport
    │       └── Serverless / ephemeral environment? → MemoryTransport

Critical Warnings

NEVER call ServerTransport.get_object() in Python -- it is NOT implemented and raises SpeckleException. ALWAYS use operations.receive() or copy_object_and_children() instead.

NEVER call send() with use_default_cache=False and an empty transport list -- this raises SpeckleException because there is no destination for the data.

NEVER rely on MemoryTransport for persistent storage -- all data is lost when the process exits or the transport is garbage collected.

NEVER call get_all_objects() on a large SQLiteTransport -- this loads the entire database into memory and causes memory exhaustion on large caches.

NEVER create a ServerTransport without authentication -- all Speckle Server API calls require a valid token. Construction succeeds but every operation fails.

NEVER omit CancellationToken in C# interactive applications -- without it, long send/receive operations cannot be gracefully stopped.

NEVER forget to call end_write() after manual transport writes -- batched data may not be flushed. Use operations.send() instead, which manages the lifecycle automatically.

ALWAYS use the default cache (use_default_cache=True) during send unless you have a specific reason not to -- without it, every receive requires a full re-download from the server.


Transport Interface

All transports implement a common interface that decouples serialization from storage. The serializer writes to any transport without knowing the backend.

Python: AbstractTransport

All Python transports inherit from AbstractTransport (ABC). Core methods:

| Method | Purpose | |--------|---------| | save_object(id, serialized_object) | Store one serialized object by hash | | get_object(id) -> Optional[str] | Retrieve by hash, None if not found | | has_objects(id_list) -> Dict[str, bool] | Bulk existence check | | begin_write() | Signal start of write batch | | end_write() | Flush pending writes | | save_object_from_transport(id, source) | Copy from another transport | | copy_object_and_children(id, target) | Copy object tree to target |

C#: ITransport

The C# interface adds async support, cancellation, progress reporting, and telemetry:

| Member | Purpose | |--------|---------| | SaveObject(id, serializedObject) | Enqueue object for storage | | GetObject(id) -> Task | Async retrieval by hash | | HasObjects(objectIds) -> Task> | Async bulk existence check | | BeginWrite() / EndWrite() | Write lifecycle control | | WriteComplete() -> Task | Await completion of all queued writes | | CancellationToken | Graceful cancellation support | | OnProgressAction | IProgress callback | | Elapsed | TimeSpan for performance measurement |

IBlobCapableTransport extends ITransport with BlobStorageFolder and SaveBlob(Blob) for binary file support.


ServerTransport

Communicates with a Speckle Server over HTTP. Primary transport for collaborative workflows.

Python Constructor

ServerTransport(
    stream_id: str,
    client: Optional[SpeckleClient] = None,   # Auth path 1
    account: Optional[Account] = None,         # Auth path 2
    token: Optional[str] = None,               # Auth path 3 (pair with url)
    url: Optional[str] = None,                 # Auth path 3 (pair with token)
    name: str = "RemoteTransport",
)

You MUST provide exactly one authentication path:

  1. client -- an already-authenticated SpeckleClient
  2. account -- an Account object containing token + server URL
  3. token + url -- raw credentials

C# Constructor

new ServerTransport(
    ISpeckleHttp http,
    ISdkActivityFactory activityFactory,
    Account account,
    string streamId,
    int timeoutSeconds = 60,
    string? blobStorageFolder = null
)

Uses dependency injection for ISpeckleHttp and ISdkActivityFactory. Authentication via Account.token.

Implementation Details

| Aspect | Python | C# | |--------|--------|----| | Batch upload size | 1 MB | Configurable via send buffer | | get_object() | NOT implemented (raises exception) | Async, functional | | Deduplication | Defers to copy operations | Calls HasObjects() before upload | | Background sending | No | Dedicated SendingThreadMain() thread | | Blob support | No | Yes (IBlobCapableTransport) |

Server API Endpoints

| Endpoint | Purpose | |----------|---------| | /objects/{stream_id}/{id}/single | Download single object | | /api/getobjects/{stream_id} | Batch download multiple objects |


SQLiteTransport

Persistent local storage using SQLite. Serves as the default local cache for all Speckle operations.

Constructors

Python:

SQLiteTransport(
    base_path: str = None,       # Defaults to Speckle app data path
    app_name: str = None,
    scope: str = None,           # Database filename (default: "Objects.db")
    max_batch_size_mb: float = None,
)

C#:

new SQLiteTransport(
    string? basePath = null,          // Defaults to SpecklePathProvider
    string? applicationName = null,   // Default: "Speckle"
    string? scope = null              // Default: "Data"
)

Path construction: {basePath}/{applicationName}/{scope}.db

Default Data Paths Per OS

| OS | Default Path | |----|-------------| | Windows | %APPDATA%\Speckle (typically C:\Users\{user}\AppData\Roaming\Speckle) | | macOS | ~/.config/Speckle | | Linux | $XDG_DATA_HOME/Speckle or ~/.local/share/Speckle |

Default cache database: {speckle_dir}/Data.db (C#) or {speckle_dir}/Objects.db (Python).

Write Optimization

  • Python: Accumulates objects in _current_batch, flushes via executemany() with INSERT OR IGNORE when batch size exceeds max_batch_size_mb
  • C#: Uses ConcurrentQueue with a 500ms auto-flush timer, processes up to 1,000 items per transaction

MemoryTransport

Stores objects in an in-memory dictionary. Simplest transport.

Python: Dict[str, str] backing store. save_object_from_transport() and copy_object_and_children() are NOT implemented.

C#: ConcurrentDictionary backing store. Full ITransport implementation including async methods.

Use cases: Unit testing, temporary pipelines, serverless functions, benchmarking serialization speed.

Limitation: No size limits -- large datasets consume proportional memory. All data lost on garbage collection.


DiskTransport (C# Only)

Stores each object as a separate file on the filesystem. Useful for project-local storage, git-tracked objects, network drive sharing, and human-readable debugging.

For project-local SQLite storage (better performance for large datasets), use SQLiteTransport with a custom basePath instead.


Send Flow

Python: operations.send()

send(
    base: Base,
    transports: Optional[List[AbstractTransport]] = None,
    use_default_cache: bool = True,
) -> str  # Returns root object hash

Flow:

  1. If use_default_cache=True → prepend a SQLiteTransport to the transport list
  2. If use_default_cache=False AND no transports → raise SpeckleException
  3. Create BaseObjectSerializer with all transports
  4. Serialize root object recursively -- each finished object is immediately sent to ALL transports
  5. String representations are garbage collected after sending (memory optimization)
  6. Return root object hash

C#: Operations.Send()

async Task convertedReferences)> Send(
    Base value,
    IReadOnlyCollection transports,
    IProgress? onProgressAction = null,
    CancellationToken cancellationToken = default
)

Flow:

  1. Validate: value not null, transports not empty
  2. Configure each transport with progress action and cancellation token
  3. Call BeginWrite() on all transports
  4. Serialize via SpeckleObjectSerializer
  5. Call EndWrite() on all transports (in finally block)
  6. Return tuple of (root hash, converted references dictionary)

Multi-transport: Objects are written to ALL provided transports simultaneously.


Receive Flow

Python: operations.receive()

receive(
    obj_id: str,
    remote_transport: Optional[AbstractTransport] = None,
    local_transport: Optional[AbstractTransport] = None,
) -> Base

C#: Operations.Receive()

async Task Receive(
    string objectId,
    ITransport? remoteTransport = null,
    ITransport? localTransport = null,
    IProgress? onProgressAction = null,
    CancellationToken cancellationToken = default
)

Cache-First Strategy (Both SDKs)

  1. If localTransport is None → create default SQLiteTransport
  2. Check local transport for the object
  3. If found locally → deserialize directly from cache
  4. If NOT found → call copy_object_and_children() on remote transport:
  • Download root object
  • Check which children exist locally
  • Download only missing children in batches
  • Write all to local transport
  1. Deserialize from local transport
  2. Return reconstructed Base object

The local transport is ALWAYS checked first. After a remote fetch, objects are cached locally for future use.


Caching Strategy

Content-Addressed Immutability

Speckle objects are content-addressed: every object's id is a SHA256 hash of its content. This means:

  • An object with a given id ALWAYS has the same content
  • Cached data is NEVER stale -- objects are immutable
  • New versions of conceptual objects (e.g., a modified wall) have DIFFERENT ids
  • No cache invalidation logic is needed

Cache Growth

The cache grows monotonically -- there is no built-in garbage collection or LRU eviction. Users can manually delete the cache database (it is recreated on next use), but all previously cached objects must be re-downloaded.

Deduplication During Send (C#)

  1. Serialize all objects locally
  2. Call HasObjects() on the server with the list of object ids
  3. Upload only objects the server does not already have

Sending the same data twice transmits only the delta. A model where 5% of objects changed uploads only that 5%.


Progress Reporting

C# -- IProgress

var progress = new Progress(args =>
{
    Console.WriteLine($"{args.ProgressEvent}: {args.Count}");
});
await Operations.Send(data, transports, onProgressAction: progress);

Python -- Transport Object Count

transport = ServerTransport(stream_id="...", client=client)
hash = send(my_object, transports=[transport])
# After send: transport.saved_obj_count contains the number of objects sent

Reference Links

  • [references/methods.md](references/methods.md) -- API signatures for all transport types in Python and C#
  • [references/examples.md](references/examples.md) -- Working code examples for send/receive with transports
  • [references/anti-patterns.md](references/anti-patterns.md) -- Transport misuse patterns with fixes

Official Sources

  • https://speckle.guide/dev/transports.html
  • https://speckle.guide/dev/dotnet.html
  • https://speckle.guide/dev/python.html
  • https://github.com/specklesystems/specklepy
  • https://github.com/specklesystems/speckle-sharp-sdk

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.