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.2.tar.gz (43.5 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.2-py3-none-any.whl (25.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: pcresolve-1.0.2.tar.gz
  • Upload date:
  • Size: 43.5 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.2.tar.gz
Algorithm Hash digest
SHA256 4d758f9acbec45188106a2127b26e493823f09781bddf0682ed2888e01cd6da1
MD5 5b0a8309a34e271fa11cc0a1a2c045c1
BLAKE2b-256 c10c801f1bbc963ca843086c436e93197763519ef688120e4aab86666c9ec6cd

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pcresolve-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 25.0 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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 58e50944efaafced062f2422d8e93127f78f260617bb3e29119b38bc11fdeac2
MD5 903d9f083ac81b81dfff6e4149869b20
BLAKE2b-256 c775be3cf777c401ae9841f62caea907e133214b3ae3d86b8198b3f136cd7a8e

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