Skip to main content

Python package introspection and analysis tool

Project description

pypkgview

A Python package introspection tool that parses source code via AST and exports the full API surface into structured, queryable formats.

What it does

pypkgview walks a Python package's source tree, statically analyzes every module, and extracts:

  • Classes — bases, decorators, metaclasses, descriptors, nested classes
  • Functions — async, generators, generator delegation, decorators
  • Imports — direct, internal (relative/absolute), and external, with full alias resolution
  • Constants — module-level constants and variable declarations

No importing. No running code. Pure AST analysis.

Why it's useful

Most tools that understand Python packages require importing them. pypkgview works entirely from source — meaning it works on packages you don't have installed, packages with heavy dependencies, or packages you're auditing without wanting to execute.

The structured output is queryable. With the SQLite exporter you can ask questions like:

-- What is the most inherited base class across the package?
SELECT b.name, COUNT(*) as count
FROM bases b
GROUP BY b.name
ORDER BY count DESC;

-- Which modules have the most complex API surface?
SELECT m.name, COUNT(DISTINCT c.id) as classes, COUNT(DISTINCT f.id) as functions
FROM modules m
LEFT JOIN classes c ON c.module_id = m.id
LEFT JOIN functions f ON f.module_id = m.id
GROUP BY m.id
ORDER BY classes + functions DESC;

-- Find all generator functions
SELECT m.name, f.name, f.has_generator_delegation
FROM functions f
JOIN modules m ON m.id = f.module_id
WHERE f.is_generator = 1;

Installation

pip install pypkgview

Usage

from pypkgview.engine import DiscoverEngine
from pypkgview.walker import ModuleWalker
from pypkgview.exporters import YamlExporter, JSONExporter, SqliteExporter

# point at the package source directory
engine = DiscoverEngine(
    file_path="/path/to/package",
    module_walker_type=ModuleWalker
)

# export to YAML
YamlExporter().export(engine)

# export to JSON
JSONExporter().export(engine)

# export to SQLite
SqliteExporter().export(engine)

Exporters

Exporter Output Best for
YamlExporter <package>.yaml Human reading, diffs
JSONExporter <package>/<module>.json Programmatic consumption
SqliteExporter <package>.db Querying, analysis

Schema

The SQLite exporter produces the following schema:

modules    (id, name)
classes    (id, module_id, name, is_descriptor, descriptor_type, is_nested, parent_class, has_metaclass, metaclass)
bases      (id, class_id, name)
functions  (id, module_id, name, is_async, is_generator, has_generator_delegation)
decorators (id, class_id, function_id, name)
constants  (id, module_id, name, type)
imports    (id, module_id, source, name, type)

What it can tell you

Architecture — which modules are pure data, which are pure logic, where complexity is concentrated.

Inheritance — the full base class hierarchy across the package, who inherits what and how many times.

API surface — public vs internal, deprecated vs current, how much changed between versions.

Dependencies — what external packages a module leans on, hidden coupling to third-party internals.

Version diffing — run against two versions of the same package and diff the databases to generate a structural changelog.

Example findings

Running pypkgview against real packages reveals things that docs won't tell you:

  • FastAPI — the entire OpenAPI schema lives in one module (fastapi.openapi.models, 42 classes). Zero async module-level functions — all async logic lives inside class methods.
  • Pydantic v2 — ships a full copy of v1 internally (pydantic.v1.*). The two codebases are nearly identical in size. The real engine lives in pydantic._internal — 28 modules, 190 functions, mostly invisible to users.

Architecture

datastructures.py   — typed data containers (Class, Discover Protocol)
parser.py           — AST NodeVisitor, extracts raw nodes
walker.py           — resolves AST nodes into structured dicts, handles import aliasing
engine.py           — walks the file system, orchestrates walker per module
exporters.py        — pluggable export backends (YAML, JSON, SQLite)

Exporters are interchangeable via the Exporter Protocol — adding a new export format requires no changes to any other file.

Extending

To add a new exporter implement the Exporter Protocol:

from pypkgview.datastructures import Discover
from pypkgview.exporters import Exporter

class MyExporter:
    def export(self, discover: Discover) -> None:
        for module in discover:
            # module is a dict {module_name: {classes, functions, imports, constants}}
            ...

Limitations

  • Analyzes module-level functions only — class methods are captured on the class but not individually queryable in the current schema
  • Import resolution depends on static analysis — dynamic imports (__import__, importlib) are not captured
  • Type annotations are not currently extracted

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pypkgview-0.1.0.tar.gz (22.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pypkgview-0.1.0-py3-none-any.whl (21.8 kB view details)

Uploaded Python 3

File details

Details for the file pypkgview-0.1.0.tar.gz.

File metadata

  • Download URL: pypkgview-0.1.0.tar.gz
  • Upload date:
  • Size: 22.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for pypkgview-0.1.0.tar.gz
Algorithm Hash digest
SHA256 91aff4af13fa45c1b3af09ff1959d79522c790ec4c6ae63e84faf1a582758cde
MD5 f5bef717502338ae7afb995a1733d478
BLAKE2b-256 b96013ace4ad5e0adb012e3d2a17da2f13fe83875a65c337ca900456a051fbd0

See more details on using hashes here.

File details

Details for the file pypkgview-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: pypkgview-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 21.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for pypkgview-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4315805a198c683723295b16100a059444c8954042a20bb4e958c4aba672dbd7
MD5 da810306baa2944d01a3dc80d2a30a70
BLAKE2b-256 b18a2853a0b26f6d07066f6b51429ce60e4c3746d20d2f2cabf2bb675e7790c3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page