Skip to main content

Crivo

Give it a list of keywords. It searches Pixabay for each one, shows you the candidates in your browser so you can pick the image you want, then resizes your picks to one size and hands them back in a zip, with a CREDITS.txt naming every contributor.

It is for the job of "I have a hundred words and need one picture for each, all the same size", where the searching, downloading, resizing and packaging are tedious and the choosing is the only part that needs you.

$ crivo run examples/keywords_sample.txt --size 256
Searching 12 keywords on Pixabay...
  1 / 12  apple
  ...
12 with results
Pick your images at http://127.0.0.1:52431/?t=...
Downloading 11 images...
Wrote crivo.zip with 11 images for 11 keywords, plus CREDITS.txt.

You need your own Pixabay API key

Crivo does not ship, share or proxy a key. Everyone who runs it uses their own, which is free: log in at https://pixabay.com/api/docs/ and the key is shown in the parameters table. Pixabay ties keys to accounts and rate limits them per key, so a shared key would not work well for anyone.

Put it in the environment, or in a .env file in the folder you run Crivo from:

$ cp .env.example .env        # then edit .env and paste your key
PIXABAY_API_KEY=your_key_here

The key is deliberately not a command-line option: a flag ends up in your shell history and in the process list that every user on the machine can read. .env is gitignored. Crivo never writes the key into its cache, its output or an error message.

Install

Python 3.10 or newer, on Windows, macOS or Linux.

$ pipx install crivo

pipx puts Crivo in its own isolated environment and the crivo command on your PATH, without a virtual environment to create or activate by hand. No pipx? pip install --user crivo works too, just without the isolation from your other Python packages.

To build from a checkout instead — to try an unreleased change — see CONTRIBUTING.md.

Use

$ crivo run keywords.txt

Crivo searches every keyword, then prints an address and opens it in your browser. For each keyword you can:

  • pick an image by clicking it (click another to change your mind);
  • skip the keyword;
  • search again with a different term, if nothing shown is right;
  • load more results without losing what you have already picked.

Every image shows its contributor's name and a link to its Pixabay page. When you press Finish, Crivo downloads your picks, resizes them and writes the zip.

The selection page after searching three keywords, showing a grid of candidates for each

The same page after picking one image per keyword: each pick is checked, and the header shows the count

Keywords

Source Example
A .txt file, one keyword per line crivo run keywords.txt
A .csv file with a header row crivo run words.csv --column word
Standard input cat keywords.txt | crivo run -
Directly on the command line crivo run -k apple -k "hot-dog | hot dog"
Typed or pasted into a box on the page crivo run (no keywords at all)

With no keywords given, the page opens with a box to paste your list into. The search then runs behind the page, which shows how far it has got and fills in each keyword as it is searched, so you can start choosing before it is finished. The box takes the same format as a .txt file.

Blank lines and lines starting with # are ignored. To name the file after one thing and search for another, write label | search term:

hot-dog | hot dog

gives you hot-dog.png, found by searching for "hot dog". In a CSV the label is read from a column headed keyword or label (otherwise the first) and the search term from one headed term or search; --column and --term-column choose other columns. Labels become file names, so a label repeated in a different case is dropped and reported.

examples/keywords_sample.txt is a small list to try it on.

Options

crivo run --help lists everything. The ones you are most likely to want:

Option What it does
-n, --candidates N Images shown per keyword, 3 to 200 (default 5). Pixabay's smallest page is 3.
--size WxH Output size (default 512x512).
--mode crop|pad|fit crop fills the size and cuts the overflow; pad fits inside and fills the rest; fit fits inside and stops, so sizes are not uniform.
--format png|jpeg|webp Output format (default png, which keeps transparency).
--background #RRGGBB The fill for pad, and what a JPEG is flattened onto. Default: transparent, or white for JPEG.
--term-template '{term} icon' Wrap every search term, for example to find icons or flat illustrations.
--image-type, --orientation, --category, --colors, --min-width, --min-height, --safesearch, --editors-choice, --order, --lang Pixabay's own search filters.
--multiple Allow more than one image per keyword (apple.png, apple-2.png, ...).
-o, --output ZIP Where to write the zip (default crivo.zip). It is not replaced unless you pass --overwrite.
--work-dir DIR Search cache, downloaded originals and the saved session (default .crivo).
--resume / --restart Continue the saved session, or throw an unfinished one away and start over.
--no-browser Print the address instead of opening it.

Pausing and resuming

Your picks are saved as you make them, in session.json inside the work directory (.crivo by default). Close the terminal, press Ctrl-C, or shut the laptop, and carry on later:

$ crivo run --resume

Resuming reads the keywords from the saved session, so you give it none, and it does not search again for anything already searched: the page comes back as you left it. Options that affect the output (--size, --mode, --format, -o) are taken from the new command, so you can change your mind about them.

Starting a new run while an unfinished session is saved is refused, so that a long afternoon of picking is not thrown away by accident. Pass --restart when you mean to start over. A session whose zip has been written is finished with, and the next run replaces it without asking.

A session file holds Pixabay's image addresses, which are meant for short-term display. Resuming one that is more than a day old works, and warns you that a thumbnail or a download may no longer load. The file never contains your API key.

What you get

A zip of the resized images, each named after its keyword, and a CREDITS.txt:

apple.png
  Keyword:      apple
  Pixabay page: https://pixabay.com/photos/...
  Contributor:  someone

When something goes wrong

Nothing that can go wrong on the network or at Pixabay ends the run with a traceback.

  • A keyword with no results, or whose search failed, is flagged on the page. Search again with another term, or skip it.
  • If Pixabay refuses your key, the rate limit is used up, or Pixabay cannot be reached three times in a row, Crivo stops searching and says so. What it found is kept, the page still opens, and the remaining keywords show as not searched so you can retry them. A failing request is tried a few times with growing pauses and then given up on; Crivo does not keep looping in the background.
  • A picked image that cannot be downloaded is left out of the zip and listed after the run.

Searches are cached for 24 hours, and downloaded originals are kept in the work directory, so running the same list again costs no requests.

Exit codes: 0 done; 1 something you can fix (a bad option, a missing keyword file or key, an output file that already exists); 3 the zip was written but some picks are missing from it; 130 you pressed Ctrl-C.

About Pixabay, and what you are agreeing to

Crivo is a small tool that talks to Pixabay's API on your behalf and is built to respect Pixabay's API terms:

  • No permanent hotlinking. Pixabay's image addresses are only used to show you the search results while you choose. Once you pick, the image is downloaded, and everything after that uses your local copy.
  • Attribution where results are shown. Each candidate carries its contributor's name and a link to its Pixabay page, and the zip includes a CREDITS.txt.
  • Caching and rate limits. Search results are cached for 24 hours, requests are held to Pixabay's limit of 100 per minute per key, and a rate-limit response is waited out.
  • Human-paced. A person chooses every image. Crivo is not a way to bulk-download Pixabay, and it will not run searches in an unattended loop.

The MIT licence in this repository covers Crivo's code only. It says nothing about the images you download: those are under the Pixabay Content License, which is what allows you to use and modify them (resizing included), commercially or not, without attribution. It does not cover everything that can appear in an image: some contain trademarks, logos or recognisable people that carry rights Pixabay does not clear. Looking at what you pick is your responsibility, above all for a commercial project.

The repository contains no Pixabay images and never will; please do not commit any.

Status

Crivo is at version 0.x. The whole pipeline works and is covered by automated tests on Windows, macOS and Linux, but those tests use a simulated Pixabay and never touch the network. It has been run against the live API on Windows, where it found and fixed a real bug that no simulated test could. The same run has not yet been made on macOS or Linux, so expect a rough edge or two there. Bug reports with the message Crivo printed are welcome.

Contributing

See CONTRIBUTING.md.

Release files for crivo 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for crivo 0.1.0
File Size Uploaded
crivo-0.1.0.tar.gz 942.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for crivo 0.1.0
File Interpreter ABI Platform
crivo-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 1.0 MB

Release files / crivo-0.1.0.tar.gz

Download URL crivo-0.1.0.tar.gz
Size 942.3 kB
Tags Source
SHA-256 checksum
How to use checksums
b905e32323bf5e2ee1b52457f1f6dbc395e325823f20880dc16175b2b9419a21
BLAKE2b-256 checksum
How to use checksums
dab6f53eeaa846b9844d23da93af28447681dd005bf1cdd5d22385cfe03da7f6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.

Transparency log

Release files / crivo-0.1.0-py3-none-any.whl

Download URL crivo-0.1.0-py3-none-any.whl
Size 60.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
46ab70b80e0d56faa32f2909e5fd8efc19b05026c5fdc8edffbe8c2c9f283320
BLAKE2b-256 checksum
How to use checksums
e80184f1cce64e5e00f139ab1ffd4d92c9442f07f0a6e2255c23ab75bf70cdad
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page