Skip to main content

Static analysis tool for tracing Python API calls to their origin library

Project description

PCResolve — Python API Call Chain Tracing

Static analysis tool that traces every API call in a Python project back to its origin library (e.g. requests, numpy, flask). Each call is classified by definition origin (not data flow): a locally defined function is local even if it internally calls third-party APIs. Other classifications include python for builtins and the top-level library name for third-party / stdlib calls. When container iteration produces ambiguous candidates, the result is a merged label like [requests,numpy].

PyPI License: MIT

Installation

pip install pcresolve

For development:

pip install -e .

No third-party dependencies — pcresolve uses only the Python standard library (ast, os, sys, builtins, copy, typing).

Requires Python 3.9+.

Quick Start

CLI

# Human-readable output
pcresolve /path/to/project

# JSON output
pcresolve --json /path/to/project

# Or as a module
python -m pcresolve /path/to/project

Library API

from pcresolve import analyze_project, analyze_source

# Analyze an entire project
result = analyze_project("/path/to/project")
for call in result.all_api_calls:
    print(f"{call.expression} -> {call.top_library}")

# Analyze a single source string
code = '''
import requests
resp = requests.get("https://example.com")
'''
result = analyze_source(code, file_path="example.py")
for sym, top in result.symbols.items():
    print(f"{sym} -> {top}")

Public API

Name Description
analyze_project(root) Full project analysis, returns ProjectAnalysis
analyze_source(code) Single-file analysis, returns FileAnalysis
scan_directory(root) Discover .py/.pyi files, returns list[str]
ProjectAnalyzer(root) Orchestrator class (step-by-step control)
SingleFileAnalyzer() AST visitor class for one file
ModuleMapper(root) File-path to module-name bidirectional mapping
SymbolTable() Per-symbol chain tracking
FileScanner() File system scanner

Output Types

@dataclass
class ApiCall:
    expression: str       # "requests.get('url')"
    top_library: str      # "requests", "python", "local"
    base_symbol: str      # Root symbol name
    chain: list           # Resolution chain

@dataclass
class FileAnalysis:
    file_path: str
    module_name: str
    symbols: dict         # symbol -> top-level source
    chains: dict          # symbol -> resolution chain
    api_calls: list

@dataclass
class ProjectAnalysis:
    project_root: str
    files: list
    all_api_calls: list

Supported Patterns

  • Direct import + direct call
  • from/as import + alias call
  • Variable binding / container storage (dict, list, tuple, set)
  • partial / lambda wrappers
  • Class encapsulation & inheritance
  • Cross-file shared third-party instances
  • Decorator pattern
  • Context managers / protocols (with, async with)
  • Chained calls / fluent API
  • getattr / importlib.import_module dynamic calls
  • for loop container iteration (with merged ambiguous candidates)
  • Tuple unpacking (e.g., a, b = connect())
  • List / set / dict comprehension
  • BinOp receiver method calls (e.g., (a - b).method())
  • Broken attribute chains across Call nodes (e.g., .last().dt.days())
  • Self-referencing variable reassignment (e.g., df = df.dropna())
  • async def / async for support
  • Wildcard import from local modules

Known Limitations

  • partial alias: a = partial; a(requests.get, ...) resolves to functools instead of requests. The static analysis only recognizes direct partial(...) calls, not aliases to partial.
  • Multiple inheritance method attribution: When a class inherits from multiple bases, method resolution stops at the first base that traces to an external library. A locally defined method may be misattributed if an external base class appears earlier in the MRO.
  • Container iteration in single-file mode: for f in {requests.get, np.sum}: f(...) produces an unresolved structured tuple in SingleFileAnalyzer. Full resolution to a merged candidate like [requests,numpy] happens only in the cross-file stage.
  • Dynamic import_module with variables: importlib.import_module(name) only resolves when name is a string literal. Variable arguments produce an unresolved result.
  • Multiple return values: When a function has multiple return statements, only the first encountered return value is recorded. Later branches (e.g., else paths) are not tracked.

Running Tests

python -m pytest tests/ -v

License

PCResolve is licensed under the MIT License. See LICENSE for details.

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

pcresolve-1.0.3.tar.gz (45.7 kB view details)

Uploaded Source

Built Distribution

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

pcresolve-1.0.3-py3-none-any.whl (26.8 kB view details)

Uploaded Python 3

File details

Details for the file pcresolve-1.0.3.tar.gz.

File metadata

  • Download URL: pcresolve-1.0.3.tar.gz
  • Upload date:
  • Size: 45.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.13

File hashes

Hashes for pcresolve-1.0.3.tar.gz
Algorithm Hash digest
SHA256 ffbd287f54b9d599cea8ac5fb2975de1014f8c924c3e54eabc9e8a0bbfde7f2f
MD5 8d28e4459a73fbc4daeb71b7a10db00e
BLAKE2b-256 8414cbcf3e7d1c31d64978102ed3e57600dab07ed347eae1896e16c75b333320

See more details on using hashes here.

File details

Details for the file pcresolve-1.0.3-py3-none-any.whl.

File metadata

  • Download URL: pcresolve-1.0.3-py3-none-any.whl
  • Upload date:
  • Size: 26.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.13

File hashes

Hashes for pcresolve-1.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 5bb649cd455e4cccc8573661510c58bd853b50396fad092ee2c9c078e291eadd
MD5 81e0ac056e2d13a7824eda461350d64b
BLAKE2b-256 79a0d5278da145458c0959720d062f707fd3d2520b1aceee9f0a6b5eb7619643

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