flowquery 1.0.16 → 1.0.17

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 (318) hide show
  1. package/.github/workflows/python-publish.yml +97 -0
  2. package/dist/compute/runner.d.ts +3 -2
  3. package/dist/compute/runner.d.ts.map +1 -1
  4. package/dist/compute/runner.js +7 -7
  5. package/dist/compute/runner.js.map +1 -1
  6. package/dist/flowquery.min.js +1 -1
  7. package/dist/graph/data.d.ts +31 -0
  8. package/dist/graph/data.d.ts.map +1 -0
  9. package/dist/graph/data.js +110 -0
  10. package/dist/graph/data.js.map +1 -0
  11. package/dist/graph/database.d.ts +20 -0
  12. package/dist/graph/database.d.ts.map +1 -0
  13. package/dist/graph/database.js +77 -0
  14. package/dist/graph/database.js.map +1 -0
  15. package/dist/graph/hops.d.ts +11 -0
  16. package/dist/graph/hops.d.ts.map +1 -0
  17. package/dist/graph/hops.js +25 -0
  18. package/dist/graph/hops.js.map +1 -0
  19. package/dist/graph/node.d.ts +35 -0
  20. package/dist/graph/node.d.ts.map +1 -0
  21. package/dist/graph/node.js +113 -0
  22. package/dist/graph/node.js.map +1 -0
  23. package/dist/graph/node_data.d.ts +11 -0
  24. package/dist/graph/node_data.d.ts.map +1 -0
  25. package/dist/graph/node_data.js +20 -0
  26. package/dist/graph/node_data.js.map +1 -0
  27. package/dist/graph/node_reference.d.ts +10 -0
  28. package/dist/graph/node_reference.d.ts.map +1 -0
  29. package/dist/graph/node_reference.js +52 -0
  30. package/dist/graph/node_reference.js.map +1 -0
  31. package/dist/graph/pattern.d.ts +18 -0
  32. package/dist/graph/pattern.d.ts.map +1 -0
  33. package/dist/graph/pattern.js +114 -0
  34. package/dist/graph/pattern.js.map +1 -0
  35. package/dist/graph/pattern_expression.d.ts +14 -0
  36. package/dist/graph/pattern_expression.d.ts.map +1 -0
  37. package/dist/graph/pattern_expression.js +58 -0
  38. package/dist/graph/pattern_expression.js.map +1 -0
  39. package/dist/graph/patterns.d.ts +11 -0
  40. package/dist/graph/patterns.d.ts.map +1 -0
  41. package/dist/graph/patterns.js +49 -0
  42. package/dist/graph/patterns.js.map +1 -0
  43. package/dist/graph/physical_node.d.ts +10 -0
  44. package/dist/graph/physical_node.d.ts.map +1 -0
  45. package/dist/graph/physical_node.js +40 -0
  46. package/dist/graph/physical_node.js.map +1 -0
  47. package/dist/graph/physical_relationship.d.ts +10 -0
  48. package/dist/graph/physical_relationship.d.ts.map +1 -0
  49. package/dist/graph/physical_relationship.js +40 -0
  50. package/dist/graph/physical_relationship.js.map +1 -0
  51. package/dist/graph/relationship.d.ts +40 -0
  52. package/dist/graph/relationship.d.ts.map +1 -0
  53. package/dist/graph/relationship.js +124 -0
  54. package/dist/graph/relationship.js.map +1 -0
  55. package/dist/graph/relationship_data.d.ts +12 -0
  56. package/dist/graph/relationship_data.d.ts.map +1 -0
  57. package/dist/graph/relationship_data.js +40 -0
  58. package/dist/graph/relationship_data.js.map +1 -0
  59. package/dist/graph/relationship_match_collector.d.ts +19 -0
  60. package/dist/graph/relationship_match_collector.d.ts.map +1 -0
  61. package/dist/graph/relationship_match_collector.js +55 -0
  62. package/dist/graph/relationship_match_collector.js.map +1 -0
  63. package/dist/graph/relationship_reference.d.ts +8 -0
  64. package/dist/graph/relationship_reference.d.ts.map +1 -0
  65. package/dist/graph/relationship_reference.js +37 -0
  66. package/dist/graph/relationship_reference.js.map +1 -0
  67. package/dist/parsing/base_parser.d.ts +1 -0
  68. package/dist/parsing/base_parser.d.ts.map +1 -1
  69. package/dist/parsing/base_parser.js +4 -1
  70. package/dist/parsing/base_parser.js.map +1 -1
  71. package/dist/parsing/context.d.ts +2 -2
  72. package/dist/parsing/context.js +5 -5
  73. package/dist/parsing/expressions/boolean.d.ts +8 -0
  74. package/dist/parsing/expressions/boolean.d.ts.map +1 -0
  75. package/dist/parsing/expressions/boolean.js +26 -0
  76. package/dist/parsing/expressions/boolean.js.map +1 -0
  77. package/dist/parsing/expressions/expression.d.ts +4 -1
  78. package/dist/parsing/expressions/expression.d.ts.map +1 -1
  79. package/dist/parsing/expressions/expression.js +15 -8
  80. package/dist/parsing/expressions/expression.js.map +1 -1
  81. package/dist/parsing/expressions/operator.d.ts +1 -1
  82. package/dist/parsing/expressions/operator.d.ts.map +1 -1
  83. package/dist/parsing/expressions/operator.js.map +1 -1
  84. package/dist/parsing/functions/function_factory.d.ts +13 -13
  85. package/dist/parsing/functions/function_factory.d.ts.map +1 -1
  86. package/dist/parsing/functions/function_factory.js +20 -18
  87. package/dist/parsing/functions/function_factory.js.map +1 -1
  88. package/dist/parsing/operations/create_node.d.ts +14 -0
  89. package/dist/parsing/operations/create_node.d.ts.map +1 -0
  90. package/dist/parsing/operations/create_node.js +51 -0
  91. package/dist/parsing/operations/create_node.js.map +1 -0
  92. package/dist/parsing/operations/create_relationship.d.ts +14 -0
  93. package/dist/parsing/operations/create_relationship.d.ts.map +1 -0
  94. package/dist/parsing/operations/create_relationship.js +51 -0
  95. package/dist/parsing/operations/create_relationship.js.map +1 -0
  96. package/dist/parsing/operations/match.d.ts +15 -0
  97. package/dist/parsing/operations/match.d.ts.map +1 -0
  98. package/dist/parsing/operations/match.js +45 -0
  99. package/dist/parsing/operations/match.js.map +1 -0
  100. package/dist/parsing/operations/operation.d.ts +1 -0
  101. package/dist/parsing/operations/operation.d.ts.map +1 -1
  102. package/dist/parsing/operations/operation.js +6 -0
  103. package/dist/parsing/operations/operation.js.map +1 -1
  104. package/dist/parsing/operations/return.d.ts +1 -0
  105. package/dist/parsing/operations/return.d.ts.map +1 -1
  106. package/dist/parsing/operations/return.js +7 -1
  107. package/dist/parsing/operations/return.js.map +1 -1
  108. package/dist/parsing/operations/where.d.ts +1 -1
  109. package/dist/parsing/operations/where.d.ts.map +1 -1
  110. package/dist/parsing/operations/where.js +4 -0
  111. package/dist/parsing/operations/where.js.map +1 -1
  112. package/dist/parsing/parser.d.ts +10 -0
  113. package/dist/parsing/parser.d.ts.map +1 -1
  114. package/dist/parsing/parser.js +344 -5
  115. package/dist/parsing/parser.js.map +1 -1
  116. package/dist/parsing/token_to_node.d.ts.map +1 -1
  117. package/dist/parsing/token_to_node.js +7 -0
  118. package/dist/parsing/token_to_node.js.map +1 -1
  119. package/dist/tokenization/keyword.d.ts +1 -0
  120. package/dist/tokenization/keyword.d.ts.map +1 -1
  121. package/dist/tokenization/keyword.js +1 -0
  122. package/dist/tokenization/keyword.js.map +1 -1
  123. package/dist/tokenization/token.d.ts +4 -0
  124. package/dist/tokenization/token.d.ts.map +1 -1
  125. package/dist/tokenization/token.js +14 -1
  126. package/dist/tokenization/token.js.map +1 -1
  127. package/dist/tokenization/token_type.d.ts +1 -0
  128. package/dist/tokenization/token_type.d.ts.map +1 -1
  129. package/dist/tokenization/token_type.js +1 -0
  130. package/dist/tokenization/token_type.js.map +1 -1
  131. package/dist/tokenization/tokenizer.d.ts +2 -1
  132. package/dist/tokenization/tokenizer.d.ts.map +1 -1
  133. package/dist/tokenization/tokenizer.js +25 -12
  134. package/dist/tokenization/tokenizer.js.map +1 -1
  135. package/docs/flowquery.min.js +1 -1
  136. package/flowquery-py/README.md +166 -0
  137. package/flowquery-py/pyproject.toml +75 -0
  138. package/flowquery-py/setup_env.ps1 +92 -0
  139. package/flowquery-py/setup_env.sh +87 -0
  140. package/flowquery-py/src/__init__.py +34 -0
  141. package/flowquery-py/src/__main__.py +10 -0
  142. package/flowquery-py/src/compute/__init__.py +5 -0
  143. package/flowquery-py/src/compute/runner.py +60 -0
  144. package/flowquery-py/src/extensibility.py +52 -0
  145. package/flowquery-py/src/graph/__init__.py +31 -0
  146. package/flowquery-py/src/graph/data.py +118 -0
  147. package/flowquery-py/src/graph/database.py +82 -0
  148. package/flowquery-py/src/graph/hops.py +43 -0
  149. package/flowquery-py/src/graph/node.py +112 -0
  150. package/flowquery-py/src/graph/node_data.py +26 -0
  151. package/flowquery-py/src/graph/node_reference.py +49 -0
  152. package/flowquery-py/src/graph/pattern.py +125 -0
  153. package/flowquery-py/src/graph/pattern_expression.py +62 -0
  154. package/flowquery-py/src/graph/patterns.py +42 -0
  155. package/flowquery-py/src/graph/physical_node.py +40 -0
  156. package/flowquery-py/src/graph/physical_relationship.py +36 -0
  157. package/flowquery-py/src/graph/relationship.py +135 -0
  158. package/flowquery-py/src/graph/relationship_data.py +33 -0
  159. package/flowquery-py/src/graph/relationship_match_collector.py +77 -0
  160. package/flowquery-py/src/graph/relationship_reference.py +21 -0
  161. package/flowquery-py/src/io/__init__.py +5 -0
  162. package/flowquery-py/src/io/command_line.py +67 -0
  163. package/flowquery-py/src/parsing/__init__.py +17 -0
  164. package/flowquery-py/src/parsing/alias.py +20 -0
  165. package/flowquery-py/src/parsing/alias_option.py +11 -0
  166. package/flowquery-py/src/parsing/ast_node.py +146 -0
  167. package/flowquery-py/src/parsing/base_parser.py +84 -0
  168. package/flowquery-py/src/parsing/components/__init__.py +19 -0
  169. package/flowquery-py/src/parsing/components/csv.py +8 -0
  170. package/flowquery-py/src/parsing/components/from_.py +10 -0
  171. package/flowquery-py/src/parsing/components/headers.py +12 -0
  172. package/flowquery-py/src/parsing/components/json.py +8 -0
  173. package/flowquery-py/src/parsing/components/null.py +10 -0
  174. package/flowquery-py/src/parsing/components/post.py +8 -0
  175. package/flowquery-py/src/parsing/components/text.py +8 -0
  176. package/flowquery-py/src/parsing/context.py +50 -0
  177. package/flowquery-py/src/parsing/data_structures/__init__.py +15 -0
  178. package/flowquery-py/src/parsing/data_structures/associative_array.py +41 -0
  179. package/flowquery-py/src/parsing/data_structures/json_array.py +30 -0
  180. package/flowquery-py/src/parsing/data_structures/key_value_pair.py +38 -0
  181. package/flowquery-py/src/parsing/data_structures/lookup.py +49 -0
  182. package/flowquery-py/src/parsing/data_structures/range_lookup.py +42 -0
  183. package/flowquery-py/src/parsing/expressions/__init__.py +57 -0
  184. package/flowquery-py/src/parsing/expressions/boolean.py +20 -0
  185. package/flowquery-py/src/parsing/expressions/expression.py +138 -0
  186. package/flowquery-py/src/parsing/expressions/expression_map.py +26 -0
  187. package/flowquery-py/src/parsing/expressions/f_string.py +27 -0
  188. package/flowquery-py/src/parsing/expressions/identifier.py +20 -0
  189. package/flowquery-py/src/parsing/expressions/number.py +32 -0
  190. package/flowquery-py/src/parsing/expressions/operator.py +169 -0
  191. package/flowquery-py/src/parsing/expressions/reference.py +47 -0
  192. package/flowquery-py/src/parsing/expressions/string.py +27 -0
  193. package/flowquery-py/src/parsing/functions/__init__.py +75 -0
  194. package/flowquery-py/src/parsing/functions/aggregate_function.py +60 -0
  195. package/flowquery-py/src/parsing/functions/async_function.py +62 -0
  196. package/flowquery-py/src/parsing/functions/avg.py +55 -0
  197. package/flowquery-py/src/parsing/functions/collect.py +75 -0
  198. package/flowquery-py/src/parsing/functions/function.py +68 -0
  199. package/flowquery-py/src/parsing/functions/function_factory.py +173 -0
  200. package/flowquery-py/src/parsing/functions/function_metadata.py +149 -0
  201. package/flowquery-py/src/parsing/functions/functions.py +59 -0
  202. package/flowquery-py/src/parsing/functions/join.py +47 -0
  203. package/flowquery-py/src/parsing/functions/keys.py +34 -0
  204. package/flowquery-py/src/parsing/functions/predicate_function.py +46 -0
  205. package/flowquery-py/src/parsing/functions/predicate_sum.py +47 -0
  206. package/flowquery-py/src/parsing/functions/rand.py +28 -0
  207. package/flowquery-py/src/parsing/functions/range_.py +34 -0
  208. package/flowquery-py/src/parsing/functions/reducer_element.py +15 -0
  209. package/flowquery-py/src/parsing/functions/replace.py +37 -0
  210. package/flowquery-py/src/parsing/functions/round_.py +32 -0
  211. package/flowquery-py/src/parsing/functions/size.py +32 -0
  212. package/flowquery-py/src/parsing/functions/split.py +47 -0
  213. package/flowquery-py/src/parsing/functions/stringify.py +47 -0
  214. package/flowquery-py/src/parsing/functions/sum.py +51 -0
  215. package/flowquery-py/src/parsing/functions/to_json.py +33 -0
  216. package/flowquery-py/src/parsing/functions/type_.py +47 -0
  217. package/flowquery-py/src/parsing/functions/value_holder.py +24 -0
  218. package/flowquery-py/src/parsing/logic/__init__.py +15 -0
  219. package/flowquery-py/src/parsing/logic/case.py +29 -0
  220. package/flowquery-py/src/parsing/logic/else_.py +12 -0
  221. package/flowquery-py/src/parsing/logic/end.py +8 -0
  222. package/flowquery-py/src/parsing/logic/then.py +12 -0
  223. package/flowquery-py/src/parsing/logic/when.py +10 -0
  224. package/flowquery-py/src/parsing/operations/__init__.py +35 -0
  225. package/flowquery-py/src/parsing/operations/aggregated_return.py +24 -0
  226. package/flowquery-py/src/parsing/operations/aggregated_with.py +22 -0
  227. package/flowquery-py/src/parsing/operations/call.py +74 -0
  228. package/flowquery-py/src/parsing/operations/create_node.py +34 -0
  229. package/flowquery-py/src/parsing/operations/create_relationship.py +34 -0
  230. package/flowquery-py/src/parsing/operations/group_by.py +130 -0
  231. package/flowquery-py/src/parsing/operations/limit.py +22 -0
  232. package/flowquery-py/src/parsing/operations/load.py +140 -0
  233. package/flowquery-py/src/parsing/operations/match.py +29 -0
  234. package/flowquery-py/src/parsing/operations/operation.py +69 -0
  235. package/flowquery-py/src/parsing/operations/projection.py +21 -0
  236. package/flowquery-py/src/parsing/operations/return_op.py +50 -0
  237. package/flowquery-py/src/parsing/operations/unwind.py +37 -0
  238. package/flowquery-py/src/parsing/operations/where.py +41 -0
  239. package/flowquery-py/src/parsing/operations/with_op.py +18 -0
  240. package/flowquery-py/src/parsing/parser.py +1011 -0
  241. package/flowquery-py/src/parsing/token_to_node.py +109 -0
  242. package/flowquery-py/src/tokenization/__init__.py +23 -0
  243. package/flowquery-py/src/tokenization/keyword.py +48 -0
  244. package/flowquery-py/src/tokenization/operator.py +29 -0
  245. package/flowquery-py/src/tokenization/string_walker.py +158 -0
  246. package/flowquery-py/src/tokenization/symbol.py +19 -0
  247. package/flowquery-py/src/tokenization/token.py +659 -0
  248. package/flowquery-py/src/tokenization/token_mapper.py +52 -0
  249. package/flowquery-py/src/tokenization/token_type.py +21 -0
  250. package/flowquery-py/src/tokenization/tokenizer.py +214 -0
  251. package/flowquery-py/src/tokenization/trie.py +124 -0
  252. package/flowquery-py/src/utils/__init__.py +6 -0
  253. package/flowquery-py/src/utils/object_utils.py +20 -0
  254. package/flowquery-py/src/utils/string_utils.py +113 -0
  255. package/flowquery-py/tests/__init__.py +1 -0
  256. package/flowquery-py/tests/compute/__init__.py +1 -0
  257. package/flowquery-py/tests/compute/test_runner.py +1335 -0
  258. package/flowquery-py/tests/graph/__init__.py +1 -0
  259. package/flowquery-py/tests/graph/test_create.py +56 -0
  260. package/flowquery-py/tests/graph/test_data.py +73 -0
  261. package/flowquery-py/tests/graph/test_match.py +40 -0
  262. package/flowquery-py/tests/parsing/__init__.py +1 -0
  263. package/flowquery-py/tests/parsing/test_context.py +34 -0
  264. package/flowquery-py/tests/parsing/test_expression.py +49 -0
  265. package/flowquery-py/tests/parsing/test_parser.py +674 -0
  266. package/flowquery-py/tests/test_extensibility.py +611 -0
  267. package/flowquery-py/tests/tokenization/__init__.py +1 -0
  268. package/flowquery-py/tests/tokenization/test_token_mapper.py +60 -0
  269. package/flowquery-py/tests/tokenization/test_tokenizer.py +164 -0
  270. package/flowquery-py/tests/tokenization/test_trie.py +30 -0
  271. package/flowquery-vscode/flowQueryEngine/flowquery.min.js +1 -1
  272. package/misc/apps/RAG/package.json +1 -1
  273. package/misc/apps/RAG/src/components/AdaptiveCardRenderer.tsx +76 -8
  274. package/misc/apps/RAG/src/components/index.ts +19 -10
  275. package/misc/apps/RAG/src/plugins/loaders/MockData.ts +70 -140
  276. package/misc/apps/RAG/src/prompts/FlowQuerySystemPrompt.ts +12 -0
  277. package/package.json +1 -1
  278. package/src/compute/runner.ts +24 -19
  279. package/src/graph/data.ts +112 -0
  280. package/src/graph/database.ts +63 -0
  281. package/src/graph/hops.ts +22 -0
  282. package/src/graph/node.ts +99 -0
  283. package/src/graph/node_data.ts +18 -0
  284. package/src/graph/node_reference.ts +33 -0
  285. package/src/graph/pattern.ts +101 -0
  286. package/src/graph/pattern_expression.ts +37 -0
  287. package/src/graph/patterns.ts +36 -0
  288. package/src/graph/physical_node.ts +23 -0
  289. package/src/graph/physical_relationship.ts +23 -0
  290. package/src/graph/relationship.ts +116 -0
  291. package/src/graph/relationship_data.ts +27 -0
  292. package/src/graph/relationship_match_collector.ts +58 -0
  293. package/src/graph/relationship_reference.ts +24 -0
  294. package/src/parsing/base_parser.ts +20 -14
  295. package/src/parsing/context.ts +14 -14
  296. package/src/parsing/expressions/boolean.ts +21 -0
  297. package/src/parsing/expressions/expression.ts +34 -26
  298. package/src/parsing/expressions/operator.ts +19 -1
  299. package/src/parsing/functions/function_factory.ts +45 -45
  300. package/src/parsing/operations/create_node.ts +39 -0
  301. package/src/parsing/operations/create_relationship.ts +38 -0
  302. package/src/parsing/operations/match.ts +31 -0
  303. package/src/parsing/operations/operation.ts +3 -0
  304. package/src/parsing/operations/return.ts +11 -7
  305. package/src/parsing/operations/where.ts +10 -6
  306. package/src/parsing/parser.ts +346 -8
  307. package/src/parsing/token_to_node.ts +6 -0
  308. package/src/tokenization/keyword.ts +41 -40
  309. package/src/tokenization/token.ts +21 -1
  310. package/src/tokenization/token_type.ts +2 -1
  311. package/src/tokenization/tokenizer.ts +52 -31
  312. package/tests/compute/runner.test.ts +654 -0
  313. package/tests/extensibility.test.ts +97 -93
  314. package/tests/graph/create.test.ts +36 -0
  315. package/tests/graph/data.test.ts +58 -0
  316. package/tests/graph/match.test.ts +29 -0
  317. package/tests/parsing/parser.test.ts +273 -2
  318. package/tests/tokenization/tokenizer.test.ts +90 -0
@@ -0,0 +1,166 @@
1
+ # FlowQuery Python Implementation
2
+
3
+ This is the Python implementation of FlowQuery, a declarative query language for data processing pipelines.
4
+
5
+ ## Installation
6
+
7
+ ### From Source
8
+
9
+ ```bash
10
+ git clone https://github.com/microsoft/FlowQuery.git
11
+ cd FlowQuery/flowquery-py
12
+ pip install -e .
13
+ ```
14
+
15
+ ### With Development Dependencies
16
+
17
+ ```bash
18
+ pip install -e ".[dev]"
19
+ ```
20
+
21
+ ## Quick Start
22
+
23
+ ### Command Line Interface
24
+
25
+ After installation, you can start the interactive REPL:
26
+
27
+ ```bash
28
+ flowquery
29
+ ```
30
+
31
+ ### Using Conda (Alternative)
32
+
33
+ **Windows (PowerShell):**
34
+
35
+ ```powershell
36
+ cd flowquery-py
37
+ .\setup_env.ps1
38
+ conda activate flowquery
39
+ ```
40
+
41
+ **Linux/macOS:**
42
+
43
+ ```bash
44
+ cd flowquery-py
45
+ chmod +x setup_env.sh
46
+ ./setup_env.sh
47
+ conda activate flowquery
48
+ ```
49
+
50
+ The setup scripts automatically:
51
+
52
+ 1. Read the Python version from `pyproject.toml`
53
+ 2. Create a conda environment named `flowquery`
54
+ 3. Install the package with all dev dependencies
55
+
56
+ ## Requirements
57
+
58
+ - Python 3.10+ (defined in `pyproject.toml`)
59
+ - pytest (for running tests)
60
+ - pytest-asyncio (for async test support)
61
+ - aiohttp (for HTTP requests)
62
+
63
+ All dependencies are managed in `pyproject.toml`.
64
+
65
+ ## Programmatic Usage
66
+
67
+ ```python
68
+ import asyncio
69
+ from flowquery import Runner
70
+
71
+ runner = Runner("WITH 1 as x RETURN x + 1 as result")
72
+ asyncio.run(runner.run())
73
+ print(runner.results) # [{'result': 2}]
74
+ ```
75
+
76
+ ## Running Tests
77
+
78
+ ```bash
79
+ pytest tests/
80
+ ```
81
+
82
+ ## Project Structure
83
+
84
+ ```
85
+ flowquery-py/
86
+ ├── pyproject.toml # Dependencies & project config (single source of truth)
87
+ ├── setup_env.ps1 # Windows conda setup script
88
+ ├── setup_env.sh # Linux/macOS conda setup script
89
+ ├── README.md
90
+ ├── src/
91
+ │ ├── __init__.py # Main package entry point
92
+ │ ├── extensibility.py # Public API for custom functions
93
+ │ ├── compute/
94
+ │ │ └── runner.py # Query execution engine
95
+ │ ├── graph/
96
+ │ │ ├── node.py # Graph node representation
97
+ │ │ ├── relationship.py # Graph relationship representation
98
+ │ │ ├── pattern.py # Pattern matching
99
+ │ │ └── database.py # In-memory graph database
100
+ │ ├── io/
101
+ │ │ └── command_line.py # Interactive REPL
102
+ │ ├── parsing/
103
+ │ │ ├── parser.py # Main parser
104
+ │ │ ├── ast_node.py # AST node base class
105
+ │ │ ├── expressions/ # Expression types (numbers, strings, operators)
106
+ │ │ ├── functions/ # Built-in and custom functions
107
+ │ │ ├── operations/ # Query operations (WITH, RETURN, UNWIND, etc.)
108
+ │ │ ├── components/ # LOAD clause components
109
+ │ │ ├── data_structures/ # Arrays, objects, lookups
110
+ │ │ └── logic/ # CASE/WHEN/THEN/ELSE
111
+ │ ├── tokenization/
112
+ │ │ ├── tokenizer.py # Lexer
113
+ │ │ ├── token.py # Token class
114
+ │ │ └── ... # Token types and mappers
115
+ │ └── utils/
116
+ │ ├── string_utils.py # String manipulation utilities
117
+ │ └── object_utils.py # Object utilities
118
+ └── tests/
119
+ ├── test_extensibility.py
120
+ ├── compute/
121
+ │ └── test_runner.py
122
+ ├── graph/
123
+ │ ├── test_create.py
124
+ │ ├── test_data.py
125
+ │ └── test_match.py
126
+ ├── parsing/
127
+ │ ├── test_parser.py
128
+ │ ├── test_context.py
129
+ │ └── test_expression.py
130
+ └── tokenization/
131
+ ├── test_tokenizer.py
132
+ ├── test_token_mapper.py
133
+ └── test_trie.py
134
+ ```
135
+
136
+ ## Creating Custom Functions
137
+
138
+ ```python
139
+ from flowquery.extensibility import Function, FunctionDef
140
+
141
+ @FunctionDef({
142
+ "description": "Converts a string to uppercase",
143
+ "category": "string",
144
+ "parameters": [
145
+ {"name": "text", "description": "String to convert", "type": "string"}
146
+ ],
147
+ "output": {"description": "Uppercase string", "type": "string"}
148
+ })
149
+ class UpperCase(Function):
150
+ def __init__(self):
151
+ super().__init__("uppercase")
152
+ self._expected_parameter_count = 1
153
+
154
+ def value(self) -> str:
155
+ return str(self.get_children()[0].value()).upper()
156
+ ```
157
+
158
+ ## License
159
+
160
+ MIT License - see [LICENSE](LICENSE) for details.
161
+
162
+ ## Links
163
+
164
+ - [Homepage](https://github.com/microsoft/FlowQuery/flowquery-py)
165
+ - [Repository](https://github.com/microsoft/FlowQuery/flowquery-py)
166
+ - [Issues](https://github.com/microsoft/FlowQuery/issues)
@@ -0,0 +1,75 @@
1
+ [project]
2
+ name = "flowquery"
3
+ version = "1.0.0"
4
+ description = "A declarative query language for data processing pipelines"
5
+ readme = "README.md"
6
+ requires-python = ">=3.10"
7
+ license = {text = "MIT"}
8
+ authors = [
9
+ {name = "FlowQuery Contributors"}
10
+ ]
11
+ keywords = ["query", "data-processing", "pipeline", "declarative"]
12
+ classifiers = [
13
+ "Development Status :: 4 - Beta",
14
+ "Intended Audience :: Developers",
15
+ "License :: OSI Approved :: MIT License",
16
+ "Operating System :: OS Independent",
17
+ "Programming Language :: Python :: 3",
18
+ "Programming Language :: Python :: 3.10",
19
+ "Programming Language :: Python :: 3.11",
20
+ "Programming Language :: Python :: 3.12",
21
+ "Topic :: Database :: Front-Ends",
22
+ "Topic :: Software Development :: Libraries :: Python Modules",
23
+ ]
24
+ dependencies = [
25
+ "aiohttp>=3.8.0",
26
+ ]
27
+
28
+ [project.scripts]
29
+ flowquery = "flowquery.io.command_line:main"
30
+
31
+ [project.urls]
32
+ Homepage = "https://github.com/microsoft/FlowQuery/flowquery-py"
33
+ Repository = "https://github.com/microsoft/FlowQuery/flowquery-py"
34
+ Documentation = "https://github.com/microsoft/FlowQuery/flowquery-py#readme"
35
+ Issues = "https://github.com/microsoft/FlowQuery/issues"
36
+
37
+ [project.optional-dependencies]
38
+ dev = [
39
+ "pytest>=7.0.0",
40
+ "pytest-asyncio>=0.21.0",
41
+ ]
42
+
43
+ [build-system]
44
+ requires = ["setuptools>=61.0"]
45
+ build-backend = "setuptools.build_meta"
46
+
47
+ [tool.setuptools.package-dir]
48
+ "flowquery" = "src"
49
+ "flowquery.compute" = "src/compute"
50
+ "flowquery.graph" = "src/graph"
51
+ "flowquery.io" = "src/io"
52
+ "flowquery.parsing" = "src/parsing"
53
+ "flowquery.parsing.components" = "src/parsing/components"
54
+ "flowquery.parsing.data_structures" = "src/parsing/data_structures"
55
+ "flowquery.parsing.expressions" = "src/parsing/expressions"
56
+ "flowquery.parsing.functions" = "src/parsing/functions"
57
+ "flowquery.parsing.logic" = "src/parsing/logic"
58
+ "flowquery.parsing.operations" = "src/parsing/operations"
59
+ "flowquery.tokenization" = "src/tokenization"
60
+ "flowquery.utils" = "src/utils"
61
+
62
+ [tool.setuptools]
63
+ packages = ["flowquery", "flowquery.compute", "flowquery.graph", "flowquery.io", "flowquery.parsing", "flowquery.parsing.components", "flowquery.parsing.data_structures", "flowquery.parsing.expressions", "flowquery.parsing.functions", "flowquery.parsing.logic", "flowquery.parsing.operations", "flowquery.tokenization", "flowquery.utils"]
64
+
65
+ [tool.pytest.ini_options]
66
+ minversion = "7.0"
67
+ asyncio_mode = "auto"
68
+ testpaths = ["tests"]
69
+ python_files = ["test_*.py"]
70
+ python_classes = ["Test*"]
71
+ python_functions = ["test_*"]
72
+ addopts = "-v --tb=short"
73
+
74
+ [tool.pytest-asyncio]
75
+ mode = "auto"
@@ -0,0 +1,92 @@
1
+ # FlowQuery Python Environment Setup Script for Windows (PowerShell)
2
+ # This script creates a conda environment for FlowQuery development
3
+
4
+ Write-Host "========================================"
5
+ Write-Host "FlowQuery Python Environment Setup"
6
+ Write-Host "========================================"
7
+ Write-Host ""
8
+
9
+ # Check if conda is available
10
+ $condaPath = Get-Command conda -ErrorAction SilentlyContinue
11
+ if (-not $condaPath) {
12
+ Write-Host "ERROR: Conda is not installed or not in PATH." -ForegroundColor Red
13
+ Write-Host "Please install Anaconda or Miniconda first."
14
+ exit 1
15
+ }
16
+
17
+ # Set environment name
18
+ $envName = "flowquery"
19
+
20
+ # Get Python version from pyproject.toml
21
+ $pyprojectContent = Get-Content "pyproject.toml" -Raw
22
+ if ($pyprojectContent -match 'requires-python\s*=\s*">=([0-9.]+)"') {
23
+ $pythonVersion = $matches[1]
24
+ } else {
25
+ $pythonVersion = "3.10" # fallback
26
+ }
27
+ Write-Host "Using Python version: $pythonVersion"
28
+
29
+ # Check if environment already exists
30
+ $envList = conda env list
31
+ if ($envList -match "^$envName\s") {
32
+ Write-Host "Environment '$envName' already exists."
33
+ $recreate = Read-Host "Do you want to recreate it? (y/n)"
34
+ if ($recreate -eq "y" -or $recreate -eq "Y") {
35
+ Write-Host "Removing existing environment..."
36
+ conda env remove -n $envName -y
37
+ } else {
38
+ Write-Host "Keeping existing environment..."
39
+ Write-Host ""
40
+ Write-Host "========================================"
41
+ Write-Host "Environment ready!"
42
+ Write-Host "========================================"
43
+ Write-Host ""
44
+ Write-Host "To activate the environment, run:"
45
+ Write-Host " conda activate $envName" -ForegroundColor Cyan
46
+ Write-Host ""
47
+ Write-Host "To run tests:"
48
+ Write-Host " pytest tests/" -ForegroundColor Cyan
49
+ Write-Host ""
50
+ Write-Host "To deactivate when done:"
51
+ Write-Host " conda deactivate" -ForegroundColor Cyan
52
+ exit 0
53
+ }
54
+ }
55
+
56
+ # Create the environment
57
+ Write-Host ""
58
+ Write-Host "Creating conda environment '$envName' with Python $pythonVersion..."
59
+ conda create -n $envName python=$pythonVersion pip -y
60
+
61
+ if ($LASTEXITCODE -ne 0) {
62
+ Write-Host ""
63
+ Write-Host "ERROR: Failed to create conda environment." -ForegroundColor Red
64
+ exit 1
65
+ }
66
+
67
+ # Activate and install package in dev mode
68
+ Write-Host ""
69
+ Write-Host "Installing package in development mode..."
70
+ conda activate $envName
71
+ pip install -e ".[dev]"
72
+
73
+ if ($LASTEXITCODE -ne 0) {
74
+ Write-Host ""
75
+ Write-Host "ERROR: Failed to install package." -ForegroundColor Red
76
+ exit 1
77
+ }
78
+
79
+ Write-Host ""
80
+ Write-Host "========================================"
81
+ Write-Host "Environment created successfully!" -ForegroundColor Green
82
+ Write-Host "========================================"
83
+ Write-Host ""
84
+ Write-Host "To activate the environment, run:"
85
+ Write-Host " conda activate $envName" -ForegroundColor Cyan
86
+ Write-Host ""
87
+ Write-Host "To run tests:"
88
+ Write-Host " pytest tests/" -ForegroundColor Cyan
89
+ Write-Host ""
90
+ Write-Host "To deactivate when done:"
91
+ Write-Host " conda deactivate" -ForegroundColor Cyan
92
+ Write-Host ""
@@ -0,0 +1,87 @@
1
+ #!/bin/bash
2
+ # FlowQuery Python Environment Setup Script for Linux/macOS
3
+ # This script creates a conda environment for FlowQuery development
4
+
5
+ echo "========================================"
6
+ echo "FlowQuery Python Environment Setup"
7
+ echo "========================================"
8
+ echo
9
+
10
+ # Check if conda is available
11
+ if ! command -v conda &> /dev/null; then
12
+ echo "ERROR: Conda is not installed or not in PATH."
13
+ echo "Please install Anaconda or Miniconda first."
14
+ exit 1
15
+ fi
16
+
17
+ # Set environment name
18
+ ENV_NAME="flowquery"
19
+
20
+ # Get Python version from pyproject.toml
21
+ PYTHON_VERSION=$(grep -oP 'requires-python\s*=\s*">=\K[0-9.]+' pyproject.toml 2>/dev/null || echo "3.10")
22
+ echo "Using Python version: $PYTHON_VERSION"
23
+
24
+ # Check if environment already exists
25
+ if conda env list | grep -q "^${ENV_NAME} "; then
26
+ echo "Environment '${ENV_NAME}' already exists."
27
+ read -p "Do you want to recreate it? (y/n): " RECREATE
28
+ if [[ "$RECREATE" =~ ^[Yy]$ ]]; then
29
+ echo "Removing existing environment..."
30
+ conda env remove -n "$ENV_NAME" -y
31
+ else
32
+ echo "Keeping existing environment..."
33
+ echo
34
+ echo "========================================"
35
+ echo "Environment ready!"
36
+ echo "========================================"
37
+ echo
38
+ echo "To activate the environment, run:"
39
+ echo " conda activate $ENV_NAME"
40
+ echo
41
+ echo "To run tests:"
42
+ echo " pytest tests/"
43
+ echo
44
+ echo "To deactivate when done:"
45
+ echo " conda deactivate"
46
+ exit 0
47
+ fi
48
+ fi
49
+
50
+ # Create the environment
51
+ echo
52
+ echo "Creating conda environment '${ENV_NAME}' with Python ${PYTHON_VERSION}..."
53
+ conda create -n "$ENV_NAME" python="$PYTHON_VERSION" pip -y
54
+
55
+ if [ $? -ne 0 ]; then
56
+ echo
57
+ echo "ERROR: Failed to create conda environment."
58
+ exit 1
59
+ fi
60
+
61
+ # Activate and install package in dev mode
62
+ echo
63
+ echo "Installing package in development mode..."
64
+ source "$(conda info --base)/etc/profile.d/conda.sh"
65
+ conda activate "$ENV_NAME"
66
+ pip install -e ".[dev]"
67
+
68
+ if [ $? -ne 0 ]; then
69
+ echo
70
+ echo "ERROR: Failed to install package."
71
+ exit 1
72
+ fi
73
+
74
+ echo
75
+ echo "========================================"
76
+ echo "Environment created successfully!"
77
+ echo "========================================"
78
+ echo
79
+ echo "To activate the environment, run:"
80
+ echo " conda activate $ENV_NAME"
81
+ echo
82
+ echo "To run tests:"
83
+ echo " pytest tests/"
84
+ echo
85
+ echo "To deactivate when done:"
86
+ echo " conda deactivate"
87
+ echo
@@ -0,0 +1,34 @@
1
+ """
2
+ FlowQuery - A declarative query language for data processing pipelines.
3
+
4
+ This is the Python implementation of FlowQuery.
5
+ """
6
+
7
+ from .compute.runner import Runner
8
+ from .io.command_line import CommandLine
9
+ from .parsing.parser import Parser
10
+ from .parsing.functions.function import Function
11
+ from .parsing.functions.aggregate_function import AggregateFunction
12
+ from .parsing.functions.async_function import AsyncFunction
13
+ from .parsing.functions.predicate_function import PredicateFunction
14
+ from .parsing.functions.reducer_element import ReducerElement
15
+ from .parsing.functions.function_metadata import (
16
+ FunctionDef,
17
+ FunctionMetadata,
18
+ FunctionCategory,
19
+ )
20
+
21
+ __all__ = [
22
+ "Runner",
23
+ "CommandLine",
24
+ "Parser",
25
+ "Function",
26
+ "AggregateFunction",
27
+ "AsyncFunction",
28
+ "PredicateFunction",
29
+ "ReducerElement",
30
+ "FunctionDef",
31
+ "FunctionMetadata",
32
+ "FunctionCategory",
33
+ ]
34
+
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env python
2
+ """FlowQuery command-line entry point.
3
+
4
+ Run with: python -m src
5
+ """
6
+
7
+ from . import CommandLine
8
+
9
+ if __name__ == "__main__":
10
+ CommandLine().loop()
@@ -0,0 +1,5 @@
1
+ """Compute module for FlowQuery."""
2
+
3
+ from .runner import Runner
4
+
5
+ __all__ = ["Runner"]
@@ -0,0 +1,60 @@
1
+ """Executes a FlowQuery statement and retrieves the results."""
2
+
3
+ from typing import Any, Dict, List, Optional
4
+
5
+ from ..parsing.ast_node import ASTNode
6
+ from ..parsing.operations.operation import Operation
7
+ from ..parsing.parser import Parser
8
+
9
+
10
+ class Runner:
11
+ """Executes a FlowQuery statement and retrieves the results.
12
+
13
+ The Runner class parses a FlowQuery statement into an AST and executes it,
14
+ managing the execution flow from the first operation to the final return statement.
15
+
16
+ Example:
17
+ runner = Runner("WITH 1 as x RETURN x")
18
+ await runner.run()
19
+ print(runner.results) # [{ x: 1 }]
20
+ """
21
+
22
+ def __init__(
23
+ self,
24
+ statement: Optional[str] = None,
25
+ ast: Optional[ASTNode] = None
26
+ ):
27
+ """Creates a new Runner instance and parses the FlowQuery statement.
28
+
29
+ Args:
30
+ statement: The FlowQuery statement to execute
31
+ ast: An already-parsed AST (optional)
32
+
33
+ Raises:
34
+ ValueError: If neither statement nor AST is provided
35
+ """
36
+ if (statement is None or statement == "") and ast is None:
37
+ raise ValueError("Either statement or AST must be provided")
38
+
39
+ _ast = ast if ast is not None else Parser().parse(statement)
40
+ self._first: Operation = _ast.first_child()
41
+ self._last: Operation = _ast.last_child()
42
+
43
+ async def run(self) -> None:
44
+ """Executes the parsed FlowQuery statement.
45
+
46
+ Raises:
47
+ Exception: If an error occurs during execution
48
+ """
49
+ await self._first.initialize()
50
+ await self._first.run()
51
+ await self._first.finish()
52
+
53
+ @property
54
+ def results(self) -> List[Dict[str, Any]]:
55
+ """Gets the results from the executed statement.
56
+
57
+ Returns:
58
+ The results from the last operation (typically a RETURN statement)
59
+ """
60
+ return self._last.results
@@ -0,0 +1,52 @@
1
+ """FlowQuery Extensibility API
2
+
3
+ This module provides all the exports needed to create custom FlowQuery functions.
4
+
5
+ Example:
6
+ from flowquery.extensibility import Function, FunctionDef
7
+
8
+ @FunctionDef({
9
+ 'description': "Converts a string to uppercase",
10
+ 'category': "string",
11
+ 'parameters': [{'name': "text", 'description': "String to convert", 'type': "string"}],
12
+ 'output': {'description': "Uppercase string", 'type': "string"}
13
+ })
14
+ class UpperCase(Function):
15
+ def __init__(self):
16
+ super().__init__("uppercase")
17
+ self._expected_parameter_count = 1
18
+
19
+ def value(self) -> str:
20
+ return str(self.get_children()[0].value()).upper()
21
+ """
22
+
23
+ # Base function classes for creating custom functions
24
+ from .parsing.functions.function import Function
25
+ from .parsing.functions.aggregate_function import AggregateFunction
26
+ from .parsing.functions.async_function import AsyncFunction
27
+ from .parsing.functions.predicate_function import PredicateFunction
28
+ from .parsing.functions.reducer_element import ReducerElement
29
+
30
+ # Decorator and metadata types for function registration
31
+ from .parsing.functions.function_metadata import (
32
+ FunctionDef,
33
+ FunctionMetadata,
34
+ FunctionDefOptions,
35
+ ParameterSchema,
36
+ OutputSchema,
37
+ FunctionCategory,
38
+ )
39
+
40
+ __all__ = [
41
+ "Function",
42
+ "AggregateFunction",
43
+ "AsyncFunction",
44
+ "PredicateFunction",
45
+ "ReducerElement",
46
+ "FunctionDef",
47
+ "FunctionMetadata",
48
+ "FunctionDefOptions",
49
+ "ParameterSchema",
50
+ "OutputSchema",
51
+ "FunctionCategory",
52
+ ]
@@ -0,0 +1,31 @@
1
+ """Graph module for FlowQuery."""
2
+
3
+ from .node import Node
4
+ from .relationship import Relationship
5
+ from .pattern import Pattern
6
+ from .patterns import Patterns
7
+ from .pattern_expression import PatternExpression
8
+ from .database import Database
9
+ from .hops import Hops
10
+ from .node_data import NodeData
11
+ from .node_reference import NodeReference
12
+ from .relationship_data import RelationshipData
13
+ from .relationship_reference import RelationshipReference
14
+ from .physical_node import PhysicalNode
15
+ from .physical_relationship import PhysicalRelationship
16
+
17
+ __all__ = [
18
+ "Node",
19
+ "Relationship",
20
+ "Pattern",
21
+ "Patterns",
22
+ "PatternExpression",
23
+ "Database",
24
+ "Hops",
25
+ "NodeData",
26
+ "NodeReference",
27
+ "RelationshipData",
28
+ "RelationshipReference",
29
+ "PhysicalNode",
30
+ "PhysicalRelationship",
31
+ ]