Metadata-Version: 2.4
Name: promptbid
Version: 0.1.0
Summary: Python SDK for PromptBid - Real-time bidding platform for AI app monetization
Project-URL: Homepage, https://promptbid.io
Project-URL: Documentation, https://docs.promptbid.io
Project-URL: Repository, https://github.com/promptbid/sdk-python
Project-URL: Issues, https://github.com/promptbid/sdk-python/issues
Author-email: PromptBid Team <dev@promptbid.io>
License: MIT
License-File: LICENSE
Keywords: ads,bidding,openrtb,promptbid,rtb
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
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 :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Requires-Dist: httpx>=0.24.0
Requires-Dist: pydantic>=2.0.0
Provides-Extra: async
Requires-Dist: httpx[http2]>=0.24.0; extra == 'async'
Provides-Extra: dev
Requires-Dist: black>=23.0.0; extra == 'dev'
Requires-Dist: mypy>=1.0.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Description-Content-Type: text/markdown

# PromptBid Python SDK

A comprehensive Python SDK for interacting with PromptBid's real-time bidding platform for AI app monetization. Supports both synchronous and asynchronous clients for builders (publishers) and advertisers.

## Installation

Install the SDK using pip:

```bash
pip install promptbid
```

For async support with HTTP/2:

```bash
pip install promptbid[async]
```

## Quick Start

### For Builders (Publishers)

Get ads to display in your AI app and record interactions:

```python
from promptbid import PromptBid

# Initialize the client with your API key
pb = PromptBid(api_key="pb_live_your_key_here")

# Request ads for a conversation
ads = pb.get_ads(
    conversation_id="conv_abc123",
    session_id="sess_xyz789",
    message="I need help with Python",
    categories=["IAB1", "IAB2"],
    keywords=["programming", "python"],
    slot_count=2
)

# Display ads and record interactions
for ad in ads:
    print(f"[Sponsored] {ad['headline']}")
    print(f"  {ad['description']}")
    print(f"  {ad['cta_text']} → {ad['cta_url']}")

    # When user clicks the ad
    if user_clicked(ad['impression_id']):
        pb.record_click(ad['impression_id'])

# Get your earnings
earnings = pb.get_builder_earnings()
print(f"Total Earnings: ${earnings.total_earnings:.2f}")
print(f"Pending Payout: ${earnings.pending_payout:.2f}")

pb.close()
```

### For Advertisers

Create and manage ad campaigns:

```python
from promptbid import PromptBid

pb = PromptBid(api_key="ad_live_your_key_here")

# Create a new campaign
campaign = pb.create_campaign(
    name="Summer Sale Campaign",
    bid_amount=2.50,  # $2.50 CPM
    daily_budget=100.0,  # $100/day
    total_budget=1000.0,  # $1000 total
    creative={
        "headline": "Summer Sale - 50% Off",
        "description": "Get ready for summer with our amazing deals",
        "cta_text": "Shop Now",
        "cta_url": "https://example.com/summer-sale",
        "image_url": "https://example.com/image.jpg"
    }
)

print(f"Campaign created: {campaign.id}")
print(f"Status: {campaign.status}")

# List your campaigns
campaigns = pb.list_campaigns(status="active", limit=10)
print(f"Active campaigns: {len(campaigns['items'])}")

# Update a campaign
updated = pb.update_campaign(
    campaign_id=campaign.id,
    bid_amount=3.0,
    daily_budget=150.0
)

# Pause a campaign
paused = pb.pause_campaign(campaign.id)
print(f"Campaign paused: {paused.status}")

# Resume a campaign
resumed = pb.resume_campaign(campaign.id)
print(f"Campaign resumed: {resumed.status}")

# Check your balance
balance = pb.get_advertiser_balance()
print(f"Account Balance: ${balance['balance']:.2f}")

# Add funds
pb.deposit(100.0)  # Deposit $100

pb.close()
```

## Async Support

Use the async client for high-concurrency applications:

```python
import asyncio
from promptbid import AsyncPromptBid

async def main():
    async with AsyncPromptBid(api_key="pb_live_your_key_here") as pb:
        # Get ads
        ads = await pb.get_ads(
            conversation_id="conv_123",
            session_id="sess_456",
            message="Help me"
        )

        # Record clicks in parallel
        tasks = [pb.record_click(ad['impression_id']) for ad in ads]
        results = await asyncio.gather(*tasks)

        # Get earnings
        earnings = await pb.get_builder_earnings()
        print(f"Earnings: ${earnings.total_earnings:.2f}")

asyncio.run(main())
```

## Authentication

The SDK supports two authentication methods:

1. **API Key Authentication** (recommended)
   ```python
   pb = PromptBid(api_key="pb_live_xxxx")
   ```

2. **Email/Password Authentication**
   ```python
   pb = PromptBid(api_key="temp_key")
   builder = pb.builder_login(email="you@example.com", password="your_password")
   # API key is now updated in the client
   ```

## API Reference

### Bidding Endpoints (Builders)

#### get_ads()
Request ads for a conversation context.

```python
ads = pb.get_ads(
    conversation_id="conv_abc123",  # Required
    session_id="sess_xyz789",        # Required
    message="I need help",            # Optional
    categories=["IAB1"],              # Optional
    keywords=["python"],              # Optional
    slot_count=2                      # Optional (1-3)
)
```

**Returns:** List of ad dictionaries with fields: `impression_id`, `headline`, `description`, `cta_text`, `cta_url`, `image_url`, `position`, `sponsored`

#### record_click()
Record when a user clicks on a served ad.

```python
success = pb.record_click(impression_id="imp_abc123")
```

**Returns:** Boolean indicating success

### Builder Profile Endpoints

#### builder_register()
Register a new builder account.

```python
response = pb.builder_register(
    name="My App",
    email="you@example.com",
    app_name="ChatBot Pro",
    app_url="https://chatbot.example.com",
    app_description="Advanced AI chatbot",
    categories=["IAB1", "IAB2"],
    password="secure_password"  # Optional
)
```

#### builder_login()
Login with email and password.

```python
builder = pb.builder_login(
    email="you@example.com",
    password="secure_password"
)
```

#### get_builder_profile()
Get your builder profile.

```python
profile = pb.get_builder_profile()
print(profile.app_name)
print(profile.monthly_impressions)
```

#### update_builder_profile()
Update your builder profile.

```python
updated = pb.update_builder_profile(
    app_name="Updated Name",
    app_url="https://new-url.example.com",
    categories=["IAB1", "IAB3"]
)
```

#### get_builder_earnings()
Get your earnings summary.

```python
earnings = pb.get_builder_earnings()
print(f"Total: ${earnings.total_earnings:.2f}")
print(f"Pending: ${earnings.pending_payout:.2f}")
print(f"Last 30 days: ${earnings.last_30_days_earnings:.2f}")
print(f"Impressions: {earnings.impression_count}")
```

#### reset_builder_api_key()
Rotate your API key.

```python
builder = pb.reset_builder_api_key()
# The client's API key is automatically updated
print(f"New API key: {builder.api_key}")
```

### Advertiser Profile Endpoints

#### advertiser_register()
Register a new advertiser account.

```python
response = pb.advertiser_register(
    name="My Company",
    email="you@example.com",
    company_url="https://company.example.com",
    logo_url="https://company.example.com/logo.png",
    industry="Technology",
    monthly_budget=5000.0,
    daily_budget=500.0,
    password="secure_password"  # Optional
)
```

#### advertiser_login()
Login with email and password.

```python
advertiser = pb.advertiser_login(
    email="you@example.com",
    password="secure_password"
)
```

#### get_advertiser_profile()
Get your advertiser profile.

```python
profile = pb.get_advertiser_profile()
print(profile.name)
print(profile.balance)
```

#### update_advertiser_profile()
Update your advertiser profile.

```python
updated = pb.update_advertiser_profile(
    company_url="https://new-site.example.com",
    industry="E-commerce",
    daily_budget=600.0
)
```

#### get_advertiser_balance()
Get your account balance and spending information.

```python
balance = pb.get_advertiser_balance()
print(f"Balance: ${balance['balance']:.2f}")
print(f"Total Spend: ${balance['total_spend']:.2f}")
print(f"Remaining Budget: ${balance['remaining_budget']:.2f}")
```

#### deposit()
Add funds to your account.

```python
updated_profile = pb.deposit(amount=100.0)  # $100
```

#### reset_advertiser_api_key()
Rotate your API key.

```python
advertiser = pb.reset_advertiser_api_key()
print(f"New API key: {advertiser.api_key}")
```

### Campaign Endpoints

#### create_campaign()
Create a new advertising campaign.

```python
campaign = pb.create_campaign(
    name="Summer Sale",
    bid_amount=2.5,
    daily_budget=100.0,
    total_budget=1000.0,
    creative_type="native",
    targeting={
        "categories": ["IAB1", "IAB2"],
        "keywords": ["summer", "sale"],
        "exclude_categories": ["IAB8"]
    },
    creative={
        "headline": "50% Off Summer Sale",
        "description": "Limited time offer",
        "cta_text": "Shop Now",
        "cta_url": "https://example.com",
        "image_url": "https://example.com/ad.jpg"
    },
    frequency_cap=3  # Max 3 impressions per session per day
)
```

#### list_campaigns()
List your campaigns with optional filtering.

```python
campaigns = pb.list_campaigns(
    status="active",  # Filter by status
    limit=20,
    offset=0
)

for campaign in campaigns['items']:
    print(f"{campaign.name}: ${campaign.balance:.2f} spent")

print(f"Total campaigns: {campaigns['total']}")
```

#### get_campaign()
Get a single campaign.

```python
campaign = pb.get_campaign(campaign_id="camp_abc123")
print(f"CTR: {campaign.ctr:.2f}%")
print(f"Spent: ${campaign.spent:.2f}")
```

#### update_campaign()
Update a campaign.

```python
updated = pb.update_campaign(
    campaign_id="camp_abc123",
    bid_amount=3.0,
    daily_budget=150.0,
    creative={
        "headline": "New Headline",
        "description": "New description"
    }
)
```

#### pause_campaign()
Pause a campaign.

```python
paused = pb.pause_campaign(campaign_id="camp_abc123")
print(paused.status)  # "paused"
```

#### resume_campaign()
Resume a paused campaign.

```python
resumed = pb.resume_campaign(campaign_id="camp_abc123")
print(resumed.status)  # "active"
```

#### delete_campaign()
Soft-delete a campaign.

```python
deleted = pb.delete_campaign(campaign_id="camp_abc123")
print(deleted.status)  # "deleted"
```

### Payment Endpoints

#### create_checkout_session()
Create a Stripe Checkout session for deposits.

```python
session = pb.create_checkout_session(amount=100.0)  # $100
print(f"Checkout URL: {session.url}")
```

#### get_payment_history()
Get payment history for your account.

```python
history = pb.get_payment_history(limit=20, offset=0)
for payment in history.payments:
    print(f"{payment.type}: ${payment.amount:.2f} ({payment.status})")
```

#### create_builder_connect_account()
Create a Stripe Connect account for payouts.

```python
account = pb.create_builder_connect_account()
print(f"Account ID: {account['account_id']}")
```

#### get_builder_onboarding_link()
Get Stripe onboarding link.

```python
link = pb.get_builder_onboarding_link(account_id="acct_abc123")
print(f"Onboarding URL: {link['onboarding_url']}")
```

#### request_builder_payout()
Request a payout to your Stripe account.

```python
payout = pb.request_builder_payout(
    amount=500.0,  # $500
    account_id="acct_abc123"
)
print(f"Payout ID: {payout['payout_id']}")
print(f"Status: {payout['status']}")
```

#### get_builder_payment_history()
Get payment history for builder account.

```python
history = pb.get_builder_payment_history(limit=20)
```

## Error Handling

The SDK raises specific exceptions for different error types:

```python
from promptbid import (
    PromptBidError,
    AuthenticationError,
    ValidationError,
    NotFoundError,
    RateLimitError,
    ServerError
)

try:
    campaign = pb.get_campaign(campaign_id="nonexistent")
except NotFoundError as e:
    print(f"Campaign not found: {e.message}")
except AuthenticationError as e:
    print(f"Invalid API key: {e.message}")
except ValidationError as e:
    print(f"Invalid parameters: {e.message}")
except RateLimitError as e:
    print(f"Rate limited, retry after {e}")
except ServerError as e:
    print(f"Server error: {e.message}")
except PromptBidError as e:
    print(f"Generic error: {e.message}")
```

## Configuration

### Custom Base URL

```python
pb = PromptBid(
    api_key="pb_live_xxxx",
    base_url="https://api.staging.promptbid.ai"
)
```

### Custom Timeout and Retries

```python
pb = PromptBid(
    api_key="pb_live_xxxx",
    timeout=60.0,  # 60 second timeout
    max_retries=5   # Retry up to 5 times
)
```

### Debug Logging

```python
pb = PromptBid(
    api_key="pb_live_xxxx",
    debug=True
)
```

## Context Manager Usage

Both sync and async clients support context managers:

```python
# Sync
with PromptBid(api_key="pb_live_xxxx") as pb:
    ads = pb.get_ads(...)

# Async
async with AsyncPromptBid(api_key="pb_live_xxxx") as pb:
    ads = await pb.get_ads(...)
```

## Models

The SDK includes Pydantic models for type safety:

- **Advertiser**: Advertiser profile with budget and balance info
- **Builder**: Builder profile with app details
- **Campaign**: Campaign with metrics and budget info
- **Earnings**: Builder earnings summary
- **PaymentHistory**: Payment transaction record
- **CheckoutSessionResponse**: Stripe checkout session

## Best Practices

1. **Store API keys securely**: Use environment variables or secrets management
   ```python
   import os
   api_key = os.getenv("PROMPTBID_API_KEY")
   ```

2. **Use context managers**: Ensures proper resource cleanup
   ```python
   with PromptBid(api_key=api_key) as pb:
       ads = pb.get_ads(...)
   ```

3. **Handle rate limits**: Implement exponential backoff
   ```python
   from promptbid import RateLimitError
   import time

   for attempt in range(3):
       try:
           ads = pb.get_ads(...)
           break
       except RateLimitError:
           time.sleep(2 ** attempt)
   ```

4. **Monitor quota**: Check available balance before creating campaigns
   ```python
   balance = pb.get_advertiser_balance()
   if balance['balance'] < campaign_budget:
       raise ValueError("Insufficient balance")
   ```

## Support

For issues, feature requests, or questions:
- Documentation: https://docs.promptbid.ai
- GitHub: https://github.com/promptbid/sdk-python
- Email: dev@promptbid.ai

## License

MIT License - see LICENSE file for details
