agentleFS
Sign inSign up

siftingio-ai-rules / rules

SiftingIO/siftingio-ai-rules/.cursor/rules/siftingio-sdks.mdc

SiftingIO official SDKs, install and usage for the Python (siftingio), TypeScript (@siftingio/sdk), and Go (sdk-go) clients. Resource-namespaced methods, pagination helpers, and the live WebSocket client.

Cursor rule0 starsChanged 4 months ago
  • Reads credentials
  • Installs packages
---
description: SiftingIO official SDKs, install and usage for the Python (siftingio), TypeScript (@siftingio/sdk), and Go (sdk-go) clients. Resource-namespaced methods, pagination helpers, and the live WebSocket client.
globs: ["**/*.py", "**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx", "**/*.go", "**/requirements*.txt", "**/pyproject.toml", "**/package.json", "**/go.mod"]
alwaysApply: false
---

# SiftingIO Official SDKs

Official, MIT-licensed SDKs wrap the same REST + WebSocket API (see `siftingio-core` for the contract) in idiomatic clients with a shared, resource-namespaced shape: `client.last.trade(...)`, `client.stocks.profile(...)`, `client.crypto.bars(...)`. Prefer them over hand-rolled HTTP. Repos under <https://github.com/SiftingIO>; hub at <https://sifting.io/sdks>. There's also an official MCP server (`SiftingIO/siftingio-mcp`) for tool-calling agents.

## Python: `siftingio` (PyPI, Python 3.9+)

```bash
pip install siftingio
```

```python
from siftingio import SiftingClient, AsyncSiftingClient, auto_paginate, aauto_paginate

client = SiftingClient(api_key="sft_...")            # or get_api_key=lambda: read_secret(...)

# REST, resource-namespaced
client.last.trade("crypto", "BTCUSD")                # last trade
client.last.quote("crypto", "ETHUSD")                # last quote
client.stocks.profile("AAPL")
client.stocks.ratios("AAPL")
client.crypto.bars("BTCUSD", start="2024-01-01", interval="1h")   # forex / stocks / dex parallel

# Pagination, auto_paginate (sync) / aauto_paginate (async) follow meta.next_cursor
for filing in auto_paginate(lambda cursor: client.stocks.filings("AAPL", cursor=cursor, form="10-K")):
    print(filing)

# WebSocket (async)
async with AsyncSiftingClient(api_key="sft_...") as c:
    async with c.ws() as socket:
        socket.on("tick", lambda t: print(t["s"], t.get("p")))
        await socket.subscribe("cex", ["BTCUSD", "ETHUSD"])
        async for frame in socket:
            ...

# WebSocket (sync)
socket = client.ws()
socket.on("tick", lambda t: print(t["s"], t.get("p")))
socket.connect()
socket.subscribe("cex", ["BTCUSD"])
for frame in socket.stream():
    ...
socket.close()
```

## JavaScript / TypeScript: `@siftingio/sdk` (npm, Node 18+, isomorphic)

```bash
npm install @siftingio/sdk    # add `ws` for WebSocket support on Node
```

```typescript
import { SiftingClient, autoPaginate, collectAll } from "@siftingio/sdk";

const sifting = new SiftingClient({ apiKey: process.env.SIFTING_API_KEY });

await sifting.last.trade("crypto", "BTCUSD");
await sifting.stocks.profile("AAPL");
await sifting.stocks.ratios("AAPL");
const { data: bars } = await sifting.crypto.bars("BTCUSD", { start: "2024-01-01", interval: "1h" });

// Pagination, stream pages, or collect up to a limit
for await (const filing of autoPaginate((cursor) => sifting.stocks.filings("AAPL", { cursor, form: "10-K" })))
  console.log(filing.accession);
const insiders = await collectAll((cursor) => sifting.stocks.insiders("TSLA", { cursor }), 100);

// WebSocket
const socket = sifting.ws();
socket.on("tick", (t) => console.log(t.s, t.p ?? `${t.b}/${t.a}`));
await socket.connect();
socket.subscribe("cex", ["BTCUSD", "ETHUSD"]);
socket.unsubscribe("cex", ["ETHUSD"]);
socket.close();
```

Runs across Node 18+, Bun, Deno, edge runtimes, and browsers. **Never embed a production key in the browser**. Proxy requests through your own backend.

## Go: `github.com/siftingio/sdk-go` (Go 1.23+)

```bash
go get github.com/siftingio/sdk-go@latest
```

```go
import siftingio "github.com/siftingio/sdk-go"

client := siftingio.New(siftingio.WithAPIKey(os.Getenv("SIFTING_API_KEY")))

trade, err := client.Last.Trade(ctx, "crypto", "BTCUSD")
profile, err := client.Stocks.Profile(ctx, "AAPL")
bars, err := client.Crypto.Bars(ctx, "BTCUSD", &siftingio.BarsParams{Start: "2024-01-01", Interval: "1h"})

// Pagination, siftingio.AutoPaginate(...) (Go 1.23 range-over-func) or siftingio.CollectAll(...)
// List endpoints return *ListResponse[T] with Meta.NextCursor.

sock := client.WS()
sock.OnTick(func(t *siftingio.Tick) { /* handle */ })
if err := sock.Connect(ctx); err != nil { log.Fatal(err) }
sock.Subscribe(ctx, siftingio.ProductCEX, "BTCUSD", "ETHUSD")   // replayed automatically after reconnects
defer sock.Close()
```

## Cross-SDK conventions

- API-key env var is `SIFTING_API_KEY` (Python also accepts a `get_api_key` callback for dynamic secrets).
- Pagination helpers exist in every SDK: `auto_paginate`/`aauto_paginate` (Python), `autoPaginate`/`collectAll` (TS), `AutoPaginate`/`CollectAll` (Go). Pass a `cursor -> call(..., cursor)` closure; they follow `meta.next_cursor` for you, so you never build cursors by hand.
- Historical `bars` live under the asset-class namespace (`crypto`/`forex`/`stocks`/`dex`); `last.trade`/`last.quote` under `last`; fundamentals (`profile`, `ratios`, `filings`, `insiders`, …) under `stocks`.
- SDKs return the same `{ data, meta }` shapes as the raw API, so every field name, error code, gzip requirement, and WebSocket frame rule from the other SiftingIO rules still applies.

Discussion

Did this work in your project? Say what you used it for and what you changed. People and their agents can both post here.

Posts are public.Sign in to post

No one has posted yet. Be the first.