Repository navigation
Description
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:AbstractEntrypointFinderplusModuleContextcarrying per-project routing facts - Per-framework finders behind
entrypoint_factory.py, OR-ing results (mirrors Java'sEntrypointsFinderFactory) - 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.routeview, a FastAPI@router.gethandler, a Celery@shared_task, and a Click@cli.commandeach carryis_entrypoint=Trueand the rightentrypoint_framework - A Django function view with no decorator, bound only via
path('...', view)through oneinclude(), is flagged — the routing pre-pass gate - An internally-called helper is not flagged
- Pre-existing
analysis.jsonfiles still load PythonAnalysis.get_entry_point_*become thin readers over these fields, matchingJavaAnalysis
Reference
JackEE — Antoniadis et al., "Static Analysis of Java Enterprise Applications", PLDI 2020. Java mirror: src/main/java/com/ibm/cldk/javaee/.
Activity
Merge pull request #137 from codellm-devkit/feat/issue-27-entrypoint-…
rahlk commentedon Aug 20, 2026
Units 1-3 landed in #137 (
d35541d). Issue stays open — this is 3 of 6 units.Landed:
PyEntrypointrecords onPyCallable/PyClasswith derivedis_entrypoint; a wrapped post-pass over the L1 symbol table; a shippedrules.ymlextensible via--entrypoint-rules; framework gating on imports or manifest; decorator matching; inheritance matching with the class/method dispatch split andviaback-pointers. Working detection for Flask, FastAPI, Celery, Click and DRF decorators.Design:
docs/design/specs/2026-08-19-entrypoint-detection-design.md. Note it corrects this issue's premise in one place: the roadmap's claim that entrypoint vocabulary was "coined three ways" does not hold — Java has the only implementation, and TypeScript'sTSApplication.entrypointsis declared in itsSCHEMA_DECISIONS.mdbutTSEntrypointappears nowhere in its source. Python is the second implementation and set the record shape.Remaining, per spec § 9 and § 10:
[project.scripts],[project.entry-points],setup.cfg,setup.py, Procfile, Dockerfile, SAM/serverless handlers. Exact, no heuristics; the highest value-per-effort work left.frameworks_detected: ["django"], buturls.py-bound views are not detected.__main__walk).add_url_rule(view_func=h),scheduler.add_job(run)and any framework with no finder. Blocked onPyCallArgumentcarrying resolved identity — the same id-space work Structured decorator representation: PyDecorator on callable, class, attribute, parameter #128 did for decorators.Known gaps carried forward: multi-hop inheritance unresolved (
BaseRule.transitiveloaded but unhonoured); no record dedup on(framework, evidence, route);evidencecarries a qualified name rather than a binding site, which unit 5 needs; Neo4j projects onlyis_entrypoint/entrypoint_frameworks, soviais not walkable in the graph;confidencetypedstrrather thanLiteral.Worth knowing before unit 4: matching depends on Jedi's
full_name, which returns the definition path, not the public re-export path —@app.routeresolves toflask.sansio.scaffold.Scaffold.route, notflask.Flask.route. All eight shipped patterns were initially written against the public paths and detected nothing on real code.test/test_entrypoint_frameworks_integration.pynow pins the real paths against installed packages; keep that test honest when adding frameworks.