agentleFS
SiteSkillsSiteSkills/siteskills-cowork-plugin/skills/pypi/SKILL.md

pypi

Skill0 starsChanged 9 months agoMITView on GitHub

Use when finding Python packages, reading descriptions, checking version history, or getting pip install commands. Provides API and navigation flows for pypi.org.

  • Installs packages

1 other project uses a version of this.

Adopted by

Most recently taken up by

  • Other versions1 project uses a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 1

    1. apache/skywalking-ai-sessionizer★ 7same name

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

  • In this repository6 other files it gives its agents.

The file

Show its rules and text

We split this skill into the rules it gives an agent

14 rules. About 0 are common, 3 are distinctive, and 11 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈3

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 11

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Search: No clean JSON search API — use browser or navigate directly to /project/{name}/

    line 23
  2. Distinctive:

    Use selectors and Navigation Flows below

    line 28
  3. Distinctive:

    Default to Programmatic: if you know the package name — one call returns everything

    line 32
  4. Very specific:

    Note: Search results do not include the current version number.

    line 101
  5. Very specific:

    Read info.version — this is the latest stable version

    line 257
  6. Very specific:

    Read info.requires_python — confirm compatibility with user's Python version

    line 258
  7. Very specific:

    Read vulnerabilities[] — if non-empty, mention known CVEs

    line 259
  8. Very specific:

    Read releases keys — count total releases.

    line 267
  9. Very specific:

    Read releases[latest][0].upload_time_iso_8601 — when was the last release?

    line 268
  10. Very specific:

    Read info.home_page and project_urls.Source — is there a linked repo?

    line 269
  11. Very specific:

    Read vulnerabilities[] — any unpatched CVEs?

    line 270
  12. Very specific:

    MPA with server-rendered HTML: No JS framework. Every page navigation is a full page load.

    line 288
  13. Distinctive:

    Tabs are already in DOM: All three tab panels (description, history, files) are server-rendered on the same page.

    line 289
  14. Very specific:

    Version history is fully inline: All releases are listed in the #history panel with no pagination, even for packages with 100+ versions.

    line 290

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

PyPI — Python Package Index

Overview

Covers the full read workflow on PyPI: searching for packages, reading package detail pages (description, version history, download files), and retrieving metadata via the JSON API. The JSON API is the recommended approach for automated workflows — no CAPTCHA, no browser required.

Not covered here: Package upload/publishing, account management, user profiles, API tokens.

Auth required for: Uploading packages, managing releases. All browsing and search are public.


Agent Paths

Programmatic [API] — No browser needed

  • Package metadata + all versions: GET https://pypi.org/pypi/{name}/json
  • Specific version metadata: GET https://pypi.org/pypi/{name}/{version}/json
  • Search: No clean JSON search API — use browser or navigate directly to /project/{name}/

Required headers: None — all public endpoints are open

Browser [Browser] — Requires browser control

  • Use selectors and Navigation Flows below
  • Required when: searching without knowing the package name, browsing download files, reading classifiers/maintainer info

When to use which

  • Default to Programmatic if you know the package name — one call returns everything
  • Use Browser when: you need to search for a package by description (not name), or the task involves downloading/copying the pip install command
  • Avoid browser search (/search/) — hCaptcha blocks automated browsers. Use the JSON API instead.

Agent Knowledge Note

Most frontier LLMs have PyPI's API and package structure in training data. This skill adds value via:

  • hCaptcha on /search/ — automated browsers are consistently blocked on the search results page. Training data may suggest using the search UI; the correct path is the JSON API or direct /project/{name}/ navigation.
  • Tabs are preloaded, not lazy — Description, History, and Files tabs are all server-rendered in one HTML response. Tab click is CSS-only. Never wait for a network event after clicking a tab. This is the opposite of crates.io.
  • Search results show no version number — The .package-snippet elements contain the creation date, not the current version. To get the version, navigate to /project/{name}/ or use the JSON API.
  • robots.txt disallows /search* — scraping the search page is against ToS; combined with hCaptcha, the JSON API is the correct path.

Site Map

PageURL PatternNotes
Homepagehttps://pypi.org/Search form
Search resultshttps://pypi.org/search/?q={query}hCaptcha-protected for bots — see Gotchas
Package detailhttps://pypi.org/project/{name}/Description, history, files tabs
Specific versionhttps://pypi.org/project/{name}/{version}/Version-pinned detail
JSON API (latest)https://pypi.org/pypi/{name}/jsonFull metadata, no auth, no CAPTCHA
JSON API (version)https://pypi.org/pypi/{name}/{version}/jsonSpecific version metadata

Page Structures

Homepage

ElementSelectorNotes
Search inputinput[name="q"]Placeholder: "Type '/' to search projects"
Search submitbutton.search-form__button
Nav: Log ina[href^="/account/login/"]
Nav: Registera[href="/account/register/"]

Package Detail (/project/{name}/)

ElementSelectorNotes
Copy pip installbutton.copy-tooltipCopies pip install {name}==version to clipboard
Latest version badgea.status-badgeText: "Latest version" — shows "Yanked" for yanked releases
Description tab#description-tabaria-label="Project description..."
History tab#history-tabaria-label="Release history..."
Files tab#files-tabaria-label="Download files..."
Version history entriesa.cardEach card links to /project/{name}/{version}/
Version number (in card)a.card > p.release__versionText: e.g. "2.32.5" — direct child <p> inside card
Release date (in card)a.card > p.release__version-date timedatetime attr has ISO timestamp; text is humanized date
Maintainer linksa[href^="/user/"]Links to each maintainer's profile
Classifier linksa[href^="/search/?c="]Filter search by classifier (license, Python version, etc.)
Project homepage/source linksa.vertical-tabs__tab[href^="http"]Homepage, docs, source in sidebar
Report malwarea[role="button"][href*="submit-malware-report"]

Search Results (/search/?q={query})

ElementSelectorNotes
Result items.package-snippetEach result is an <a> wrapping name + date + description
Result name.package-snippet__namePackage name
Result creation date.package-snippet__createdWhen the package was first published — not current version
Result description.package-snippet__descriptionOne-line summary
Pagination nexta[aria-label="Next page"]Absent on last page
hCaptcha (if blocked)button#capSubmitAutomated browsers may see this instead of results

Note: Search results do not include the current version number. For current version, navigate to /project/{name}/ or use the JSON API.

Files Tab (within package detail, #files panel)

ElementSelectorNotes
File name filterinput[name="bdist-filenames-filter"]Filter wheel filenames
Interpreter filterselect[name="bdist-tags-interpreters"]e.g. cp313, py3
ABI filterselect[name="bdist-tags-abis"]e.g. cp313, none
Platform filterselect[name="bdist-tags-platforms"]e.g. win_amd64, any
Source dist linka[href$=".tar.gz"]Direct download URL
Wheel linka[href$=".whl"]Direct download URL

Navigation Flows

Flow: Search for a Package [Browser]

Starting point: https://pypi.org/ Prerequisites: None

StepActionTargetValueWait ForTimeout
1navigate—https://pypi.org/input[name="q"] visible5s
2typeinput[name="q"]Search term——
3pressinput[name="q"]EnterURL contains /search/3s

Success state: URL is https://pypi.org/search/?q={term} with .package-snippet results visible.

Branching:

  • If button#capSubmit appears → hCaptcha is blocking — search not available for this browser session. Navigate directly to /project/{name}/ if you know the package name, or use the JSON API: GET https://pypi.org/pypi/{name}/json

Flow: View Package Detail [Browser]

Starting point: Any page Prerequisites: None

StepActionTargetValueWait ForTimeout
1navigate—https://pypi.org/project/{name}/#description-tab visible5s
2readbutton.copy-tooltip, a.status-badge, page body—Description loaded—

Success state: Package page with description, version badge, maintainers, and sidebar links visible. Install command visible in header area.


Flow: Browse Version History [Browser]

Starting point: https://pypi.org/project/{name}/ Prerequisites: None

StepActionTargetWait ForTimeout
1click#history-tabHistory panel visible1s
2reada.cardAll version cards rendered—

To navigate to a specific version:

StepActionTargetWait ForTimeout
3clicka.card:has-text("{version}")Version detail page3s

Success state: URL becomes https://pypi.org/project/{name}/{version}/ with that version's metadata. Status badge may read "Latest version" or "Yanked".


Flow: Get Package Metadata [API]

Starting point: None — direct HTTP fetch Prerequisites: None

StepActionTargetNotes
1fetchhttps://pypi.org/pypi/{name}/jsonReturns full metadata as JSON
2readinfo.name, info.version, info.summaryCore fields

Success state: JSON with top-level keys info, releases, urls, vulnerabilities.


API Response Shapes

GET /pypi/{name}/json

{
  "info": {
    "name": "requests",
    "version": "2.32.3",
    "summary": "Python HTTP for Humans.",
    "requires_python": ">=3.8",
    "home_page": "https://requests.readthedocs.io",
    "license": "Apache-2.0",
    "author": "Kenneth Reitz",
    "author_email": "me@kennethreitz.org",
    "requires_dist": [
      "charset-normalizer<4,>=2",
      "idna<4,>=2.5",
      "urllib3<3,>=1.21.1",
      "certifi>=2017.4.17"
    ],
    "classifiers": [
      "License :: OSI Approved :: Apache Software License",
      "Programming Language :: Python :: 3.11"
    ],
    "project_urls": {
      "Homepage": "https://requests.readthedocs.io",
      "Source": "https://github.com/psf/requests"
    }
  },
  "releases": {
    "2.32.3": [
      {
        "filename": "requests-2.32.3-py3-none-any.whl",
        "url": "https://files.pythonhosted.org/packages/.../requests-2.32.3-py3-none-any.whl",
        "size": 64928,
        "upload_time_iso_8601": "2024-05-29T15:37:05.856790Z",
        "requires_python": ">=3.8",
        "yanked": false,
        "yanked_reason": null
      }
    ]
  },
  "urls": [
    {
      "filename": "requests-2.32.3-py3-none-any.whl",
      "url": "https://files.pythonhosted.org/packages/...",
      "packagetype": "bdist_wheel"
    }
  ],
  "vulnerabilities": []
}

Key fields:

FieldDescription
info.versionLatest version string
info.requires_pythonPython version constraint
info.requires_dist[]PEP 508 dependency strings
releasesObject keyed by version string → array of distribution files
releases[ver][].yankedtrue means this specific file is yanked
urls[]Download URLs for latest version
vulnerabilities[]Known CVEs from OSV database — empty array = no known vulns

Common Agent Tasks

"What version of {package} should I install?"

  1. Fetch: GET https://pypi.org/pypi/{name}/json
  2. Read info.version — this is the latest stable version
  3. Read info.requires_python — confirm compatibility with user's Python version
  4. Read vulnerabilities[] — if non-empty, mention known CVEs
  5. Output: pip install {name}=={version} and any compatibility caveats

"Is {package} actively maintained?"

  1. Fetch: GET https://pypi.org/pypi/{name}/json
  2. Read releases keys — count total releases; sort and get the 3 most recent
  3. Read releases[latest][0].upload_time_iso_8601 — when was the last release?
  4. Read info.home_page and project_urls.Source — is there a linked repo?
  5. Read vulnerabilities[] — any unpatched CVEs?
  6. Output: latest release date, total release count, source link, vulnerability count

"Compare {pkg1} and {pkg2}"

  1. Fetch both in parallel: GET /pypi/{pkg1}/json and GET /pypi/{pkg2}/json
  2. Compare: info.version, info.requires_python, info.license
  3. Compare dependency count: len(info.requires_dist)
  4. Compare release history: len(releases) and recency of latest release
  5. Compare vulnerability status: len(vulnerabilities) for each
  6. Output: side-by-side table of version / Python req / license / dep count / release count / last release / vuln count

Dynamic Content Patterns

  • MPA with server-rendered HTML: No JS framework. Every page navigation is a full page load. Use domcontentloaded.
  • Tabs are already in DOM: All three tab panels (description, history, files) are server-rendered on the same page. Clicking a tab toggles CSS visibility only — no network request, no waiting.
  • Version history is fully inline: All releases are listed in the #history panel with no pagination, even for packages with 100+ versions.
  • hCaptcha on /search/: Automated headless browsers are frequently challenged by hCaptcha on the search endpoint. Direct package URLs (/project/{name}/) and the JSON API are unaffected.
  • Yanked releases: Appear in history with " yanked" in the card text. pip will refuse to install them unless the version is pinned exactly.

Timing & Waiting

TransitionWait ForTypical Delay
Page navigationdomcontentloaded0.5–2s
Tab click (description/history/files)No wait — content already in DOM<100ms
Search submitURL changes to /search/1–3s

Rate Limits

ScopeLimitNotes
JSON APINo documented rate limitRequests are served by CDN; generally very permissive
Browser /search/hCaptcha-gatedAutomated browsers are blocked; use API instead
Download filesBandwidth throttling on very large downloadsNot relevant for metadata tasks

Parallel requests: Safe to fire multiple metadata API requests in parallel — the JSON API is CDN-backed and handles high concurrency.


Common Gotchas

  1. hCaptcha blocks automated search — /search/ is blocked for headless browsers. Detect via button#capSubmit. Workaround: use the JSON API (https://pypi.org/pypi/{name}/json) or navigate directly to /project/{name}/ if you know the package name.
  2. Tabs don't trigger network requests — Description, history, and files content are all server-rendered in one HTML response. Clicking #history-tab just toggles visibility. Never wait for a network event after tab click.
  3. Package name canonicalization — PyPI treats hyphens and underscores as equivalent, and names are case-insensitive. pip_tools, pip-tools, and Pip-Tools all go to the same page. The canonical name is in info.name from the JSON API.
  4. Yanked releases still appear in history — Yanked versions stay visible in a.card entries with "yanked" in the text. They won't install via pip without explicit version pinning.
  5. robots.txt disallows /search* — Well-behaved crawlers should not scrape search. Combined with hCaptcha, the intended path for programmatic lookup is the JSON API.
  6. Version history shows all releases — No pagination on the history tab. document.querySelectorAll('a.card').length gives the total release count.
  7. History entries from JSON API — releases key in the JSON API response is an object keyed by version string. Iterate Object.keys(data.releases).reverse() for chronological order.

Anti-Patterns

  • NEVER use the browser search page for automation — hCaptcha blocks headless browsers on /search/. Use GET /pypi/{name}/json or navigate directly to /project/{name}/.
  • NEVER wait for a network event after clicking a tab — tabs are preloaded in the HTML. Waiting for networkidle or load after a tab click will timeout or proceed immediately with wrong content.
  • NEVER expect version number in search results — .package-snippet elements show the creation date (.package-snippet__created), not the current version. There is no current version in search results — go to the detail page or API.
  • NEVER use .card__title to extract version — the version text is in a.card > p.release__version (direct child <p>). .card__title does not exist.
  • NEVER assume releases is an array — releases is an object keyed by version string, not an array. Iterate Object.keys(data.releases).

Freshness

Skill verified2026-02-20
API stable since2018 — PyPI JSON API (PEP 503 + warehouse); breaking changes are extremely rare
Selector stabilityHIGH — PyPI uses intentional class names (.package-snippet, a.card, .copy-tooltip); no hashing
Breaking change riskLow — PyPI is very conservative about UI changes

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.