Verifying Python package metadata before installing
Before installing a Python package you haven't used before — particularly one that is new, obscure, or requested by an LLM code assistant — a quick manual verification takes two minutes and catches the majority of obvious typosquatting and malicious package attempts.
Step 1: Verify the package exists on PyPI and check its age
# Quick check — does the package exist and how old is it?
pip index versions <package-name> 2>/dev/null | head -3
# Or via the PyPI JSON API:
curl -s https://pypi.org/pypi/<package-name>/json | \
python3 -c "import json,sys; d=json.load(sys.stdin); \
print('Latest:', list(d['releases'].keys())[-1]); \
print('First release:', min(d['releases'].keys()))"
A package published last week with one version deserves more scrutiny than a package with four years of release history.
Step 2: Check the download count
# pypistats — download counts for any PyPI package
pip install pypistats
pypistats recent <package-name>
A package with 200 total downloads and no release before last week is a red flag. Most legitimate packages accumulate thousands of downloads before attracting significant attention.
Step 3: Find and review the source code
Every legitimate package should have a source code repository. Find it on the PyPI package page (https://pypi.org/project/<package-name>/). The "Homepage" or "Source" links in the project links section should point to GitHub, GitLab, or a similar repository.
If there's no source code link, that's a warning sign. If the source code link is a newly-created repository with one commit, that's a stronger warning sign.
Once you have the repository, review:
- Is there a
setup.pywith acmdclassoverride? What does it do? - Is there a
pyproject.tomlwith[build-system]hooks? What do they do? - Does the package make any network calls in module initialization code (
__init__.py)?
This review doesn't need to be exhaustive — you're looking for obviously suspicious patterns, not auditing the entire codebase.
Step 4: Check the publisher account
curl -s https://pypi.org/pypi/<package-name>/json | \
python3 -c "import json,sys; d=json.load(sys.stdin); \
print('Author:', d['info']['author']); \
print('Maintainer:', d['info']['maintainer'])"
Check the publisher's PyPI profile. How many other packages have they published? When did they first publish? An account with one package published last week, no other packages, and no visible online presence is a higher-risk publisher than an account with a five-year history of well-maintained packages.
Step 5: Check if the name is similar to another package
# Quick typosquat check — compare against a package you intended to install
from difflib import SequenceMatcher
def similarity(a, b):
return SequenceMatcher(None, a, b).ratio()
intended = 'requests'
actual = 'requsets' # what you typed
print(f"Similarity: {similarity(intended, actual):.2%}") # 93.33%
If the package name is more than 80% similar to a package you know is legitimate, verify you spelled it correctly.
What Veln automates
All five of these checks are automated in Veln's Tier 1 pipeline:
- Package age: cooling gate (min 2 hours since publication)
- Community installs: consensus check (min 10 observations)
- Publisher account age: publisher reputation signal
- Source code review: Veln Lens (AST analysis, 22 obfuscation rules)
- Typosquat check: Levenshtein distance against your lockfile packages and top-5,000 list
Manual verification is useful for packages you're specifically evaluating before adding to your project. Veln provides automated, comprehensive verification for every install — including transitive dependencies you would never manually check.
Manual verification catches obvious risks. Veln catches the rest, automatically, on every install.