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
|
@@ -0,0 +1,285 @@
|
|
|
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
|
+
last_rules_start = -1
|
|
96
|
+
last_rules_end = -1
|
|
97
|
+
|
|
98
|
+
# First, find the LAST "These Rules Fired" section
|
|
99
|
+
for i, each_logic_line in enumerate(logic_lines):
|
|
100
|
+
if "These Rules Fired" in each_logic_line:
|
|
101
|
+
last_rules_start = i + 1 # Start collecting from next line
|
|
102
|
+
last_rules_end = -1 # Reset end marker to find the next COMPLETE
|
|
103
|
+
elif last_rules_start > 0 and last_rules_end == -1:
|
|
104
|
+
if 'Logic Phase:' in each_logic_line and 'COMPLETE' in each_logic_line:
|
|
105
|
+
last_rules_end = i
|
|
106
|
+
|
|
107
|
+
# Now process the file, collecting logic log and extracting the last rules section
|
|
108
|
+
for i, each_logic_line in enumerate(logic_lines):
|
|
109
|
+
each_logic_line = remove_trailer(each_logic_line)
|
|
110
|
+
|
|
111
|
+
if is_logic_log:
|
|
112
|
+
if "These Rules Fired" in each_logic_line:
|
|
113
|
+
is_logic_log = False
|
|
114
|
+
else:
|
|
115
|
+
logic_log.append(each_logic_line)
|
|
116
|
+
|
|
117
|
+
# Extract rules from the last "These Rules Fired" section
|
|
118
|
+
if last_rules_start <= i < last_rules_end:
|
|
119
|
+
# Skip empty lines
|
|
120
|
+
if each_logic_line.strip():
|
|
121
|
+
wiki_data.append(each_logic_line + " ")
|
|
122
|
+
|
|
123
|
+
wiki_data.append("```")
|
|
124
|
+
wiki_data.append(f'**Logic Log** in Scenario: {scenario}')
|
|
125
|
+
wiki_data.append("```")
|
|
126
|
+
for each_logic_log in logic_log:
|
|
127
|
+
each_line = remove_trailer(each_logic_log)
|
|
128
|
+
wiki_data.append(each_line)
|
|
129
|
+
wiki_data.append("```")
|
|
130
|
+
wiki_data.append("</details>")
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def get_docStrings(steps_dir: str):
|
|
134
|
+
steps_dir_files = os.listdir(steps_dir)
|
|
135
|
+
indent = 4 # skip leading blanks
|
|
136
|
+
for each_steps_dir_file in steps_dir_files:
|
|
137
|
+
each_steps_dir_file_path = Path(steps_dir).joinpath(each_steps_dir_file)
|
|
138
|
+
if each_steps_dir_file_path.is_file():
|
|
139
|
+
with open(each_steps_dir_file_path) as f:
|
|
140
|
+
step_code = f.readlines()
|
|
141
|
+
# print(f'Found File: {str(each_steps_dir_file_path)}')
|
|
142
|
+
for index, each_step_code_line in enumerate(step_code):
|
|
143
|
+
if each_step_code_line.startswith('@when'):
|
|
144
|
+
comment_start = index + 2
|
|
145
|
+
if '"""' in step_code[comment_start]:
|
|
146
|
+
# print(".. found doc string")
|
|
147
|
+
doc_string_line = comment_start+1
|
|
148
|
+
doc_string = []
|
|
149
|
+
while (True):
|
|
150
|
+
if '"""' in step_code[doc_string_line]:
|
|
151
|
+
break
|
|
152
|
+
doc_string.append(step_code[doc_string_line][indent:])
|
|
153
|
+
doc_string_line += 1
|
|
154
|
+
scenario_line = doc_string_line+1
|
|
155
|
+
if 'scenario_name' not in step_code[scenario_line]:
|
|
156
|
+
print(f'\n** Warning - scenario_name not found '\
|
|
157
|
+
f'in file {str(each_steps_dir_file_path)}, '\
|
|
158
|
+
f'after line {scenario_line} -- skipped')
|
|
159
|
+
else:
|
|
160
|
+
scenario_code_line = step_code[scenario_line]
|
|
161
|
+
scenario_name_start = scenario_code_line.find("'") + 1
|
|
162
|
+
scenario_name_end = scenario_code_line[scenario_name_start+1:].find("'")
|
|
163
|
+
scenario_name = scenario_code_line[scenario_name_start:
|
|
164
|
+
scenario_name_end + scenario_name_start+1]
|
|
165
|
+
if scenario_name == debug_scenario:
|
|
166
|
+
print(f'got {debug_scenario}')
|
|
167
|
+
scenario_trunc = get_truncated_scenario_name(scenario_name)
|
|
168
|
+
# print(f'.... truncated scenario_name: {scenario_trunc} in {scenario_code_line}')
|
|
169
|
+
scenario_doc_strings[scenario_trunc] = doc_string
|
|
170
|
+
# print("that's all, folks")
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def main(behave_log: str, scenario_logs: str, wiki: str, prepend_wiki: str):
|
|
174
|
+
""" main driver """
|
|
175
|
+
get_docStrings(steps_dir="features/steps")
|
|
176
|
+
|
|
177
|
+
get_current_readme(prepend_wiki=prepend_wiki)
|
|
178
|
+
|
|
179
|
+
contents = None
|
|
180
|
+
with open(behave_log) as f:
|
|
181
|
+
contents = f.readlines()
|
|
182
|
+
|
|
183
|
+
just_saw_then = False
|
|
184
|
+
current_scenario = ""
|
|
185
|
+
for each_line in contents:
|
|
186
|
+
# Show logic when we hit a blank line after assertions OR when starting a new scenario
|
|
187
|
+
if just_saw_then and (each_line == "\n" or each_line.startswith(" Scenario")):
|
|
188
|
+
show_logic(scenario=current_scenario, logic_logs_dir=scenario_logs)
|
|
189
|
+
just_saw_then = False
|
|
190
|
+
|
|
191
|
+
if each_line.startswith("Feature"):
|
|
192
|
+
wiki_data.append(" ")
|
|
193
|
+
wiki_data.append(" ")
|
|
194
|
+
each_line = "## " + each_line
|
|
195
|
+
|
|
196
|
+
if each_line.startswith(" Scenario"):
|
|
197
|
+
# Extract scenario name for logic lookup
|
|
198
|
+
current_scenario = each_line.strip().replace("Scenario: ", "").replace(" ", " ").strip()
|
|
199
|
+
wiki_data.append(" ")
|
|
200
|
+
wiki_data.append(" ")
|
|
201
|
+
wiki_data.append("### " + each_line[2:]) # Add scenario header
|
|
202
|
+
each_line = tab + each_line
|
|
203
|
+
|
|
204
|
+
if each_line.startswith(" Given") or \
|
|
205
|
+
each_line.startswith(" When") or \
|
|
206
|
+
each_line.startswith(" Then") or \
|
|
207
|
+
each_line.startswith(" And"):
|
|
208
|
+
if each_line.startswith(" Then") or each_line.startswith(" And"):
|
|
209
|
+
just_saw_then = True
|
|
210
|
+
# Add subtle formatting to keywords
|
|
211
|
+
for keyword in ["Given", "When", "Then", "And"]:
|
|
212
|
+
if f" {keyword} " in each_line:
|
|
213
|
+
each_line = each_line.replace(f" {keyword} ", f" **{keyword}** ")
|
|
214
|
+
break
|
|
215
|
+
each_line = tab + tab + each_line
|
|
216
|
+
|
|
217
|
+
each_line = each_line[:-1]
|
|
218
|
+
debug_loc = each_line.find(behave_debug_info)
|
|
219
|
+
if debug_loc > 0:
|
|
220
|
+
each_line = each_line[0 : debug_loc]
|
|
221
|
+
each_line = each_line.rstrip()
|
|
222
|
+
|
|
223
|
+
each_line = each_line + " " # wiki for "new line"
|
|
224
|
+
|
|
225
|
+
wiki_data.append(each_line)
|
|
226
|
+
|
|
227
|
+
# Show logic for the last scenario
|
|
228
|
+
if current_scenario and just_saw_then:
|
|
229
|
+
show_logic(scenario=current_scenario, logic_logs_dir=scenario_logs)
|
|
230
|
+
|
|
231
|
+
with open(wiki, 'w') as rpt:
|
|
232
|
+
rpt.write('\n'.join(wiki_data))
|
|
233
|
+
wiki_full_path = Path(wiki).absolute()
|
|
234
|
+
print(f'Wiki Output: {wiki_full_path}\n\n')
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def print_args(args, msg):
|
|
239
|
+
print(msg)
|
|
240
|
+
for each_arg in args:
|
|
241
|
+
print(f' {each_arg}')
|
|
242
|
+
print(" ")
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
@click.group()
|
|
246
|
+
@click.pass_context
|
|
247
|
+
def cli(ctx):
|
|
248
|
+
"""
|
|
249
|
+
Combine behave.log and scenario_logic_logs to create Behave Logic Report
|
|
250
|
+
|
|
251
|
+
"""
|
|
252
|
+
pass
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
@cli.command("run")
|
|
256
|
+
@click.pass_context
|
|
257
|
+
@click.option('--behave_log',
|
|
258
|
+
default=f'logs/behave.log', # cwd set to test/api_logic_server_behave
|
|
259
|
+
# prompt="Log from behave test suite run [behave.log]",
|
|
260
|
+
help="Help")
|
|
261
|
+
@click.option('--scenario_logs',
|
|
262
|
+
default=f'logs/scenario_logic_logs',
|
|
263
|
+
# prompt="Logic Log directory from ",
|
|
264
|
+
help="Help")
|
|
265
|
+
@click.option('--wiki',
|
|
266
|
+
default=f'reports/Behave Logic Report.md',
|
|
267
|
+
# prompt="Log from behave test suite run [api_logic_server_behave]",
|
|
268
|
+
help="Help")
|
|
269
|
+
@click.option('--prepend_wiki',
|
|
270
|
+
default=f'reports/Behave Logic Report Intro micro.md',
|
|
271
|
+
# prompt="Log from behave test suite run [Behave Logic Report Intro]",
|
|
272
|
+
help="Help")
|
|
273
|
+
def run(ctx, behave_log: str, scenario_logs: str, wiki: str, prepend_wiki: str):
|
|
274
|
+
main(behave_log = behave_log, scenario_logs = scenario_logs, wiki = wiki, prepend_wiki = prepend_wiki)
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
if __name__ == '__main__': # debugger & python command line start here
|
|
278
|
+
# eg: python api_logic_server_cli/cli.py create --project_name=~/Desktop/test_project
|
|
279
|
+
# unix: python api_logic_server_cli/cli.py create --project_name=/home/ApiLogicProject
|
|
280
|
+
|
|
281
|
+
print(f'\nBehave Logic Report 1.1, started at {os.getcwd()}')
|
|
282
|
+
commands = sys.argv
|
|
283
|
+
if len(sys.argv) > 1:
|
|
284
|
+
print_args(commands, f'\n\nCommand Line Arguments:')
|
|
285
|
+
cli()
|
|
@@ -1,51 +1,52 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
---
|
|
2
|
+
title: Copilot Instructions for basic_demo Project
|
|
3
|
+
Description: Project-level instructions for AI assistants conducting guided tours
|
|
4
|
+
Source: ApiLogicServer-src/prototypes/basic_demo/.github/.copilot-instructions.md
|
|
5
|
+
Propagation: CLI create command → created projects
|
|
6
|
+
Usage: AI assistants read this when user says "guide me through"
|
|
7
|
+
version: 2.1
|
|
8
|
+
changelog:
|
|
9
|
+
- 2.1 (Oct 2025) - Streamlined OBX, emphasized uncustomized template, friendly collaborative tone
|
|
10
|
+
- 2.0 (Oct 2025) - Added provocation method, spreadsheet analogy, timing checkpoints
|
|
11
|
+
---
|
|
3
12
|
|
|
4
13
|
# GitHub Copilot Instructions for GenAI-Logic (aka API Logic Server) Projects
|
|
5
14
|
|
|
6
|
-
|
|
15
|
+
⚠️ **IMPORTANT FOR AI ASSISTANTS**: When user first opens this project or asks you to read instructions, present the Welcome section below directly to the user. Do not explain that you're following instructions - just present the welcome message naturally. The technical reference sections after the welcome are for later consultation only.
|
|
7
16
|
|
|
8
|
-
|
|
17
|
+
---
|
|
9
18
|
|
|
10
|
-
##
|
|
19
|
+
## Welcome
|
|
11
20
|
|
|
12
|
-
**
|
|
21
|
+
**Welcome! This is your basic_demo project.**
|
|
13
22
|
|
|
14
|
-
|
|
15
|
-
- **Logic Discovery**: Business rules automatically loaded from `logic/logic_discovery/use_case.py` via `logic/logic_discovery/auto_discovery.py`
|
|
16
|
-
- **API Discovery**: Custom APIs automatically loaded from `api/api_discovery/[service_name].py` via `api/api_discovery/auto_discovery.py`
|
|
17
|
-
- Do NOT manually duplicate rule calls or API registrations
|
|
23
|
+
This is a complete, working microservice auto-generated from a database schema - **uncustomized**, so you can see what to expect when you create projects from your own databases.
|
|
18
24
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
```
|
|
25
|
+
**What's already created from introspecting the database schema:**
|
|
26
|
+
- **Admin Web Application** - Live at `http://localhost:5656`
|
|
27
|
+
- **REST API Endpoints** - All database tables exposed at `/api/*`
|
|
28
|
+
- **Database Models** - Complete SQLAlchemy ORM in `database/models.py`
|
|
29
|
+
- **Authentication System** - JWT-based auth framework
|
|
30
|
+
- **Business Logic Engine** - Declarative rules system
|
|
26
31
|
|
|
27
|
-
|
|
32
|
+
---
|
|
28
33
|
|
|
29
|
-
|
|
34
|
+
**First, we'll briefly explore what's automatically created. Then I'll show you how I can help you customize it - adding logic, security, and API endpoints.**
|
|
30
35
|
|
|
31
|
-
**
|
|
36
|
+
Want to get started? Press **F5** to start the server with debugger support, then open `http://localhost:5656`. (There are also run configurations for running tests and other tasks.)
|
|
32
37
|
|
|
33
|
-
|
|
34
|
-
2. **REST API Endpoints** - All database tables exposed at `/api/*`
|
|
35
|
-
3. **Database Models** - Complete SQLAlchemy ORM in `database/models.py`
|
|
36
|
-
4. **Authentication System** - JWT-based auth framework
|
|
37
|
-
5. **Business Logic Engine** - Declarative rules system
|
|
38
|
+
---
|
|
38
39
|
|
|
39
|
-
|
|
40
|
+
## Technical Reference (For AI Assistant - Do Not Present to User Unless Asked)
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
The sections below contain detailed technical information for when we're actively working on specific tasks. These are reference materials, not introductory content.
|
|
42
43
|
|
|
43
|
-
|
|
44
|
+
---
|
|
44
45
|
|
|
45
|
-
|
|
46
|
+
I'll present these as choices - we'll tackle them one at a time.
|
|
46
47
|
|
|
47
48
|
### Set Up Virtual Environment
|
|
48
|
-
If it
|
|
49
|
+
If it's not already set, we can often find a `venv` in the GenAI-Logic Manager - a parent or grandparent directory.
|
|
49
50
|
|
|
50
51
|
### 🚀 To Run This Project
|
|
51
52
|
|
|
@@ -220,6 +221,86 @@ See `test/api_logic_server_behave/` for examples and [published report](https://
|
|
|
220
221
|
4. ❌ Step execution: `step_impl.execute_step()` → ✅ Use: `context.execute_steps('when Step')`
|
|
221
222
|
5. ❌ Reusing test data → ✅ Create fresh with: `f"{name} {int(time.time()*1000)}"`
|
|
222
223
|
|
|
224
|
+
**For detailed test creation patterns, see `docs/training/testing.md` which documents all critical rules including Rule #0.5 (Behave Step Ordering).**
|
|
225
|
+
|
|
226
|
+
#### Critical Learnings: Behave Logic Report Generation
|
|
227
|
+
|
|
228
|
+
**PROBLEM**: Reports not showing logic details for test scenarios.
|
|
229
|
+
|
|
230
|
+
**ROOT CAUSES DISCOVERED**:
|
|
231
|
+
|
|
232
|
+
1. **Empty behave.log** (Most Common Issue)
|
|
233
|
+
- ❌ Running: `python behave_run.py`
|
|
234
|
+
- ✅ Must run: `python behave_run.py --outfile=logs/behave.log`
|
|
235
|
+
- Without `--outfile`, behave.log remains empty (0 bytes) and report has no content
|
|
236
|
+
|
|
237
|
+
2. **Scenario Name Mismatch**
|
|
238
|
+
- Log files must match scenario names from .feature file
|
|
239
|
+
- ❌ Using custom names: `scenario_name = f'B2B Order - {quantity} {product_name}'`
|
|
240
|
+
- ✅ Use actual scenario: `scenario_name = context.scenario.name`
|
|
241
|
+
- Report generator truncates to 25 chars and looks for matching .log files
|
|
242
|
+
|
|
243
|
+
3. **Report Generator Logic Bug**
|
|
244
|
+
- Original code only showed logic when blank line followed "Then" step
|
|
245
|
+
- Only worked for ~30% of scenarios (those with blank lines in behave.log)
|
|
246
|
+
- ✅ Fixed: Trigger logic display when next scenario starts OR at end of file
|
|
247
|
+
|
|
248
|
+
**CORRECT PATTERN FOR WHEN STEPS**:
|
|
249
|
+
|
|
250
|
+
```python
|
|
251
|
+
@when('B2B order placed for "{customer_name}" with {quantity:d} {product_name}')
|
|
252
|
+
def step_impl(context, customer_name, quantity, product_name):
|
|
253
|
+
"""
|
|
254
|
+
Phase 2: CREATE using OrderB2B API - Tests OrderB2B integration
|
|
255
|
+
"""
|
|
256
|
+
scenario_name = context.scenario.name # ← CRITICAL: Use actual scenario name
|
|
257
|
+
test_utils.prt(f'\n{scenario_name}\n', scenario_name)
|
|
258
|
+
|
|
259
|
+
# ... test implementation ...
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
**WORKFLOW FOR REPORT GENERATION**:
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
# 1. Run tests WITH outfile to generate behave.log
|
|
266
|
+
python behave_run.py --outfile=logs/behave.log
|
|
267
|
+
|
|
268
|
+
# 2. Generate report (reads behave.log + scenario_logic_logs/*.log)
|
|
269
|
+
python behave_logic_report.py run
|
|
270
|
+
|
|
271
|
+
# 3. View report
|
|
272
|
+
open reports/Behave\ Logic\ Report.md
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
**WHAT THE REPORT SHOWS**:
|
|
276
|
+
- Each scenario gets a `<details>` section with:
|
|
277
|
+
- **Rules Used**: Which declarative rules fired (numbered list)
|
|
278
|
+
- **Logic Log**: Complete trace showing before→after values for all adjustments
|
|
279
|
+
- Demonstrates the 44X code reduction by showing rule automation
|
|
280
|
+
|
|
281
|
+
**DEBUGGING TIPS**:
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
# Check if behave.log has content
|
|
285
|
+
ls -lh logs/behave.log # Should be several KB, not 0 bytes
|
|
286
|
+
|
|
287
|
+
# Check if scenario logs exist with correct names
|
|
288
|
+
ls logs/scenario_logic_logs/ | head -10
|
|
289
|
+
|
|
290
|
+
# Count detail sections in report (should equal number of scenarios)
|
|
291
|
+
grep -c "<details markdown>" reports/Behave\ Logic\ Report.md
|
|
292
|
+
|
|
293
|
+
# View a specific scenario's log directly
|
|
294
|
+
cat logs/scenario_logic_logs/Delete_Item_Reduces_Order.log
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
**KEY INSIGHT**: The report generator uses a two-step process:
|
|
298
|
+
1. Reads behave.log for scenario structure (Given/When/Then steps)
|
|
299
|
+
2. Matches scenario names to .log files in scenario_logic_logs/
|
|
300
|
+
3. Injects logic details at the right location in the report
|
|
301
|
+
|
|
302
|
+
If scenario names don't match between behave.log and .log filenames, logic details won't appear!
|
|
303
|
+
|
|
223
304
|
### Adding MCP
|
|
224
305
|
|
|
225
306
|
The API is automatically MCP-enabled. The project includes a comprehensive MCP client executor at `integration/mcp/mcp_client_executor.py`, but to enable the **user interface** for MCP requests, you must run this command:
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
## Basic Demo Sample
|
|
2
|
+
|
|
3
|
+
This is a basic demonstration project created from a simple natural language prompt using API Logic Server's GenAI capabilities.
|
|
4
|
+
|
|
5
|
+
### Data Model
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
### Creation Prompt
|
|
10
|
+
|
|
11
|
+
This project was created from the following natural language prompt:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
Create a system with customers, orders, items and products.
|
|
15
|
+
|
|
16
|
+
Include a notes field for orders.
|
|
17
|
+
|
|
18
|
+
Use case: Check Credit
|
|
19
|
+
1. The Customer's balance is less than the credit limit
|
|
20
|
+
2. The Customer's balance is the sum of the Order amount_total where date_shipped is null
|
|
21
|
+
3. The Order's amount_total is the sum of the Item amount
|
|
22
|
+
4. The Item amount is the quantity * unit_price
|
|
23
|
+
5. The Item unit_price is copied from the Product unit_price
|
|
24
|
+
|
|
25
|
+
Use case: App Integration
|
|
26
|
+
1. Send the Order to Kafka topic 'order_shipping' if the date_shipped is not None.
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The sample Scenarios below were chosen to illustrate the basic patterns of using rules. Open the disclosure box ("Tests - and their logic...") to see the implementation and notes.
|
|
30
|
+
|
|
31
|
+
The following report was created during test suite execution.
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# Behave Logic Report
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
## Basic Demo Sample
|
|
2
|
+
|
|
3
|
+
This is a basic demonstration project created from a simple natural language prompt using API Logic Server's GenAI capabilities (with a custom Behave Report Intro).
|
|
4
|
+
|
|
5
|
+
### Data Model
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
### Creation Prompt
|
|
10
|
+
|
|
11
|
+
This project was created from the following natural language prompt:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
Create a system with customers, orders, items and products.
|
|
15
|
+
|
|
16
|
+
Include a notes field for orders.
|
|
17
|
+
|
|
18
|
+
Use case: Check Credit
|
|
19
|
+
1. The Customer's balance is less than the credit limit
|
|
20
|
+
2. The Customer's balance is the sum of the Order amount_total where date_shipped is null
|
|
21
|
+
3. The Order's amount_total is the sum of the Item amount
|
|
22
|
+
4. The Item amount is the quantity * unit_price
|
|
23
|
+
5. The Item unit_price is copied from the Product unit_price
|
|
24
|
+
|
|
25
|
+
Use case: App Integration
|
|
26
|
+
1. Send the Order to Kafka topic 'order_shipping' if the date_shipped is not None.
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The sample Scenarios below were chosen to illustrate the basic patterns of using rules. Open the disclosure box ("Tests - and their logic...") to see the implementation and notes.
|
|
30
|
+
|
|
31
|
+
The following report was created during test suite execution.
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# Behave Logic Report
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Instant Microservices - with Logic and Security
|
|
3
3
|
notes: gold is proto (-- doc); alert for apostrophe
|
|
4
|
+
do_process_code_block_titles: True
|
|
4
5
|
version: 0.23 from docsite, for readme 7/11/2025
|
|
5
6
|
---
|
|
6
7
|
<style>
|
|
@@ -18,8 +19,13 @@ This illustrates basic [GenAI-Logic](https://www.genai-logic.com/product/key-fea
|
|
|
18
19
|
2. Adding declarative logic and security, and
|
|
19
20
|
3. Customizing your project using your IDE and Python<br><br>
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
**🤖 Two Ways to Explore:**
|
|
23
|
+
|
|
24
|
+
* **Self-Paced:** Follow the sections below at your own speed
|
|
25
|
+
* **AI-Guided Tour:** Say to Copilot: *"Guide me through basic_demo"*
|
|
26
|
+
|
|
27
|
+
**Bootstrap Copilot:**
|
|
28
|
+
```bash title='🤖 Bootstrap Copilot by pasting the following into the chat'
|
|
23
29
|
Please find and read `.github/.copilot-instructions.md`.
|
|
24
30
|
```
|
|
25
31
|
|
|
@@ -152,9 +158,10 @@ And you are ready to Vibe:
|
|
|
152
158
|
* Instead of creating data mockups, you have a **running API server with real data**
|
|
153
159
|
* Instead of starting from scratch, you have a **running multi-page app**
|
|
154
160
|
* And, you'll have projects that are **architecturally correct:** shared logic, enforced in the server, available for both User Interfaces and services.
|
|
155
|
-
* Then, use you favorite Vibe tools with your running API
|
|
161
|
+
* Then, use you favorite Vibe tools with your running API:
|
|
156
162
|
|
|
157
163
|
|
|
164
|
+
**Customize using Natural Language:**
|
|
158
165
|
```txt title='Customize using Natural Language'
|
|
159
166
|
In the ui/react app, Update the Product list to provide users an option to see results in a list, or in cards.
|
|
160
167
|
```
|
|
@@ -294,7 +301,7 @@ Note that it's a `Multi-Table Transaction`, as indicated by the indentation. Th
|
|
|
294
301
|
|
|
295
302
|
**b. 40X More Concise**
|
|
296
303
|
|
|
297
|
-
The 5 spreadsheet-like rules represent the same logic as 200 lines of code, [shown here](https://github.com/
|
|
304
|
+
The 5 spreadsheet-like rules represent the same logic as 200 lines of code, [shown here](https://apilogicserver.github.io/Docs/https://github.com/ApiLogicServer/basic_demo/blob/main/logic/procedural/declarative-vs-procedural-comparison). That's a remarkable 40X decrease in the backend half of the system.
|
|
298
305
|
|
|
299
306
|
> 💡 No FrankenCode<br>Note the rules look like syntactically correct requirements. They are not turned into piles of unmanageable "frankencode" - see [models not frankencode](https://www.genai-logic.com/faqs#h.3fe4qv21qtbs).
|
|
300
307
|
|
|
@@ -358,6 +365,7 @@ Or, use the command line.
|
|
|
358
365
|
> Since the CLI does not pass an auth token,
|
|
359
366
|
you must first stop the server and disable security.
|
|
360
367
|
|
|
368
|
+
**MCP from the command line:**
|
|
361
369
|
```bash title='MCP from the command line'
|
|
362
370
|
python integration/mcp/mcp_client_executor.py mcp
|
|
363
371
|
```
|