ApiLogicServer 15.2.0__py3-none-any.whl → 15.2.7__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.
- api_logic_server_cli/api_logic_server.py +3 -2
- api_logic_server_cli/prototypes/base/.github/.copilot-instructions.md +115 -31
- api_logic_server_cli/prototypes/base/docs/training/testing.md +116 -18
- api_logic_server_cli/prototypes/base/test/api_logic_server_behave/behave_logic_report.py +55 -29
- api_logic_server_cli/prototypes/base/test/api_logic_server_behave/behave_logic_report.py.bak +285 -0
- api_logic_server_cli/prototypes/{base/.github/.copilot-instructionsZ.mdx → basic_demo/.github/.copilot-instructions.md} +111 -30
- api_logic_server_cli/prototypes/basic_demo/customizations/test/api_logic_server_behave/reports/Behave Logic Report Intro micro.md +35 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/test/api_logic_server_behave/reports/Behave Logic Report Intro.md +35 -0
- api_logic_server_cli/prototypes/basic_demo/readme.md +12 -4
- api_logic_server_cli/prototypes/basic_demo/tutor.md +1196 -0
- api_logic_server_cli/prototypes/manager/.github/.copilot-instructions.md +50 -23
- api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/.github/.copilot-instructions.md +3 -0
- api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/docs/training/testing.md +305 -21
- api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/behave_logic_report.py +13 -84
- api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/behave_logic_report.py.bak +282 -0
- api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/features/order_processing.feature +59 -50
- api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/features/steps/order_processing_steps.py +395 -248
- api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/logs/behave.log +66 -62
- api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/logs/scenario_logic_logs/Carbon_Neutral_Discount_A.log +51 -41
- api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/logs/scenario_logic_logs/Change_Order_Customer.log +29 -0
- api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/logs/scenario_logic_logs/Change_Product_in_Item.log +35 -0
- api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/logs/scenario_logic_logs/Delete_Item_Reduces_Order.log +39 -19
- api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/logs/scenario_logic_logs/Exceed_Credit_Limit_Rejec.log +36 -45
- api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/logs/scenario_logic_logs/Good_Order_Placed_via_B2B.log +50 -40
- api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/logs/scenario_logic_logs/Item_Quantity_Change.log +33 -0
- api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/logs/scenario_logic_logs/Multi-Item_Order_via_B2B_.log +67 -0
- api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/logs/scenario_logic_logs/Ship_Order_Excludes_from_.log +24 -14
- api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/logs/scenario_logic_logs/Transaction_Processing.log +26 -17
- api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/logs/scenario_logic_logs/Unship_Order_Includes_in_.log +24 -14
- api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/reports/Behave Logic Report.md +361 -146
- api_logic_server_cli/prototypes/manager/system/ApiLogicServer-Internal-Dev/copilot-dev-context.md +275 -4
- api_logic_server_cli/prototypes/manager/system/app_model_editor/test/api_logic_server_behave/behave_logic_report.py +13 -75
- api_logic_server_cli/prototypes/manager/system/app_model_editor/test/api_logic_server_behave/behave_logic_report.py.bak +256 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/test/api_logic_server_behave/behave_logic_report.py +13 -75
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/test/api_logic_server_behave/behave_logic_report.py.bak +256 -0
- api_logic_server_cli/prototypes/nw/test/api_logic_server_behave/reports/Behave Logic Report Intro micro.md +17 -0
- api_logic_server_cli/prototypes/nw/test/api_logic_server_behave/reports/Behave Logic Report Intro.md +17 -0
- {apilogicserver-15.2.0.dist-info → apilogicserver-15.2.7.dist-info}/METADATA +103 -23
- {apilogicserver-15.2.0.dist-info → apilogicserver-15.2.7.dist-info}/RECORD +43 -30
- {apilogicserver-15.2.0.dist-info → apilogicserver-15.2.7.dist-info}/WHEEL +0 -0
- {apilogicserver-15.2.0.dist-info → apilogicserver-15.2.7.dist-info}/entry_points.txt +0 -0
- {apilogicserver-15.2.0.dist-info → apilogicserver-15.2.7.dist-info}/licenses/LICENSE +0 -0
- {apilogicserver-15.2.0.dist-info → apilogicserver-15.2.7.dist-info}/top_level.txt +0 -0
|
@@ -176,81 +176,19 @@ def main(behave_log: str, scenario_logs: str, wiki: str, prepend_wiki: str):
|
|
|
176
176
|
wiki_data.append(" ")
|
|
177
177
|
each_line = "## " + each_line
|
|
178
178
|
if each_line.startswith(" Scenario"):
|
|
179
|
-
|
|
180
|
-
if each_line.startswith(" Given") or \
|
|
181
|
-
each_line.startswith(" When") or \
|
|
182
|
-
each_line.startswith(" Then"):
|
|
183
|
-
if each_line.startswith(" Then"):
|
|
184
|
-
just_saw_then = True
|
|
185
|
-
each_line = tab + tab + each_line
|
|
186
|
-
|
|
187
|
-
each_line = each_line[:-1]
|
|
188
|
-
debug_loc = each_line.find(behave_debug_info)
|
|
189
|
-
if debug_loc > 0:
|
|
190
|
-
each_line = each_line[0 : debug_loc]
|
|
191
|
-
each_line = each_line.rstrip()
|
|
192
|
-
if "Scenario" in each_line:
|
|
179
|
+
# Extract scenario name for logic lookup
|
|
193
180
|
current_scenario = each_line[18:]
|
|
194
181
|
wiki_data.append(" ")
|
|
195
182
|
wiki_data.append(" ")
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
def print_args(args, msg):
|
|
210
|
-
print(msg)
|
|
211
|
-
for each_arg in args:
|
|
212
|
-
print(f' {each_arg}')
|
|
213
|
-
print(" ")
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
@click.group()
|
|
217
|
-
@click.pass_context
|
|
218
|
-
def cli(ctx):
|
|
219
|
-
"""
|
|
220
|
-
Combine behave.log and scenario_logic_logs to create Behave Logic Report
|
|
221
|
-
|
|
222
|
-
"""
|
|
223
|
-
pass
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
@cli.command("run")
|
|
227
|
-
@click.pass_context
|
|
228
|
-
@click.option('--behave_log',
|
|
229
|
-
default=f'logs/behave.log', # cwd set to test/api_logic_server_behave
|
|
230
|
-
# prompt="Log from behave test suite run [behave.log]",
|
|
231
|
-
help="Help")
|
|
232
|
-
@click.option('--scenario_logs',
|
|
233
|
-
default=f'logs/scenario_logic_logs',
|
|
234
|
-
# prompt="Logic Log directory from ",
|
|
235
|
-
help="Help")
|
|
236
|
-
@click.option('--wiki',
|
|
237
|
-
default=f'reports/Behave Logic Report.md',
|
|
238
|
-
# prompt="Log from behave test suite run [api_logic_server_behave]",
|
|
239
|
-
help="Help")
|
|
240
|
-
@click.option('--prepend_wiki',
|
|
241
|
-
default=f'reports/Behave Logic Report Intro micro.md',
|
|
242
|
-
# prompt="Log from behave test suite run [Behave Logic Report Intro]",
|
|
243
|
-
help="Help")
|
|
244
|
-
def run(ctx, behave_log: str, scenario_logs: str, wiki: str, prepend_wiki: str):
|
|
245
|
-
main(behave_log = behave_log, scenario_logs = scenario_logs, wiki = wiki, prepend_wiki = prepend_wiki)
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
if __name__ == '__main__': # debugger & python command line start here
|
|
249
|
-
# eg: python api_logic_server_cli/cli.py create --project_name=~/Desktop/test_project
|
|
250
|
-
# unix: python api_logic_server_cli/cli.py create --project_name=/home/ApiLogicProject
|
|
251
|
-
|
|
252
|
-
print(f'\nBehave Logic Report 1.1, started at {os.getcwd()}')
|
|
253
|
-
commands = sys.argv
|
|
254
|
-
if len(sys.argv) > 1:
|
|
255
|
-
print_args(commands, f'\n\nCommand Line Arguments:')
|
|
256
|
-
cli()
|
|
183
|
+
# Remove the debug info (# features/...) from the scenario name
|
|
184
|
+
debug_loc = current_scenario.find(behave_debug_info)
|
|
185
|
+
if debug_loc > 0:
|
|
186
|
+
current_scenario = current_scenario[0:debug_loc].strip()
|
|
187
|
+
wiki_data.append(" ")
|
|
188
|
+
wiki_data.append(" ")
|
|
189
|
+
# Remove debug info from header line too
|
|
190
|
+
header_line = each_line[2:]
|
|
191
|
+
debug_loc = header_line.find(behave_debug_info)
|
|
192
|
+
if debug_loc > 0:
|
|
193
|
+
header_line = header_line[0:debug_loc].rstrip()
|
|
194
|
+
wiki_data.append("### " + header_line) # Add scenario header
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
import os
|
|
4
|
+
import ast
|
|
5
|
+
import sys
|
|
6
|
+
import click
|
|
7
|
+
|
|
8
|
+
"""
|
|
9
|
+
Creates wiki file from test/behave/behave.log, with rule use.
|
|
10
|
+
|
|
11
|
+
Tips
|
|
12
|
+
* use 2 spaces (at end) for newline
|
|
13
|
+
* for tab: & emsp;
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
tab = " "
|
|
18
|
+
behave_debug_info = " # "
|
|
19
|
+
wiki_data = []
|
|
20
|
+
debug_scenario = "XXGood Order Custom Service"
|
|
21
|
+
|
|
22
|
+
scenario_doc_strings = {}
|
|
23
|
+
""" dict of scenario_name, array of strings """
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def remove_trailer(line: str) -> str:
|
|
27
|
+
""" remove everything after the ## """
|
|
28
|
+
end_here = line.find("\t\t##")
|
|
29
|
+
result = line[0:end_here]
|
|
30
|
+
return result
|
|
31
|
+
|
|
32
|
+
def line_spacer():
|
|
33
|
+
wiki_data.append("\n")
|
|
34
|
+
wiki_data.append(" ")
|
|
35
|
+
wiki_data.append(" ")
|
|
36
|
+
wiki_data.append("\n")
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def get_current_readme(prepend_wiki: str):
|
|
40
|
+
""" initialize wiki_data with readme up to {report_name} """
|
|
41
|
+
report_name = "Behave Logic Report"
|
|
42
|
+
with open(prepend_wiki) as readme:
|
|
43
|
+
readme_lines = readme.readlines()
|
|
44
|
+
need_spacer = True
|
|
45
|
+
for each_readme_line in readme_lines:
|
|
46
|
+
if '# ' + report_name in each_readme_line:
|
|
47
|
+
need_spacer = False
|
|
48
|
+
break
|
|
49
|
+
wiki_data.append(each_readme_line[0:-1])
|
|
50
|
+
if need_spacer:
|
|
51
|
+
line_spacer()
|
|
52
|
+
wiki_data.append(f'# {report_name}')
|
|
53
|
+
|
|
54
|
+
def get_truncated_scenario_name(scenario_name: str) -> str:
|
|
55
|
+
""" address max file length (chop at 26), illegal characters """
|
|
56
|
+
scenario_trunc = scenario_name
|
|
57
|
+
if scenario_trunc is not None and len(scenario_trunc) >= 26:
|
|
58
|
+
scenario_trunc = scenario_name[0:25]
|
|
59
|
+
scenario_trunc = f'{str(scenario_trunc).replace(" ", "_")}'
|
|
60
|
+
return scenario_trunc
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def show_logic(scenario: str, logic_logs_dir: str):
|
|
64
|
+
""" insert s{logic_logs_dir}/scenario.log into wiki_data as disclosure area """
|
|
65
|
+
scenario_trunc = get_truncated_scenario_name(scenario)
|
|
66
|
+
logic_file_name = f'{logic_logs_dir}/{scenario_trunc}.log'
|
|
67
|
+
logic_file_name_path = Path(logic_file_name)
|
|
68
|
+
if not logic_file_name_path.is_file(): # debug code
|
|
69
|
+
# wiki_data.append(f'unable to find Logic Log file: {logic_file_name}')
|
|
70
|
+
if scenario == debug_scenario:
|
|
71
|
+
print(f'RELATIVE: {logic_file_name} in {os.getcwd()}')
|
|
72
|
+
full_name = f'{os.getcwd()}/{logic_file_name}'
|
|
73
|
+
print(f'..FULL: {os.getcwd()}/{logic_file_name}')
|
|
74
|
+
logic_file_name = '{logic_logs_dir}/test.log'
|
|
75
|
+
with open(logic_file_name) as logic:
|
|
76
|
+
logic_lines = logic.readlines()
|
|
77
|
+
else:
|
|
78
|
+
logic_log = []
|
|
79
|
+
rules_used = []
|
|
80
|
+
wiki_data.append("<details markdown>")
|
|
81
|
+
wiki_data.append("<summary>Tests - and their logic - are transparent.. click to see Logic</summary>")
|
|
82
|
+
line_spacer()
|
|
83
|
+
scenario_trunc = get_truncated_scenario_name(scenario)
|
|
84
|
+
if scenario_trunc in scenario_doc_strings:
|
|
85
|
+
wiki_data.append(f'**Logic Doc** for scenario: {scenario}')
|
|
86
|
+
wiki_data.append(" ")
|
|
87
|
+
for each_doc_string_line in scenario_doc_strings[scenario_trunc]:
|
|
88
|
+
wiki_data.append(each_doc_string_line[0: -1])
|
|
89
|
+
line_spacer()
|
|
90
|
+
wiki_data.append(f'**Rules Used** in Scenario: {scenario}')
|
|
91
|
+
wiki_data.append("```")
|
|
92
|
+
with open(logic_file_name) as logic:
|
|
93
|
+
logic_lines = logic.readlines()
|
|
94
|
+
is_logic_log = True
|
|
95
|
+
for each_logic_line in logic_lines:
|
|
96
|
+
each_logic_line = remove_trailer(each_logic_line)
|
|
97
|
+
if is_logic_log:
|
|
98
|
+
if "Rules Fired" in each_logic_line:
|
|
99
|
+
is_logic_log = False
|
|
100
|
+
continue
|
|
101
|
+
else:
|
|
102
|
+
logic_log.append(each_logic_line)
|
|
103
|
+
else:
|
|
104
|
+
if 'logic_logger - INFO' in each_logic_line:
|
|
105
|
+
pass
|
|
106
|
+
break
|
|
107
|
+
wiki_data.append(each_logic_line + " ")
|
|
108
|
+
wiki_data.append("```")
|
|
109
|
+
wiki_data.append(f'**Logic Log** in Scenario: {scenario}')
|
|
110
|
+
wiki_data.append("```")
|
|
111
|
+
for each_logic_log in logic_log:
|
|
112
|
+
each_line = remove_trailer(each_logic_log)
|
|
113
|
+
wiki_data.append(each_line)
|
|
114
|
+
wiki_data.append("```")
|
|
115
|
+
wiki_data.append("</details>")
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def get_docStrings(steps_dir: str):
|
|
119
|
+
steps_dir_files = os.listdir(steps_dir)
|
|
120
|
+
indent = 4 # skip leading blanks
|
|
121
|
+
for each_steps_dir_file in steps_dir_files:
|
|
122
|
+
each_steps_dir_file_path = Path(steps_dir).joinpath(each_steps_dir_file)
|
|
123
|
+
if each_steps_dir_file_path.is_file():
|
|
124
|
+
with open(each_steps_dir_file_path) as f:
|
|
125
|
+
step_code = f.readlines()
|
|
126
|
+
# print(f'Found File: {str(each_steps_dir_file_path)}')
|
|
127
|
+
for index, each_step_code_line in enumerate(step_code):
|
|
128
|
+
if each_step_code_line.startswith('@when'):
|
|
129
|
+
comment_start = index + 2
|
|
130
|
+
if '"""' in step_code[comment_start]:
|
|
131
|
+
# print(".. found doc string")
|
|
132
|
+
doc_string_line = comment_start+1
|
|
133
|
+
doc_string = []
|
|
134
|
+
while (True):
|
|
135
|
+
if '"""' in step_code[doc_string_line]:
|
|
136
|
+
break
|
|
137
|
+
doc_string.append(step_code[doc_string_line][indent:])
|
|
138
|
+
doc_string_line += 1
|
|
139
|
+
scenario_line = doc_string_line+1
|
|
140
|
+
if 'scenario_name' not in step_code[scenario_line]:
|
|
141
|
+
print(f'\n** Warning - scenario_name not found '\
|
|
142
|
+
f'in file {str(each_steps_dir_file_path)}, '\
|
|
143
|
+
f'after line {scenario_line} -- skipped')
|
|
144
|
+
else:
|
|
145
|
+
scenario_code_line = step_code[scenario_line]
|
|
146
|
+
scenario_name_start = scenario_code_line.find("'") + 1
|
|
147
|
+
scenario_name_end = scenario_code_line[scenario_name_start+1:].find("'")
|
|
148
|
+
scenario_name = scenario_code_line[scenario_name_start:
|
|
149
|
+
scenario_name_end + scenario_name_start+1]
|
|
150
|
+
if scenario_name == debug_scenario:
|
|
151
|
+
print(f'got {debug_scenario}')
|
|
152
|
+
scenario_trunc = get_truncated_scenario_name(scenario_name)
|
|
153
|
+
# print(f'.... truncated scenario_name: {scenario_trunc} in {scenario_code_line}')
|
|
154
|
+
scenario_doc_strings[scenario_trunc] = doc_string
|
|
155
|
+
# print("that's all, folks")
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def main(behave_log: str, scenario_logs: str, wiki: str, prepend_wiki: str):
|
|
159
|
+
""" main driver """
|
|
160
|
+
get_docStrings(steps_dir="features/steps")
|
|
161
|
+
|
|
162
|
+
get_current_readme(prepend_wiki=prepend_wiki)
|
|
163
|
+
|
|
164
|
+
contents = None
|
|
165
|
+
with open(behave_log) as f:
|
|
166
|
+
contents = f.readlines()
|
|
167
|
+
|
|
168
|
+
just_saw_then = False
|
|
169
|
+
current_scenario = ""
|
|
170
|
+
for each_line in contents:
|
|
171
|
+
if just_saw_then and each_line == "\n":
|
|
172
|
+
show_logic(scenario=current_scenario, logic_logs_dir=scenario_logs)
|
|
173
|
+
just_saw_then = False
|
|
174
|
+
if each_line.startswith("Feature"):
|
|
175
|
+
wiki_data.append(" ")
|
|
176
|
+
wiki_data.append(" ")
|
|
177
|
+
each_line = "## " + each_line
|
|
178
|
+
if each_line.startswith(" Scenario"):
|
|
179
|
+
each_line = tab + each_line
|
|
180
|
+
if each_line.startswith(" Given") or \
|
|
181
|
+
each_line.startswith(" When") or \
|
|
182
|
+
each_line.startswith(" Then"):
|
|
183
|
+
if each_line.startswith(" Then"):
|
|
184
|
+
just_saw_then = True
|
|
185
|
+
each_line = tab + tab + each_line
|
|
186
|
+
|
|
187
|
+
each_line = each_line[:-1]
|
|
188
|
+
debug_loc = each_line.find(behave_debug_info)
|
|
189
|
+
if debug_loc > 0:
|
|
190
|
+
each_line = each_line[0 : debug_loc]
|
|
191
|
+
each_line = each_line.rstrip()
|
|
192
|
+
if "Scenario" in each_line:
|
|
193
|
+
current_scenario = each_line[18:]
|
|
194
|
+
wiki_data.append(" ")
|
|
195
|
+
wiki_data.append(" ")
|
|
196
|
+
wiki_data.append("### " + each_line[8:])
|
|
197
|
+
|
|
198
|
+
each_line = each_line + " " # wiki for "new line"
|
|
199
|
+
|
|
200
|
+
wiki_data.append(each_line)
|
|
201
|
+
|
|
202
|
+
with open(wiki, 'w') as rpt:
|
|
203
|
+
rpt.write('\n'.join(wiki_data))
|
|
204
|
+
wiki_full_path = Path(wiki).absolute()
|
|
205
|
+
print(f'Wiki Output: {wiki_full_path}\n\n')
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def print_args(args, msg):
|
|
210
|
+
print(msg)
|
|
211
|
+
for each_arg in args:
|
|
212
|
+
print(f' {each_arg}')
|
|
213
|
+
print(" ")
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
@click.group()
|
|
217
|
+
@click.pass_context
|
|
218
|
+
def cli(ctx):
|
|
219
|
+
"""
|
|
220
|
+
Combine behave.log and scenario_logic_logs to create Behave Logic Report
|
|
221
|
+
|
|
222
|
+
"""
|
|
223
|
+
pass
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
@cli.command("run")
|
|
227
|
+
@click.pass_context
|
|
228
|
+
@click.option('--behave_log',
|
|
229
|
+
default=f'logs/behave.log', # cwd set to test/api_logic_server_behave
|
|
230
|
+
# prompt="Log from behave test suite run [behave.log]",
|
|
231
|
+
help="Help")
|
|
232
|
+
@click.option('--scenario_logs',
|
|
233
|
+
default=f'logs/scenario_logic_logs',
|
|
234
|
+
# prompt="Logic Log directory from ",
|
|
235
|
+
help="Help")
|
|
236
|
+
@click.option('--wiki',
|
|
237
|
+
default=f'reports/Behave Logic Report.md',
|
|
238
|
+
# prompt="Log from behave test suite run [api_logic_server_behave]",
|
|
239
|
+
help="Help")
|
|
240
|
+
@click.option('--prepend_wiki',
|
|
241
|
+
default=f'reports/Behave Logic Report Intro micro.md',
|
|
242
|
+
# prompt="Log from behave test suite run [Behave Logic Report Intro]",
|
|
243
|
+
help="Help")
|
|
244
|
+
def run(ctx, behave_log: str, scenario_logs: str, wiki: str, prepend_wiki: str):
|
|
245
|
+
main(behave_log = behave_log, scenario_logs = scenario_logs, wiki = wiki, prepend_wiki = prepend_wiki)
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
if __name__ == '__main__': # debugger & python command line start here
|
|
249
|
+
# eg: python api_logic_server_cli/cli.py create --project_name=~/Desktop/test_project
|
|
250
|
+
# unix: python api_logic_server_cli/cli.py create --project_name=/home/ApiLogicProject
|
|
251
|
+
|
|
252
|
+
print(f'\nBehave Logic Report 1.1, started at {os.getcwd()}')
|
|
253
|
+
commands = sys.argv
|
|
254
|
+
if len(sys.argv) > 1:
|
|
255
|
+
print_args(commands, f'\n\nCommand Line Arguments:')
|
|
256
|
+
cli()
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
## Northwind Sample
|
|
2
|
+
|
|
3
|
+
This is the sample project from API Logic Server, based on the [Northwind database](https://apilogicserver.github.io/Docs/Sample-Database/) (sqlite database located in the `database` folder - no installation required):
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
>
|
|
8
|
+
|
|
9
|
+
The sample Scenarios below were chosen to illustrate the basic patterns of using
|
|
10
|
+
rules. Open the disclosure box ("Tests - and their logic...") to see the implementation and notes.
|
|
11
|
+
|
|
12
|
+
The following report was created during test suite execution.
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# Behave Logic Report
|
|
17
|
+
|
api_logic_server_cli/prototypes/nw/test/api_logic_server_behave/reports/Behave Logic Report Intro.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
## Northwind Sample
|
|
2
|
+
|
|
3
|
+
This is the sample project from API Logic Server, based on the [Northwind database](https://apilogicserver.github.io/Docs/Sample-Database/) (sqlite database located in the `database` folder - no installation required):
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
>
|
|
8
|
+
|
|
9
|
+
The sample Scenarios below were chosen to illustrate the basic patterns of using
|
|
10
|
+
rules. Open the disclosure box ("Tests - and their logic...") to see the implementation and notes.
|
|
11
|
+
|
|
12
|
+
The following report was created during test suite execution.
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# Behave Logic Report
|
|
17
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ApiLogicServer
|
|
3
|
-
Version: 15.2.
|
|
3
|
+
Version: 15.2.7
|
|
4
4
|
Author-email: Val Huber <apilogicserver@gmail.com>
|
|
5
5
|
License-Expression: BSD-3-Clause
|
|
6
6
|
Project-URL: Homepage, https://www.genai-logic.com
|
|
@@ -83,7 +83,7 @@ Dynamic: license-file
|
|
|
83
83
|
[](https://pypi.python.org/pypi/apilogicserver/)
|
|
84
84
|
[](https://pypi.python.org/pypi/apilogicserver/)
|
|
85
85
|
|
|
86
|
-
**
|
|
86
|
+
**Create instant microservices from your database or natural language prompt** - working API + Admin App + Logic in 5 seconds, with 40X code reduction through declarative rules.
|
|
87
87
|
|
|
88
88
|
Create **instant microservices** (MCP-enabled API + Admin App + Business Logic) from your database or a natural language prompt:
|
|
89
89
|
|
|
@@ -104,10 +104,10 @@ source venv/bin/activate # windows: venv\Scripts\activate
|
|
|
104
104
|
python -m pip install ApiLogicServer
|
|
105
105
|
|
|
106
106
|
# Start the Manager (opens readme with instructions)
|
|
107
|
-
|
|
107
|
+
genai-logic start
|
|
108
108
|
|
|
109
109
|
# Create project from your database (or use sample)
|
|
110
|
-
|
|
110
|
+
genai-logic create --project_name=my_app --db_url=
|
|
111
111
|
|
|
112
112
|
# Run it
|
|
113
113
|
cd my_app
|
|
@@ -116,12 +116,15 @@ python api_logic_server_run.py
|
|
|
116
116
|
|
|
117
117
|
**What you get in 5 seconds:**
|
|
118
118
|
- 🚀 **JSON:API** - Endpoints for every table with filtering, pagination, related data
|
|
119
|
-
- 📱 **Admin App** - Multi-page React app with automatic joins
|
|
119
|
+
- 📱 **Instant Admin App UI** - Multi-page React app with automatic joins (runs immediately)
|
|
120
|
+
- 🎨 **Custom Apps via API** - Use the API with your favorite vibe tools (Cursor, Bolt, Lovable, etc.) OR leverage GenAI-Logic training for Copilot to build custom UIs ([see this article](https://medium.com/@valjhuber/enterprise-vibe-automation-b40c8f750a1d))
|
|
120
121
|
- 🧠 **Logic Engine** - Spreadsheet-like rules (40X more concise than code)
|
|
121
122
|
- 🔐 **Security** - Row-level authorization, JWT authentication
|
|
122
123
|
- 🐳 **Docker-ready** - Pre-configured containers for deployment
|
|
123
124
|
|
|
124
|
-
**
|
|
125
|
+
**Mix and match:** Use the instant Admin App for backoffice tasks AND build custom UIs with vibe tools for advanced features like cards and maps - all powered by the same logic-enabled API.
|
|
126
|
+
|
|
127
|
+
**[📖 8-minute video demo](https://www.youtube.com/watch?v=Z4_NJIm5rFs&t=323s)** | **[📚 Full Documentation](https://apilogicserver.github.io/Docs/)** | **[🏠 Home](https://www.genai-logic.com)**
|
|
125
128
|
|
|
126
129
|
---
|
|
127
130
|
|
|
@@ -137,23 +140,75 @@ python api_logic_server_run.py
|
|
|
137
140
|
| Traditional Approach | API Logic Server |
|
|
138
141
|
|---------------------|------------------|
|
|
139
142
|
| Weeks to create API endpoints | **5 seconds** (automated) |
|
|
140
|
-
| 200+ lines of update logic code | **5 rules** (40X reduction) |
|
|
141
|
-
| Manual screen painting | **Automated** from data model |
|
|
143
|
+
| 200+ lines of update logic code | **5 rules** (40X reduction - to see an A/B Comparision, [click here](https://github.com/ApiLogicServer/basic_demo/blob/main/logic/procedural/declarative-vs-procedural-comparison.md) |
|
|
144
|
+
| Manual screen painting | **Automated** from data model, plus vibe-enabled custom UIs |
|
|
142
145
|
| Hard to integrate systems | **MCP-enabled** APIs |
|
|
143
146
|
| Opaque procedural code | **Declarative** living documentation |
|
|
144
147
|
|
|
145
148
|
---
|
|
146
149
|
|
|
147
|
-
## 💡 Use
|
|
150
|
+
## 💡 When to Use API Logic Server
|
|
151
|
+
|
|
152
|
+
### ✅ Ideal Use Cases
|
|
153
|
+
|
|
154
|
+
API Logic Server excels at **data-centric business applications** where the complexity is in multi-table calculations, constraints, and derivations:
|
|
148
155
|
|
|
149
|
-
- **🔌 Application Integration** - Instant APIs for legacy databases
|
|
150
|
-
- **⚡ Rapid Prototyping** - Working backend in minutes
|
|
156
|
+
- **🔌 Application Integration** - Instant APIs for legacy databases (modernization without rewrite)
|
|
157
|
+
- **⚡ Rapid Prototyping** - Working backend in minutes for validation
|
|
151
158
|
- **🤖 GenAI Backends** - Natural language → working microservice
|
|
152
159
|
- **🏢 Backoffice Apps** - Admin dashboards for data maintenance
|
|
153
160
|
- **🔗 Microservices** - Decompose monoliths with instant services
|
|
161
|
+
- **📊 Business Rule Automation** - Complex calculations, cascading updates, constraint checking
|
|
162
|
+
- **🔄 CRUD-Heavy Applications** - Order management, inventory, customer systems
|
|
163
|
+
- **🏛️ Legacy Modernization** - MCP-enable existing databases, create modern API layer while legacy apps continue running
|
|
164
|
+
|
|
165
|
+
**Sweet Spot:** Applications where business logic complexity >> UI complexity
|
|
166
|
+
|
|
167
|
+
### ⚠️ Not Recommended For
|
|
168
|
+
|
|
169
|
+
API Logic Server is optimized for data-centric business logic, but **less suited** for:
|
|
170
|
+
|
|
171
|
+
- **Real-time streaming systems** - Use Kafka/Flink for high-throughput event processing
|
|
172
|
+
- **Complex UI/UX interactions** - Works great as the backend, but not a UI framework
|
|
173
|
+
- **Machine learning pipelines** - Use TensorFlow/PyTorch for ML workflows
|
|
174
|
+
- **Low-level system programming** - Traditional languages better suited
|
|
175
|
+
- **Document/content management** - Use specialized CMS platforms
|
|
176
|
+
- **Simple static websites** - Overkill for basic content delivery
|
|
177
|
+
|
|
178
|
+
**For these scenarios, traditional approaches are more appropriate.** API Logic Server can still serve as the backend for hybrid architectures.
|
|
154
179
|
|
|
155
180
|
---
|
|
156
181
|
|
|
182
|
+
|
|
183
|
+
## ❓ Frequently Asked Questions
|
|
184
|
+
|
|
185
|
+
**Q: How is this different from low-code platforms (Retool, OutSystems, Hasura)?**
|
|
186
|
+
|
|
187
|
+
A: Unlike pure low-code platforms, API Logic Server generates **standard Python projects you own, extend and deploy**. Screen creation is by vibe tools rather than screen painting. Unlike API generators, it includes sophisticated multi-table logic automation (40X code reduction). **[Read detailed comparison →](https://medium.com/@valjhuber/declarative-genai-the-architecture-behind-enterprise-vibe-automation-1b8a4fe4fbd7)**
|
|
188
|
+
|
|
189
|
+
**Q: Isn't this just vendor lock-in?**
|
|
190
|
+
|
|
191
|
+
A: It's **free and open source**. The declarative rules sit on top of standard (readable, version-controlled) Python — you can always drop down to procedural code. If you ever need to migrate away, you can either keep using the rules engine (it's just a library) or replace declarative rules with equivalent procedural code using standard SQLAlchemy events.
|
|
192
|
+
|
|
193
|
+
**Q: Can I customize the generated app?**
|
|
194
|
+
|
|
195
|
+
A: **Absolutely.** You can override the UI, extend APIs, and plug in your own logic — using standard Python, SQLAlchemy, and any Vibe tool. The generated project is a starting point, not a black box. **[See customization patterns →](https://apilogicserver.github.io/Docs/Logic/)**
|
|
196
|
+
|
|
197
|
+
**Q: What happens when logic doesn't fit the declarative model?**
|
|
198
|
+
|
|
199
|
+
A: The declarative engine handles **over 95%** of typical business logic (calculations, validations, cascading updates). For complex workflows, state machines, or external integrations, you write standard Python event handlers that coexist with declarative rules. The engine calls your code at the right time — no conflict, full extensibility.
|
|
200
|
+
|
|
201
|
+
**Q: How long does it take developers to become productive?**
|
|
202
|
+
|
|
203
|
+
A: Developers can start writing rules immediately using natural language, and the DSL syntax is intuitive. Understanding the engine's optimization strategies (pruning, chaining) takes a few days of practice. **Most teams are fully productive within a week.**
|
|
204
|
+
|
|
205
|
+
**Q: What if I have questions or need help?**
|
|
206
|
+
|
|
207
|
+
A: Join our **[Discord community](https://discord.gg/fNRTTVFT)** for real-time help, check **[GitHub Discussions](https://github.com/ApiLogicServer/ApiLogicServer-src/discussions)**, or browse the **[comprehensive documentation](https://apilogicserver.github.io/Docs/)**.
|
|
208
|
+
|
|
209
|
+
**[→ More FAQs in detailed article](https://medium.com/@valjhuber/declarative-genai-the-architecture-behind-enterprise-vibe-automation-1b8a4fe4fbd7#faqs)**
|
|
210
|
+
|
|
211
|
+
---
|
|
157
212
|
## 🏗️ Architecture
|
|
158
213
|
|
|
159
214
|
```
|
|
@@ -188,22 +243,28 @@ python api_logic_server_run.py
|
|
|
188
243
|
|
|
189
244
|
```
|
|
190
245
|
my_app/
|
|
191
|
-
├── api/ # JSON:API endpoints
|
|
246
|
+
├── api/ # JSON:API endpoints (for Admin App AND custom UIs)
|
|
192
247
|
│ ├── expose_api_models.py
|
|
193
248
|
│ └── customize_api.py # Add custom endpoints
|
|
194
|
-
├── ui/admin/ # Admin App
|
|
249
|
+
├── ui/admin/ # Instant Admin App (ready to run)
|
|
195
250
|
│ └── admin.yaml # Declare UI behavior
|
|
196
|
-
├── logic/ # Business Logic
|
|
251
|
+
├── logic/ # Business Logic (enforced on ALL API calls)
|
|
197
252
|
│ └── declare_logic.py # Spreadsheet-like rules
|
|
198
253
|
├── security/ # Authentication & Authorization
|
|
199
254
|
│ └── declare_security.py
|
|
200
255
|
├── database/ # SQLAlchemy models
|
|
201
256
|
│ └── models.py
|
|
202
257
|
├── tests/ # BDD tests (Behave)
|
|
258
|
+
├── docs/
|
|
259
|
+
│ └── training/ # GenAI-Logic training for Copilot
|
|
203
260
|
└── devops/
|
|
204
261
|
└── docker/ # Deployment configs
|
|
205
262
|
```
|
|
206
263
|
|
|
264
|
+
**Two UI approaches (use both!):**
|
|
265
|
+
1. **Instant Admin App** - Runs immediately for backoffice/internal users
|
|
266
|
+
2. **Custom UIs** - Build with vibe tools (Cursor, Bolt, etc.) OR use GenAI-Logic Copilot training to create React/Vue/Angular apps that consume the API
|
|
267
|
+
|
|
207
268
|
---
|
|
208
269
|
|
|
209
270
|
## 🚀 Key Features
|
|
@@ -258,7 +319,7 @@ GET /api/Customer?filter[Balance][$gt]=1000&sort=-Balance&page[size]=10
|
|
|
258
319
|
|
|
259
320
|
#### Create from Natural Language
|
|
260
321
|
```bash
|
|
261
|
-
|
|
322
|
+
genai-logic genai --using=prompt.txt
|
|
262
323
|
```
|
|
263
324
|
|
|
264
325
|
**Example prompt:**
|
|
@@ -272,24 +333,24 @@ Constraint: customer balance cannot exceed credit limit.
|
|
|
272
333
|
```
|
|
273
334
|
|
|
274
335
|
**Result:** Working microservice with logic in 10 seconds!
|
|
275
|
-
|
|
276
336
|
#### AI-Assisted Development
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
337
|
+
|
|
338
|
+
Every created project includes **AI tutoring** to help you get oriented and productive quickly:
|
|
339
|
+
|
|
340
|
+
- 🤖 **Copilot instructions** (`.copilot-instructions.md`) - When you open a project, Copilot presents a friendly welcome message explaining what's already built and what you can do next. Ask Copilot to "read instructions" anytime for guidance.
|
|
341
|
+
- 📚 **Training materials** (`docs/training/`) - Comprehensive guides for all features
|
|
280
342
|
- 🔍 **Logic from natural language** (translate English → rules)
|
|
281
343
|
|
|
282
344
|
```python
|
|
283
345
|
# Paste into Copilot: "Create logic for check credit"
|
|
284
346
|
# Copilot generates the 5 rules above!
|
|
285
347
|
```
|
|
286
|
-
|
|
287
348
|
### 4️⃣ Living Documentation
|
|
288
349
|
|
|
289
350
|
**Automated test generation** from your rules:
|
|
290
351
|
```bash
|
|
291
352
|
# Generate Behave tests from declared logic
|
|
292
|
-
|
|
353
|
+
genai-logic add-tests
|
|
293
354
|
|
|
294
355
|
# Run tests
|
|
295
356
|
behave
|
|
@@ -302,11 +363,11 @@ python behave_logic_report.py
|
|
|
302
363
|
|
|
303
364
|
---
|
|
304
365
|
|
|
305
|
-
## 🎬 Video Overview (
|
|
366
|
+
## 🎬 Video Overview (8 min)
|
|
306
367
|
|
|
307
368
|
See how **Microservice Automation** creates and runs a microservice - a multi-page app and an API:
|
|
308
369
|
|
|
309
|
-
[](https://www.youtube.com/watch?v=
|
|
370
|
+
[](https://www.youtube.com/watch?v=Z4_NJIm5rFs&t=323s "Microservice Automation")
|
|
310
371
|
|
|
311
372
|
---
|
|
312
373
|
|
|
@@ -485,6 +546,25 @@ Built on the shoulders of giants:
|
|
|
485
546
|
|
|
486
547
|
---
|
|
487
548
|
|
|
549
|
+
|
|
550
|
+
## 📝 In-Depth Articles
|
|
551
|
+
|
|
552
|
+
These Medium articles provide comprehensive context on architecture, use cases, and the reasoning behind API Logic Server:
|
|
553
|
+
|
|
554
|
+
| Article | Topic | Key Insights |
|
|
555
|
+
|---------|-------|--------------|
|
|
556
|
+
| **[Welcome to GenAI-Logic](https://medium.com/@valjhuber/welcome-to-genai-logic-a610ba14bd72)** | Vision & Overview | Big picture: Does GenAI deliver business agility? Start here for context. |
|
|
557
|
+
| **[Declarative GenAI Architecture](https://medium.com/@valjhuber/declarative-genai-the-architecture-behind-enterprise-vibe-automation-1b8a4fe4fbd7)** | Technical Deep Dive | NL → DSL → Engines pattern, FrankenCode problem, **includes FAQ section** |
|
|
558
|
+
| **[Declarative Logic: Living in a Procedural World](https://medium.com/@valjhuber/declarative-logic-living-in-a-procedural-world-6c5b20552c6b)** | Architecture Philosophy | How declarative rules work in Python, the paradox resolved |
|
|
559
|
+
| **[Living With Logic in the Enterprise](https://medium.com/@valjhuber/living-with-logic-7e202782d0c5)** | Production Patterns | Debugging, testing, performance, customization in real deployments |
|
|
560
|
+
| **[Business User / IT Collaboration](https://medium.com/@valjhuber/declarative-genai-business-user-it-collaboration-c5547776ff7d)** | Team Dynamics | How logic acts as a contract between business and IT |
|
|
561
|
+
| **[Vibe an MCP Server](https://medium.com/@valjhuber/vibe-an-mcp-server-declarative-genai-logic-dec16719c004)** | MCP Integration | Creating MCP-enabled services with natural language |
|
|
562
|
+
| **[Probabilistic and Deterministic Logic](https://medium.com/@valjhuber/probabilistic-and-deterministic-logic-9a38f98d24a8)** | AI + Rules | Engineering reliability into agentic systems (AI at runtime + rules) |
|
|
563
|
+
| **[Enterprise Vibe Automation](https://medium.com/@valjhuber/enterprise-vibe-automation-b40c8f750a1d)** | GenAI Workflows | Full-stack automation from prompts |
|
|
564
|
+
|
|
565
|
+
**These articles represent significant research and real-world experience** - they address common questions, architectural decisions, and lessons learned from 40+ years of declarative technology evolution.
|
|
566
|
+
|
|
567
|
+
---
|
|
488
568
|
## 📞 Connect
|
|
489
569
|
|
|
490
570
|
- **🏠 Home:** [genai-logic.com](https://www.genai-logic.com)
|