ApiLogicServer 14.3.25__py3-none-any.whl → 14.5.0__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 (167) hide show
  1. api_logic_server_cli/add_cust/add_cust.py +283 -0
  2. api_logic_server_cli/api_logic_server.py +18 -250
  3. api_logic_server_cli/api_logic_server_info.yaml +3 -3
  4. api_logic_server_cli/cli.py +54 -35
  5. api_logic_server_cli/create_from_model/__pycache__/api_logic_server_utils.cpython-312.pyc +0 -0
  6. api_logic_server_cli/create_from_model/__pycache__/create_db_from_model.cpython-312.pyc +0 -0
  7. api_logic_server_cli/create_from_model/__pycache__/dbml.cpython-312.pyc +0 -0
  8. api_logic_server_cli/create_from_model/__pycache__/ont_build.cpython-312.pyc +0 -0
  9. api_logic_server_cli/create_from_model/__pycache__/ont_create.cpython-312.pyc +0 -0
  10. api_logic_server_cli/create_from_model/api_logic_server_utils.py +47 -0
  11. api_logic_server_cli/create_from_model/create_db_from_model.py +2 -0
  12. api_logic_server_cli/create_from_model/dbml.py +113 -58
  13. api_logic_server_cli/create_from_model/ont_build.py +102 -74
  14. api_logic_server_cli/create_from_model/ont_create.py +7 -6
  15. api_logic_server_cli/create_from_model/safrs-react-admin-npm-build/static/.DS_Store +0 -0
  16. api_logic_server_cli/database/basic_demo.sqlite +0 -0
  17. api_logic_server_cli/database/basic_demo.txt +1 -0
  18. api_logic_server_cli/database/basic_demo_wg.sqlite +0 -0
  19. api_logic_server_cli/database/nw-gold-fix.sql +62 -0
  20. api_logic_server_cli/database/nw-gold.sqlite +0 -0
  21. api_logic_server_cli/{prototypes/manager/webgenai → fragments}/docker-compose.yml +1 -1
  22. api_logic_server_cli/genai/genai.py +42 -11
  23. api_logic_server_cli/genai/genai_graphics.py +252 -38
  24. api_logic_server_cli/genai/genai_svcs.py +20 -12
  25. api_logic_server_cli/manager.py +22 -12
  26. api_logic_server_cli/prototypes/.DS_Store +0 -0
  27. api_logic_server_cli/prototypes/base/.DS_Store +0 -0
  28. api_logic_server_cli/prototypes/base/.vscode/launch.json +22 -2
  29. api_logic_server_cli/prototypes/base/api/expose_api_models.py +3 -1
  30. api_logic_server_cli/prototypes/base/api_logic_server_run.py +5 -2
  31. api_logic_server_cli/prototypes/base/config/activate_logicbank.py +1 -0
  32. api_logic_server_cli/prototypes/base/config/config.py +123 -25
  33. api_logic_server_cli/prototypes/base/config/default.env +7 -1
  34. api_logic_server_cli/prototypes/base/config/logging.yml +1 -0
  35. api_logic_server_cli/prototypes/base/config/server_setup.py +33 -1
  36. api_logic_server_cli/prototypes/base/database/test_data/readme.md +5 -2
  37. api_logic_server_cli/prototypes/base/devops/docker-standard-image/docker-compose-standard-image.yml +7 -2
  38. api_logic_server_cli/prototypes/base/docs/training/logic_bank_api.prompt +314 -0
  39. api_logic_server_cli/prototypes/base/docs/training/logic_example.py +41 -0
  40. api_logic_server_cli/prototypes/base/integration/kafka/kafka_producer.py +12 -5
  41. api_logic_server_cli/prototypes/base/integration/n8n/n8n_producer.py +68 -21
  42. api_logic_server_cli/prototypes/base/integration/n8n/n8n_readme.md +19 -0
  43. api_logic_server_cli/prototypes/base/integration/system/FlaskKafka.py +5 -1
  44. api_logic_server_cli/prototypes/base/test/basic/server_test.py +1 -1
  45. api_logic_server_cli/prototypes/base/ui/templates/bar_chart.jinja +64 -0
  46. api_logic_server_cli/prototypes/basic_demo/README.md +29 -52
  47. api_logic_server_cli/prototypes/basic_demo/customizations/api/.DS_Store +0 -0
  48. api_logic_server_cli/prototypes/basic_demo/customizations/api/api_discovery/mcp_server_executor.py +138 -0
  49. api_logic_server_cli/prototypes/basic_demo/customizations/api/api_discovery/openapi.py +92 -0
  50. api_logic_server_cli/prototypes/basic_demo/customizations/api/api_discovery/proper_update_def.json +71 -0
  51. api_logic_server_cli/prototypes/basic_demo/customizations/config/default.env +13 -0
  52. api_logic_server_cli/prototypes/basic_demo/customizations/database/db.sqlite +0 -0
  53. api_logic_server_cli/prototypes/basic_demo/customizations/database/models.py +131 -0
  54. api_logic_server_cli/prototypes/basic_demo/customizations/integration/.DS_Store +0 -0
  55. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/.DS_Store +0 -0
  56. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/1_langchain_loader.py +71 -0
  57. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/2_gpt_mcp_prompt.txt +19 -0
  58. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/README_mcp.md +13 -0
  59. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/mcp_client_executor.py +295 -0
  60. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/mcp_schema.txt +47 -0
  61. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/mcp_server_discovery.json +9 -0
  62. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/multi_mcp_flow/multi_mcp_flow.png +0 -0
  63. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/multi_mcp_flow/multi_mcp_orchestration.yaml +49 -0
  64. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/multi_mcp_flow/wny mcp flows.png +0 -0
  65. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/natlang_to_api.py +73 -0
  66. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/curl.txt +5 -0
  67. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/images/MCP Overview.png +0 -0
  68. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/images/MCP_Arch.png +0 -0
  69. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/images/MCP_Overview_Executor.png +0 -0
  70. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/invoke_llm/1 - prompt_messages_array.json +10 -0
  71. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/invoke_llm/2 - completion_tool_context.json +12 -0
  72. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/llm_schema.txt +38 -0
  73. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/nw_swagger_2.yaml +17393 -0
  74. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/nw_swagger_3.yaml +16660 -0
  75. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/nw_swagger_3_relaxed.yaml +109 -0
  76. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/proxy_server.py +51 -0
  77. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/proxy_serverZ.py +72 -0
  78. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/validate_jsonapi.py +64 -0
  79. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/run_executor.py +23 -0
  80. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/swagger_converter.py +65 -0
  81. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/z_old/3_executor_test_agent.py +52 -0
  82. api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/3_executor_test_agent.py +52 -0
  83. api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/README_functon.md +201 -0
  84. api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/ai_plugin.json +17 -0
  85. api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/nw-swagger_3.json +1731 -0
  86. api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/snippets.txt +5 -0
  87. api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/swagger_3 genai_demo_with_get.json +1731 -0
  88. api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/swagger_3.json +1782 -0
  89. api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/swagger_3_genai_demo.json +264 -0
  90. api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/swagger_3_genai_demo_with_update.json +1782 -0
  91. api_logic_server_cli/prototypes/basic_demo/customizations/logic/declare_logic.py +62 -44
  92. api_logic_server_cli/prototypes/basic_demo/customizations/security/declare_security.py +11 -12
  93. api_logic_server_cli/prototypes/basic_demo/customizations/ui/admin/admin.yaml +166 -0
  94. api_logic_server_cli/prototypes/basic_demo/iteration/api/{customize_api.py → api_discovery/order_b2b.py} +17 -23
  95. api_logic_server_cli/prototypes/basic_demo/iteration/database/db.sqlite +0 -0
  96. api_logic_server_cli/prototypes/basic_demo/iteration/integration/row_dict_maps/OrderB2B.py +6 -5
  97. api_logic_server_cli/prototypes/basic_demo/iteration/integration/row_dict_maps/OrderShipping.py +4 -4
  98. api_logic_server_cli/prototypes/basic_demo/iteration/logic/declare_logic.py +69 -43
  99. api_logic_server_cli/prototypes/basic_demo/iteration/ui/admin/admin.yaml +125 -50
  100. api_logic_server_cli/prototypes/genai_demo/ui/admin/admin.yaml +1 -1
  101. api_logic_server_cli/prototypes/manager/README.md +30 -4
  102. api_logic_server_cli/prototypes/manager/README_X.md +663 -0
  103. api_logic_server_cli/prototypes/manager/system/genai/.DS_Store +0 -0
  104. api_logic_server_cli/prototypes/manager/system/genai/examples/.DS_Store +0 -0
  105. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/.DS_Store +0 -0
  106. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo.prompt +0 -10
  107. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo.response_example +32 -10
  108. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/docs/002_create_db_models.prompt +4 -4
  109. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/docs/003_create_db_models.response +77 -47
  110. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_informal.prompt +1 -1
  111. api_logic_server_cli/prototypes/manager/system/genai/graphics_templates/dashboard_services.jinja +83 -0
  112. api_logic_server_cli/prototypes/manager/system/genai/graphics_templates/graphics_dashboard_WIP.py +34 -0
  113. api_logic_server_cli/prototypes/manager/system/genai/graphics_templates/{graphics_services.py → graphics_services_api_xxx.py} +0 -9
  114. api_logic_server_cli/prototypes/manager/system/genai/graphics_templates/graphics_services_db.jinja +46 -0
  115. api_logic_server_cli/prototypes/manager/system/genai/graphics_templates/graphics_services_db_each_method.jinja +36 -0
  116. api_logic_server_cli/prototypes/manager/system/genai/prompt_inserts/graphics.prompt +7 -3
  117. api_logic_server_cli/prototypes/manager/system/genai/prompt_inserts/response_format.prompt +8 -1
  118. api_logic_server_cli/prototypes/manager/system/install-ApiLogicServer-dev/install-ApiLogicServer-dev.ps1 +100 -0
  119. api_logic_server_cli/prototypes/manager/system/install-ApiLogicServer-dev/install-ApiLogicServer-dev.sh +116 -0
  120. api_logic_server_cli/prototypes/manager/system/install-ApiLogicServer-dev/readme.md +7 -0
  121. api_logic_server_cli/prototypes/manager/system/style-guide.yaml +2 -2
  122. api_logic_server_cli/prototypes/manager/webgenai/README.md +6 -0
  123. api_logic_server_cli/prototypes/nw/docs/graphics/count_orders_by_category.prompt +1 -0
  124. api_logic_server_cli/prototypes/nw/docs/graphics/order_count_by_month.prompt +1 -0
  125. api_logic_server_cli/prototypes/nw/docs/graphics/request copy.json +892 -0
  126. api_logic_server_cli/prototypes/nw/docs/graphics/request.json +6 -0
  127. api_logic_server_cli/prototypes/nw/docs/graphics/response.json +17 -0
  128. api_logic_server_cli/prototypes/nw/docs/graphics/response.yaml +59 -0
  129. api_logic_server_cli/prototypes/nw/docs/graphics/sales_by_category.prompt +1 -0
  130. api_logic_server_cli/prototypes/nw/ui/admin/home.js +5 -4
  131. api_logic_server_cli/prototypes/nw/ui/app_model_custom.yaml +851 -1082
  132. api_logic_server_cli/prototypes/nw_no_cust/Tutorial.md +45 -26
  133. api_logic_server_cli/prototypes/nw_no_cust/api/api_discovery/openapi.py +130 -0
  134. api_logic_server_cli/prototypes/nw_no_cust/api/api_discovery/proper_update_def.json +71 -0
  135. api_logic_server_cli/prototypes/nw_no_cust/config/default.env +13 -0
  136. api_logic_server_cli/prototypes/nw_no_cust/docs/graphics/count_orders_by_category.prompt +1 -0
  137. api_logic_server_cli/prototypes/nw_no_cust/docs/graphics/sales_by_employee.prompt +1 -0
  138. api_logic_server_cli/prototypes/ont_app/ontimize_seed/nginx/nginx.conf +2 -2
  139. api_logic_server_cli/prototypes/ont_app/ontimize_seed/package-lock.json +9725 -1180
  140. api_logic_server_cli/prototypes/ont_app/ontimize_seed/package.json +6 -9
  141. api_logic_server_cli/prototypes/ont_app/ontimize_seed/src/app/app.config.ts +2 -1
  142. api_logic_server_cli/prototypes/ont_app/ontimize_seed/src/app/shared/app.services.config.ts +1 -1
  143. api_logic_server_cli/prototypes/ont_app/ontimize_seed/src/assets/css/app.scss +4 -0
  144. api_logic_server_cli/prototypes/ont_app/ontimize_seed/src/assets/i18n/en.json +1 -1
  145. api_logic_server_cli/prototypes/ont_app/ontimize_seed/src/assets/i18n/es.json +14 -12
  146. api_logic_server_cli/prototypes/ont_app/ontimize_seed/src/environments/environment.prod.ts +5 -5
  147. api_logic_server_cli/prototypes/ont_app/ontimize_seed/src/environments/environment.ts +5 -5
  148. api_logic_server_cli/prototypes/ont_app/templates/app_config.jinja +1 -1
  149. api_logic_server_cli/prototypes/ont_app/templates/date_template.html +1 -1
  150. api_logic_server_cli/prototypes/ont_app/templates/detail_template.html +1 -1
  151. api_logic_server_cli/prototypes/ont_app/templates/new_template.html +16 -16
  152. api_logic_server_cli/prototypes/ont_app/templates/textarea_template.html +1 -1
  153. api_logic_server_cli/prototypes/ont_app/templates/timestamp_template.html +1 -1
  154. api_logic_server_cli/prototypes/sample_ai/logic/declare_logic.py +30 -13
  155. apilogicserver-14.5.0.dist-info/METADATA +76 -0
  156. {apilogicserver-14.3.25.dist-info → apilogicserver-14.5.0.dist-info}/RECORD +160 -88
  157. {apilogicserver-14.3.25.dist-info → apilogicserver-14.5.0.dist-info}/WHEEL +1 -1
  158. api_logic_server_cli/prototypes/basic_demo/apply_customizations.ps1 +0 -17
  159. api_logic_server_cli/prototypes/basic_demo/apply_customizations.sh +0 -14
  160. api_logic_server_cli/prototypes/basic_demo/apply_iteration.ps1 +0 -20
  161. api_logic_server_cli/prototypes/basic_demo/apply_iteration.sh +0 -15
  162. api_logic_server_cli/prototypes/manager/system/genai/graphics_templates/service_template_jsonapi_rpc.jinja +0 -37
  163. api_logic_server_cli/prototypes/manager/system/genai/graphics_templates/service_template_unused.jinja +0 -38
  164. apilogicserver-14.3.25.dist-info/METADATA +0 -167
  165. {apilogicserver-14.3.25.dist-info → apilogicserver-14.5.0.dist-info}/entry_points.txt +0 -0
  166. {apilogicserver-14.3.25.dist-info → apilogicserver-14.5.0.dist-info}/licenses/LICENSE +0 -0
  167. {apilogicserver-14.3.25.dist-info → apilogicserver-14.5.0.dist-info}/top_level.txt +0 -0
@@ -12,7 +12,7 @@ import api_logic_server_cli.api_logic_server as PR
12
12
 
13
13
  def create_manager(clean: bool, open_with: str, api_logic_server_path: Path,
14
14
  volume: str = "", open_manager: bool = True, samples: bool = True):
15
- """Implements als start to create manager - called from api_logic_server_cli/cli.py
15
+ """Implements `als start` to create manager - called from api_logic_server_cli/cli.py
16
16
 
17
17
  create Manager at os.getcwd(), including:
18
18
 
@@ -27,11 +27,11 @@ def create_manager(clean: bool, open_with: str, api_logic_server_path: Path,
27
27
  Bit tricky to find find cli in subdirectories of the lib path for manager run launches
28
28
 
29
29
  Args:
30
- clean (bool): _description_
31
- open_with (str): _description_
30
+ clean (bool): Overlay existing manager (projects and web_genai retained)
31
+ open_with (str): IDE to use
32
32
  api_logic_server_path (Path): _description_
33
33
  volume (str, optional): _description_. Defaults to "".
34
- open_manager (bool, optional): _description_. Defaults to True.
34
+ open_manager (bool, optional): Whether to open IDE at Manager. Defaults to True.
35
35
  """
36
36
 
37
37
  log = logging.getLogger(__name__)
@@ -68,8 +68,9 @@ def create_manager(clean: bool, open_with: str, api_logic_server_path: Path,
68
68
  docker_volume = volume + '/'
69
69
 
70
70
  to_dir = Path(os.getcwd())
71
+ """ location for creating (cleaning) the Manager """
71
72
  path = Path(__file__)
72
- from_dir = api_logic_server_path.joinpath('prototypes/manager')
73
+ from_dir_proto_mgr = api_logic_server_path.joinpath('prototypes/manager')
73
74
  to_dir_str = str(to_dir)
74
75
  to_dir_check = Path(to_dir).joinpath('venv')
75
76
  if not Path(to_dir).joinpath('venv').exists():
@@ -85,12 +86,12 @@ def create_manager(clean: bool, open_with: str, api_logic_server_path: Path,
85
86
  if to_dir_check.exists() and not clean:
86
87
  manager_exists = True
87
88
  if env_path.exists():
88
- log.info(f" Using manager at: {to_dir}\n\n")
89
+ log.info(f" Using existing manager (update .env APILOGICSERVER_AUTO_OPEN, only) at: {to_dir}\n\n")
89
90
  else:
90
91
  log.info(f" Refreshing .env in manager at: {to_dir}\n\n")
91
- copied_env = shutil.copy(src=from_dir.joinpath('settings.txt'), dst=to_dir.joinpath('.env'))
92
+ copied_env = shutil.copy(src=from_dir_proto_mgr.joinpath('settings.txt'), dst=to_dir.joinpath('.env'))
92
93
  os.remove(to_dir.joinpath('settings.txt'))
93
- else:
94
+ else: # new Manager, or clean existing manager
94
95
  mgr_save_level = log.level
95
96
  codegen_logger = logging.getLogger('sqlacodegen_wrapper.sqlacodegen.sqlacodegen.codegen')
96
97
  codegen_logger_save_level= codegen_logger.level
@@ -99,8 +100,16 @@ def create_manager(clean: bool, open_with: str, api_logic_server_path: Path,
99
100
  if to_dir_check.exists():
100
101
  log.info(f" Cleaning manager at: {to_dir}\n\n")
101
102
 
102
- copied_path = shutil.copytree(src=from_dir, dst=to_dir, dirs_exist_ok=True) # issue: not permitted
103
- copied_env = shutil.copy(src=from_dir.joinpath('settings.txt'), dst=to_dir.joinpath('.env'))
103
+ # create the manager system files and shell scripts (samples created below).
104
+ copied_path = shutil.copytree(src=from_dir_proto_mgr, dst=to_dir, dirs_exist_ok=True, ) # issue: not permitted
105
+ copied_env = shutil.copy(src=from_dir_proto_mgr.joinpath('settings.txt'), dst=to_dir.joinpath('.env'))
106
+ web_genai_docker = to_dir.joinpath('webgenai/docker-compose.yml')
107
+ if web_genai_docker.exists():
108
+ log.debug(' .. WebGenAI docker_compose unaltered (license preserved)')
109
+ else:
110
+ log.debug(' .. WebGenAI docker_compose created')
111
+ copied_env = shutil.copy(src=api_logic_server_path.joinpath('fragments/docker-compose.yml'),
112
+ dst=web_genai_docker)
104
113
  os.remove(to_dir.joinpath('settings.txt'))
105
114
  log.debug(f" .. created manager\n")
106
115
 
@@ -128,7 +137,7 @@ def create_manager(clean: bool, open_with: str, api_logic_server_path: Path,
128
137
  else:
129
138
  if project.is_docker:
130
139
  log.debug(f" tutorial not created for docker\n\n")
131
- else:
140
+ elif create_manager := False:
132
141
  tutorial_project = PR.ProjectRun(command="tutorial",
133
142
  project_name='./samples',
134
143
  db_url="",
@@ -136,7 +145,8 @@ def create_manager(clean: bool, open_with: str, api_logic_server_path: Path,
136
145
  open_with="NO_AUTO_OPEN"
137
146
  )
138
147
  tutorial_project = tutorial_project.tutorial(msg="Creating:") ##, create='tutorial')
139
-
148
+ else:
149
+ log.debug(f"For Tutorial, use Northwind and basic_demo\n\n")
140
150
  samples_project = PR.ProjectRun(command= "create", project_name=f'{docker_volume}samples/nw_sample', db_url='nw+', open_with="NO_AUTO_OPEN")
141
151
  log.setLevel(mgr_save_level)
142
152
  log.disabled = False # todo why was it reset?
@@ -22,6 +22,25 @@
22
22
  "console": "internalConsole",
23
23
  "internalConsoleOptions": "openOnSessionStart"
24
24
  },
25
+ {
26
+ "name": "ApiLogicServer DEBUG",
27
+ "type": "debugpy",
28
+ "cwd": "${workspaceFolder}",
29
+ "env": {
30
+ "PYTHONPATH": "",
31
+ "EXPERIMENT": "",
32
+ "PYTHONHASHSEED": "0",
33
+ "APILOGICPROJECT_LOGGING_CONFIG": "config/logging.yml",
34
+ "APILOGICPROJECT_STOP_OK": "True",
35
+ "APILOGICPROJECT_DEBUG": "False"},
36
+ "request": "launch",
37
+ "program": "api_logic_server_run.py",
38
+ "redirectOutput": true,
39
+ "justMyCode": false,
40
+ "args": ["--flask_host=localhost", "--port=5656", "--swagger_port=5656", "--swagger_host=localhost", "--verbose=False"],
41
+ "console": "internalConsole",
42
+ "internalConsoleOptions": "openOnSessionStart"
43
+ },
25
44
  {
26
45
  "name": " - API Logic Server - VERBOSE",
27
46
  "type": "debugpy",
@@ -76,7 +95,8 @@
76
95
  "internalConsoleOptions": "openOnSessionStart"
77
96
  },
78
97
  {
79
- "name": " - test/basic/server_test.py",
98
+ "name": "Test - test/basic/server_test.py",
99
+ // use this for test programs, eg to test the server
80
100
  "type": "debugpy",
81
101
  "request": "launch",
82
102
  "cwd": "${workspaceFolder}",
@@ -93,7 +113,7 @@
93
113
  "request": "launch",
94
114
  "cwd": "${workspaceFolder}/ui/app",
95
115
  "runtimeExecutable": "npm",
96
- "runtimeArgs": ["install"],
116
+ "runtimeArgs": ["install --force"],
97
117
  "console": "integratedTerminal"
98
118
  },
99
119
  {
@@ -4,6 +4,8 @@ import importlib
4
4
  import pathlib
5
5
  import logging as logging
6
6
  import flask_sqlalchemy
7
+ from config.config import Args
8
+ from config import config
7
9
 
8
10
  # use absolute path import for easier multi-{app,model,db} support
9
11
  database = __import__('database')
@@ -40,7 +42,7 @@ def expose_models(api, method_decorators = []):
40
42
  """
41
43
 
42
44
  debug_inspect_list = inspect.getmembers(database.models)
43
- pass
45
+
44
46
  # Get all the subclasses of the Base class and expose them in the api
45
47
  for name, obj in inspect.getmembers(database.models):
46
48
  if inspect.isclass(obj) and issubclass(obj, database.models.SAFRSBaseX) and obj is not database.models.SAFRSBaseX:
@@ -31,7 +31,7 @@ import os, logging, logging.config, sys, yaml # failure here means venv probabl
31
31
  from flask_sqlalchemy import SQLAlchemy
32
32
  import json
33
33
  from pathlib import Path
34
- from config.config import Args
34
+ from config.config import Args # sets up logging
35
35
  from config import server_setup
36
36
 
37
37
  current_path = os.path.abspath(os.path.dirname(__file__))
@@ -68,8 +68,11 @@ import ui.admin.admin_loader as AdminLoader
68
68
  from security.system.authentication import configure_auth
69
69
  import oracledb
70
70
 
71
+ if os.getenv("EXPERIMENT") == '+':
72
+ app_logger = logging.getLogger("api_logic_server_app")
73
+ else:
74
+ app_logger = server_setup.logging_setup()
71
75
 
72
- app_logger = server_setup.logging_setup()
73
76
 
74
77
 
75
78
  # ==================================
@@ -40,6 +40,7 @@ def activate_logicbank(session, constraint_handler):
40
40
  app_logger.exception(e)
41
41
  if not os.environ.get("WG_PROJECT") == "True":
42
42
  # Continue if inside WebGenAI
43
+ # see: https://apilogicserver.github.io/Docs/WebGenAI-CLI/#wg_rules-and-ide-rules
43
44
  raise e
44
45
  logic_logger.setLevel(logic_logger_level)
45
46
 
@@ -4,11 +4,12 @@ from pathlib import Path
4
4
  import os
5
5
  import typing
6
6
  from dotenv import load_dotenv
7
- import logging
7
+ import logging, logging.config
8
8
  from enum import Enum
9
9
  import socket
10
10
  import json
11
11
 
12
+
12
13
  '''
13
14
  #als: configuration settings
14
15
 
@@ -57,6 +58,39 @@ def is_docker() -> bool:
57
58
  # assert path_result == env_result
58
59
  return path_result
59
60
 
61
+
62
+
63
+ # ==================================
64
+ # LOGGING SETUP
65
+ # ==================================
66
+
67
+ def logging_setup() -> logging.Logger:
68
+ """
69
+ Setup Logging
70
+ """
71
+ import yaml
72
+ global app_logger, debug_value, project_path
73
+ logging_config = f'{project_path}/config/logging.yml'
74
+ if os.getenv('APILOGICPROJECT_LOGGING_CONFIG'):
75
+ logging_config = project_path.joinpath(os.getenv("APILOGICPROJECT_LOGGING_CONFIG"))
76
+ with open(logging_config,'rt') as f: # see also logic/declare_logic.py
77
+ config=yaml.safe_load(f.read())
78
+ f.close()
79
+ logging.config.dictConfig(config) # log levels: notset 0, debug 10, info 20, warn 30, error 40, critical 50
80
+ app_logger = logging.getLogger("api_logic_server_app")
81
+ debug_value = os.getenv('APILOGICPROJECT_DEBUG')
82
+ if debug_value is not None: # > export APILOGICPROJECT_DEBUG=True
83
+ debug_value = debug_value.upper()
84
+ if debug_value.startswith("F") or debug_value.startswith("N"):
85
+ app_logger.setLevel(logging.INFO)
86
+ else:
87
+ app_logger.setLevel(logging.DEBUG)
88
+ app_logger.debug(f'\nDEBUG level set from env\n')
89
+ # app_logger.info(f'\nAPI Logic Project Server Setup ({project_name}) Starting with CLI args: \n.. {args}\n')
90
+ # app_logger.info(f'Created August 03, 2024 09:34:01 at {str(project_path)}\n')
91
+ return app_logger
92
+
93
+
60
94
  class Config:
61
95
  """
62
96
 
@@ -67,6 +101,8 @@ class Config:
67
101
  Code should therefore access these ONLY as described in Args, below.
68
102
 
69
103
  """
104
+ if os.getenv("EXPERIMENT") == '+':
105
+ logging_setup() # set up logging as early as possible so capture critical config logging
70
106
 
71
107
  # Project Creation Defaults (overridden from args, env variables)
72
108
  CREATED_API_PREFIX = "/api"
@@ -171,31 +207,35 @@ class Config:
171
207
  KAFKA_CONSUMER = None
172
208
  KAFKA_CONSUMER_GROUP = None
173
209
  KAFKA_SERVER = None
174
- #KAFKA_SERVER = os.getenv('KAFKA_SERVER','localhost:9092') # if running locally default
175
- if KAFKA_SERVER:
210
+ KAFKA_SERVER = os.getenv('KAFKA_SERVER', None) # 'localhost:9092' # if running locally default
211
+ if KAFKA_SERVER is not None and KAFKA_SERVER != "None" and KAFKA_SERVER != "":
176
212
  app_logger.info(f'config.py - KAFKA_SERVER: {KAFKA_SERVER}')
177
213
  KAFKA_PRODUCER = os.getenv('KAFKA_PRODUCER',{"bootstrap.servers": f"{KAFKA_SERVER}"}) # , "client.id": "aaa.b.c.d"}'
178
- KAFKA_CONSUMER_GROUP = os.getenv('KAFKA_CONSUMER_GROUP','als-default-group1')
179
- KAFKA_CONSUMER = os.getenv('KAFKA_CONSUMER', {"bootstrap.servers": f"{KAFKA_SERVER}", "group.id": f"{KAFKA_CONSUMER_GROUP}", "enable.auto.commit": "false", "auto.offset.reset": "earliest"})
214
+ KAFKA_CONSUMER_GROUP = os.getenv('KAFKA_CONSUMER_GROUP') #'als-default-group1'
215
+ if KAFKA_CONSUMER_GROUP is not None: # and KAFKA_CONSUMER_GROUP != "None":
216
+ KAFKA_CONSUMER = os.getenv('KAFKA_CONSUMER', {"bootstrap.servers": f"{KAFKA_SERVER}", "group.id": f"{KAFKA_CONSUMER_GROUP}", "enable.auto.commit": "false", "auto.offset.reset": "earliest"})
180
217
  else:
181
218
  app_logger.info(f'config.py - KAFKA_SERVER: {KAFKA_SERVER} - not set, no kafka producer/consumer')
182
- print(f'config.py - KAFKA_PRODUCER: {KAFKA_PRODUCER}')
183
- print(f'config.py - KAFKA_CONSUMER: {KAFKA_CONSUMER}')
184
- print(f'config.py - KAFKA_CONSUMER_GROUP: {KAFKA_CONSUMER_GROUP}')
185
- print(f'config.py - KAFKA_SERVER: {KAFKA_SERVER}')
219
+ producer_is_empty = "" == KAFKA_PRODUCER
220
+ app_logger.info(f'config.py - KAFKA_PRODUCER: {KAFKA_PRODUCER} (is_empty={producer_is_empty})')
221
+ app_logger.info(f'config.py - KAFKA_CONSUMER: {KAFKA_CONSUMER}')
222
+ app_logger.info(f'config.py - KAFKA_CONSUMER_GROUP: {KAFKA_CONSUMER_GROUP}')
223
+ app_logger.info(f'config.py - KAFKA_SERVER: {KAFKA_SERVER}')
186
224
  # N8N Webhook Args (for testing)
187
225
  # see https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.webhook/?utm_source=n8n_app&utm_medium=node_settings_modal-credential_link&utm_campaign=n8n-nodes-base.webhook#path
226
+ # N8N is a workflow automation tool that allows you to connect different applications and automate tasks between them.
188
227
  wh_scheme = "http"
189
228
  wh_server = "localhost" # or cloud.n8n.io...
190
229
  wh_port = 5678
191
- wh_endpoint = "webhook-test"
192
- wh_path = "002fa0e8-f7aa-4e04-b4e3-e81aa29c6e69"
193
- token = "YWRtaW46cA=="
194
- N8N_PRODUCER = {"authorization": f"Basic {token}", "n8n_url": f'"{wh_scheme}://{wh_server}:{wh_port}/{wh_endpoint}/{wh_path}"'}
230
+ wh_endpoint = "webhook-test" # This comes from the WebHook node in n8n
231
+ wh_path = "002fa0e8-f7aa-4e04-b4e3-e81aa29c6e69" # This comes from the WebHook node in n8n
232
+ wh_token = "YWRtaW46cA==" # This is the base64 encoded string of username:password (e.g. admin:password)
233
+ N8N_PRODUCER = {"authorization": f"Basic {wh_token}", "n8n_url": f'"{wh_scheme}://{wh_server}:{wh_port}/{wh_endpoint}/{wh_path}"'}
195
234
  # Or enter the n8n_url directly:
196
- N8N_PRODUCER = {"authorization": f"Basic {token}","n8n_url":"http://localhost:5678/webhook-test/002fa0e8-f7aa-4e04-b4e3-e81aa29c6e69"}
235
+ #N8N_PRODUCER = {"authorization": f"Basic {wh_token}","n8n_url":"http://localhost:5678/webhook-test/002fa0e8-f7aa-4e04-b4e3-e81aa29c6e69"}
197
236
  N8N_PRODUCER = None # comment out to enable N8N producer
198
- # Consumer under consideration
237
+ # See integration/n8n/n8n_readme.md for more details
238
+
199
239
 
200
240
  OPT_LOCKING = "optional"
201
241
  if os.getenv('OPT_LOCKING'): # e.g. export OPT_LOCKING=required
@@ -260,14 +300,19 @@ class Args():
260
300
  self.kafka_producer = Config.KAFKA_PRODUCER
261
301
  self.kafka_consumer = Config.KAFKA_CONSUMER
262
302
  self.kafka_consumer_group = Config.KAFKA_CONSUMER_GROUP
263
- self.n8n_producer = Config.N8N_PRODUCER
264
303
  self.keycloak_base = Config.KEYCLOAK_BASE
265
304
  self.keycloak_realm = Config.KEYCLOAK_REALM
266
305
  self.keycloak_base_url = Config.KEYCLOAK_BASE_URL
267
306
  self.keycloak_client_id = Config.KEYCLOAK_CLIENT_ID
268
307
  self.backtic_as_quote = Config.BACKTIC_AS_QUOTE
269
308
  self.service_type = Config.ONTIMIZE_SERVICE_TYPE
270
-
309
+ self.wh_scheme = Config.wh_scheme
310
+ self.wh_server = Config.wh_server
311
+ self.wh_port = Config.wh_port
312
+ self.wh_endpoint = Config.wh_endpoint
313
+ self.wh_path = Config.wh_path
314
+ self.wh_token = Config.wh_token
315
+ self.n8n_producer = Config.N8N_PRODUCER
271
316
  self.verbose = False
272
317
  self.create_and_run = False
273
318
 
@@ -479,10 +524,13 @@ class Args():
479
524
  def kafka_producer(self) -> dict:
480
525
  """ kafka connect string """
481
526
  if "KAFKA_PRODUCER" in self.flask_app.config and self.flask_app.config["KAFKA_PRODUCER"] is not None:
482
- value = self.flask_app.config["KAFKA_PRODUCER"]
483
- if not isinstance(value, dict):
484
- value = json.loads(self.flask_app.config["KAFKA_PRODUCER"])
485
- return value
527
+ if self.flask_app.config["KAFKA_PRODUCER"] is not None:
528
+ value = self.flask_app.config["KAFKA_PRODUCER"]
529
+ if isinstance(value, dict):
530
+ pass # eg, from VSCode Run Config: "APILOGICPROJECT_KAFKA_PRODUCER": "{\"bootstrap.servers\": \"localhost:9092\"}",
531
+ else:
532
+ value = json.loads(self.flask_app.config["KAFKA_PRODUCER"])
533
+ return value
486
534
  return None
487
535
 
488
536
  @kafka_producer.setter
@@ -494,7 +542,9 @@ class Args():
494
542
  """ kafka enable consumer """
495
543
  if "KAFKA_CONSUMER" in self.flask_app.config and self.flask_app.config["KAFKA_CONSUMER"] is not None:
496
544
  value = self.flask_app.config["KAFKA_CONSUMER"]
497
- if not isinstance(value, dict):
545
+ if isinstance(value, dict):
546
+ pass # eg, from VSCode Run Config: "APILOGICPROJECT_KAFKA_PRODUCER": "{\"bootstrap.servers\": \"localhost:9092\"}",
547
+ else:
498
548
  value = json.loads(self.flask_app.config["KAFKA_CONSUMER"])
499
549
  return value
500
550
  return None
@@ -533,7 +583,56 @@ class Args():
533
583
  def n8n_producer(self, a: str):
534
584
  self.flask_app.config["N8N_PRODUCER"] = a
535
585
 
536
-
586
+ # WebHook Args (used by N8N producer - see n8n_producer above)
587
+ @property
588
+ def wh_scheme(self) -> str:
589
+ """ n8n connect string """
590
+ return self.flask_app.config["WH_SCHEME"]
591
+ @wh_scheme.setter
592
+ def wh_scheme(self, a: str):
593
+ self.flask_app.config["WH_SCHEME"] = a
594
+
595
+ @property
596
+ def wh_server(self) -> str:
597
+ """ n8n connect string """
598
+ return self.flask_app.config["WH_SERVER"]
599
+ @wh_server.setter
600
+ def wh_server(self, a: str):
601
+ self.flask_app.config["WH_SERVER"] = a
602
+
603
+ @property
604
+ def wh_port(self) -> str:
605
+ """ n8n connect string """
606
+ return self.flask_app.config["WH_PORT"]
607
+
608
+ @wh_port.setter
609
+ def wh_port(self, a: str):
610
+ self.flask_app.config["WH_PORT"] = a
611
+
612
+ @property
613
+ def wh_endpoint(self) -> str:
614
+ """ n8n connect string """
615
+ return self.flask_app.config["WH_ENDPOINT"]
616
+ @wh_endpoint.setter
617
+ def wh_endpoint(self, a: str):
618
+ self.flask_app.config["WH_ENDPOINT"] = a
619
+ @property
620
+ def wh_path(self) -> str:
621
+ """ n8n connect string """
622
+ return self.flask_app.config["WH_PATH"]
623
+
624
+ @wh_path.setter
625
+ def wh_path(self, a: str):
626
+ self.flask_app.config["WH_PATH"] = a
627
+ @property
628
+ def wh_token(self) -> str:
629
+ """ n8n connect string """
630
+ return self.flask_app.config["WH_TOKEN"]
631
+ @wh_token.setter
632
+ def wh_token(self, a: str):
633
+ self.flask_app.config["WH_TOKEN"] = a
634
+
635
+
537
636
  def __str__(self) -> str:
538
637
  rtn = f'.. flask_host: {self.flask_host}, port: {self.port}, \n'\
539
638
  f'.. swagger_host: {self.swagger_host}, swagger_port: {self.swagger_port}, \n'\
@@ -652,5 +751,4 @@ class Args():
652
751
  args.swagger_port = 443
653
752
  args.http_scheme = 'https'
654
753
 
655
- return
656
-
754
+ return
@@ -4,4 +4,10 @@ SQLAlCHEMY_ECHO = False
4
4
  # AGGREGATE_DEFAULTS = True
5
5
  # ALL_DEFAULTS = True
6
6
  # APILOGICPROJECT_KAFKA_PRODUCER = "{\"bootstrap.servers\": \"localhost:9092\"}"
7
- # SQLALCHEMY_DATABASE_URI=db.sqlite
7
+ # SQLALCHEMY_DATABASE_URI=db.sqlite
8
+
9
+ SECURITY_ENABLED = false
10
+
11
+ # if using tunnel for mcp, function, or ai_plugin
12
+ # eg, https://tunnel_url.ngrok-free.app
13
+ API_LOGIC_SERVER_TUNNEL = "TUNNEL_URL"
@@ -1,4 +1,5 @@
1
1
  version: 1
2
+ # notset 0, debug 10, info 20, warn 30, error 40, critical 50
2
3
 
3
4
  formatters:
4
5
  simple:
@@ -9,6 +9,24 @@
9
9
  #
10
10
  ###############################################################################
11
11
 
12
+ """
13
+ Operation:
14
+ 1. api_logic_server_run.py - imports config
15
+ 1. captures args
16
+ 2. api_logic_server_run.py - imports server_setup
17
+ 1. server_setup#logging_setup()
18
+ 3. api_logic_server_run.py - server_setup.api_logic_server_setup
19
+ On error, NOT CALLED: constraint_handler or ValidationErrorExt (!)
20
+
21
+ + Operation:
22
+ 1. api_logic_server_run.py - imports config
23
+ 1. captures args
24
+ 1. config#logging_setup()
25
+ 2. api_logic_server_run.py - imports server_setup
26
+ 3. api_logic_server_run.py - server_setup.api_logic_server_setup
27
+
28
+ """
29
+
12
30
  start_up_message = "normal start"
13
31
 
14
32
  import traceback
@@ -25,6 +43,8 @@ except:
25
43
  from flask_sqlalchemy import SQLAlchemy
26
44
  import json
27
45
  from pathlib import Path
46
+ if os.getenv("EXPERIMENT") == '+':
47
+ import config
28
48
  from config.config import Args
29
49
 
30
50
 
@@ -88,6 +108,9 @@ import integration.kafka.kafka_consumer as kafka_consumer
88
108
  import integration.n8n.n8n_producer as n8n_producer
89
109
 
90
110
 
111
+ if os.getenv("EXPERIMENT") == '+':
112
+ app_logger = logging.getLogger("api_logic_server_app")
113
+
91
114
 
92
115
  class SAFRSAPI(_SAFRSAPI):
93
116
  """
@@ -121,7 +144,7 @@ def get_args(flask_app: Flask) -> Args:
121
144
 
122
145
  import config.config as config
123
146
  flask_app.config.from_object(config.Config)
124
- app_logger.debug(f"\nserver_setup - get_args: Config args: \n{args}") # FIXME # config file (e.g., db uri's)
147
+ app_logger.debug(f"\nserver_setup - get_args: Config args: \n{args}") # # config file (e.g., db uri's)
125
148
 
126
149
  args.get_cli_args(dunder_name=__name__, args=args)
127
150
  app_logger.debug(f"\nserver_setup - get_args: CLI args: \n{args}") # api_logic_server_run cl args
@@ -351,4 +374,13 @@ def api_logic_server_setup(flask_app: Flask, args: Args):
351
374
  db_logger.setLevel(db_log_level)
352
375
  authorization_logger.setLevel(authorization_log_level)
353
376
 
377
+ if os.getenv('APILOGICPROJECT_DEBUG'): # temp debug since logging in config is not happening
378
+ KAFKA_SERVER = os.getenv('KAFKA_SERVER')
379
+ is_empty = False
380
+ if KAFKA_SERVER is not None:
381
+ is_empty = KAFKA_SERVER == ""
382
+ is_none = KAFKA_SERVER is None
383
+ app_logger.debug(f'\nDEBUG KAFKA_SERVER: [{KAFKA_SERVER}] (is_empty: {is_empty}) (is_none: {is_none}) \n')
384
+ app_logger.debug(f'... Args.instance.kafka_producer: {Args.instance.kafka_producer}\n')
385
+
354
386
 
@@ -1,10 +1,13 @@
1
+ This rebuilds test data into `database/test_data/db.sqlite`, for example as used by genai project creation.
2
+
1
3
  ChatGPT sometimes fails to build proper test data that matches the derivation rules.
2
4
 
3
5
  You can rebuild the test data, using Logic Bank rules for proper derivations, to rebuild your `database/db.sqlite` (make a copy first to preserve your existing data).
4
6
 
5
-
6
7
  ```
7
8
  als genai-utils --rebuild-test-data
8
9
  ```
9
10
 
10
- You can explore the generated `database/test_data/test_data_code.py` to control test data generation.
11
+ You can explore the generated `database/test_data/test_data_code.py` to control test data generation.
12
+
13
+ If required, you can copy `database/test_data/test_data_preamble.py` to a new file, to rebuild your database (e.g., from an altered model file), and load your own test data (if any).
@@ -14,8 +14,13 @@ services:
14
14
  image: apilogicserver/api_logic_server
15
15
  container_name: api_logic_project
16
16
  environment:
17
- - APILOGICPROJECT_VERBOSE=true
18
- - SECURITY_ENABLED=true
17
+ - APILOGICPROJECT_VERBOSE=false
18
+ - APILOGICPROJECT_SECURITY_ENABLED=false
19
+ - APILOGICPROJECT_KEYCLOAK_REALM=kcals
20
+ # use your IP, below....
21
+ - APILOGICPROJECT_KEYCLOAK_BASE_URL=http://10.0.0.249:8080/realms/kcals
22
+ - APILOGICPROJECT_KEYCLOAK_BASE=http://10.0.0.249:8080
23
+ - APILOGICPROJECT_KEYCLOAK_CLIENT_ID=alsclient
19
24
  env_file:
20
25
  - ./env.list
21
26
  volumes: