Metadata-Version: 2.4
Name: metascrape
Version: 1.0.0
Summary: Official Python client for the MetaScrape API — extract metadata from any URL in one call
Author-email: "Shane Code (Shane Burrell)" <support@shaneburrell.com>
License-Expression: MIT
Project-URL: Homepage, https://metascrape.shanecode.org
Project-URL: Documentation, https://metascrape.shanecode.org
Project-URL: Repository, https://pypi.org/project/metascrape/
Keywords: metascrape,metadata,scraper,open-graph,og-tags,twitter-card,seo,link-preview,url-metadata,web-scraping,meta-tags,favicon,unfurl
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
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: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# metascrape

Official Python client for the **MetaScrape API** -- extract metadata from any URL in one call.

Get Open Graph tags, Twitter Cards, favicons, canonical URLs, and more with a single request. Zero dependencies. Works with Python 3.8+.

## Install

```bash
pip install metascrape
```

## Quick Start

```python
from metascrape import MetaScrape

ms = MetaScrape("your-api-key")

meta = ms.extract("https://example.com")
print(meta["title"])       # "Example Domain"
print(meta["og"]["image"]) # "https://example.com/image.png"
print(meta["description"]) # "An example website"
```

## Getting an API Key

1. Sign up at [metascrape.shanecode.org](https://metascrape.shanecode.org)
2. Your API key is returned on login

Or use the SDK directly:

```python
from metascrape import MetaScrape

# Create an account
MetaScrape.signup("you@example.com", "your-password")

# Login to get your API key
result = MetaScrape.login("you@example.com", "your-password")
print(result["api_key"])  # Use this for all authenticated requests
```

## API Reference

### `MetaScrape(api_key, base_url=None)`

Create a client instance.

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `api_key` | `str` | *required* | Your MetaScrape API key |
| `base_url` | `str` | `https://api.shanecode.org` | API base URL |

### `ms.extract(url)`

Extract metadata from a URL. Returns the metadata dict directly (envelope is unwrapped).

```python
meta = ms.extract("https://github.com")
```

**Returns:**

| Field | Type | Description |
|-------|------|-------------|
| `title` | `str` | Page title |
| `description` | `str` | Meta description |
| `og` | `dict` | Open Graph tags (title, description, image, type, site_name) |
| `twitter` | `dict` | Twitter Card tags (card, title, description, image, site) |
| `favicon` | `str` | Favicon URL |
| `canonical_url` | `str` | Canonical URL |
| `language` | `str` | Page language |
| `structured_data` | `list` | JSON-LD structured data |
| `response_time_ms` | `int` | Extraction time in milliseconds |

### `ms.usage()`

Get your current month's API usage.

```python
usage = ms.usage()
print(f"{usage['used']} / {usage['limit']} requests used")
```

**Returns:** `{"plan": str, "used": int, "limit": int, "remaining": int}`

### `MetaScrape.signup(email, password, base_url=None)`

Class method. Create a new account. No API key required.

```python
MetaScrape.signup("you@example.com", "secure-password")
```

### `MetaScrape.login(email, password, base_url=None)`

Class method. Login and retrieve your API key. No API key required.

```python
result = MetaScrape.login("you@example.com", "secure-password")
api_key = result["api_key"]
```

## Error Handling

The client raises `MetaScrapeError` for non-2xx responses:

```python
from metascrape import MetaScrape, MetaScrapeError

ms = MetaScrape("your-api-key")

try:
    meta = ms.extract("https://example.com")
except MetaScrapeError as e:
    print(e.status_code)  # 401, 429, etc.
    print(e.message)      # "invalid API key", "rate limit exceeded", etc.
```

## Pricing

| Plan | Requests/month | Price |
|------|---------------|-------|
| Free | 100 | $0 |
| Hobby | 1,000 | $9/mo |
| Growth | 10,000 | $29/mo |
| Business | 100,000 | $79/mo |

Start free at [metascrape.shanecode.org](https://metascrape.shanecode.org).

## Links

- [Full Documentation](https://metascrape.shanecode.org)
- [Sign Up / Get API Key](https://metascrape.shanecode.org)
- [npm Package](https://www.npmjs.com/package/@shanecode/metascrape) (Node.js SDK)
- [ShaneCode](https://shanecode.org)

## License

MIT -- see [LICENSE](./LICENSE)

---

Built by [ShaneCode](https://shanecode.org) -- https://shanecode.org
