Metadata-Version: 2.4
Name: vivly
Version: 0.5.0b1
Summary: Python client + CLI for the Vivly social-data API (X / Reddit) with smart prompt-based routing.
Project-URL: Homepage, https://reddit-dev.vivly.in
Author-email: Vivly <vg@vivly.in>
License: MIT
License-File: LICENSE
Keywords: reddit,scraping,twitter,vivly,x
Classifier: Development Status :: 3 - Alpha
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: WWW/HTTP
Requires-Python: >=3.9
Requires-Dist: httpx>=0.24
Requires-Dist: python-dotenv>=1.0
Provides-Extra: dev
Requires-Dist: build; extra == 'dev'
Requires-Dist: pytest>=7; extra == 'dev'
Requires-Dist: twine; extra == 'dev'
Description-Content-Type: text/markdown

# vivly

Python client for the Vivly social-data API. One bearer key, two live sources:
**X (Twitter)** and **Reddit**, plus a smart **router** that picks sources from a
plain-language prompt.

## Install

This is a beta release, so the `--pre` flag is required:

```bash
pip install --pre vivly==0.5.0b1
```

## Authenticate

The client needs a personal access token (looks like `vk_live_...`). Two ways to
provide it:

```bash
# Option A: log in interactively (opens a browser, stores the token at
# ~/.config/vivly/config.json with 0600 perms)
vivly login

# Option B: set it yourself if you were handed a token
export VIVLY_API_KEY="vk_live_..."
```

A `.env` file in the working directory is auto-loaded. Resolution order:
explicit `api_key=` argument, then `VIVLY_API_KEY` (or legacy `VIVLY_SKILL_KEY`),
then `.env`, then `~/.config/vivly/config.json`.

## Usage

```python
from vivly import VivlyClient

with VivlyClient() as v:
    # Reddit: one-shot retrieval. Auto-discovers subreddits, searches them,
    # and LLM-filters the results for relevance.
    r = v.reddit.search("claude code agents", max_posts=10)
    for post in r["posts"]:
        print(post["score"], post["title"], post["url"])

    # X / Twitter: blocking helper that starts a scrape, polls, and returns items.
    # (Runs a paid third-party actor server-side; expect a few seconds to minutes.)
    tweets = v.x.scrape('"san antonio" arena Spurs lang:en', max_items=50)
    for t in tweets:
        print(t["metrics"]["likes"], t["text"][:80])

    # Smart router: describe what you want; it plans + runs the right sources.
    result = v.route("what are people saying about claude code on reddit",
                     force_sources=["reddit"], max_items=20)
```

If you'd rather drive the X scrape yourself instead of the blocking helper:

```python
started = v.x.scrape_start("query lang:en", max_items=50)
status  = v.x.scrape_status(started["run_id"])
items   = v.x.scrape_items(started["dataset_id"])
```

## Errors

```python
from vivly import VivlyError, AuthError, RateLimitError, NotFoundError
```

`AuthError` (401/403) usually means a missing, revoked, or mistyped token.

## License

MIT
