stophy 0.3.0 → 1.0.1
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.
- package/README.md +84 -84
- package/dist/index.cjs +558 -334
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +22667 -1403
- package/dist/index.d.ts +22667 -1403
- package/dist/index.js +558 -334
- package/dist/index.js.map +1 -1
- package/package.json +18 -10
package/README.md
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
Official TypeScript SDK for [Stophy](https://stophy.dev) **YouTube context API for AI agents**. Search videos, fetch transcripts, read comments and live chat, inspect channels and playlists, use YouTube Music and YouTube Kids, and get autocomplete suggestions, all returned as structured JSON.
|
|
1
|
+
# Stophy for TypeScript
|
|
4
2
|
|
|
3
|
+
Live data from 40+ sites for AI agents in TypeScript: web search, YouTube, Reddit, Google Maps, Amazon, jobs, real estate, ads, stocks and crypto. Every method and result is typed.
|
|
5
4
|
|
|
6
5
|
## Install
|
|
7
6
|
|
|
@@ -9,112 +8,113 @@ Official TypeScript SDK for [Stophy](https://stophy.dev) **YouTube context API
|
|
|
9
8
|
npm install stophy
|
|
10
9
|
```
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
## Quick start
|
|
11
|
+
## Try it without a key
|
|
15
12
|
|
|
16
13
|
```ts
|
|
17
14
|
import { Stophy } from "stophy";
|
|
18
15
|
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
"https://www.youtube.com/watch?v=D7liwdjvhWc",
|
|
22
|
-
);
|
|
23
|
-
console.log(result.data.text);
|
|
16
|
+
const result = await new Stophy().web.search({ query: "bun runtime" });
|
|
17
|
+
console.log(result.data.results);
|
|
24
18
|
```
|
|
25
19
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
| `stophy.transcript(url)` | Timestamped captions and full text |
|
|
32
|
-
| `stophy.comments(url, options?)` | Top-level comments |
|
|
33
|
-
| `stophy.replies(token)` | Replies for a comment thread |
|
|
34
|
-
| `stophy.liveChat(url, options?)` | Live stream chat messages |
|
|
35
|
-
| `stophy.search(query, options?)` | Search with filters |
|
|
36
|
-
| `stophy.channel(url, options?)` | Channel metadata and content |
|
|
37
|
-
| `stophy.playlist(url, options?)` | Playlist items, paginated |
|
|
38
|
-
| `stophy.suggest(query, options?)` | Search autocomplete suggestions |
|
|
39
|
-
| `stophy.music(body)` | YouTube Music search, suggestions, songs, lyrics, albums, artists, playlists |
|
|
40
|
-
| `stophy.kids(body)` | YouTube Kids search and video metadata |
|
|
41
|
-
| `stophy.credits()` | Current credit balance |
|
|
42
|
-
| `stophy.logs(query?)` | Recent request logs |
|
|
43
|
-
| `stophy.usage(query?)` | Daily credit/request counts |
|
|
44
|
-
|
|
45
|
-
### Examples
|
|
20
|
+
Web search, YouTube search, and YouTube transcripts work without a key, with a small free allowance. Every other method throws a `StophyError` with the code `unauthorized`.
|
|
21
|
+
|
|
22
|
+
## Use an API key
|
|
23
|
+
|
|
24
|
+
Get a key from the [dashboard](https://stophy.dev/dashboard). Keys start with `st_`. Set it as `STOPHY_API_KEY`, or pass it in:
|
|
46
25
|
|
|
47
26
|
```ts
|
|
48
|
-
|
|
49
|
-
const results = await stophy.search("typescript tutorial", {
|
|
50
|
-
sortBy: "popularity",
|
|
51
|
-
duration: "long",
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
// Comments (top-level), then replies to a comment.
|
|
55
|
-
// `video()` is overloaded on `type`, so `data` is typed - no casts needed.
|
|
56
|
-
const comments = await stophy.comments(videoUrl, { sortBy: "top" });
|
|
57
|
-
const firstReplyToken = comments.data.items[0]?.repliesToken;
|
|
58
|
-
if (firstReplyToken) {
|
|
59
|
-
const replies = await stophy.replies(firstReplyToken);
|
|
60
|
-
}
|
|
27
|
+
const stophy = new Stophy({ apiKey: "st_..." });
|
|
61
28
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
tab: "video",
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
// Autocomplete
|
|
68
|
-
const { data: s } = await stophy.suggest("react", { hl: "en", gl: "US" });
|
|
69
|
-
console.log(s.suggestions);
|
|
70
|
-
|
|
71
|
-
// YouTube Music
|
|
72
|
-
const music = await stophy.music({
|
|
73
|
-
type: "search",
|
|
74
|
-
q: "lofi",
|
|
75
|
-
searchType: "song",
|
|
76
|
-
});
|
|
77
|
-
console.log(music.data.items);
|
|
78
|
-
|
|
79
|
-
// YouTube Kids
|
|
80
|
-
const kids = await stophy.kids({ type: "search", q: "science" });
|
|
81
|
-
console.log(kids.data.items);
|
|
82
|
-
|
|
83
|
-
// Account
|
|
84
|
-
console.log((await stophy.credits()).data.credits);
|
|
29
|
+
const videos = await stophy.youtube.search({ query: "bun runtime", limit: 5 });
|
|
30
|
+
console.log(videos.data.results);
|
|
85
31
|
```
|
|
86
32
|
|
|
87
|
-
|
|
33
|
+
`new Stophy("st_...")` works too.
|
|
34
|
+
|
|
35
|
+
Methods follow the source and the command: `stophy.maps.search(...)`, `stophy.reddit.subreddit(...)`, `stophy.youtube.comments.replies(...)`. Each result has `data`, `creditsUsed`, and `requestId`.
|
|
36
|
+
|
|
37
|
+
## More sources
|
|
38
|
+
|
|
39
|
+
A YouTube transcript, Reddit posts, Google Maps reviews and an Amazon product:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
const stophy = new Stophy({ apiKey: "st_..." });
|
|
43
|
+
|
|
44
|
+
const transcript = await stophy.youtube.transcript({ video: "dQw4w9WgXcQ", includeTimestamps: true });
|
|
45
|
+
console.log(transcript.data.text, transcript.data.segments);
|
|
46
|
+
|
|
47
|
+
const posts = await stophy.reddit.search({ query: "bun runtime", sort: "top", within: "month" });
|
|
48
|
+
console.log(posts.data.results);
|
|
49
|
+
|
|
50
|
+
const places = await stophy.maps.search({ query: "coffee", near: "Austin, TX", limit: 5 });
|
|
51
|
+
const placeId = places.data.places[0]?.id;
|
|
52
|
+
if (placeId) {
|
|
53
|
+
const reviews = await stophy.maps.reviews({ place: placeId, limit: 20 });
|
|
54
|
+
console.log(reviews.data.reviews);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const product = await stophy.amazon.product({ product: "B08N5WRWNW", country: "us" });
|
|
58
|
+
console.log(product.data.product.title, product.data.product.price);
|
|
59
|
+
```
|
|
88
60
|
|
|
89
|
-
|
|
61
|
+
## Get markdown for a model
|
|
90
62
|
|
|
91
63
|
```ts
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
token = page.data.continuationToken ?? undefined;
|
|
97
|
-
} while (token);
|
|
64
|
+
const markdown = await stophy.youtube.search(
|
|
65
|
+
{ query: "bun runtime", limit: 5 },
|
|
66
|
+
{ format: "markdown" },
|
|
67
|
+
);
|
|
98
68
|
```
|
|
99
69
|
|
|
100
|
-
|
|
70
|
+
With `format: "markdown"`, the method returns a string.
|
|
71
|
+
|
|
72
|
+
## Get the next page
|
|
73
|
+
|
|
74
|
+
When there are more results, `data.cursor` is set. Pass it back to get the next page:
|
|
101
75
|
|
|
102
|
-
|
|
76
|
+
```ts
|
|
77
|
+
const first = await stophy.reddit.search({ query: "bun" });
|
|
78
|
+
const next = await stophy.reddit.search({ query: "bun", cursor: first.data.cursor });
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Handle errors
|
|
103
82
|
|
|
104
83
|
```ts
|
|
105
|
-
import {
|
|
84
|
+
import { StophyError } from "stophy";
|
|
106
85
|
|
|
107
86
|
try {
|
|
108
|
-
await stophy.
|
|
109
|
-
} catch (
|
|
110
|
-
if (
|
|
111
|
-
console.error
|
|
112
|
-
// err.code: "UNAUTHORIZED" | "INSUFFICIENT_CREDITS" | "BAD_REQUEST" |
|
|
113
|
-
// "INVALID_INPUT" | "NOT_FOUND" | "CONCURRENCY_LIMITED" | "INTERNAL_ERROR"
|
|
87
|
+
await stophy.reddit.search({ query: "bun" });
|
|
88
|
+
} catch (error) {
|
|
89
|
+
if (error instanceof StophyError) {
|
|
90
|
+
console.log(error.code, error.retryable, error.retryAfterSeconds);
|
|
114
91
|
}
|
|
115
92
|
}
|
|
116
93
|
```
|
|
117
94
|
|
|
95
|
+
`StophyError` has `code`, `message`, `retryable`, `retryAfterSeconds`, `status`, and `requestId`.
|
|
96
|
+
|
|
97
|
+
The SDK retries network errors and the HTTP statuses 429, 500, 502, 503, and 504, and it waits as long as the API asks. If the API asks for a wait longer than 60 seconds, the SDK throws right away with `retryAfterSeconds` set.
|
|
98
|
+
|
|
99
|
+
## Options
|
|
100
|
+
|
|
101
|
+
| Option | Default | What it does |
|
|
102
|
+
| --- | --- | --- |
|
|
103
|
+
| `apiKey` | `STOPHY_API_KEY` | Your API key |
|
|
104
|
+
| `baseUrl` | `STOPHY_BASE_URL`, or the Stophy API | The server to call |
|
|
105
|
+
| `maxRetries` | `2` | Retries per request. `0` turns retries off. |
|
|
106
|
+
| `timeoutMs` | `30000` | Time limit for each attempt. A timed-out attempt is not retried. |
|
|
107
|
+
|
|
108
|
+
Each method also takes `signal` to cancel the request.
|
|
109
|
+
|
|
110
|
+
## Check your account
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
const usage = await stophy.usage();
|
|
114
|
+
const logs = await stophy.logs({ days: 7, page: 0 });
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
`usage` returns your balance and your all-time usage. `logs` returns your recent requests. Both need an API key.
|
|
118
118
|
|
|
119
119
|
## License
|
|
120
120
|
|