Skip to main content

It is a wrapper around pywikibot to make uploading to Wikimedia Commons from CLI simpler.

screenshot

Install

From PyPI:

pip install pwb-wrapper-for-simpler-uploading-to-commons

With shell autocompletion support:

pip install 'pwb-wrapper-for-simpler-uploading-to-commons[autocomplete]'

Usage

Installed CLI command:

pwb-upload --file my.jpg --source https://example.com --license 'PD-old' --category 'Sunsets in Batumi' --date '2025-12-27' --desc 'A beautiful sunset from the beach' --target myrenamed.jpg

For multiple categories, repeat --category:

pwb-upload --file my.jpg --category 'Sunsets in Batumi' --category 'Evening in Georgia' --date '2025-12-27'

Use folder name in category:

pwb-upload --category "Kaspiy ${PWD##*/}" --license 'PD-scan|PD-old-assumed-expired' --source https://dspace.nplg.gov.ge/handle/1234/387883 --dateParse

Category and prefix is the same:

S='xxx' pwb-upload --category "$S" --prefix "$S "

Default source is {{own}}.

Default license is cc-by-4.0.

--author for example [[User:Globustut|Globustut]]

--date in format YYYY-MM-DD.

--dateParse extracts year from a filename (1xxx or 2xxx).

--date and --dateParse are mutually exclusive.

--target (file name on Commons) is optional.

--prefix (prefix for file name on Commons) is optional.

--i lets you start from a specific index.

--recursive includes files from subfolders when no file is specified.

You can upload with minimal arguments:

pwb-upload --file my.jpg --category 'Sunsets in Batumi' --date '2025-12-27'

Or pass the file as positional argument:

pwb-upload my.jpg --category 'Sunsets in Batumi' --date '2025-12-27'

Or upload without category, date, and dateParse (set them later on Commons):

pwb-upload my.jpg

If no file is specified, it uploads eligible files from the current folder (no subfolders by default):

pwb-upload --category 'My category' --author '[[User:Globustut|Globustut]]' --license 'self|CC-BY-4.0|author=Globustut' --date 2005

To include subfolders:

pwb-upload --recursive

For local development (without installation), you can still run:

./upload.py --file my.jpg

Author: for the current user use me.

MP4 videos

MP4 inputs are automatically converted with FFmpeg to WebM with AV1 video and Opus audio before uploading:

pwb-upload --category 'Bagrati Cathedral after restoration' Bagrati-Cathedral2026september-cross-ans-walking-man.mp4

This uploads Bagrati-Cathedral2026september-cross-ans-walking-man.webm. Conversion also applies to --file, folder uploads, and --recursive, including uppercase .MP4 extensions. A custom --target gets a .webm extension, and --prefix works as usual.

Install an FFmpeg build with the libsvtav1 and libopus encoders and ensure ffmpeg is on PATH. Check availability with ffmpeg -hide_banner -encoders. Other file formats do not require FFmpeg.

Encoding uses AV1 CRF 28, preset 6, 10-bit YUV 4:2:0, and Opus at 160 kb/s and 48 kHz. The first video stream and optional first audio stream are selected; silent videos work too. Resolution and frame rate are not intentionally reduced. The terminal shows an updating encoding progress line, warnings, and errors; FFmpeg metadata and SVT-AV1 startup and memory reports are suppressed. These codecs are supported by Commons video formats.

The original MP4 and any existing neighboring WebM remain untouched. The converted file is stored in the system temporary directory and removed when the upload finishes, fails, or is interrupted. Set TMPDIR to a directory with enough free space for large videos. Upload retries reuse the conversion; a new invocation encodes again. Conversion failures stop before uploading and exit with an error.

As a temporary workaround for an SVT-AV1 3.1.2 encoder hang, FFmpeg is stopped if its frame count, media timestamp, and output byte count do not advance for 60 seconds. The script discards the partial output and retries conversion once with fewer encoder workers (-svtav1-params lp=1), retaining the codec and quality settings. This retry can encode more slowly. A second stall exits with an error instead of uploading incomplete media. Encoding can run longer than 60 seconds while progress continues. Remove this workaround once a fixed encoder version is required and verified.

Autocompletion

Enable completion for the installed command:

eval "$(register-python-argcomplete pwb-upload)"

Release to PyPI

Release scripts in this repository:

  • release_minor.sh bumps x.y.z -> x.(y+1).0
  • release_patch.sh bumps x.y.z -> x.y.(z+1)
  • release-added.sh uses already staged files and already bumped version in pyproject.toml (no git add .)

Call them from git (one-time setup):

git config alias.release-minor '!f() { repo=$(git rev-parse --show-toplevel) && bash "$repo/release_minor.sh" "$@"; }; f'
git config alias.release-patch '!f() { repo=$(git rev-parse --show-toplevel) && bash "$repo/release_patch.sh" "$@"; }; f'
git config alias.release-added '!f() { repo=$(git rev-parse --show-toplevel) && bash "$repo/release-added.sh" "$@"; }; f'

Then run:

git release-minor 'Release message'
git release-patch 'Release message'
git release-added 'Release message'

Build distribution files:

python3 -m build

Upload to TestPyPI:

python3 -m twine upload --repository testpypi dist/*

Upload to PyPI:

python3 -m twine upload dist/*

Wikidata item about this tool https://www.wikidata.org/wiki/Q137601716

Commons category https://commons.wikimedia.org/wiki/Category:Uploaded_with_pwb_wrapper_script_by_Vitaly_Zdanevich

SonarCloud https://sonarcloud.io/project/overview?id=vitaly-zdanevich_pwb_wrapper_for_simpler_uploading_to_commons

See also

My another Python script for uploading to Commons from gThumb

My web extension for uploading to Commons

All upload tools

CLI upload tools

This tool is mentioned at my blog post https://diff.wikimedia.org/2026/04/09/preserve-old-public-domain-newspapers-and-books-from-archive-websites/

Metadata

Release files for pwb-wrapper-for-simpler-uploading-to-commons 1.8.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 pwb-wrapper-for-simpler-uploading-to-commons 1.8.0
File Size Uploaded
pwb_wrapper_for_simpler_uploading_to_commons-1.8.0.tar.gz 12.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pwb-wrapper-for-simpler-uploading-to-commons 1.8.0
File Interpreter ABI Platform
pwb_wrapper_for_simpler_uploading_to_commons-1.8.0-py3-none-any.whl Python 3 none any Details

Total release size: 24.6 kB

Release files / pwb_wrapper_for_simpler_uploading_to_commons-1.8.0.tar.gz

Download URL pwb_wrapper_for_simpler_uploading_to_commons-1.8.0.tar.gz
Size 12.2 kB
Tags Source
SHA-256 checksum
How to use checksums
cea2572f70bb86b4bf70a82ca6e1b5677ee4797fd75aae14b3eb1cce17a231a1
BLAKE2b-256 checksum
How to use checksums
60f6cafe699d5d2ba72456a921808c7f7a131bb356f1d7a4f3017b8a4291ceca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.15

Release files / pwb_wrapper_for_simpler_uploading_to_commons-1.8.0-py3-none-any.whl

Download URL pwb_wrapper_for_simpler_uploading_to_commons-1.8.0-py3-none-any.whl
Size 12.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
43aa0d5befe78350a26346c6ce16661d53c19ec9808effd50f6b803ab4624b02
BLAKE2b-256 checksum
How to use checksums
8cdf708e4cebde42a9f7c92655293736b549f37886661914c3df5a0143fcb141
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.15

Release history Release notifications | RSS feed

This release

1.8.0 This release

2 release files

1.7.0

2 release files

1.6.2

2 release files

1.6.1

2 release files

1.6.0

2 release files

1.5.9

2 release files

1.5.8

2 release files

1.5.7

2 release files

1.5.6

2 release files

1.5.5

2 release files

1.5.4

2 release files

1.5.3

2 release files

1.5.2

2 release files

1.5.1

2 release files

1.5.0

2 release files

1.4.0

2 release files

1.3.0

2 release files

1.2.3

2 release files

1.2.2

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.9.0

2 release files

0.8.4

2 release files

0.8.3

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.4

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