Metadata-Version: 2.4
Name: redd
Version: 0.1.0
Summary: Reddit Extraction and Data Dumper — a modern, async-ready library for extracting Reddit data without API keys.
Project-URL: Homepage, https://github.com/eliasbiondo/redd
Project-URL: Repository, https://github.com/eliasbiondo/redd
Project-URL: Issues, https://github.com/eliasbiondo/redd/issues
Author-email: Elias Biondo <contato@eliasbiondo.com>
License: MIT
License-File: LICENSE
Keywords: async,data,extraction,reddit,scraper
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown

<div align="center">

# 🔴 REDD

**Reddit Extraction and Data Dumper**

[![PyPI version](https://img.shields.io/pypi/v/redd.svg)](https://pypi.org/project/redd/)
[![Python](https://img.shields.io/pypi/pyversions/redd.svg)](https://pypi.org/project/redd/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

*A modern, async-ready Python library for extracting Reddit data — no API keys required.*

</div>

---

## ✨ Features

- **No API keys** — uses Reddit's public `.json` endpoints
- **Sync & Async** — choose `Redd` or `AsyncRedd` depending on your stack
- **Typed models** — frozen dataclasses, not raw dicts
- **Hexagonal architecture** — swap HTTP adapters freely
- **Auto-pagination** — fetch hundreds of posts with a single call
- **User-Agent rotation** — built-in rotation to reduce ban risk
- **Proxy support** — pass a proxy URL and you're set
- **Throttling** — configurable random sleep between paginated requests

## 📦 Installation

```bash
pip install redd
```

For **async** support (uses `httpx`):

```bash
pip install redd[async]
```

> Or with `uv`:
> ```bash
> uv add redd
> ```

## 🚀 Quick Start

### Sync

```python
from redd import Redd, Category, TimeFilter

with Redd() as r:
    # Search Reddit
    results = r.search("Python programming", limit=5)
    for item in results:
        print(f"  {item.title} → {item.url}")

    # Fetch top posts from a subreddit
    posts = r.get_subreddit_posts(
        "Python",
        limit=10,
        category=Category.TOP,
        time_filter=TimeFilter.WEEK,
    )
    for post in posts:
        print(f"  [{post.score:>5}] {post.title}")

    # Get full post details with comments
    detail = r.get_post("/r/Python/comments/abc123/example_post/")
    print(f"  {detail.title} — {len(detail.comments)} comments")

    # Scrape user activity
    items = r.get_user("spez", limit=10)
    for item in items:
        print(f"  [{item.kind}] {item.title or item.body[:80]}")
```

### Async

```python
import asyncio
from redd import AsyncRedd

async def main():
    async with AsyncRedd() as r:
        results = await r.search("machine learning", limit=5)
        for item in results:
            print(item.title)

asyncio.run(main())
```

## 📖 API Reference

### Clients

| Class | Description |
|-------|-------------|
| `Redd` | Synchronous client (uses `requests`) |
| `AsyncRedd` | Asynchronous client (uses `httpx`) |

Both support context managers and share the **exact same API surface**:

### Methods

| Method | Description |
|--------|-------------|
| `search(query, *, limit, sort, after, before)` | Search all of Reddit |
| `search_subreddit(subreddit, query, *, limit, sort, after, before)` | Search within a subreddit |
| `get_post(permalink)` | Get full post details + comment tree |
| `get_user(username, *, limit)` | Get a user's recent activity |
| `get_subreddit_posts(subreddit, *, limit, category, time_filter)` | Fetch subreddit listings |
| `get_user_posts(username, *, limit, category, time_filter)` | Fetch a user's submitted posts |
| `download_image(image_url, *, output_dir)` | Download an image |
| `close()` | Release HTTP resources |

### Models

| Model | Fields |
|-------|--------|
| `SearchResult` | `title`, `url`, `description`, `subreddit` |
| `PostDetail` | `title`, `author`, `body`, `score`, `url`, `subreddit`, `created_utc`, `num_comments`, `comments` |
| `Comment` | `author`, `body`, `score`, `replies` |
| `SubredditPost` | `title`, `author`, `permalink`, `score`, `num_comments`, `created_utc`, `subreddit`, `url`, `image_url`, `thumbnail_url` |
| `UserItem` | `kind`, `subreddit`, `url`, `created_utc`, `title`, `body` |

### Enums

| Enum | Values |
|------|--------|
| `Category` | `HOT`, `TOP`, `NEW`, `RISING` |
| `UserCategory` | `HOT`, `TOP`, `NEW` |
| `TimeFilter` | `HOUR`, `DAY`, `WEEK`, `MONTH`, `YEAR`, `ALL` |
| `SortOrder` | `RELEVANCE`, `HOT`, `TOP`, `NEW`, `COMMENTS` |

### Configuration

```python
r = Redd(
    proxy="http://user:pass@host:port",  # optional proxy
    timeout=15.0,                        # request timeout (seconds)
    rotate_user_agent=True,              # rotate UA per request
    throttle=(1.0, 3.0),                 # random sleep range between pages
)
```

## 🏗️ Architecture

REDD follows **hexagonal architecture** (ports & adapters):

```
src/redd/
├── __init__.py           # Public API
├── _client.py            # Sync client (Redd)
├── _async_client.py      # Async client (AsyncRedd)
├── _parsing.py           # JSON → domain models (I/O-free)
├── _exceptions.py        # Error hierarchy
│
├── domain/               # Pure domain layer
│   ├── models.py         # Frozen dataclasses
│   └── enums.py          # Type-safe enumerations
│
├── ports/                # Abstract interfaces
│   └── http.py           # HttpPort & AsyncHttpPort protocols
│
└── adapters/             # Concrete implementations
    ├── http_sync.py      # requests-based adapter
    └── http_async.py     # httpx-based adapter
```

## ⚠️ Disclaimer

> Use responsibly. Reddit may rate-limit or ban IPs that make excessive requests.
> Consider using rotating proxies for large-scale scraping.

## 📄 License

MIT © [Elias Biondo](mailto:contato@eliasbiondo.com)
