ApiLogicServer 14.2.2__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.
Files changed (23) hide show
  1. {ApiLogicServer-14.2.2.dist-info → ApiLogicServer-14.2.20.dist-info}/METADATA +1 -1
  2. {ApiLogicServer-14.2.2.dist-info → ApiLogicServer-14.2.20.dist-info}/RECORD +23 -22
  3. api_logic_server_cli/api_logic_server.py +44 -10
  4. api_logic_server_cli/api_logic_server_info.yaml +3 -3
  5. api_logic_server_cli/cli.py +9 -3
  6. api_logic_server_cli/genai/client.py +24 -0
  7. api_logic_server_cli/genai/genai.py +24 -17
  8. api_logic_server_cli/genai/genai_logic_builder.py +7 -24
  9. api_logic_server_cli/genai/genai_svcs.py +7 -6
  10. api_logic_server_cli/genai/genai_utils.py +0 -1
  11. api_logic_server_cli/prototypes/base/config/config.py +10 -6
  12. api_logic_server_cli/prototypes/base/database/bind_dbs.py +2 -1
  13. api_logic_server_cli/prototypes/base/logic/logic_discovery/auto_discovery.py +3 -0
  14. api_logic_server_cli/prototypes/genai_demo/database/models.py +11 -55
  15. api_logic_server_cli/prototypes/genai_demo/logic/declare_logic.py +1 -1
  16. api_logic_server_cli/prototypes/manager/.vscode/launch.json +3 -3
  17. api_logic_server_cli/prototypes/manager/README.md +7 -7
  18. api_logic_server_cli/prototypes/manager/system/genai/create_db_models_inserts/create_db_models_imports.py +1 -0
  19. api_logic_server_cli/tools/mini_skel/run.py +1 -0
  20. {ApiLogicServer-14.2.2.dist-info → ApiLogicServer-14.2.20.dist-info}/LICENSE +0 -0
  21. {ApiLogicServer-14.2.2.dist-info → ApiLogicServer-14.2.20.dist-info}/WHEEL +0 -0
  22. {ApiLogicServer-14.2.2.dist-info → ApiLogicServer-14.2.20.dist-info}/entry_points.txt +0 -0
  23. {ApiLogicServer-14.2.2.dist-info → ApiLogicServer-14.2.20.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: ApiLogicServer
3
- Version: 14.2.2
3
+ Version: 14.2.20
4
4
  Author-email: Val Huber <apilogicserver@gmail.com>
5
5
  License: BSD-3-Clause
6
6
  Project-URL: Homepage, https://apilogicserver.github.io/Docs/
@@ -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=-O4Hr1FEsa5dJ-_8klsv4k3lNGv9xV6HHHoA1QV2ogE,111401
3
- api_logic_server_cli/api_logic_server_info.yaml,sha256=6WuWB58_LIBdDDU_SdjMU_fOhEfz1veP7KFxBtw-0jI,136
4
- api_logic_server_cli/cli.py,sha256=Weke_CaYY1obN8tDwp94ycqE_zkcDmcgnlFKC6NZ1fo,80286
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/genai.py,sha256=N1egCY5PmCSRDIfKZjr4t7JAz6ZJ4NzjtvDqWwlQKcM,57128
471
- api_logic_server_cli/genai/genai_logic_builder.py,sha256=_IC0js0l-RojdOD_qSZPixNmLM7m2FdGdgQvpUqodQY,24150
472
- api_logic_server_cli/genai/genai_svcs.py,sha256=my5ix1wGiSnVVJF67Kc0YZz4rFNXCFcf6MoeHoLcB5s,41326
473
- api_logic_server_cli/genai/genai_utils.py,sha256=gijq_pbT7c7AUU0cZm5_2jMt1WNkxE8ncfV7H44oKJw,17168
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=WhaAtr4y9HgEP1UWjHVUShakDsggNlRW6Wm-2IQKAaI,24783
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=dCCIYRu-_K44IeAqxEXWoSsjxRB1N6JRg3DTY6GnaIw,677
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=GzQ-r0K5zGFeSu7xIQKiMHA-XxLs6pViiogBU6vMwPk,1639
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=oAfzhWi2CpfROWnElsvOka8r51XeFs_OcfSuM3U2ho8,5694
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=nYT7shtoFdycfTAthNao3eO7LPVDMB6leHkLqhddG0k,5056
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=xJ7pQQOdJr9U1zO-wFPgogCJBXvh-pTbgl8M_cSrkEg,20077
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=k-AYfJq3TSAH5cHvS-X2umyFkCjPTGFx88eFEFfSkMg,32502
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=tAfUHNhiWYSgch484sDwLtjIBQPV9-TcgyHvsCB2Dhw,939
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=v37OTWfCWvfAiP9cvTxwe7xBuu3w1X2mNxuL_bAyI6g,1619
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.2.dist-info/LICENSE,sha256=67BS7VC-Z8GpaR3wijngQJkHWV04qJrwQArVgn9ldoI,1485
6245
- ApiLogicServer-14.2.2.dist-info/METADATA,sha256=HLlF8z-ZOaeqpr7S4kxcNl-CWSOd-ZN06Cg66BuHXrA,6446
6246
- ApiLogicServer-14.2.2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
6247
- ApiLogicServer-14.2.2.dist-info/entry_points.txt,sha256=KiLloZJ3c_RW-nIDqBtoE0WEsQTnZ3dELwHLWi23LMA,103
6248
- ApiLogicServer-14.2.2.dist-info/top_level.txt,sha256=-r0AT_GEApleihg-jIh0OMvzzc0BO1RuhhOpE91H5qI,21
6249
- ApiLogicServer-14.2.2.dist-info/RECORD,,
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.02"
15
+ __version__ = "14.02.20"
16
16
  recent_changes = \
17
17
  f'\n\nRecent Changes:\n' +\
18
- "\t01/13/2024 - 14.02.01: webg logic, support for import/merge of WebGenAI projects into Dev projects, rebuilt test data \n"\
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.project_name == 'genai_demo':
413
- create_utils.copy_md(project = project, from_doc_file = "Sample-Genai.md", to_project_file='Sample-Genai.md')
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
- copyfile(db_loc, target_db_loc_actual)
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
- # FIXME remove from api import <project.bind_key>_expose_api_models
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
- 1. Deep copy prototypes/genai_demo (adds logic and security)
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]: # FIXME drop old code
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 13, 2025 20:22:40
2
- last_created_project_name: ../../../servers/ApiLogicProject
3
- last_created_version: 14.02.01
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
@@ -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
- prompt="File or dir (determines project name)",
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 project_name == 'genai_demo' and create_utils.does_file_contain(search_for="Customer", in_file=models_py_path):
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
- in_logic = False
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 += "\n # LogicBank Disabled \n"
504
- translated_logic += "\n # End Logic from GenAI\n\n"
505
- utils.insert_lines_at(lines=translated_logic,
506
- file_name=logic_file,
507
- at='discover_logic()',
508
- after=True)
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
- genai_svcs.rebuild_test_data_for_project(
540
- use_project_path = self.project.project_directory_path,
541
- project = self.project,
542
- use_existing_response = True,
543
- response = response_file)
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
- if use_svs := True:
303
- response_dict_str = call_chatgpt(
304
- messages=self.messages,
305
- api_version=self.project.genai_version,
306
- using=self.project.project_directory_path.joinpath('docs/logic_suggestions')
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
- log.info(f"Svcs log file: /tmp/genai_svcs.log")
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, response_format=WGResult,
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
- 'authentication': flask_app.config['SQLALCHEMY_DATABASE_URI_AUTHENTICATION']
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
@@ -23,6 +23,9 @@ def discover_logic():
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
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
+
26
29
  wg_logic_path = Path(__file__).parent.parent.joinpath("wg_rules")
27
30
  for root, dirs, files in os.walk(wg_logic_path):
28
31
  for file in files:
@@ -16,9 +16,9 @@ from sqlalchemy.ext.declarative import declarative_base
16
16
  # mypy: ignore-errors
17
17
  ########################################################################################################################
18
18
 
19
- from safrs import SAFRSBase
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(SAFRSBase, Base):
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
- @_check_sum_.setter
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(SAFRSBase, Base):
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
- S_CheckSum = _check_sum_
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.balance}) exceeds credit limit ({row.credit_limit})")
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 a project from one of the system/genai/examples",
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/${input:inputGenaiProjectName}"],
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 --using=genai_demo.prompt --repaired-response=system/genai/examples/genai_demo/genai_demo_iteration/005_create_db_models.response-example
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 `Sample-Genai.md`, Explore Customizations.
143
+ a. Review `Tutorial.md`, Explore Customizations.
144
144
 
145
145
  ![GenAI Automation](system/images/genai.png)
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 --using=genai_demo.prompt --repaired-response=system/genai/examples/genai_demo/genai_demo_fixup_required.json --project-name=genai_demo_fixup_required
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 --using=genai_demo.prompt --repaired-response=genai_demo_fixup_required/docs/fixup/response_fixup.json --project-name=fixed_project
301
+ als genai --repaired-response=genai_demo_fixup_required/docs/fixup/response_fixup.json --project-name=fixed_project
302
302
  ```
303
303
 
304
304
  &nbsp;
@@ -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 --using=genai_demo.prompt --repaired-response=system/genai/examples/genai_demo/genai_demo.response_example --project-name=genai_demo
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 --using=genai_demo.prompt --repaired-response=system/genai/temp/chatgpt_retry.response
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 *
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env python
1
2
  """
2
3
  Minimal run script for the API Logic Project
3
4