code-node-graph 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. code_node/__init__.py +40 -0
  2. code_node/__main__.py +7 -0
  3. code_node/analysis/__init__.py +3 -0
  4. code_node/analysis/aws_model.py +197 -0
  5. code_node/analysis/findings.py +462 -0
  6. code_node/analysis/graph.py +780 -0
  7. code_node/analysis/mapping.py +114 -0
  8. code_node/analysis/model.py +289 -0
  9. code_node/analysis/reader.py +1926 -0
  10. code_node/analysis/syntax.py +220 -0
  11. code_node/analysis/terms.py +505 -0
  12. code_node/cli.py +316 -0
  13. code_node/deploys/__init__.py +321 -0
  14. code_node/deploys/sam.py +371 -0
  15. code_node/deploys/serverless.py +117 -0
  16. code_node/kit/__init__.py +4 -0
  17. code_node/kit/blocks.py +184 -0
  18. code_node/kit/fmt.py +389 -0
  19. code_node/kit/highlight.py +131 -0
  20. code_node/kit/render.py +1066 -0
  21. code_node/kit/text.py +81 -0
  22. code_node/libraries/__init__.py +333 -0
  23. code_node/libraries/llm.py +124 -0
  24. code_node/libraries/mongo.py +169 -0
  25. code_node/libraries/redis.py +253 -0
  26. code_node/libraries/sql.py +232 -0
  27. code_node/pages.py +92 -0
  28. code_node/platforms/__init__.py +203 -0
  29. code_node/platforms/aws_lambda.py +290 -0
  30. code_node/platforms/web.py +301 -0
  31. code_node/project.py +402 -0
  32. code_node/report/__init__.py +3 -0
  33. code_node/report/brands.py +244 -0
  34. code_node/report/build.py +119 -0
  35. code_node/report/editor.py +40 -0
  36. code_node/report/graph.py +1411 -0
  37. code_node/report/logos/README.md +8 -0
  38. code_node/report/logos/anthropic-icon.svg +1 -0
  39. code_node/report/logos/aws-amplify.svg +1 -0
  40. code_node/report/logos/aws-api-gateway.svg +1 -0
  41. code_node/report/logos/aws-appflow.svg +1 -0
  42. code_node/report/logos/aws-appsync.svg +1 -0
  43. code_node/report/logos/aws-athena.svg +1 -0
  44. code_node/report/logos/aws-backup.svg +1 -0
  45. code_node/report/logos/aws-batch.svg +1 -0
  46. code_node/report/logos/aws-certificate-manager.svg +1 -0
  47. code_node/report/logos/aws-cloudformation.svg +1 -0
  48. code_node/report/logos/aws-cloudfront.svg +1 -0
  49. code_node/report/logos/aws-cloudtrail.svg +1 -0
  50. code_node/report/logos/aws-cloudwatch.svg +1 -0
  51. code_node/report/logos/aws-codebuild.svg +1 -0
  52. code_node/report/logos/aws-codecommit.svg +1 -0
  53. code_node/report/logos/aws-codedeploy.svg +1 -0
  54. code_node/report/logos/aws-codepipeline.svg +1 -0
  55. code_node/report/logos/aws-cognito.svg +1 -0
  56. code_node/report/logos/aws-config.svg +1 -0
  57. code_node/report/logos/aws-documentdb.svg +1 -0
  58. code_node/report/logos/aws-dynamodb.svg +1 -0
  59. code_node/report/logos/aws-ec2.svg +1 -0
  60. code_node/report/logos/aws-ecs.svg +1 -0
  61. code_node/report/logos/aws-eks.svg +1 -0
  62. code_node/report/logos/aws-elasticache.svg +1 -0
  63. code_node/report/logos/aws-elb.svg +1 -0
  64. code_node/report/logos/aws-eventbridge.svg +1 -0
  65. code_node/report/logos/aws-glacier.svg +1 -0
  66. code_node/report/logos/aws-glue.svg +1 -0
  67. code_node/report/logos/aws-iam.svg +1 -0
  68. code_node/report/logos/aws-keyspaces.svg +1 -0
  69. code_node/report/logos/aws-kinesis.svg +1 -0
  70. code_node/report/logos/aws-kms.svg +1 -0
  71. code_node/report/logos/aws-lake-formation.svg +1 -0
  72. code_node/report/logos/aws-lambda.svg +1 -0
  73. code_node/report/logos/aws-lightsail.svg +1 -0
  74. code_node/report/logos/aws-mq.svg +1 -0
  75. code_node/report/logos/aws-msk.svg +1 -0
  76. code_node/report/logos/aws-neptune.svg +1 -0
  77. code_node/report/logos/aws-open-search.svg +1 -0
  78. code_node/report/logos/aws-quicksight.svg +1 -0
  79. code_node/report/logos/aws-rds.svg +1 -0
  80. code_node/report/logos/aws-redshift.svg +1 -0
  81. code_node/report/logos/aws-route53.svg +1 -0
  82. code_node/report/logos/aws-s3.svg +1 -0
  83. code_node/report/logos/aws-secrets-manager.svg +1 -0
  84. code_node/report/logos/aws-ses.svg +1 -0
  85. code_node/report/logos/aws-shield.svg +1 -0
  86. code_node/report/logos/aws-sns.svg +1 -0
  87. code_node/report/logos/aws-sqs.svg +1 -0
  88. code_node/report/logos/aws-step-functions.svg +1 -0
  89. code_node/report/logos/aws-systems-manager.svg +1 -0
  90. code_node/report/logos/aws-timestream.svg +1 -0
  91. code_node/report/logos/aws-waf.svg +1 -0
  92. code_node/report/logos/aws-xray.svg +1 -0
  93. code_node/report/logos/aws.svg +1 -0
  94. code_node/report/logos/azure-icon.svg +1 -0
  95. code_node/report/logos/django-icon.svg +1 -0
  96. code_node/report/logos/elasticsearch.svg +1 -0
  97. code_node/report/logos/fastapi-icon.svg +1 -0
  98. code_node/report/logos/firebase-icon.svg +1 -0
  99. code_node/report/logos/flask.svg +1 -0
  100. code_node/report/logos/google-cloud.svg +1 -0
  101. code_node/report/logos/kafka-icon.svg +1 -0
  102. code_node/report/logos/mariadb-icon.svg +1 -0
  103. code_node/report/logos/mongodb-icon.svg +1 -0
  104. code_node/report/logos/mysql-icon.svg +1 -0
  105. code_node/report/logos/openai-icon.svg +1 -0
  106. code_node/report/logos/postgresql.svg +1 -0
  107. code_node/report/logos/python.svg +1 -0
  108. code_node/report/logos/rabbitmq-icon.svg +1 -0
  109. code_node/report/logos/redis.svg +1 -0
  110. code_node/report/logos/serverless.svg +1 -0
  111. code_node/report/logos/slack-icon.svg +1 -0
  112. code_node/report/logos/small/aws-api-gateway.svg +1 -0
  113. code_node/report/logos/small/aws-appflow.svg +1 -0
  114. code_node/report/logos/small/aws-appsync.svg +1 -0
  115. code_node/report/logos/small/aws-athena.svg +1 -0
  116. code_node/report/logos/small/aws-backup.svg +1 -0
  117. code_node/report/logos/small/aws-batch.svg +1 -0
  118. code_node/report/logos/small/aws-certificate-manager.svg +1 -0
  119. code_node/report/logos/small/aws-cloudformation.svg +1 -0
  120. code_node/report/logos/small/aws-cloudfront.svg +1 -0
  121. code_node/report/logos/small/aws-cloudtrail.svg +1 -0
  122. code_node/report/logos/small/aws-cloudwatch.svg +1 -0
  123. code_node/report/logos/small/aws-codebuild.svg +1 -0
  124. code_node/report/logos/small/aws-codecommit.svg +1 -0
  125. code_node/report/logos/small/aws-codedeploy.svg +1 -0
  126. code_node/report/logos/small/aws-codepipeline.svg +1 -0
  127. code_node/report/logos/small/aws-cognito.svg +1 -0
  128. code_node/report/logos/small/aws-config.svg +1 -0
  129. code_node/report/logos/small/aws-documentdb.svg +1 -0
  130. code_node/report/logos/small/aws-dynamodb.svg +1 -0
  131. code_node/report/logos/small/aws-ec2.svg +1 -0
  132. code_node/report/logos/small/aws-ecs.svg +1 -0
  133. code_node/report/logos/small/aws-eks.svg +1 -0
  134. code_node/report/logos/small/aws-elasticache.svg +1 -0
  135. code_node/report/logos/small/aws-elb.svg +1 -0
  136. code_node/report/logos/small/aws-eventbridge.svg +1 -0
  137. code_node/report/logos/small/aws-glacier.svg +1 -0
  138. code_node/report/logos/small/aws-glue.svg +1 -0
  139. code_node/report/logos/small/aws-iam.svg +1 -0
  140. code_node/report/logos/small/aws-keyspaces.svg +1 -0
  141. code_node/report/logos/small/aws-kinesis.svg +1 -0
  142. code_node/report/logos/small/aws-kms.svg +1 -0
  143. code_node/report/logos/small/aws-lake-formation.svg +1 -0
  144. code_node/report/logos/small/aws-lambda.svg +1 -0
  145. code_node/report/logos/small/aws-mq.svg +1 -0
  146. code_node/report/logos/small/aws-msk.svg +1 -0
  147. code_node/report/logos/small/aws-neptune.svg +1 -0
  148. code_node/report/logos/small/aws-open-search.svg +1 -0
  149. code_node/report/logos/small/aws-quicksight.svg +1 -0
  150. code_node/report/logos/small/aws-rds.svg +1 -0
  151. code_node/report/logos/small/aws-redshift.svg +1 -0
  152. code_node/report/logos/small/aws-route53.svg +1 -0
  153. code_node/report/logos/small/aws-s3.svg +1 -0
  154. code_node/report/logos/small/aws-secrets-manager.svg +1 -0
  155. code_node/report/logos/small/aws-ses.svg +1 -0
  156. code_node/report/logos/small/aws-shield.svg +1 -0
  157. code_node/report/logos/small/aws-sns.svg +1 -0
  158. code_node/report/logos/small/aws-sqs.svg +1 -0
  159. code_node/report/logos/small/aws-step-functions.svg +1 -0
  160. code_node/report/logos/small/aws-systems-manager.svg +1 -0
  161. code_node/report/logos/small/aws-timestream.svg +1 -0
  162. code_node/report/logos/small/aws-waf.svg +1 -0
  163. code_node/report/logos/small/aws-xray.svg +1 -0
  164. code_node/report/logos/snowflake-icon.svg +1 -0
  165. code_node/report/logos/sqlite.svg +1 -0
  166. code_node/report/logos/stripe.svg +1 -0
  167. code_node/report/logos/supabase-icon.svg +1 -0
  168. code_node/report/logos/twilio-icon.svg +1 -0
  169. code_node/report/outline.py +219 -0
  170. code_node/report/style.py +358 -0
  171. code_node/report/tabs.py +73 -0
  172. code_node/report/walk.py +624 -0
  173. code_node/serve.py +277 -0
  174. code_node_graph-0.1.0.dist-info/METADATA +165 -0
  175. code_node_graph-0.1.0.dist-info/RECORD +178 -0
  176. code_node_graph-0.1.0.dist-info/WHEEL +4 -0
  177. code_node_graph-0.1.0.dist-info/entry_points.txt +2 -0
  178. code_node_graph-0.1.0.dist-info/licenses/LICENSE +201 -0
@@ -0,0 +1,119 @@
1
+ """
2
+ The page code-node draws for one entry point: tabs for the graph and the walk through its steps.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import Any
8
+
9
+ from ..kit.blocks import _Note, _Text
10
+ from ..kit.fmt import _plural
11
+
12
+ from ..analysis.findings import _listed, _short_name
13
+ from ..analysis.graph import CodeGraph, code_graph
14
+ from ..analysis.model import CodeMap
15
+ from .graph import _Graph
16
+ from .tabs import _Tabs
17
+ from .walk import _Walk, walk_stops
18
+
19
+
20
+ def _closing_note(cmap: CodeMap, graph: CodeGraph) -> str:
21
+ said = [
22
+ "It reads the code with Python's ast module and runs none of it. It follows calls into the folder's own "
23
+ "functions and the boto3 clients it makes; calls through a value handed in from elsewhere, or made inside "
24
+ "a library, aren't followed, so there may be more than it lists."
25
+ ]
26
+ fn = cmap.function
27
+ if fn is not None and getattr(fn, "source", ""):
28
+ said.append(
29
+ f"Where it runs comes from {fn.name} in {fn.source}: its environment variables, timeout and "
30
+ "what its role allows are checked against the code."
31
+ )
32
+ services = list(dict.fromkeys(call.service for call in cmap.library_calls))
33
+ if services:
34
+ said.append(f"Calls to {_listed(services, 4)} are read by code-node's library plugins.")
35
+ if graph.hidden:
36
+ said.append(
37
+ f"The graph leaves out {_plural(graph.hidden, 'function')} to stay readable: run with --all to "
38
+ "draw every one."
39
+ )
40
+ if cmap.other_files:
41
+ said.append(
42
+ f"{_plural(cmap.other_files, 'other Python file')} in the folder "
43
+ f"{'is' if cmap.other_files == 1 else 'are'}n't imported from here, so they're left out."
44
+ )
45
+ if cmap.unreached:
46
+ said.append(
47
+ f"{_plural(cmap.unreached, 'function')} in the files it read never "
48
+ f"run{'s' if cmap.unreached == 1 else ''} from {_short_name(cmap.entry or '')}()."
49
+ )
50
+ if cmap.limited:
51
+ said.append(f"To keep it short, it {cmap.limited}.")
52
+ return " ".join(said)
53
+
54
+
55
+ def page_blocks(
56
+ cmap: CodeMap,
57
+ *,
58
+ project: str,
59
+ max_functions: int,
60
+ max_depth: int,
61
+ sources: dict[str, str] | None = None,
62
+ editor: str = "",
63
+ ) -> list[Any]:
64
+ """
65
+ The whole page for one entry point, as report blocks: tabs for the graph and the walk through its steps, with the
66
+ entry point and the folder beside them. sources is the code read, {file: its text}: with it, a box of the graph
67
+ clicked shows its code. editor is a link from editor_link(), to open the code at a line in an editor.
68
+ """
69
+ if cmap.note:
70
+ return [_Note(cmap.note)]
71
+ blocks: list[Any] = []
72
+ if cmap.entry is None and cmap.handlers:
73
+ blocks.append(
74
+ _Note(
75
+ f"{cmap.handler} isn't a function in {cmap.handler_file}. Its functions that look like "
76
+ f"entry points: {', '.join(cmap.handlers)}."
77
+ )
78
+ )
79
+ graph = code_graph(cmap, max_functions=max_functions, max_depth=max_depth)
80
+ entry = _short_name(cmap.entry) if cmap.entry else None
81
+ walk = _Walk(
82
+ cmap.startup,
83
+ cmap.steps,
84
+ f"What each call does, step by step from {entry}()" if entry else "What each call does",
85
+ calls_title=f"Each call, from {entry}()" if entry else "Each call",
86
+ functions=cmap.functions,
87
+ sources=sources or {},
88
+ editor=editor,
89
+ )
90
+ tabs: list[tuple[str, str, list[Any]]] = []
91
+ if graph.nodes:
92
+ tabs.append(
93
+ (
94
+ "Graph",
95
+ f"{len(graph.nodes)} box{'' if len(graph.nodes) == 1 else 'es'}",
96
+ [
97
+ _Graph(
98
+ graph,
99
+ "How it fits together: what comes in, who calls whom, and what it reaches",
100
+ sources=sources or {},
101
+ editor=editor,
102
+ ),
103
+ _Text(
104
+ graph.mermaid(),
105
+ code=True,
106
+ collapsed=True,
107
+ title=("The same graph in Mermaid, to paste in a Markdown file, a wiki or a pull request"),
108
+ ),
109
+ ],
110
+ )
111
+ )
112
+ tabs.append(("Step by step", _plural(len(walk_stops(walk)), "step"), [walk]))
113
+ read = f"{_plural(cmap.files, 'file')}, {cmap.lines:,} lines, nothing run" if cmap.files else ""
114
+ blocks.append(
115
+ _Tabs(
116
+ tabs, caption=cmap.handler, about=" · ".join(filter(None, [project, read])), foot=_closing_note(cmap, graph)
117
+ )
118
+ )
119
+ return blocks
@@ -0,0 +1,40 @@
1
+ """
2
+ Links that open a line of the code in an editor: VS Code's and Cursor's vscode:// and cursor:// links, with the
3
+ remote form inside WSL, where the editor runs on Windows and the code is in the Linux distro.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from urllib.parse import quote
9
+
10
+ EDITORS = {"vscode": "VS Code", "cursor": "Cursor"} # --editor's choices besides none, and the name each link says
11
+
12
+
13
+ def editor_link(editor: str, root: str, wsl: str = "") -> str:
14
+ """
15
+ A link to a line of a file under root in the editor, with {file} and {line} left to fill in (open_at fills them),
16
+ or '' for none. wsl is the WSL distro the code is in ('Ubuntu'), when it is.
17
+ """
18
+ if editor not in EDITORS:
19
+ return ""
20
+ path = root.replace("\\", "/").rstrip("/")
21
+ path = quote(path if path.startswith("/") else "/" + path, safe="/:") # C:/code -> /C:/code
22
+ if wsl:
23
+ return f"{editor}://vscode-remote/wsl+{quote(wsl)}{path}/{{file}}:{{line}}"
24
+ return f"{editor}://file{path}/{{file}}:{{line}}"
25
+
26
+
27
+ def open_at(link: str, file: str, line: int) -> str:
28
+ """
29
+ The link for one line of a file (its path from the folder read), or '' with no link.
30
+ """
31
+ if not link:
32
+ return ""
33
+ return link.replace("{file}", quote(file)).replace("{line}", str(max(1, line)))
34
+
35
+
36
+ def editor_name(link: str) -> str:
37
+ """
38
+ The editor a link opens, by name: 'VS Code'.
39
+ """
40
+ return EDITORS.get(link.partition("://")[0], "your editor")