ApiLogicServer 14.2.1__py3-none-any.whl → 14.2.20__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.
- {ApiLogicServer-14.2.1.dist-info → ApiLogicServer-14.2.20.dist-info}/METADATA +1 -1
- {ApiLogicServer-14.2.1.dist-info → ApiLogicServer-14.2.20.dist-info}/RECORD +23 -22
- api_logic_server_cli/api_logic_server.py +44 -10
- api_logic_server_cli/api_logic_server_info.yaml +3 -3
- api_logic_server_cli/cli.py +9 -3
- api_logic_server_cli/genai/client.py +24 -0
- api_logic_server_cli/genai/genai.py +24 -17
- api_logic_server_cli/genai/genai_logic_builder.py +7 -24
- api_logic_server_cli/genai/genai_svcs.py +7 -6
- api_logic_server_cli/genai/genai_utils.py +0 -1
- api_logic_server_cli/prototypes/base/config/config.py +10 -6
- api_logic_server_cli/prototypes/base/database/bind_dbs.py +2 -1
- api_logic_server_cli/prototypes/base/logic/logic_discovery/auto_discovery.py +17 -0
- api_logic_server_cli/prototypes/genai_demo/database/models.py +11 -55
- api_logic_server_cli/prototypes/genai_demo/logic/declare_logic.py +1 -1
- api_logic_server_cli/prototypes/manager/.vscode/launch.json +3 -3
- api_logic_server_cli/prototypes/manager/README.md +7 -7
- api_logic_server_cli/prototypes/manager/system/genai/create_db_models_inserts/create_db_models_imports.py +1 -0
- api_logic_server_cli/tools/mini_skel/run.py +1 -0
- {ApiLogicServer-14.2.1.dist-info → ApiLogicServer-14.2.20.dist-info}/LICENSE +0 -0
- {ApiLogicServer-14.2.1.dist-info → ApiLogicServer-14.2.20.dist-info}/WHEEL +0 -0
- {ApiLogicServer-14.2.1.dist-info → ApiLogicServer-14.2.20.dist-info}/entry_points.txt +0 -0
- {ApiLogicServer-14.2.1.dist-info → ApiLogicServer-14.2.20.dist-info}/top_level.txt +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
api_logic_server_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
api_logic_server_cli/api_logic_server.py,sha256=
|
|
3
|
-
api_logic_server_cli/api_logic_server_info.yaml,sha256=
|
|
4
|
-
api_logic_server_cli/cli.py,sha256
|
|
2
|
+
api_logic_server_cli/api_logic_server.py,sha256=smHGo-90nfLN1kNAgsCz8J9eobshNdQK-QNhbLMSfBU,113245
|
|
3
|
+
api_logic_server_cli/api_logic_server_info.yaml,sha256=RA62dqr8CYcNPxXun37L_wTpOO8Wub6wnE-XK8_4beU,123
|
|
4
|
+
api_logic_server_cli/cli.py,sha256=-BcfW4QE0MnTi_ZRFZEcYy7l0A6TXjGgOnexpYfEmL4,80583
|
|
5
5
|
api_logic_server_cli/cli_args_base.py,sha256=lr27KkOB7_WpZwTs7LgiK8LKDIHMKQkoZCTnE99BFxw,3280
|
|
6
6
|
api_logic_server_cli/cli_args_project.py,sha256=I5no_fGRV_ZsK3SuttVDAaQYI4Q5zCjx6LojGkM024w,4645
|
|
7
7
|
api_logic_server_cli/extended_builder.py,sha256=EhtXGAt_RrDR2tCtgvc2U82we7fr-F6pP-e6HS6dQWQ,13867
|
|
@@ -467,10 +467,11 @@ api_logic_server_cli/fragments/modelsZZ.py,sha256=EDWnf4gyOoenPn5OuQyWWa2GJVMiw4
|
|
|
467
467
|
api_logic_server_cli/fragments/nw_virtual_attrs.py,sha256=7hgvhnO1UcJ6OoPKCxR5bn71zZEe7gsk4odtoswqKj8,888
|
|
468
468
|
api_logic_server_cli/fragments/ui_basic_web_app_runZZ.py,sha256=UllBIkKHlUE3nyDE1qtFWCA-NTE1ltYxPvVUd7lZI5U,870
|
|
469
469
|
api_logic_server_cli/genai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
470
|
-
api_logic_server_cli/genai/
|
|
471
|
-
api_logic_server_cli/genai/
|
|
472
|
-
api_logic_server_cli/genai/
|
|
473
|
-
api_logic_server_cli/genai/
|
|
470
|
+
api_logic_server_cli/genai/client.py,sha256=36gyz-dqxj4dJj1SGtO9NZsy9-cfnf4d7uahHimwqHk,772
|
|
471
|
+
api_logic_server_cli/genai/genai.py,sha256=DfB_e7guERV3y7BgyTVcFaQFJNpJbzj5QXOZeRpjf-k,57781
|
|
472
|
+
api_logic_server_cli/genai/genai_logic_builder.py,sha256=bUGXxKNqe-JX34AL1aa2z1_XfBppd8rw1BRCBRD01Ak,23209
|
|
473
|
+
api_logic_server_cli/genai/genai_svcs.py,sha256=xS44_lirAZGbTlyZqJA3gO-EkQgmFCoA8MVoMtmVbuw,41223
|
|
474
|
+
api_logic_server_cli/genai/genai_utils.py,sha256=DKhIb0P-7Ps1a1jIXyDOlTT8DwXn4-c7LRrV83GgnC8,17128
|
|
474
475
|
api_logic_server_cli/genai/json2rules.py,sha256=ykoxxgZgqllzt8Ud06S-R_3QtumxXfmF5ksYC0Hh2Sk,2645
|
|
475
476
|
api_logic_server_cli/model_migrator/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
476
477
|
api_logic_server_cli/model_migrator/gen_behave_tests.py,sha256=2EOPlY2up_kv80LCRvxOiV-PxHW_Muq6IW8p1AwFpVU,9491
|
|
@@ -541,7 +542,7 @@ api_logic_server_cli/prototypes/base/api/system/opt_locking/opt_locking.py,sha25
|
|
|
541
542
|
api_logic_server_cli/prototypes/base/api/system/opt_locking/readme.md,sha256=Ja_-d-mxHAvOFslu6jlu18HQ3CSFaaSvphHMm3YM-Z8,6760
|
|
542
543
|
api_logic_server_cli/prototypes/base/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
543
544
|
api_logic_server_cli/prototypes/base/config/activate_logicbank.py,sha256=Z2W5vFGikBAWZs3Y_a9guWHstS8p7QXgSIC6LaiO7f4,1818
|
|
544
|
-
api_logic_server_cli/prototypes/base/config/config.py,sha256=
|
|
545
|
+
api_logic_server_cli/prototypes/base/config/config.py,sha256=pPaBBNV8hsnorKZ4f1hRRJnR32JFj7G_HNK5Wsu53NY,25186
|
|
545
546
|
api_logic_server_cli/prototypes/base/config/default.env,sha256=xMh_q1rBLLPNfzy8xzSL5xojGmvrjyWVbFwuqyfsrgQ,205
|
|
546
547
|
api_logic_server_cli/prototypes/base/config/logging-reduced.yml,sha256=N-BDIk0t5uAmw3Of_d_ueK4jx7pxNwlYbkiDd1wjRDs,2179
|
|
547
548
|
api_logic_server_cli/prototypes/base/config/logging.yml,sha256=Do1uS1EIQEuMEUUp511UfmRy9bkT6o75uHLVRJyYmjE,2268
|
|
@@ -551,7 +552,7 @@ api_logic_server_cli/prototypes/base/database/.DS_Store,sha256=8Qg_FZQkmuMuIEdT3
|
|
|
551
552
|
api_logic_server_cli/prototypes/base/database/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
552
553
|
api_logic_server_cli/prototypes/base/database/alembic.ini,sha256=N-xPrNv1gfMB8ylxm8pprtQxjwlv_9vTUSYGXnaWMnA,3027
|
|
553
554
|
api_logic_server_cli/prototypes/base/database/authentication_db.sqlite,sha256=hA71uBnrh2PVQw9YLc-YbsXjpxr2VyvfE-OhF_ssE6w,45056
|
|
554
|
-
api_logic_server_cli/prototypes/base/database/bind_dbs.py,sha256=
|
|
555
|
+
api_logic_server_cli/prototypes/base/database/bind_dbs.py,sha256=8rVKILbsgTdChmHnzzR1BmU1qovz8tB-xzPrBoEpgaw,758
|
|
555
556
|
api_logic_server_cli/prototypes/base/database/customize_models.py,sha256=U5cTWtLS0UlR7_js6D7O2JVgeMtG7IqlkSL9Ok6g_kU,580
|
|
556
557
|
api_logic_server_cli/prototypes/base/database/alembic/env.py,sha256=YIrFy7lQYTdTU0-4g7mbtK6kKZp0uKQED_ScpE7lzzc,2101
|
|
557
558
|
api_logic_server_cli/prototypes/base/database/alembic/readme.md,sha256=Quaj63-4i2qHRD0MXTb-exeE7zWIb9bHICQE_Nth0v0,775
|
|
@@ -628,7 +629,7 @@ api_logic_server_cli/prototypes/base/integration/system/FlaskKafka.py,sha256=_Us
|
|
|
628
629
|
api_logic_server_cli/prototypes/base/integration/system/RowDictMapper.py,sha256=sTAUnF5N6YfWJ5gXLHqwD6ckDcQxN3Q2U_8VCwQBT4Q,18800
|
|
629
630
|
api_logic_server_cli/prototypes/base/logic/declare_logic.py,sha256=Av8CxFC5DW1DXlVnbwVH3cWtUAWO5fIGtGRqSzGEivU,3014
|
|
630
631
|
api_logic_server_cli/prototypes/base/logic/readme_declare_logic.md,sha256=CFC13f9Z4rTkNiRoJTBEz3A2F_yRThOj-HrHDsSdKsw,6630
|
|
631
|
-
api_logic_server_cli/prototypes/base/logic/logic_discovery/auto_discovery.py,sha256=
|
|
632
|
+
api_logic_server_cli/prototypes/base/logic/logic_discovery/auto_discovery.py,sha256=z26I4SJ_1SjtoxIpiHOGg2A3hSBaTNjvaVE5BQSsl4E,1847
|
|
632
633
|
api_logic_server_cli/prototypes/base/logic/logic_discovery/__pycache__/__init__.cpython-312.pyc,sha256=5--1medTaKN83y-D_iv9EPiLD2uja_Q0r5ZkxX_pJM4,199
|
|
633
634
|
api_logic_server_cli/prototypes/base/logic/logic_discovery/__pycache__/auto_discovery.cpython-312.pyc,sha256=OHyWfpKrY0UbeSEwBnxsiIHPgpjzDSpCoyIa6ha4NVk,1579
|
|
634
635
|
api_logic_server_cli/prototypes/base/logic/logic_discovery/__pycache__/error_testing.cpython-312.pyc,sha256=NQKJ0pHsE53Nwmob8c03X_vkSV-MP_mj-1VFmJ3kRs0,2225
|
|
@@ -725,7 +726,7 @@ api_logic_server_cli/prototypes/fiddle/1. Learn APIs using Flask SqlAlchemy/data
|
|
|
725
726
|
api_logic_server_cli/prototypes/fiddle/1. Learn APIs using Flask SqlAlchemy/test/server_test.py,sha256=XWmMCqixRy7aP47rpNEOjv_4NxSi7z-8yYjtqkShLE8,786
|
|
726
727
|
api_logic_server_cli/prototypes/genai_demo/api/customize_api.py,sha256=Pbqwj0FcLIOHEaiBPOpTBFGVOniAnaabB9-x0OvT4sI,7402
|
|
727
728
|
api_logic_server_cli/prototypes/genai_demo/database/db.sqlite,sha256=Fb5yOHnS_u5QNS6wAohXup26M6at_QVknX04plwuPQM,24576
|
|
728
|
-
api_logic_server_cli/prototypes/genai_demo/database/models.py,sha256=
|
|
729
|
+
api_logic_server_cli/prototypes/genai_demo/database/models.py,sha256=grVKrT2s8SYmvglJIUcSQcWsfvtXdkwWA3Eb2sGFP2U,4045
|
|
729
730
|
api_logic_server_cli/prototypes/genai_demo/database/chatgpt/sample_ai.chatgpt,sha256=QfhYG2ykF7ntd-jw3jkuwbpHjQ7e5qmvc4U184a6vNQ,571
|
|
730
731
|
api_logic_server_cli/prototypes/genai_demo/database/chatgpt/sample_ai.sql,sha256=AZaHE8J8jWRgPxypfCeVbynbmhf5hw2ojUz0PFL2UCQ,2177
|
|
731
732
|
api_logic_server_cli/prototypes/genai_demo/database/chatgpt/sample_ai.sqlite,sha256=XbMAvWKnaG5bsicsA05-0wgd0PowZs7x3t15Qh7_wP0,24576
|
|
@@ -737,16 +738,16 @@ api_logic_server_cli/prototypes/genai_demo/database/chatgpt/__pycache__/sample_a
|
|
|
737
738
|
api_logic_server_cli/prototypes/genai_demo/integration/row_dict_maps/OrderB2B.py,sha256=TXhhw54Iyp2mf629rDT8elawOc2q-VNfUaumYBaRAto,1236
|
|
738
739
|
api_logic_server_cli/prototypes/genai_demo/integration/row_dict_maps/OrderShipping.py,sha256=4wM45eRNkDNl7vcX689VSR7BgdKvae5hD26L8XZYGfc,1197
|
|
739
740
|
api_logic_server_cli/prototypes/genai_demo/logic/cocktail-napkin.jpg,sha256=5rNSy6wvcWSHPJQZqkf2DHs19QLWiyqMBNwxGqjstZU,133075
|
|
740
|
-
api_logic_server_cli/prototypes/genai_demo/logic/declare_logic.py,sha256=
|
|
741
|
+
api_logic_server_cli/prototypes/genai_demo/logic/declare_logic.py,sha256=u_zc3lbR6G7pNFW9RAlquydQOZCsHAVVKUvtQ9_SGz8,5055
|
|
741
742
|
api_logic_server_cli/prototypes/genai_demo/security/declare_security.py,sha256=L3AL1bgdqIWQxdkJZcFVDOQ0XRpmeLAKqwlAYChFWKo,2108
|
|
742
743
|
api_logic_server_cli/prototypes/genai_demo/ui/admin/admin.yaml,sha256=9rSLJXDr5n3ILHQAU2XDjdGzql9ZyHXmwCYAmaGcH-g,2288
|
|
743
744
|
api_logic_server_cli/prototypes/manager/.DS_Store,sha256=v0WHl9kV19fTkhSl1TOZkl0d_KnhnIhXNpgTNdFVSpY,6148
|
|
744
745
|
api_logic_server_cli/prototypes/manager/.gitignore,sha256=xfAjNQHokbo6GuN1ghx-eml8tQIzwUczLC_YVzElndI,195
|
|
745
|
-
api_logic_server_cli/prototypes/manager/README.md,sha256=
|
|
746
|
+
api_logic_server_cli/prototypes/manager/README.md,sha256=SqGifi_4np5z2mJWlrjO2SHARAB9djY31hT2Ej-Fe2o,19995
|
|
746
747
|
api_logic_server_cli/prototypes/manager/settings.txt,sha256=_jjL30jomIMxG21edDfrXYRT9Zfgr_0EdUWvcEUOnFQ,368
|
|
747
748
|
api_logic_server_cli/prototypes/manager/.vscode/.DS_Store,sha256=1lFlJ5EFymdzGAUAaI30vcaaLHt3F1LwpG7xILf9jsM,6148
|
|
748
749
|
api_logic_server_cli/prototypes/manager/.vscode/ApiLogicServer.code-workspace,sha256=HFycZhs0k5fXLxEZF-FBSA2S_JRDIYtVOhqb9743hH4,296
|
|
749
|
-
api_logic_server_cli/prototypes/manager/.vscode/launch.json,sha256=
|
|
750
|
+
api_logic_server_cli/prototypes/manager/.vscode/launch.json,sha256=BK5W-HwhFGB5dczUHRow_5iWiX7ozzcdmuVIRMVb5XQ,32515
|
|
750
751
|
api_logic_server_cli/prototypes/manager/.vscode/settings.json,sha256=wQgpFvviPbZCmsf02UgrJSGAz7g3i4chDZ_AdSIOr5Y,625
|
|
751
752
|
api_logic_server_cli/prototypes/manager/system/.DS_Store,sha256=r4gY37tWmhc60MVHeHWD-ZbqQBPlXqcC7xX2NhV42AA,6148
|
|
752
753
|
api_logic_server_cli/prototypes/manager/system/Manager_workspace.code-workspace,sha256=19Acdi2ZvX5U_IMokLiVaKkIMwsSxgbw5YjaRMpBAAI,333
|
|
@@ -1190,7 +1191,7 @@ api_logic_server_cli/prototypes/manager/system/app_model_editor/venv_setup/venv.
|
|
|
1190
1191
|
api_logic_server_cli/prototypes/manager/system/app_model_editor/venv_setup/venv.sh,sha256=aWX9fa8fe6aO9ifBIZEgGY5UGh4I0arOoCwBzDsxgU8,893
|
|
1191
1192
|
api_logic_server_cli/prototypes/manager/system/genai/.DS_Store,sha256=wgfoHO202GBaqUIxU970PrbpL8rx2cRwZxzqtkUkPbI,6148
|
|
1192
1193
|
api_logic_server_cli/prototypes/manager/system/genai/create_db_models_inserts/create_db_models_create_db.py,sha256=F9UMTYVDHVUo4lxRFDYTpLtTgHer4g65Kld-hrq8mMM,589
|
|
1193
|
-
api_logic_server_cli/prototypes/manager/system/genai/create_db_models_inserts/create_db_models_imports.py,sha256=
|
|
1194
|
+
api_logic_server_cli/prototypes/manager/system/genai/create_db_models_inserts/create_db_models_imports.py,sha256=RhXYcL1MzTlYMhwX5jLv05Wqj185fpD940oRHenRxrw,967
|
|
1194
1195
|
api_logic_server_cli/prototypes/manager/system/genai/create_db_models_inserts/create_db_models_prefix.py,sha256=_rQsqDG2ieNxSsv28t7f9Z5Bs6IMASl8rVunVZIHyUk,301
|
|
1195
1196
|
api_logic_server_cli/prototypes/manager/system/genai/create_db_models_inserts/create_db_models_prefix_iteration.py,sha256=_rQsqDG2ieNxSsv28t7f9Z5Bs6IMASl8rVunVZIHyUk,301
|
|
1196
1197
|
api_logic_server_cli/prototypes/manager/system/genai/create_db_models_inserts/create_db_models_test_data.py,sha256=DjLhbtFD_qYIQhCuWFg89i0tO4N4yBQFsu-f1AHLv6Q,235
|
|
@@ -6231,7 +6232,7 @@ api_logic_server_cli/templates/index.html,sha256=HYocUaiHm0haVHGM5PqHBNyCdyYWCAU
|
|
|
6231
6232
|
api_logic_server_cli/templates/login_endpoint.txt,sha256=dB9dMnWiFB4Sd_XchZkj3sS6rhNS1Cs1bqDS-PXCeEo,900
|
|
6232
6233
|
api_logic_server_cli/templates/login_endpoint_imports.txt,sha256=0Bx5LUaLtQmNk97silIg2EPO3HeEZYP6laVmtyHlbdE,205
|
|
6233
6234
|
api_logic_server_cli/templates/opt_locking.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6234
|
-
api_logic_server_cli/tools/mini_skel/run.py,sha256=
|
|
6235
|
+
api_logic_server_cli/tools/mini_skel/run.py,sha256=4sl6RzaOkUCzm44K2vMKHQ_isvuVpEymOkfg5mb1o2I,1641
|
|
6235
6236
|
api_logic_server_cli/tools/mini_skel/database/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6236
6237
|
api_logic_server_cli/tools/mini_skel/database/bind_dbs.py,sha256=dCCIYRu-_K44IeAqxEXWoSsjxRB1N6JRg3DTY6GnaIw,677
|
|
6237
6238
|
api_logic_server_cli/tools/mini_skel/database/customize_models.py,sha256=FAkJqu_e1tFsc92-ocXdGxGWNpfeWDg8D-vEAPlxTYI,581
|
|
@@ -6241,9 +6242,9 @@ api_logic_server_cli/tools/mini_skel/database/system/SAFRSBaseX.py,sha256=p8C7AF
|
|
|
6241
6242
|
api_logic_server_cli/tools/mini_skel/database/system/TestDataBase.py,sha256=U02SYqThsbY5g3DX7XGaiMxjZBuOpzvtPS6RfI1WQFg,371
|
|
6242
6243
|
api_logic_server_cli/tools/mini_skel/logic/declare_logic.py,sha256=fTrlHyqMeZsw_TyEXFa1VlYBL7fzjZab5ONSXO7aApo,175
|
|
6243
6244
|
api_logic_server_cli/tools/mini_skel/logic/load_verify_rules.py,sha256=wzOjExm3hU_AW5D2hw0lUgAzCQd__2TrW5rM9LiBoOA,7543
|
|
6244
|
-
ApiLogicServer-14.2.
|
|
6245
|
-
ApiLogicServer-14.2.
|
|
6246
|
-
ApiLogicServer-14.2.
|
|
6247
|
-
ApiLogicServer-14.2.
|
|
6248
|
-
ApiLogicServer-14.2.
|
|
6249
|
-
ApiLogicServer-14.2.
|
|
6245
|
+
ApiLogicServer-14.2.20.dist-info/LICENSE,sha256=67BS7VC-Z8GpaR3wijngQJkHWV04qJrwQArVgn9ldoI,1485
|
|
6246
|
+
ApiLogicServer-14.2.20.dist-info/METADATA,sha256=rxchTqUMrTJ9I6AUsdVzWhMIfszd87v5zm8KnWsstPI,6447
|
|
6247
|
+
ApiLogicServer-14.2.20.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
6248
|
+
ApiLogicServer-14.2.20.dist-info/entry_points.txt,sha256=KiLloZJ3c_RW-nIDqBtoE0WEsQTnZ3dELwHLWi23LMA,103
|
|
6249
|
+
ApiLogicServer-14.2.20.dist-info/top_level.txt,sha256=-r0AT_GEApleihg-jIh0OMvzzc0BO1RuhhOpE91H5qI,21
|
|
6250
|
+
ApiLogicServer-14.2.20.dist-info/RECORD,,
|
|
@@ -12,10 +12,10 @@ ApiLogicServer CLI: given a database url, create [and run] customizable ApiLogic
|
|
|
12
12
|
Called from api_logic_server_cli.py, by instantiating the ProjectRun object.
|
|
13
13
|
'''
|
|
14
14
|
|
|
15
|
-
__version__ = "14.02.
|
|
15
|
+
__version__ = "14.02.20"
|
|
16
16
|
recent_changes = \
|
|
17
17
|
f'\n\nRecent Changes:\n' +\
|
|
18
|
-
"\t01/
|
|
18
|
+
"\t01/17/2024 - 14.02.20: WebGenAI support, genai_demo \n"\
|
|
19
19
|
"\t01/06/2024 - 14.01.00: N8N, Rebuild test data, Fixup, Project Import, Improved reporting of missing attributes, Simplified RowDictMaper \n"\
|
|
20
20
|
"\t11/18/2024 - 12.02.00: genai: 'qualified any' now supported in logic training \n"\
|
|
21
21
|
"\t10/31/2024 - 12.01.00: genai: informal rules (eg, Sum of employee salaries cannot exceed department budget) \n"\
|
|
@@ -296,7 +296,7 @@ def create_project_and_overlay_prototypes(project: 'ProjectRun', msg: str) -> st
|
|
|
296
296
|
|
|
297
297
|
from_dir = project.from_git
|
|
298
298
|
api_logic_server_dir_str = str(get_api_logic_server_dir()) # todo not req'd
|
|
299
|
-
if project.from_git.startswith("https://"):
|
|
299
|
+
if project.from_git.startswith("https://"): # warning - very old code, not tested in a long time
|
|
300
300
|
cmd = 'git clone --quiet https://github.com/valhuber/ApiLogicServerProto.git ' + project.project_directory
|
|
301
301
|
cmd = f'git clone --quiet {project.from_gitfrom_git} {project.project_directory}'
|
|
302
302
|
result = create_utils.run_command(cmd, msg=msg) # "2. Create Project")
|
|
@@ -409,8 +409,15 @@ def create_project_and_overlay_prototypes(project: 'ProjectRun', msg: str) -> st
|
|
|
409
409
|
if project.db_url == 'sqlite:///sample_ai.sqlite': # work-around - VSCode run config arg parsing (dbviz STRESS)
|
|
410
410
|
create_utils.copy_md(project = project, from_doc_file = "Sample-AI.md", to_project_file='Sample-AI.md')
|
|
411
411
|
|
|
412
|
-
if project.
|
|
413
|
-
|
|
412
|
+
if project.is_genai_demo: # overwrite logic & db, add readme
|
|
413
|
+
genai_demo_dir = (Path(api_logic_server_dir_str)).joinpath('prototypes/genai_demo')
|
|
414
|
+
# recursive_overwrite(genai_demo_dir, project.project_directory)
|
|
415
|
+
# log.info('.. ..Copy in genai_demo customizations')
|
|
416
|
+
# exit(1)
|
|
417
|
+
# readme now opens automatically, so use that...
|
|
418
|
+
shutil.move(project.project_directory_path.joinpath('readme.md'),
|
|
419
|
+
project.project_directory_path.joinpath('readme_standard.md'))
|
|
420
|
+
create_utils.copy_md(project = project, from_doc_file = "Sample-Genai.md", to_project_file='readme.md')
|
|
414
421
|
|
|
415
422
|
if "postgres" or "mysql" in project.db_url:
|
|
416
423
|
fixup_devops_for_postgres_mysql(project)
|
|
@@ -464,12 +471,14 @@ def create_project_and_overlay_prototypes(project: 'ProjectRun', msg: str) -> st
|
|
|
464
471
|
# strip sqlite://// from sqlite:////Users/val/dev/ApiLogicServer/api_logic_server_cli/database/nw-gold.sqlite
|
|
465
472
|
db_loc = project.abs_db_url.replace("sqlite:///", "")
|
|
466
473
|
target_db_loc_actual = str(project.project_directory_path.joinpath('database/db.sqlite'))
|
|
467
|
-
|
|
474
|
+
if True: # project.is_genai_demo == False: genai_demo using db from genai, not prototypes
|
|
475
|
+
copyfile(db_loc, target_db_loc_actual)
|
|
468
476
|
config_url = str(project.api_logic_server_dir_path)
|
|
469
477
|
# build this: SQLALCHEMY_DATABASE_URI = sqlite:///{str(project_abs_dir.joinpath('database/db.sqlite'))}
|
|
470
478
|
# into this: SQLALCHEMY_DATABASE_URI = f"replace_db_url"
|
|
471
479
|
replace_db_url_value = "sqlite:///{str(project_abs_dir.joinpath('database/db.sqlite'))}"
|
|
472
480
|
replace_db_url_value = f"sqlite:///../database/db.sqlite" # relative for portable sqlite
|
|
481
|
+
replace_db_url_value = "sqlite:///{db_path}"
|
|
473
482
|
|
|
474
483
|
if os.name == "nt": # windows
|
|
475
484
|
target_db_loc_actual = get_windows_path_with_slashes(target_db_loc_actual)
|
|
@@ -1123,7 +1132,7 @@ class ProjectRun(Project):
|
|
|
1123
1132
|
"""
|
|
1124
1133
|
|
|
1125
1134
|
imports = """
|
|
1126
|
-
#
|
|
1135
|
+
# TODO remove from api import <project.bind_key>_expose_api_models
|
|
1127
1136
|
from database import <project.bind_key>_models
|
|
1128
1137
|
"""
|
|
1129
1138
|
|
|
@@ -1538,7 +1547,26 @@ from database import <project.bind_key>_models
|
|
|
1538
1547
|
def add_genai_customizations(self, do_show_messages: bool = True, do_security: bool = True):
|
|
1539
1548
|
""" Add customizations to genai (default creation)
|
|
1540
1549
|
|
|
1541
|
-
|
|
1550
|
+
0. Initial: create_project_and_overlay_prototypes() -- minor: just creates the readme
|
|
1551
|
+
* When done with genai logic prompt, logic is pre-created (in logic/declare_logic.py)
|
|
1552
|
+
1. Deep copy prototypes/genai_demo (adds logic and security, and custom end point)
|
|
1553
|
+
|
|
1554
|
+
WebGenAI DX:
|
|
1555
|
+
|
|
1556
|
+
0. Convention: click the Blue Button
|
|
1557
|
+
* Home/Create Project
|
|
1558
|
+
* Home/Open App
|
|
1559
|
+
* Landing
|
|
1560
|
+
* Overview[Manager]/Open
|
|
1561
|
+
* Overview/GitHub
|
|
1562
|
+
* App Home / Develop --> GitHub
|
|
1563
|
+
0. demo --> codespaces. Where are instructions (what is CS, how do I load/run)?
|
|
1564
|
+
1. Name can be any, iff created with APILOGICPROJECT_IS_GENAI_DEMO
|
|
1565
|
+
2. Bypass duplicate discovery logic iff created with APILOGICPROJECT_IS_GENAI_DEMO
|
|
1566
|
+
3. TODO:
|
|
1567
|
+
* cd project
|
|
1568
|
+
* als add-cust # add customizations
|
|
1569
|
+
* run, and use place b2b order service - end point is not activated.
|
|
1542
1570
|
|
|
1543
1571
|
Args:
|
|
1544
1572
|
"""
|
|
@@ -1713,7 +1741,7 @@ from database import <project.bind_key>_models
|
|
|
1713
1741
|
log.info(".. complete\n")
|
|
1714
1742
|
|
|
1715
1743
|
|
|
1716
|
-
def genai_get_logic(self, prompt: str) -> list[str]: #
|
|
1744
|
+
def genai_get_logic(self, prompt: str) -> list[str]: # TODO drop old code
|
|
1717
1745
|
""" Get logic from ChatGPT prompt
|
|
1718
1746
|
Args:
|
|
1719
1747
|
"""
|
|
@@ -1838,12 +1866,18 @@ from database import <project.bind_key>_models
|
|
|
1838
1866
|
|
|
1839
1867
|
def create_database_from_genai_or_model(self) -> 'GenAI':
|
|
1840
1868
|
gen_ai = None
|
|
1869
|
+
|
|
1870
|
+
self.is_genai_demo = False
|
|
1871
|
+
if os.getenv('APILOGICPROJECT_IS_GENAI_DEMO') is not None or self.project_name == 'genai_demo':
|
|
1872
|
+
self.is_genai_demo = True
|
|
1873
|
+
|
|
1874
|
+
|
|
1841
1875
|
if self.genai_using != "":
|
|
1842
1876
|
from api_logic_server_cli.genai.genai import GenAI
|
|
1843
1877
|
gen_ai = GenAI(self)
|
|
1844
1878
|
gen_ai.create_db_models() # create_db_models.py used to create database to build project
|
|
1845
1879
|
|
|
1846
|
-
if self.from_model != "" or self.genai_using != "":
|
|
1880
|
+
if (self.from_model != "" or self.genai_using != ""): # and not self.is_genai_demo: # use create_db_from_model.py
|
|
1847
1881
|
try:
|
|
1848
1882
|
create_db_from_model.create_db(self)
|
|
1849
1883
|
# halt execution if genai already discovered errors, eg, response contains table definitions
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
last_created_date: January
|
|
2
|
-
last_created_project_name:
|
|
3
|
-
last_created_version: 14.02.
|
|
1
|
+
last_created_date: January 16, 2025 20:48:28
|
|
2
|
+
last_created_project_name: genai_demo_informal
|
|
3
|
+
last_created_version: 14.02.11
|
api_logic_server_cli/cli.py
CHANGED
|
@@ -563,8 +563,7 @@ def tutorial(ctx, create):
|
|
|
563
563
|
@main.command("genai", cls=HideDunderCommand)
|
|
564
564
|
@click.option('--using',
|
|
565
565
|
default=f'genai_demo',
|
|
566
|
-
|
|
567
|
-
help="File or dir (determines project name)")
|
|
566
|
+
help="File or dir of prompt")
|
|
568
567
|
@click.option('--db-url', 'db_url',
|
|
569
568
|
default=f'sqlite',
|
|
570
569
|
help="SQLAlchemy Database URL\n")
|
|
@@ -614,6 +613,9 @@ def genai(ctx, using, db_url, repaired_response: str,
|
|
|
614
613
|
"""
|
|
615
614
|
global command
|
|
616
615
|
import api_logic_server_cli.genai.genai as genai_svcs
|
|
616
|
+
if using is None and repaired_response is None:
|
|
617
|
+
log.error("Error - must provide --using or --repaired-response")
|
|
618
|
+
exit(1)
|
|
617
619
|
defaulted_using = using
|
|
618
620
|
if defaulted_using == 'genai_demo': # default to genai_demo.prompt
|
|
619
621
|
defaulted_using = 'system/genai/examples/genai_demo/genai_demo.prompt'
|
|
@@ -1546,12 +1548,16 @@ def add_cust(ctx, bind_key_url_separator: str, api_name: str, project_name: str)
|
|
|
1546
1548
|
log.debug(f"\ncli[add-cust] models_py_path={models_py_path}")
|
|
1547
1549
|
if not models_py_path.exists():
|
|
1548
1550
|
raise Exception("Customizations are northwind/genai-specific - models.py does not exist")
|
|
1551
|
+
|
|
1552
|
+
project_is_genai_demo = False # can't use project.is_genai_demo because this is not the create command...
|
|
1553
|
+
if project.project_directory_path.joinpath('docs/project_is_genai_demo.txt').exists():
|
|
1554
|
+
project_is_genai_demo = True
|
|
1549
1555
|
|
|
1550
1556
|
project.abs_db_url, project.nw_db_status, project.model_file_name = create_utils.get_abs_db_url("0. Using Sample DB", project)
|
|
1551
1557
|
if create_utils.does_file_contain(search_for="CategoryTableNameTest", in_file=models_py_path):
|
|
1552
1558
|
project.add_nw_customizations(do_security=False)
|
|
1553
1559
|
log.info("\nNext step - add authentication:\n $ ApiLogicServer add-auth --db_url=auth\n\n")
|
|
1554
|
-
elif
|
|
1560
|
+
elif project_is_genai_demo and create_utils.does_file_contain(search_for="Customer", in_file=models_py_path):
|
|
1555
1561
|
project.add_genai_customizations(do_security=False)
|
|
1556
1562
|
elif project_name == 'sample_ai' and create_utils.does_file_contain(search_for="CustomerName = Column(Text", in_file=models_py_path):
|
|
1557
1563
|
cocktail_napkin_path = project.project_directory_path.joinpath('logic/cocktail-napkin.jpg')
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from openai import AzureOpenAI
|
|
3
|
+
from openai import OpenAI
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def get_ai_client():
|
|
7
|
+
api_key = os.getenv("APILOGICSERVER_CHATGPT_APIKEY")
|
|
8
|
+
|
|
9
|
+
if not api_key:
|
|
10
|
+
raise Exception("APILOGICSERVER_CHATGPT_APIKEY environment variable not set")
|
|
11
|
+
|
|
12
|
+
azure_endpoint = os.getenv("APILOGICSERVER_CHATGPT_AZURE_ENDPOINT")
|
|
13
|
+
if azure_endpoint:
|
|
14
|
+
api_version = os.getenv("APILOGICSERVER_CHATGPT_AZURE_API_VERSION", "2024-10-21")
|
|
15
|
+
client = AzureOpenAI(
|
|
16
|
+
azure_endpoint = azure_endpoint,
|
|
17
|
+
api_key=api_key,
|
|
18
|
+
api_version=api_version)
|
|
19
|
+
print(f"Using Azure OpenAI, endpoint: {azure_endpoint}, version: {api_version}")
|
|
20
|
+
else:
|
|
21
|
+
client = OpenAI(api_key=api_key)
|
|
22
|
+
|
|
23
|
+
return client
|
|
24
|
+
|
|
@@ -493,19 +493,18 @@ class GenAI(object):
|
|
|
493
493
|
log.debug(f'.. removed hallucination: {each_line}')
|
|
494
494
|
return return_line
|
|
495
495
|
|
|
496
|
-
logic_enabled = True
|
|
497
496
|
logic_file = self.project.project_directory_path.joinpath('logic/declare_logic.py')
|
|
498
|
-
|
|
499
|
-
translated_logic = "\n # Logic from GenAI: (or, use your IDE w/ code completion)\n"
|
|
500
|
-
translated_logic += genai_svcs.get_code(self.response_dict.rules)
|
|
501
|
-
if self.logic_enabled == False:
|
|
497
|
+
if True: # self.project.is_genai_demo == False: translate logic
|
|
502
498
|
translated_logic = "\n # Logic from GenAI: (or, use your IDE w/ code completion)\n"
|
|
503
|
-
translated_logic +=
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
499
|
+
translated_logic += genai_svcs.get_code(self.response_dict.rules)
|
|
500
|
+
if self.logic_enabled == False:
|
|
501
|
+
translated_logic = "\n # Logic from GenAI: (or, use your IDE w/ code completion)\n"
|
|
502
|
+
translated_logic += "\n # LogicBank Disabled \n"
|
|
503
|
+
translated_logic += "\n # End Logic from GenAI\n\n"
|
|
504
|
+
utils.insert_lines_at(lines=translated_logic,
|
|
505
|
+
file_name=logic_file,
|
|
506
|
+
at='discover_logic()',
|
|
507
|
+
after=True)
|
|
509
508
|
|
|
510
509
|
readme_lines = \
|
|
511
510
|
f'\n**GenAI Microservice Automation:** after verifying, apply logic:\n' +\
|
|
@@ -535,12 +534,20 @@ class GenAI(object):
|
|
|
535
534
|
|
|
536
535
|
response_file = self.project.project_directory_path.joinpath("docs/response.json")
|
|
537
536
|
if Path(self.project.genai_using).stem == 'logic_suggestions':
|
|
538
|
-
response_file = self.project.project_directory_path.joinpath("docs/logic_suggestions/response.json")
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
537
|
+
response_file = self.project.project_directory_path.joinpath("docs/logic_suggestions/response.json")
|
|
538
|
+
elif not response_file.exists():
|
|
539
|
+
if Path(self.project.genai_repaired_response).is_file():
|
|
540
|
+
shutil.copyfile(self.project.genai_repaired_response, response_file)
|
|
541
|
+
is_genai_demo = False
|
|
542
|
+
if os.getenv('APILOGICPROJECT_IS_GENAI_DEMO') is not None or self.project.project_name == 'genai_demo':
|
|
543
|
+
self.project.project_directory_path.joinpath('docs/project_is_genai_demo.txt').touch()
|
|
544
|
+
# and DON'T create test data (db.sqlite already set up in recurive copy)
|
|
545
|
+
else: # normal path
|
|
546
|
+
genai_svcs.rebuild_test_data_for_project(
|
|
547
|
+
use_project_path = self.project.project_directory_path,
|
|
548
|
+
project = self.project,
|
|
549
|
+
use_existing_response = True,
|
|
550
|
+
response = response_file)
|
|
544
551
|
|
|
545
552
|
except: # intentional try/catch/bury - it's just docs, so don't fail
|
|
546
553
|
import traceback
|
|
@@ -298,30 +298,13 @@ class GenAILogic(object):
|
|
|
298
298
|
suggest_or_get_code_prompt = get_suggest_or_get_code_prompt()
|
|
299
299
|
self.messages.append({"role": "user", "content": suggest_or_get_code_prompt})
|
|
300
300
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
response_dict = json.loads(response_dict_str)
|
|
309
|
-
else:
|
|
310
|
-
debug_key = os.getenv("APILOGICSERVER_CHATGPT_APIKEY")
|
|
311
|
-
client = OpenAI(api_key=os.getenv("APILOGICSERVER_CHATGPT_APIKEY"))
|
|
312
|
-
model = os.getenv("APILOGICSERVER_CHATGPT_MODEL_SUGGESTION")
|
|
313
|
-
if model is None or model == "*": # system default chatgpt model
|
|
314
|
-
model = "gpt-4o-2024-08-06"
|
|
315
|
-
model = 'gpt-4o-mini' # reduces from 40 -> 7 secs
|
|
316
|
-
# 0 = 'you are', 1 = the classes, 2 = rule training
|
|
317
|
-
# FIXME - use gena0_svcs.call_chatgpt()
|
|
318
|
-
completion = client.beta.chat.completions.parse(
|
|
319
|
-
messages=self.messages, response_format=WGResult,
|
|
320
|
-
model=model # for own model, use "ft:gpt-4o-2024-08-06:personal:logicbank:ARY904vS"
|
|
321
|
-
)
|
|
322
|
-
|
|
323
|
-
data = completion.choices[0].message.content
|
|
324
|
-
response_dict = json.loads(data)
|
|
301
|
+
response_dict_str = call_chatgpt(
|
|
302
|
+
messages=self.messages,
|
|
303
|
+
api_version=self.project.genai_version,
|
|
304
|
+
using=self.project.project_directory_path.joinpath('docs/logic_suggestions')
|
|
305
|
+
)
|
|
306
|
+
response_dict = json.loads(response_dict_str)
|
|
307
|
+
|
|
325
308
|
self.response_dict = DotMap(response_dict)
|
|
326
309
|
|
|
327
310
|
# starting creating files in docs/logic_suggestions, starting with response
|
|
@@ -21,6 +21,8 @@ import ast
|
|
|
21
21
|
import astor
|
|
22
22
|
import yaml
|
|
23
23
|
|
|
24
|
+
from genai.client import get_ai_client
|
|
25
|
+
|
|
24
26
|
K_LogicBankOff = "LBX"
|
|
25
27
|
''' LBX Disable Logic (for demos) '''
|
|
26
28
|
K_LogicBankTraining = "Here is the simplified API for LogicBank"
|
|
@@ -65,7 +67,7 @@ try: # this is just for WebGenAI
|
|
|
65
67
|
# Add the file handler to the logger
|
|
66
68
|
log.addHandler(file_handler)
|
|
67
69
|
log.setLevel(logging.DEBUG)
|
|
68
|
-
|
|
70
|
+
|
|
69
71
|
except Exception as exc:
|
|
70
72
|
pass # this is just for WebGenAI, ok to ignore error
|
|
71
73
|
|
|
@@ -759,11 +761,9 @@ def call_chatgpt(messages: List[Dict[str, str]], api_version: str, using: str) -
|
|
|
759
761
|
using (str): str to save response.json (relative to cwd)
|
|
760
762
|
Returns:
|
|
761
763
|
str: response from ChatGPT
|
|
762
|
-
"""
|
|
764
|
+
"""
|
|
763
765
|
try:
|
|
764
766
|
start_time = time.time()
|
|
765
|
-
db_key = os.getenv("APILOGICSERVER_CHATGPT_APIKEY")
|
|
766
|
-
client = OpenAI(api_key=os.getenv("APILOGICSERVER_CHATGPT_APIKEY"))
|
|
767
767
|
model = api_version
|
|
768
768
|
if model == "": # default from CLI is '', meaning fall back to env variable or system default...
|
|
769
769
|
model = os.getenv("APILOGICSERVER_CHATGPT_MODEL")
|
|
@@ -772,9 +772,10 @@ def call_chatgpt(messages: List[Dict[str, str]], api_version: str, using: str) -
|
|
|
772
772
|
with open(Path(using).joinpath('request.json'), "w") as request_file: # save for debug
|
|
773
773
|
json.dump(messages, request_file, indent=4)
|
|
774
774
|
log.info(f'.. saved request: {using}/request.json')
|
|
775
|
-
|
|
775
|
+
client = get_ai_client()
|
|
776
776
|
completion = client.beta.chat.completions.parse(
|
|
777
|
-
messages=messages,
|
|
777
|
+
messages=messages,
|
|
778
|
+
response_format=WGResult,
|
|
778
779
|
# temperature=self.project.genai_temperature, values .1 and .7 made students / charges fail
|
|
779
780
|
model=model # for own model, use "ft:gpt-4o-2024-08-06:personal:logicbank:ARY904vS"
|
|
780
781
|
)
|
|
@@ -98,7 +98,6 @@ class GenAIUtils:
|
|
|
98
98
|
api_version = f"{self.genai_version}"
|
|
99
99
|
start_time = time.time()
|
|
100
100
|
db_key = os.getenv("APILOGICSERVER_CHATGPT_APIKEY", "")
|
|
101
|
-
client = OpenAI(api_key=db_key)
|
|
102
101
|
model = api_version if api_version else os.getenv("APILOGICSERVER_CHATGPT_MODEL", "gpt-4o-2024-08-06")
|
|
103
102
|
self.resolved_model = model
|
|
104
103
|
|
|
@@ -46,6 +46,7 @@ class OptLocking(ExtendedEnum):
|
|
|
46
46
|
|
|
47
47
|
basedir = path.abspath(path.dirname(__file__))
|
|
48
48
|
load_dotenv(path.join(basedir, "default.env"))
|
|
49
|
+
project_path = Path(__file__).parent.parent
|
|
49
50
|
app_logger = logging.getLogger('api_logic_server_app')
|
|
50
51
|
|
|
51
52
|
def is_docker() -> bool:
|
|
@@ -89,11 +90,10 @@ class Config:
|
|
|
89
90
|
FLASK_APP = environ.get("FLASK_APP")
|
|
90
91
|
FLASK_ENV = environ.get("FLASK_ENV")
|
|
91
92
|
DEBUG = environ.get("DEBUG")
|
|
92
|
-
|
|
93
|
-
running_at = Path(__file__)
|
|
94
|
-
project_abs_dir = running_at.parent.absolute()
|
|
93
|
+
|
|
95
94
|
|
|
96
95
|
# Database
|
|
96
|
+
db_path = str(project_path.joinpath('database/db.sqlite'))
|
|
97
97
|
SQLALCHEMY_DATABASE_URI : typing.Optional[str] = f"replace_db_url"
|
|
98
98
|
# override SQLALCHEMY_DATABASE_URI here as required
|
|
99
99
|
|
|
@@ -143,9 +143,8 @@ class Config:
|
|
|
143
143
|
app_logger.info(f'config.py - security disabled')
|
|
144
144
|
|
|
145
145
|
# Begin Multi-Database URLs (from ApiLogicServer add-db...)
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
SQLALCHEMY_DATABASE_URI_AUTHENTICATION = 'sqlite:///../database/authentication_db.sqlite'
|
|
146
|
+
auth_db_path = str(project_path.joinpath('database/authentication_db.sqlite'))
|
|
147
|
+
SQLALCHEMY_DATABASE_URI_AUTHENTICATION = f'sqlite:///{auth_db_path}'
|
|
149
148
|
app_logger.info(f'config.py - SQLALCHEMY_DATABASE_URI_AUTHENTICATION: {SQLALCHEMY_DATABASE_URI_AUTHENTICATION}\n')
|
|
150
149
|
|
|
151
150
|
# as desired, use env variable: export SQLALCHEMY_DATABASE_URI='sqlite:////Users/val/dev/servers/docker_api_logic_project/database/db.sqliteXX'
|
|
@@ -153,6 +152,11 @@ class Config:
|
|
|
153
152
|
SQLALCHEMY_DATABASE_URI_AUTHENTICATION = os.getenv('SQLALCHEMY_DATABASE_URI_AUTHENTICATION') # type: ignore # type: str
|
|
154
153
|
app_logger.debug(f'.. overridden from env variable: SQLALCHEMY_DATABASE_URI_AUTHENTICATION')
|
|
155
154
|
|
|
155
|
+
# Single Page App (SPA) Landing Page Database
|
|
156
|
+
landing_db_path = project_path.joinpath('database/db_spa.sqlite')
|
|
157
|
+
SQLALCHEMY_DATABASE_URI_LANDING = f'sqlite:///{landing_db_path}'
|
|
158
|
+
if landing_db_path.exists():
|
|
159
|
+
app_logger.info(f'config.py - SQLALCHEMY_DATABASE_URI_LANDING: {SQLALCHEMY_DATABASE_URI_LANDING}\n')
|
|
156
160
|
|
|
157
161
|
# End Multi-Database URLs (from ApiLogicServer add-db...)
|
|
158
162
|
|
|
@@ -14,7 +14,8 @@ def bind_dbs(flask_app):
|
|
|
14
14
|
""" called by api_logic_server_run to open/bind each additional database"""
|
|
15
15
|
|
|
16
16
|
flask_app.config.update(SQLALCHEMY_BINDS = {
|
|
17
|
-
|
|
17
|
+
'authentication': flask_app.config['SQLALCHEMY_DATABASE_URI_AUTHENTICATION'],
|
|
18
|
+
'landing_page' : flask_app.config['SQLALCHEMY_DATABASE_URI_LANDING'],
|
|
18
19
|
}) # make multiple databases available to SQLAlchemy
|
|
19
20
|
|
|
20
21
|
return
|
|
@@ -22,5 +22,22 @@ def discover_logic():
|
|
|
22
22
|
each_logic_file = importlib.util.module_from_spec(spec)
|
|
23
23
|
spec.loader.exec_module(each_logic_file) # runs "bare" module code (e.g., initialization)
|
|
24
24
|
each_logic_file.declare_logic() # invoke create function
|
|
25
|
+
|
|
26
|
+
if False and Path(__file__).parent.parent.parent.joinpath("docs/project_is_genai_demo.txt").exists():
|
|
27
|
+
return # for genai_demo, logic is in logic/declare_logic.py (so ignore logic_discovery)
|
|
28
|
+
|
|
29
|
+
wg_logic_path = Path(__file__).parent.parent.joinpath("wg_rules")
|
|
30
|
+
for root, dirs, files in os.walk(wg_logic_path):
|
|
31
|
+
for file in files:
|
|
32
|
+
if file.endswith(".py"):
|
|
33
|
+
spec = importlib.util.spec_from_file_location("module.name", wg_logic_path.joinpath(file))
|
|
34
|
+
if file.endswith("auto_discovery.py"):
|
|
35
|
+
pass
|
|
36
|
+
else:
|
|
37
|
+
logic.append(file)
|
|
38
|
+
each_logic_file = importlib.util.module_from_spec(spec)
|
|
39
|
+
spec.loader.exec_module(each_logic_file) # runs "bare" module code (e.g., initialization)
|
|
40
|
+
each_logic_file.init_rule() # invoke create function
|
|
41
|
+
|
|
25
42
|
app_logger.info(f"..discovered logic: {logic}")
|
|
26
43
|
return
|
|
@@ -16,9 +16,9 @@ from sqlalchemy.ext.declarative import declarative_base
|
|
|
16
16
|
# mypy: ignore-errors
|
|
17
17
|
########################################################################################################################
|
|
18
18
|
|
|
19
|
-
from
|
|
19
|
+
from database.system.SAFRSBaseX import SAFRSBaseX, TestBase
|
|
20
20
|
from flask_login import UserMixin
|
|
21
|
-
import safrs, flask_sqlalchemy
|
|
21
|
+
import safrs, flask_sqlalchemy, os
|
|
22
22
|
from safrs import jsonapi_attr
|
|
23
23
|
from flask_sqlalchemy import SQLAlchemy
|
|
24
24
|
from sqlalchemy.orm import relationship
|
|
@@ -35,12 +35,16 @@ metadata = Base.metadata
|
|
|
35
35
|
|
|
36
36
|
from sqlalchemy.dialects.sqlite import *
|
|
37
37
|
|
|
38
|
+
if os.getenv('APILOGICPROJECT_NO_FLASK') is None or os.getenv('APILOGICPROJECT_NO_FLASK') == 'None':
|
|
39
|
+
Base = SAFRSBaseX # enables rules to be used outside of Flask, e.g., test data loading
|
|
40
|
+
else:
|
|
41
|
+
Base = TestBase # ensure proper types, so rules work for data loading
|
|
42
|
+
print('*** Models.py Using TestBase ***')
|
|
38
43
|
|
|
39
44
|
|
|
40
|
-
class Customer(
|
|
45
|
+
class Customer(Base):
|
|
41
46
|
__tablename__ = 'Customers'
|
|
42
47
|
_s_collection_name = 'Customer' # type: ignore
|
|
43
|
-
__bind_key__ = 'None'
|
|
44
48
|
|
|
45
49
|
CustomerID = Column(Integer, primary_key=True)
|
|
46
50
|
CustomerName = Column(Text, nullable=False)
|
|
@@ -54,23 +58,10 @@ class Customer(SAFRSBase, Base):
|
|
|
54
58
|
# child relationships (access children)
|
|
55
59
|
OrderList : Mapped[List["Order"]] = relationship(back_populates="Customer")
|
|
56
60
|
|
|
57
|
-
@jsonapi_attr
|
|
58
|
-
def _check_sum_(self): # type: ignore [no-redef]
|
|
59
|
-
return None if isinstance(self, flask_sqlalchemy.model.DefaultMeta) \
|
|
60
|
-
else self._check_sum_property if hasattr(self,"_check_sum_property") \
|
|
61
|
-
else None # property does not exist during initialization
|
|
62
61
|
|
|
63
|
-
|
|
64
|
-
def _check_sum_(self, value): # type: ignore [no-redef]
|
|
65
|
-
self._check_sum_property = value
|
|
66
|
-
|
|
67
|
-
S_CheckSum = _check_sum_
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
class Product(SAFRSBase, Base):
|
|
62
|
+
class Product(Base):
|
|
71
63
|
__tablename__ = 'Products'
|
|
72
64
|
_s_collection_name = 'Product' # type: ignore
|
|
73
|
-
__bind_key__ = 'None'
|
|
74
65
|
|
|
75
66
|
ProductID = Column(Integer, primary_key=True)
|
|
76
67
|
ProductName = Column(Text, nullable=False)
|
|
@@ -82,23 +73,11 @@ class Product(SAFRSBase, Base):
|
|
|
82
73
|
# child relationships (access children)
|
|
83
74
|
ItemList : Mapped[List["Item"]] = relationship(back_populates="Product")
|
|
84
75
|
|
|
85
|
-
@jsonapi_attr
|
|
86
|
-
def _check_sum_(self): # type: ignore [no-redef]
|
|
87
|
-
return None if isinstance(self, flask_sqlalchemy.model.DefaultMeta) \
|
|
88
|
-
else self._check_sum_property if hasattr(self,"_check_sum_property") \
|
|
89
|
-
else None # property does not exist during initialization
|
|
90
|
-
|
|
91
|
-
@_check_sum_.setter
|
|
92
|
-
def _check_sum_(self, value): # type: ignore [no-redef]
|
|
93
|
-
self._check_sum_property = value
|
|
94
|
-
|
|
95
|
-
S_CheckSum = _check_sum_
|
|
96
76
|
|
|
97
77
|
|
|
98
|
-
class Order(
|
|
78
|
+
class Order(Base):
|
|
99
79
|
__tablename__ = 'Orders'
|
|
100
80
|
_s_collection_name = 'Order' # type: ignore
|
|
101
|
-
__bind_key__ = 'None'
|
|
102
81
|
|
|
103
82
|
OrderID = Column(Integer, primary_key=True)
|
|
104
83
|
CustomerID = Column(ForeignKey('Customers.CustomerID'))
|
|
@@ -113,23 +92,11 @@ class Order(SAFRSBase, Base):
|
|
|
113
92
|
# child relationships (access children)
|
|
114
93
|
ItemList : Mapped[List["Item"]] = relationship(back_populates="Order")
|
|
115
94
|
|
|
116
|
-
@jsonapi_attr
|
|
117
|
-
def _check_sum_(self): # type: ignore [no-redef]
|
|
118
|
-
return None if isinstance(self, flask_sqlalchemy.model.DefaultMeta) \
|
|
119
|
-
else self._check_sum_property if hasattr(self,"_check_sum_property") \
|
|
120
|
-
else None # property does not exist during initialization
|
|
121
95
|
|
|
122
|
-
@_check_sum_.setter
|
|
123
|
-
def _check_sum_(self, value): # type: ignore [no-redef]
|
|
124
|
-
self._check_sum_property = value
|
|
125
96
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
class Item(SAFRSBase, Base):
|
|
97
|
+
class Item(Base):
|
|
130
98
|
__tablename__ = 'Items'
|
|
131
99
|
_s_collection_name = 'Item' # type: ignore
|
|
132
|
-
__bind_key__ = 'None'
|
|
133
100
|
|
|
134
101
|
ItemID = Column(Integer, primary_key=True)
|
|
135
102
|
OrderID = Column(ForeignKey('Orders.OrderID'))
|
|
@@ -144,14 +111,3 @@ class Item(SAFRSBase, Base):
|
|
|
144
111
|
|
|
145
112
|
# child relationships (access children)
|
|
146
113
|
|
|
147
|
-
@jsonapi_attr
|
|
148
|
-
def _check_sum_(self): # type: ignore [no-redef]
|
|
149
|
-
return None if isinstance(self, flask_sqlalchemy.model.DefaultMeta) \
|
|
150
|
-
else self._check_sum_property if hasattr(self,"_check_sum_property") \
|
|
151
|
-
else None # property does not exist during initialization
|
|
152
|
-
|
|
153
|
-
@_check_sum_.setter
|
|
154
|
-
def _check_sum_(self, value): # type: ignore [no-redef]
|
|
155
|
-
self._check_sum_property = value
|
|
156
|
-
|
|
157
|
-
S_CheckSum = _check_sum_
|
|
@@ -47,7 +47,7 @@ def declare_logic():
|
|
|
47
47
|
Rule.copy(derive=Item.UnitPrice, from_parent=Product.UnitPrice)
|
|
48
48
|
Rule.constraint(validate=Customer,
|
|
49
49
|
as_condition=lambda row: row.Balance <= row.CreditLimit,
|
|
50
|
-
error_msg="Customer balance ({row.
|
|
50
|
+
error_msg="Customer balance ({row.Balance}) exceeds credit limit ({row.CreditLimit})")
|
|
51
51
|
|
|
52
52
|
# End Logic from GenAI
|
|
53
53
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"version": "0.2.0",
|
|
6
6
|
"configurations": [
|
|
7
7
|
{
|
|
8
|
-
"name": "1. GENAI - Create
|
|
8
|
+
"name": "1. GENAI - Create genai_logic demo project",
|
|
9
9
|
"type": "debugpy",
|
|
10
10
|
"request": "launch",
|
|
11
11
|
"program": "${workspaceFolder}/venv/lib/python3.12/site-packages/api_logic_server_cli/cli.py",
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
"APILOGICSERVER_DEBUG": "False",
|
|
19
19
|
"OPT_LOCKING": "optional"},
|
|
20
20
|
"justMyCode": false,
|
|
21
|
-
"args": [ "genai", "--retries=-1",
|
|
22
|
-
"--using=${workspaceFolder}/system/genai/examples
|
|
21
|
+
"args": [ "genai", "--retries=-1", "--project-name=genai_demo",
|
|
22
|
+
"--using=${workspaceFolder}/system/genai/examples/genai_demo/genai_demo_informal.prompt"],
|
|
23
23
|
"console": "internalConsole",
|
|
24
24
|
"internalConsoleOptions": "openOnSessionStart"
|
|
25
25
|
},
|
|
@@ -101,7 +101,7 @@ Then, try your own databases [(db-url examples here)](https://apilogicserver.git
|
|
|
101
101
|
1. If you have signed up, this will create and open a project called `genai_demo` from `genai_demo.prompt` (available in left Explorer pane):
|
|
102
102
|
|
|
103
103
|
```bash
|
|
104
|
-
als genai --using=system/genai/examples/genai_demo/genai_demo.prompt
|
|
104
|
+
als genai --using=system/genai/examples/genai_demo/genai_demo.prompt --project-name=genai_demo
|
|
105
105
|
```
|
|
106
106
|
|
|
107
107
|
|
|
@@ -109,7 +109,7 @@ als genai --using=system/genai/examples/genai_demo/genai_demo.prompt
|
|
|
109
109
|
|
|
110
110
|
|
|
111
111
|
```bash
|
|
112
|
-
als genai --
|
|
112
|
+
als genai --repaired-response=system/genai/examples/genai_demo/genai_demo_iteration/005_create_db_models.response-example --project-name=genai_demo
|
|
113
113
|
```
|
|
114
114
|
|
|
115
115
|
Verify it's operating properly:
|
|
@@ -140,7 +140,7 @@ Verify it's operating properly:
|
|
|
140
140
|
|
|
141
141
|
2. Your created project is opened in your IDE, ready to execute and customize.
|
|
142
142
|
|
|
143
|
-
a. Review `
|
|
143
|
+
a. Review `Tutorial.md`, Explore Customizations.
|
|
144
144
|
|
|
145
145
|

|
|
146
146
|
|
|
@@ -274,7 +274,7 @@ After starting the [Manager](https://apilogicserver.github.io/Docs/Manager):
|
|
|
274
274
|
|
|
275
275
|
```bash title="0. Create Project Requiring Fixup"
|
|
276
276
|
# 0. Create a project requiring fixup
|
|
277
|
-
als genai --
|
|
277
|
+
als genai --repaired-response=system/genai/examples/genai_demo/genai_demo_fixup_required.json --project-name=genai_demo_fixup_required
|
|
278
278
|
```
|
|
279
279
|
|
|
280
280
|
If you run this project, you will observe that it fails with:
|
|
@@ -298,7 +298,7 @@ Finally, use the created [fixup files](genai_demo_fixup_required/docs/fixup/) to
|
|
|
298
298
|
```bash title="2. Rebuild the project from the fixup response data model"
|
|
299
299
|
# 2. Rebuild the project from the fixup response data model
|
|
300
300
|
cd ../
|
|
301
|
-
als genai --
|
|
301
|
+
als genai --repaired-response=genai_demo_fixup_required/docs/fixup/response_fixup.json --project-name=fixed_project
|
|
302
302
|
```
|
|
303
303
|
|
|
304
304
|
|
|
@@ -390,7 +390,7 @@ als create --project-name=genai_demo --from-model=system/genai/temp/create_db_mo
|
|
|
390
390
|
Or, correct the chatgpt response, and
|
|
391
391
|
|
|
392
392
|
```bash
|
|
393
|
-
als genai --
|
|
393
|
+
als genai --repaired-response=system/genai/examples/genai_demo/genai_demo.response_example --project-name=genai_demo
|
|
394
394
|
```
|
|
395
395
|
|
|
396
396
|
We have seen failures such as:
|
|
@@ -583,7 +583,7 @@ als genai --using=system/genai/examples/genai_demo/genai_demo.prompt
|
|
|
583
583
|
|
|
584
584
|
# Or, Microservice Automation from Saved Response
|
|
585
585
|
# Admin App, API, Project
|
|
586
|
-
als genai --
|
|
586
|
+
als genai --repaired-response=system/genai/temp/chatgpt_retry.response
|
|
587
587
|
|
|
588
588
|
# Logic and Security
|
|
589
589
|
# - see logic (logic/declare_logic.py, logic/cocktail-napkin.jpg); add an Order and Item
|
|
@@ -7,6 +7,7 @@ import decimal
|
|
|
7
7
|
import logging
|
|
8
8
|
import sqlalchemy
|
|
9
9
|
from sqlalchemy.sql import func
|
|
10
|
+
from decimal import Decimal
|
|
10
11
|
from logic_bank.logic_bank import Rule
|
|
11
12
|
from sqlalchemy import create_engine, Column, Integer, String, Float, ForeignKey, Date, DateTime, Numeric, Boolean, Text, DECIMAL
|
|
12
13
|
from sqlalchemy.types import *
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|