Skip to content

Framework-independent entrypoint detection (JackEE-style finders) #27

Description

@rahlk

Is your feature request related to a problem? Please describe.

Nothing in the emitted schema says which callables a framework invokes from outside the application's own call graph. A call graph without identified roots cannot answer reachability, dead-code, or attack-surface questions, and every consumer re-derives entrypoints ad hoc.

The gap is load-bearing downstream. Java emits is_entrypoint and is_entrypoint_class (python-sdk/cldk/models/java/models.py:343,403), so JavaAnalysis.get_entry_point_* are real methods. The Python facade mirrors the same surface but all four — get_entry_point_classes, get_entry_point_methods, get_service_entry_point_classes, get_service_entry_point_methods — raise NotImplementedError (python-sdk/cldk/analysis/python/python_analysis.py:881-960), purely because the backend supplies no data.

Describe the solution you'd like

  • Schema, all defaulted: PyClass.is_entrypoint, PyClass.entrypoint_framework, PyCallable.is_entrypoint, PyCallable.entrypoint_framework
  • frameworks/_base.py: AbstractEntrypointFinder plus ModuleContext carrying per-project routing facts
  • Per-framework finders behind entrypoint_factory.py, OR-ing results (mirrors Java's EntrypointsFinderFactory)
  • Routing pre-pass in frameworks/routing/, one pass per project, emitting {qualified_name → route_metadata}
  • Wire into symbol_table_builder.py: routing pre-pass first, then set the fields during class/function construction
Finder Signals
flask @app.route, @bp.get|post|…, MethodView/View bases
fastapi @app|router.get|post|websocket, router mounts via ModuleContext
django CBV bases, DRF @api_view/@action, urls.py resolution
tornado RequestHandler subclass
celery @app.task, @shared_task, @periodic_task
aws_lambda handler(event, context) + SAM/serverless binding
cli @click.command, @app.command
grpc *Servicer subclass

Routing resolvers: django_url_resolver (path/re_path/url/include chains, .as_view()), fastapi_router_resolver (include_router(prefix=…), mount), flask_blueprint_resolver (Blueprint + register_blueprint).

Describe alternatives you've considered

Not stated in the original issue.

Additional context

Scope boundary

Entrypoints only. CRUD detection is specced separately. is_entrypoint_class covers inheritance-based entrypoints only, not a coarse "worth analyzing" filter as in Java — in Python the function-level predicate does the real work.

Caveats and known risks

  • The routing pre-pass is the only piece with no Java analog and carries most of the risk.
  • Decorator-only detection was rejected: it misses Django entirely, where views bind in urls.py.
  • Literal JackEE (Datalog/Doop fact ingestion) was rejected: this analyzer is AST-based, and Java already ported the same architecture to ASTs.
  • Resolving in the SDK was rejected: it sees only the serialized schema and cannot re-run AST passes.
  • Tree-sitter suffices for decorators and base classes; Jedi is needed only for cross-module base resolution.

Definition of done

  • A Flask @app.route view, a FastAPI @router.get handler, a Celery @shared_task, and a Click @cli.command each carry is_entrypoint=True and the right entrypoint_framework
  • A Django function view with no decorator, bound only via path('...', view) through one include(), is flagged — the routing pre-pass gate
  • An internally-called helper is not flagged
  • Pre-existing analysis.json files still load
  • PythonAnalysis.get_entry_point_* become thin readers over these fields, matching JavaAnalysis

Reference

JackEE — Antoniadis et al., "Static Analysis of Java Enterprise Applications", PLDI 2020. Java mirror: src/main/java/com/ibm/cldk/javaee/.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions