Metadata-Version: 2.4
Name: dropreply
Version: 1.0.0
Summary: Official Python SDK for DropReply — publish replies on Reddit & X
Home-page: https://dropreply.com
Author: DropReply
Author-email: support@dropreply.com
License: MIT
Project-URL: Documentation, https://docs.dropreply.com
Project-URL: Source, https://github.com/dropreply/dropreply-python
Keywords: dropreply reddit twitter api sdk social-media replies
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
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 :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.7
Description-Content-Type: text/markdown
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: keywords
Dynamic: license
Dynamic: project-url
Dynamic: requires-python
Dynamic: summary

# DropReply Python SDK

Official Python SDK for [DropReply](https://dropreply.com) — publish replies and upvotes on Reddit & X programmatically.

## Installation

```bash
pip install dropreply
```

Requires Python 3.7+. No external dependencies.

## Quick Start

```python
from dropreply import DropReply

client = DropReply("drpl_live_sk_your_key_here")

# Submit a reply
reply = client.reply(
    platform="reddit",
    target_url="https://www.reddit.com/r/startup/comments/abc123/...",
    content="Great point! We built something similar..."
)

print(reply["id"])      # 'rpl_abc123'
print(reply["status"])  # 'queued'
```

## Configuration

```python
client = DropReply(
    api_key="drpl_live_sk_xxx",
    base_url="https://api.dropreply.com",  # default
    timeout=30                             # request timeout in seconds (default: 30)
)
```

## Methods

### `client.reply(platform, target_url, content, schedule_at=None)`

Submit a reply for publishing.

```python
reply = client.reply(
    platform="reddit",         # 'reddit' or 'twitter'
    target_url="https://...",  # URL of the post to reply to
    content="Your reply text", # 10-2000 characters
    schedule_at="2026-03-25T14:00:00Z"  # optional: ISO 8601 datetime (Growth/Scale only)
)

# Returns dict:
# {
#   "id": "rpl_abc123",
#   "status": "queued",           # or "scheduled" if schedule_at was set
#   "platform": "reddit",
#   "target_url": "https://...",
#   "credit_cost": 1,
#   "schedule_at": null,          # or the scheduled datetime
#   "created_at": "2026-03-22T..."
# }
```

### `client.get_reply(reply_id)`

Get the status and details of a reply.

```python
reply = client.get_reply("rpl_abc123")

# Returns dict:
# {
#   "id": "rpl_abc123",
#   "platform": "reddit",
#   "target_url": "https://...",
#   "content": "Your reply text",
#   "credit_cost": 1,
#   "status": "published",        # 'queued' | 'scheduled' | 'publishing' | 'published' | 'failed' | 'rejected'
#   "published_url": "https://...",
#   "schedule_at": null,
#   "published_at": "2026-03-22T...",
#   "created_at": "2026-03-22T..."
# }
```

### `client.list_replies(platform=None, status=None, limit=None, offset=None)`

List replies with optional filtering and pagination.

```python
result = client.list_replies(
    platform="reddit",   # optional filter
    status="published",  # optional filter
    limit=10,            # default: 20, max: 100
    offset=0             # pagination offset
)

# Returns dict:
# {
#   "data": [ { "id": ..., "platform": ..., "status": ..., ... }, ... ],
#   "pagination": { "total": 42, "limit": 10, "offset": 0 }
# }
```

### `client.upvote(platform, target_url)`

Submit an upvote/like job.

```python
upvote = client.upvote(
    platform="reddit",
    target_url="https://www.reddit.com/r/startup/comments/abc123/..."
)

# Returns dict:
# {
#   "id": "upv_xyz789",
#   "status": "queued",
#   "platform": "reddit",
#   "target_url": "https://...",
#   "credit_cost": 0.25,
#   "created_at": "2026-03-22T..."
# }
```

### `client.usage()`

Get current credit balance and plan info.

```python
usage = client.usage()

# Returns dict:
# {
#   "plan": "growth",
#   "credits_included": 100,
#   "credits_used": 23,
#   "credits_remaining": 77,
#   "extra_credits": 0,
#   "total_available": 77,
#   "billing_period_start": "2026-03-01T...",
#   "billing_period_end": "2026-04-01T..."
# }
```

### `client.accounts_availability(platform=None)`

Check available managed accounts.

```python
result = client.accounts_availability(platform="reddit")

# Returns dict:
# {
#   "accounts": [
#     { "platform": "reddit", "available": 12 }
#   ]
# }
```

## Error Handling

All methods raise `DropReplyError` on failure:

```python
from dropreply import DropReply, DropReplyError

client = DropReply("drpl_live_sk_xxx")

try:
    client.reply(platform="reddit", target_url="...", content="...")
except DropReplyError as e:
    print(e.status_code)  # HTTP status code (e.g. 400, 402, 422)
    print(e.error_code)   # API error code (e.g. 'validation_error')
    print(e.message)      # Human-readable error message
```

Common error codes:
- `validation_error` (400) — Invalid input parameters
- `insufficient_credits` (402) — Not enough credits
- `plan_required` (403) — Feature requires a higher plan (e.g. scheduled replies)
- `not_found` (404) — Resource not found
- `moderation_rejected` (422) — Content failed moderation
- `concurrent_limit` (429) — Too many replies in progress
- `rate_limit_exceeded` (429) — Too many requests
- `internal_error` (500) — Server error

## License

MIT
