Metadata-Version: 2.4
Name: shotbot
Version: 2.0.0
Summary: CLI for the Shotbot screenshot API
Author: Valentin Beck
License: MIT
Project-URL: Homepage, https://www.shotbot.net/screenshot-cli-tools/
Keywords: screenshot,capture,api,cli,shotbot
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Environment :: Console
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# shotbot-python-cli

A single-file Python CLI for the [Shotbot](https://www.shotbot.net) screenshot API.
Same flag names, exit codes, and config-file layout as the
[PHP](https://api.shotbot.net/cli/php/shotbot) and
[Node.js](https://api.shotbot.net/cli/node/shotbot) clients | scripts written
for one work as-is with the others.

Documentation: <https://www.shotbot.net/screenshot-cli-tools/> (English) /
<https://www.shotbot.fr/outil-cli-capture-ecran/> (French).

## Requirements

- Python 3.8+
- Standard library only | no third-party dependencies.

## Install

**pip (recommended)**

```sh
pip install shotbot
```

Or with pipx (isolated environment):

```sh
pipx install shotbot
```

**curl (single file, no pip)**

```sh
curl -fsSL https://api.shotbot.net/cli/python/shotbot -o shotbot \
  && chmod +x shotbot \
  && sudo mv shotbot /usr/local/bin/
```

## First run

On first use you'll be prompted for your API key. It is saved to
`~/.shotbot-python-cli/config.json` (chmod 600). Get a key at
<https://www.shotbot.net/screenshot-api-key/>.

```
$ shotbot capture --url=https://example.com

No Shotbot API key configured.
Get one at https://www.shotbot.net/screenshot-api-key/

API key: abc123def456
✓ Saved to /home/you/.shotbot-python-cli/config.json (chmod 600)
```

## Usage

```sh
shotbot capture --url=https://example.com                             # saves ./example.com-TOKEN.jpg
shotbot capture --url=https://example.com --output=screenshots/       # into dir, auto-named
shotbot capture --url=https://example.com --output=hero.jpg           # exact path
shotbot capture --url=https://example.com --full-page --dark          # saves to cwd
shotbot capture --url=https://example.com --cdn                       # public CDN URL, no file
shotbot capture --url=https://example.com --json | jq .               # machine output, no file
```

> **Privacy:** captures are **private by default** and **saved to the current
> directory** (auto-named `HOST-TOKEN.FMT`). They are not published on
> `static.shotbot.net`: the worker writes the file to a non-public directory on
> the server, the CLI fetches it from `api.shotbot.net`, and the server-side copy
> auto-expires after a short retention window. No public URL is ever created,
> which is useful for sensitive pages (intranet, dashboards, customer data). Pass
> `--cdn` for a permanent public CDN URL instead (no local file is saved).

### Capture options

#### Free tier
| Option              | Values                                                                                              | Default  |
| ------------------- | --------------------------------------------------------------------------------------------------- | -------- |
| `--url`             | http(s) URL (required)                                                                              |          |
| `--preset`          | `og`, `mobile`, `youtube_thumbnail`, `square`, `reel`, `pinterest`, `tablet` (fills viewport / output-size / crop-height in one go) | off |
| `--frame`           | `rounded`, `shadow`, `browser_chrome`, `browser_chrome_dark`, `mobile`, `mobile_light`, `tablet`, `tablet_light`, `laptop`, `polaroid`, `gradient`, `shotbot_brand` (free accounts get a `shotbot.fr`/`.net` mark; Pro removes it) | off |
| `--format`          | `jpg`, `png`, `webp`, `webp_lossless`, `avif`, `pdf`                                                | `jpg`    |
| `--viewport`        | 360..1920 (px)                                                                                      | `1280`   |
| `--output-size`     | 120..1920 (resize the result, px)                                                                   | viewport |
| `--wait`            | Free 0..5, Pro 0..30 (seconds after page load)                                                      | `5`      |
| `--ratio`           | `16:9`, `4:3`, `1:1`, `9:16`, etc.                                                                  | `16:9`   |
| `--full-page`       | flag                                                                                                | off      |
| `--nojs`            | flag (disable JavaScript before navigation)                                                         | off      |
| `--color-scheme`    | `dark` \| `light` (sets prefers-color-scheme)                                                       | off      |
| `--hidpi`           | flag (2x DPR)                                                                                       | off      |

#### Pro
| Option                | Values                                                     |
| --------------------- | ---------------------------------------------------------- |
| `--dismiss-cookies`   | `accept` \| `reject` (auto-handle cookie consent banners)  |
| `--scroll`            | flag (scroll the page before capture; lazy-load trigger)   |
| `--block-ads`         | flag (block ad-network requests)                           |
| `--crop-height`       | 10..30000 (crops the result, overrides ratio, implies full-page) |
| `--selector`          | CSS selector (capture only the matched DOM element)        |
| `--render-region`     | `fr-paris` (free, default) \| `ca-montreal` \| `sg-singapore` \| `au-sydney` \| `vn-hanoi` — render from a real local IP in that region (see https://www.shotbot.net/geolocated-screenshots/) |
| `--http-auth-user`    | string (HTTP Basic Auth user)                              |
| `--http-auth-pass`    | string (HTTP Basic Auth password)                          |

#### PDF (only when `--format=pdf`)
| Option                | Values                                              | Default  |
| --------------------- | --------------------------------------------------- | -------- |
| `--pdf-page-size`     | `A4`, `A3`, `A5`, `Letter`, `Legal`, `Tabloid`      | `A4`     |
| `--pdf-margin`        | 0..50 (page margin in mm)                           | `10`     |
| `--pdf-scale`         | 0.10..2.00 (rendering scale)                        | `1.00`   |
| `--pdf-landscape`     | flag (landscape orientation)                        | off      |

#### CLI ergonomics
| Option         | Values                                      | Default  |
| -------------- | ------------------------------------------- | -------- |
| `--output`     | where to save; see below (default: cwd, auto-named) | cwd |
| `--cdn`        | flag (public CDN URL, no local file; default: private + saved) | off |
| `--json`       | print full JSON response, no chrome (no file saved) | off      |
| `--timeout`    | max seconds to wait for the capture         | `180`    |

Captures are **private by default and saved to the current directory** (see the
privacy note above). `--output` only changes *where* the file goes. Pass `--cdn`
for a permanent public CDN URL, or `--json` for machine output | neither saves a
local file.

### Where the file goes

By default (no flags), the file lands in the current directory, auto-named.
`--output` only changes the destination:

| Form                               | Saves to                                                   |
| ---------------------------------- | ---------------------------------------------------------- |
| *(no flag)* / `--output`           | `./<host>-<short_token>.<format>` (cwd, auto-named)        |
| `--output=screenshots/`            | `screenshots/<host>-<short_token>.<format>` (auto-named)   |
| `--output=path/to/file.jpg`        | exactly that path                                          |

Auto filename example for `https://www.example.com/`:
`example.com-a1b2c3d4.jpg` (`www.` stripped, first 8 chars of the job id, format extension).

## Persistent defaults

Save options once and they apply to every `capture`. Per-call flags always win.

```sh
shotbot set full-page                # always full-page
shotbot set output ./shots/          # always save into ./shots/
shotbot set cdn true                 # always publish to the public CDN
shotbot set viewport 1440            # always render at 1440 px
shotbot set format webp              # always webp

shotbot defaults                     # show what's stored
shotbot defaults --keys              # list every settable key + type
shotbot unset full-page              # forget that default
```

Booleans accept `true`/`false`/`yes`/`no`/`1`/`0`; bare `set <key>` on a boolean
is shorthand for `set <key> true`. Defaults live in the same `config.json` as
the API key, under a `defaults` object.

**Free tier**

| Settable key       | Type           | Notes                                    |
| ------------------ | -------------- | ---------------------------------------- |
| `format`           | string (enum)  | `jpg` / `png` / `webp` / `webp_lossless` / `avif` / `pdf` |
| `viewport`         | int            | 360..1920                                |
| `output-size`      | int            | 120..1920 (resize the result)            |
| `wait`             | int            | Free 0..5, Pro 0..30                      |
| `ratio`            | string         | `16:9`, `4:3`, `1:1`, etc.               |
| `color-scheme`     | string (enum)  | `dark` \| `light`                        |
| `full-page`        | bool           |                                          |
| `nojs`             | bool           | disable JavaScript                       |
| `hidpi`            | bool           |                                          |

**Pro**

| Settable key       | Type           | Notes                                    |
| ------------------ | -------------- | ---------------------------------------- |
| `dismiss-cookies`  | string (enum)  | `accept` \| `reject`                     |
| `scroll`           | bool           | scroll before capture                    |
| `block-ads`        | bool           |                                          |
| `crop-height`      | int            | 10..30000                                |
| `selector`         | string         | CSS selector                             |
| `render-region`    | string (enum)  | `fr-paris` / `ca-montreal` / `sg-singapore` / `au-sydney` / `vn-hanoi` |
| `http-auth-user`   | string         | HTTP Basic user                          |
| `http-auth-pass`   | string         | HTTP Basic password                      |

**PDF (only when `format=pdf`)**

| Settable key       | Type           | Notes                                    |
| ------------------ | -------------- | ---------------------------------------- |
| `pdf-page-size`    | string (enum)  | `A4`/`A3`/`A5`/`Letter`/`Legal`/`Tabloid` |
| `pdf-margin`       | int            | 0..50 (mm)                               |
| `pdf-scale`        | float          | 0.10..2.00                               |
| `pdf-landscape`    | bool           |                                          |

**CLI**

| Settable key       | Type           | Notes                                    |
| ------------------ | -------------- | ---------------------------------------- |
| `output`           | string         | default save location (path or dir); files save to cwd otherwise |
| `cdn`              | bool           | publish to the public CDN, no local file (default: private + saved) |
| `timeout`          | int            | max polling seconds                      |

### Other commands

| Command                         | What                                              |
| ------------------------------- | ------------------------------------------------- |
| `shotbot status`                | Show account plan, credits, quota, captures in flight. |
| `shotbot set <key> [value]`     | Persist a default option.                         |
| `shotbot unset <key>`           | Clear a persisted default.                        |
| `shotbot defaults [--keys]`     | List your defaults; `--keys` lists settable keys. |
| `shotbot config`                | Print the path to the config file.                |
| `shotbot reset`                 | Re-prompt for the API key.                        |
| `shotbot version`               | Print the version.                                |
| `shotbot help`                  | Show help.                                        |

## Environment

| Variable           | Effect                                                |
| ------------------ | ----------------------------------------------------- |
| `SHOTBOT_API_KEY`  | Override the stored key (useful in CI).               |
| `SHOTBOT_API_BASE` | Override the API base URL (default `https://api.shotbot.net`). |
| `NO_COLOR`         | Disable ANSI color output.                            |

## Exit codes

| Code | Meaning                                          |
| ---- | ------------------------------------------------ |
| `0`  | Success.                                         |
| `2`  | Bad invocation (missing args, bad config, etc.). |
| `3`  | Network error.                                   |
| `4`  | API returned an error response.                  |
| `5`  | Waitlisted (quota exhausted).                    |
| `6`  | Capture failed on the server side.               |
| `7`  | Polling timeout.                                 |

## CI example

```sh
export SHOTBOT_API_KEY=abc123def456
shotbot capture --url=https://staging.example.com --output=before.jpg
```

## License

MIT. See [`LICENSE`](LICENSE).
