ApiLogicServer 14.4.0__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.
- api_logic_server_cli/add_cust/add_cust.py +283 -0
- api_logic_server_cli/api_logic_server.py +15 -237
- api_logic_server_cli/api_logic_server_info.yaml +3 -3
- api_logic_server_cli/cli.py +38 -28
- api_logic_server_cli/create_from_model/__pycache__/api_logic_server_utils.cpython-312.pyc +0 -0
- api_logic_server_cli/create_from_model/__pycache__/dbml.cpython-312.pyc +0 -0
- api_logic_server_cli/create_from_model/__pycache__/ont_build.cpython-312.pyc +0 -0
- api_logic_server_cli/create_from_model/__pycache__/ont_create.cpython-312.pyc +0 -0
- api_logic_server_cli/create_from_model/api_logic_server_utils.py +47 -0
- api_logic_server_cli/create_from_model/dbml.py +113 -58
- api_logic_server_cli/create_from_model/ont_build.py +83 -60
- api_logic_server_cli/create_from_model/ont_create.py +2 -1
- api_logic_server_cli/database/basic_demo.sqlite +0 -0
- api_logic_server_cli/database/basic_demo.txt +1 -0
- api_logic_server_cli/database/basic_demo_wg.sqlite +0 -0
- api_logic_server_cli/manager.py +3 -2
- api_logic_server_cli/prototypes/base/.vscode/launch.json +3 -2
- api_logic_server_cli/prototypes/base/config/config.py +66 -11
- api_logic_server_cli/prototypes/base/config/default.env +7 -1
- api_logic_server_cli/prototypes/base/database/test_data/readme.md +2 -1
- api_logic_server_cli/prototypes/base/integration/kafka/kafka_producer.py +5 -2
- api_logic_server_cli/prototypes/base/integration/n8n/n8n_producer.py +68 -21
- api_logic_server_cli/prototypes/base/integration/n8n/n8n_readme.md +19 -0
- api_logic_server_cli/prototypes/base/test/basic/server_test.py +1 -1
- api_logic_server_cli/prototypes/basic_demo/README.md +29 -52
- api_logic_server_cli/prototypes/basic_demo/customizations/api/.DS_Store +0 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/api/api_discovery/mcp_server_executor.py +138 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/api/api_discovery/openapi.py +92 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/api/api_discovery/proper_update_def.json +71 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/config/default.env +13 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/database/db.sqlite +0 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/database/models.py +131 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/.DS_Store +0 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/.DS_Store +0 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/1_langchain_loader.py +71 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/README_mcp.md +13 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/mcp_client_executor.py +295 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/mcp_schema.txt +47 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/mcp_server_discovery.json +9 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/multi_mcp_flow/multi_mcp_flow.png +0 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/multi_mcp_flow/multi_mcp_orchestration.yaml +49 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/multi_mcp_flow/wny mcp flows.png +0 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/natlang_to_api.py +73 -0
- api_logic_server_cli/prototypes/{nw_no_cust → basic_demo/customizations}/integration/mcp/resources/curl.txt +2 -1
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/images/MCP Overview.png +0 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/images/MCP_Arch.png +0 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/images/MCP_Overview_Executor.png +0 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/invoke_llm/1 - prompt_messages_array.json +10 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/invoke_llm/2 - completion_tool_context.json +12 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/llm_schema.txt +38 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/nw_swagger_2.yaml +17393 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/nw_swagger_3_relaxed.yaml +109 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/proxy_server.py +51 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/proxy_serverZ.py +72 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/validate_jsonapi.py +64 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/swagger_converter.py +65 -0
- api_logic_server_cli/prototypes/{nw_no_cust/integration/mcp → basic_demo/customizations/integration/mcp/z_old}/3_executor_test_agent.py +20 -6
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/3_executor_test_agent.py +52 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/README_functon.md +201 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/ai_plugin.json +17 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/nw-swagger_3.json +1731 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/snippets.txt +5 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/swagger_3 genai_demo_with_get.json +1731 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/swagger_3.json +1782 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/swagger_3_genai_demo.json +264 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/swagger_3_genai_demo_with_update.json +1782 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/logic/declare_logic.py +62 -44
- api_logic_server_cli/prototypes/basic_demo/customizations/security/declare_security.py +11 -12
- api_logic_server_cli/prototypes/basic_demo/customizations/ui/admin/admin.yaml +166 -0
- api_logic_server_cli/prototypes/basic_demo/iteration/api/{customize_api.py → api_discovery/order_b2b.py} +17 -23
- api_logic_server_cli/prototypes/basic_demo/iteration/database/db.sqlite +0 -0
- api_logic_server_cli/prototypes/basic_demo/iteration/integration/row_dict_maps/OrderB2B.py +6 -5
- api_logic_server_cli/prototypes/basic_demo/iteration/integration/row_dict_maps/OrderShipping.py +4 -4
- api_logic_server_cli/prototypes/basic_demo/iteration/logic/declare_logic.py +69 -43
- api_logic_server_cli/prototypes/basic_demo/iteration/ui/admin/admin.yaml +125 -50
- api_logic_server_cli/prototypes/manager/README.md +4 -0
- api_logic_server_cli/prototypes/manager/README_X.md +663 -0
- api_logic_server_cli/prototypes/nw_no_cust/Tutorial.md +45 -26
- api_logic_server_cli/prototypes/nw_no_cust/api/api_discovery/openapi.py +130 -0
- api_logic_server_cli/prototypes/nw_no_cust/api/api_discovery/proper_update_def.json +71 -0
- api_logic_server_cli/prototypes/nw_no_cust/config/default.env +13 -0
- api_logic_server_cli/prototypes/ont_app/ontimize_seed/package-lock.json +9725 -1180
- api_logic_server_cli/prototypes/ont_app/ontimize_seed/package.json +3 -6
- api_logic_server_cli/prototypes/ont_app/ontimize_seed/src/app/shared/app.services.config.ts +1 -1
- api_logic_server_cli/prototypes/ont_app/ontimize_seed/src/assets/css/app.scss +4 -0
- api_logic_server_cli/prototypes/ont_app/ontimize_seed/src/assets/i18n/en.json +1 -1
- api_logic_server_cli/prototypes/ont_app/ontimize_seed/src/assets/i18n/es.json +14 -12
- api_logic_server_cli/prototypes/ont_app/templates/app_config.jinja +1 -1
- api_logic_server_cli/prototypes/ont_app/templates/date_template.html +1 -1
- api_logic_server_cli/prototypes/ont_app/templates/textarea_template.html +1 -1
- api_logic_server_cli/prototypes/ont_app/templates/timestamp_template.html +1 -1
- api_logic_server_cli/prototypes/sample_ai/logic/declare_logic.py +30 -13
- {apilogicserver-14.4.0.dist-info → apilogicserver-14.5.0.dist-info}/METADATA +2 -2
- {apilogicserver-14.4.0.dist-info → apilogicserver-14.5.0.dist-info}/RECORD +101 -60
- {apilogicserver-14.4.0.dist-info → apilogicserver-14.5.0.dist-info}/WHEEL +1 -1
- api_logic_server_cli/prototypes/basic_demo/apply_customizations.ps1 +0 -17
- api_logic_server_cli/prototypes/basic_demo/apply_customizations.sh +0 -14
- api_logic_server_cli/prototypes/basic_demo/apply_iteration.ps1 +0 -20
- api_logic_server_cli/prototypes/basic_demo/apply_iteration.sh +0 -15
- api_logic_server_cli/prototypes/nw_no_cust/integration/mcp/1_langchain_loader.py +0 -19
- api_logic_server_cli/prototypes/nw_no_cust/integration/mcp/README.md +0 -17
- /api_logic_server_cli/prototypes/{nw_no_cust → basic_demo/customizations}/integration/mcp/2_gpt_mcp_prompt.txt +0 -0
- /api_logic_server_cli/prototypes/{nw_no_cust → basic_demo/customizations}/integration/mcp/resources/nw_swagger_3.yaml +0 -0
- /api_logic_server_cli/prototypes/{nw_no_cust → basic_demo/customizations}/integration/mcp/run_executor.py +0 -0
- {apilogicserver-14.4.0.dist-info → apilogicserver-14.5.0.dist-info}/entry_points.txt +0 -0
- {apilogicserver-14.4.0.dist-info → apilogicserver-14.5.0.dist-info}/licenses/LICENSE +0 -0
- {apilogicserver-14.4.0.dist-info → apilogicserver-14.5.0.dist-info}/top_level.txt +0 -0
api_logic_server_cli/cli.py
CHANGED
|
@@ -1595,36 +1595,46 @@ def add_cust(ctx, bind_key_url_separator: str, api_name: str, project_name: str)
|
|
|
1595
1595
|
project_name = project.project_directory_path.parent.name if not project.project_directory_path.is_dir() else project.project_directory_path.name
|
|
1596
1596
|
models_py_path = project.project_directory_path.joinpath('database/models.py')
|
|
1597
1597
|
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1598
|
+
if use_add_cust := True:
|
|
1599
|
+
import api_logic_server_cli.add_cust.add_cust as add_cust
|
|
1600
|
+
add_cust.add_cust(project=project, project_name=project_name, models_py_path=models_py_path)
|
|
1601
|
+
pass
|
|
1602
|
+
else:
|
|
1603
|
+
log.debug(f"\ncli[add-cust] models_py_path={models_py_path}")
|
|
1604
|
+
if not models_py_path.exists():
|
|
1605
|
+
raise Exception("Customizations are northwind/genai-specific - models.py does not exist")
|
|
1606
|
+
|
|
1607
|
+
project_is_genai_demo = False # can't use project.is_genai_demo because this is not the create command...
|
|
1608
|
+
if project.project_directory_path.joinpath('docs/project_is_genai_demo.txt').exists():
|
|
1609
|
+
project_is_genai_demo = True
|
|
1610
|
+
|
|
1611
|
+
project.abs_db_url, project.nw_db_status, project.model_file_name = create_utils.get_abs_db_url("0. Using Sample DB", project)
|
|
1612
|
+
|
|
1613
|
+
if create_utils.does_file_contain(search_for="CategoryTableNameTest", in_file=models_py_path):
|
|
1614
|
+
project.add_nw_customizations(do_security=False)
|
|
1615
|
+
log.info("\nNext step - add authentication:\n $ ApiLogicServer add-auth --db_url=auth\n\n")
|
|
1616
|
+
|
|
1617
|
+
elif project_is_genai_demo and create_utils.does_file_contain(search_for="Customer", in_file=models_py_path):
|
|
1618
|
+
project.add_genai_customizations(do_security=False)
|
|
1619
|
+
|
|
1620
|
+
elif project_name == 'sample_ai' and create_utils.does_file_contain(search_for="CustomerName = Column(Text", in_file=models_py_path):
|
|
1621
|
+
cocktail_napkin_path = project.project_directory_path.joinpath('logic/cocktail-napkin.jpg')
|
|
1622
|
+
is_customized = cocktail_napkin_path.exists()
|
|
1623
|
+
if not is_customized:
|
|
1624
|
+
project.add_sample_ai_customizations()
|
|
1625
|
+
else:
|
|
1626
|
+
project.add_sample_ai_iteration()
|
|
1627
|
+
|
|
1628
|
+
elif project_name == 'basic_demo' and create_utils.does_file_contain(search_for="Customer", in_file=models_py_path):
|
|
1629
|
+
cocktail_napkin_path = project.project_directory_path.joinpath('logic/cocktail-napkin.jpg')
|
|
1630
|
+
is_customized = cocktail_napkin_path.exists()
|
|
1631
|
+
if not is_customized:
|
|
1632
|
+
project.add_basic_demo_customizations()
|
|
1633
|
+
else:
|
|
1634
|
+
project.add_basic_demo_iteration()
|
|
1601
1635
|
|
|
1602
|
-
project_is_genai_demo = False # can't use project.is_genai_demo because this is not the create command...
|
|
1603
|
-
if project.project_directory_path.joinpath('docs/project_is_genai_demo.txt').exists():
|
|
1604
|
-
project_is_genai_demo = True
|
|
1605
|
-
|
|
1606
|
-
project.abs_db_url, project.nw_db_status, project.model_file_name = create_utils.get_abs_db_url("0. Using Sample DB", project)
|
|
1607
|
-
if create_utils.does_file_contain(search_for="CategoryTableNameTest", in_file=models_py_path):
|
|
1608
|
-
project.add_nw_customizations(do_security=False)
|
|
1609
|
-
log.info("\nNext step - add authentication:\n $ ApiLogicServer add-auth --db_url=auth\n\n")
|
|
1610
|
-
elif project_is_genai_demo and create_utils.does_file_contain(search_for="Customer", in_file=models_py_path):
|
|
1611
|
-
project.add_genai_customizations(do_security=False)
|
|
1612
|
-
elif project_name == 'sample_ai' and create_utils.does_file_contain(search_for="CustomerName = Column(Text", in_file=models_py_path):
|
|
1613
|
-
cocktail_napkin_path = project.project_directory_path.joinpath('logic/cocktail-napkin.jpg')
|
|
1614
|
-
is_customized = cocktail_napkin_path.exists()
|
|
1615
|
-
if not is_customized:
|
|
1616
|
-
project.add_sample_ai_customizations()
|
|
1617
|
-
else:
|
|
1618
|
-
project.add_sample_ai_iteration()
|
|
1619
|
-
elif project_name == 'basic_demo' and create_utils.does_file_contain(search_for="Customer", in_file=models_py_path):
|
|
1620
|
-
cocktail_napkin_path = project.project_directory_path.joinpath('logic/cocktail-napkin.jpg')
|
|
1621
|
-
is_customized = cocktail_napkin_path.exists()
|
|
1622
|
-
if not is_customized:
|
|
1623
|
-
project.add_basic_demo_customizations()
|
|
1624
1636
|
else:
|
|
1625
|
-
|
|
1626
|
-
else:
|
|
1627
|
-
raise Exception("Customizations are northwind/genai-specific - models.py has neither CategoryTableNameTest nor Customer")
|
|
1637
|
+
raise Exception("Customizations are northwind/genai-specific - models.py has neither CategoryTableNameTest nor Customer")
|
|
1628
1638
|
|
|
1629
1639
|
|
|
1630
1640
|
@main.command("sample-ai", cls=HideDunderCommand, hidden=True)
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
|
|
3
|
+
import shutil
|
|
3
4
|
import subprocess, os, sys
|
|
4
5
|
from pathlib import Path
|
|
5
6
|
from os.path import abspath
|
|
@@ -335,6 +336,7 @@ def get_config(search_for: str, in_file: str) -> str:
|
|
|
335
336
|
f'.. seeking {search_for}\n'
|
|
336
337
|
f'.. in {in_file}')
|
|
337
338
|
return file_lines[insert_line].split('=')[1].strip().replace("'","",2)
|
|
339
|
+
|
|
338
340
|
def get_ontimize_apps(project_dir_path):
|
|
339
341
|
result = []
|
|
340
342
|
for name in os.listdir(f"{project_dir_path}/ui"):
|
|
@@ -346,6 +348,7 @@ def get_ontimize_apps(project_dir_path):
|
|
|
346
348
|
result.append(name)
|
|
347
349
|
log.debug(f"Found {len(result)} Ontimize app(s)")
|
|
348
350
|
return result
|
|
351
|
+
|
|
349
352
|
def does_file_contain(search_for: str, in_file: str) -> bool:
|
|
350
353
|
""" returns True if <search_for> is <in_file> """
|
|
351
354
|
with open(Path(in_file), 'r+') as fp:
|
|
@@ -482,3 +485,47 @@ def run_command(cmd: str, env=None, msg: str = "", new_line: bool=False,
|
|
|
482
485
|
elif result != "" and result != "Downloaded the skeleton app, good coding!":
|
|
483
486
|
log.debug(f'{log_msg} {cmd_to_run} result: {spaces}{result}')
|
|
484
487
|
return result.replace('\\n','\n')
|
|
488
|
+
|
|
489
|
+
|
|
490
|
+
def recursive_overwrite(src, dest, ignore=None):
|
|
491
|
+
"""
|
|
492
|
+
copyTree, with overwrite
|
|
493
|
+
thanks: https://stackoverflow.com/questions/12683834/how-to-copy-directory-recursively-in-python-and-overwrite-all
|
|
494
|
+
"""
|
|
495
|
+
if os.path.isdir(src):
|
|
496
|
+
if not os.path.isdir(dest):
|
|
497
|
+
os.makedirs(dest)
|
|
498
|
+
files = os.listdir(src)
|
|
499
|
+
if ignore is not None:
|
|
500
|
+
ignored = ignore(src, files)
|
|
501
|
+
else:
|
|
502
|
+
ignored = set()
|
|
503
|
+
for f in files:
|
|
504
|
+
if f not in ignored:
|
|
505
|
+
recursive_overwrite(os.path.join(src, f),
|
|
506
|
+
os.path.join(dest, f),
|
|
507
|
+
ignore)
|
|
508
|
+
else:
|
|
509
|
+
shutil.copyfile(src, dest)
|
|
510
|
+
|
|
511
|
+
def find_replace_recursive(directory, find, replace, filePattern):
|
|
512
|
+
"""
|
|
513
|
+
|
|
514
|
+
find_replace_recursive("some_dir", "find this", "replace with this", "*.txt")
|
|
515
|
+
|
|
516
|
+
thanks: https://stackoverflow.com/questions/4205854/recursively-find-and-replace-string-in-text-files
|
|
517
|
+
|
|
518
|
+
Args:
|
|
519
|
+
directory (_type_): _description_
|
|
520
|
+
find (_type_): _description_
|
|
521
|
+
replace (_type_): _description_
|
|
522
|
+
filePattern (_type_): _description_
|
|
523
|
+
"""
|
|
524
|
+
for path, dirs, files in os.walk(os.path.abspath(directory)):
|
|
525
|
+
for filename in fnmatch.filter(files, filePattern):
|
|
526
|
+
filepath = os.path.join(path, filename)
|
|
527
|
+
with open(filepath) as f:
|
|
528
|
+
s = f.read()
|
|
529
|
+
s = s.replace(find, replace)
|
|
530
|
+
with open(filepath, "w") as f:
|
|
531
|
+
f.write(s)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import json
|
|
1
2
|
import logging
|
|
2
3
|
from re import X
|
|
3
4
|
import shutil
|
|
@@ -68,51 +69,55 @@ class DBMLCreator(object):
|
|
|
68
69
|
self.dbms_lines.append('// Or, https://databasediagram.com/app')
|
|
69
70
|
self.dbms_lines.append('// Or, view in VSCode with extension: "DBML Live Preview"')
|
|
70
71
|
self.dbms_lines.append("")
|
|
72
|
+
self.mcp_schema = \
|
|
73
|
+
{
|
|
74
|
+
"tool_type": "json-api",
|
|
75
|
+
"schema_version": "1.0",
|
|
76
|
+
"base_url": "http://localhost:5656/api",
|
|
77
|
+
"description": f"API Logic Project: {self.mod_gen.project.project_name_last_node}",
|
|
78
|
+
"resources": [
|
|
79
|
+
]
|
|
80
|
+
}
|
|
81
|
+
|
|
71
82
|
|
|
72
|
-
def
|
|
73
|
-
"""
|
|
74
|
-
|
|
75
|
-
Table Users {
|
|
76
|
-
id integerish
|
|
77
|
-
created_at timestamp
|
|
78
|
-
}
|
|
79
|
-
Ref: users.(id) < follows.(followed_user_id)
|
|
83
|
+
def do_process_resource(self, resource_name: str)-> bool:
|
|
84
|
+
""" filter out resources that are skipped by user, start with ab etc
|
|
80
85
|
"""
|
|
86
|
+
if "ProductDetails_V" in resource_name:
|
|
87
|
+
log.debug("special table") # should not occur (--noviews)
|
|
88
|
+
if resource_name.startswith("ab_"):
|
|
89
|
+
return False # skip admin table: " + table_name + "\n
|
|
90
|
+
elif 'sqlite_sequence' in resource_name:
|
|
91
|
+
return False # skip sqlite_sequence table: " + table_name + "\n
|
|
92
|
+
elif resource_name is None:
|
|
93
|
+
return False # no class (view): " + table_name + "\n
|
|
94
|
+
elif resource_name.startswith("Ab"):
|
|
95
|
+
return False
|
|
96
|
+
return True
|
|
81
97
|
|
|
82
|
-
|
|
83
|
-
if (self.mod_gen.project.
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
description = description.replace("Table representing ", "")
|
|
106
|
-
description = description.replace("Table storing ", "")
|
|
107
|
-
description = description.replace("This table stores ", "")
|
|
108
|
-
description = description.replace("This table lists ", "")
|
|
109
|
-
description = description.replace("This table records ", "")
|
|
110
|
-
self.dbms_lines.append(f"{each_resource_name}: {description}")
|
|
111
|
-
self.dbms_lines.append("'''")
|
|
112
|
-
self.dbms_lines.append("}")
|
|
113
|
-
self.dbms_lines.append("")
|
|
114
|
-
|
|
115
|
-
|
|
98
|
+
def dbml_descriptions(self):
|
|
99
|
+
if len(self.mod_gen.project.table_descriptions) > 0:
|
|
100
|
+
self.dbms_lines.append("Project DBML {")
|
|
101
|
+
self.dbms_lines.append(" Note: '''")
|
|
102
|
+
for each_resource_name in self.mod_gen.resource_list:
|
|
103
|
+
if self.do_process_resource(each_resource_name):
|
|
104
|
+
each_resource : Resource = self.mod_gen.resource_list[each_resource_name]
|
|
105
|
+
description = "missing (requires genai creation)"
|
|
106
|
+
table_descriptions = self.mod_gen.project.table_descriptions
|
|
107
|
+
if each_resource.table_name in table_descriptions:
|
|
108
|
+
# als model desc's: api_logic_server_cli/sqlacodegen_wrapper/sqlacodegen/sqlacodegen/codegen.py
|
|
109
|
+
description = table_descriptions[each_resource.table_name]
|
|
110
|
+
description = description.replace("Table representing ", "")
|
|
111
|
+
description = description.replace("Table storing ", "")
|
|
112
|
+
description = description.replace("This table stores ", "")
|
|
113
|
+
description = description.replace("This table lists ", "")
|
|
114
|
+
description = description.replace("This table records ", "")
|
|
115
|
+
self.dbms_lines.append(f"{each_resource_name}: {description}")
|
|
116
|
+
self.dbms_lines.append("'''")
|
|
117
|
+
self.dbms_lines.append("}")
|
|
118
|
+
self.dbms_lines.append("")
|
|
119
|
+
|
|
120
|
+
def dbml_resources(self):
|
|
116
121
|
for each_resource_name in self.mod_gen.resource_list:
|
|
117
122
|
if self.do_process_resource(each_resource_name):
|
|
118
123
|
each_resource : Resource = self.mod_gen.resource_list[each_resource_name]
|
|
@@ -127,9 +132,7 @@ class DBMLCreator(object):
|
|
|
127
132
|
self.dbms_lines.append(" }")
|
|
128
133
|
self.dbms_lines.append("")
|
|
129
134
|
|
|
130
|
-
|
|
131
|
-
self.dbms_lines.append("")
|
|
132
|
-
self.dbms_lines.append("// Relationships") # Ref: users.(id) < follows.(followed_user_id)
|
|
135
|
+
def dbml_relationships(self):
|
|
133
136
|
for each_resource_name in self.mod_gen.resource_list:
|
|
134
137
|
if self.do_process_resource(each_resource_name):
|
|
135
138
|
each_resource : Resource = self.mod_gen.resource_list[each_resource_name]
|
|
@@ -152,6 +155,36 @@ class DBMLCreator(object):
|
|
|
152
155
|
if each_resource_reln.parent_resource == 'Location': # multi-field key example in nw
|
|
153
156
|
debug_stop = 'good breakpoint' # ' Ref: Order.(City, Country) < Location.(?, ?)'
|
|
154
157
|
|
|
158
|
+
def create_docs_dbml_file(self):
|
|
159
|
+
""" main driver - loop through resources, write admin.yaml - with backup, nw customization
|
|
160
|
+
|
|
161
|
+
Table Users {
|
|
162
|
+
id integerish
|
|
163
|
+
created_at timestamp
|
|
164
|
+
}
|
|
165
|
+
Ref: users.(id) < follows.(followed_user_id)
|
|
166
|
+
"""
|
|
167
|
+
|
|
168
|
+
''' decide about rebuild -- can you save positions?
|
|
169
|
+
if (self.mod_gen.project.command == "create-ui" or self.mod_gen.project.command.startswith("rebuild")) \
|
|
170
|
+
or self.mod_gen.project.command == "add_db":
|
|
171
|
+
if self.mod_gen.project.command.startswith("rebuild"):
|
|
172
|
+
log.debug(".. .. ..Use existing ui/admin directory")
|
|
173
|
+
else:
|
|
174
|
+
self.create_admin_app(msg=".. .. ..Create ui/admin")
|
|
175
|
+
'''
|
|
176
|
+
|
|
177
|
+
sys.path.append(self.mod_gen.project.os_cwd)
|
|
178
|
+
|
|
179
|
+
if do_table_descriptions := True:
|
|
180
|
+
self.dbml_descriptions()
|
|
181
|
+
|
|
182
|
+
self.dbml_resources()
|
|
183
|
+
|
|
184
|
+
self.dbms_lines.append("")
|
|
185
|
+
self.dbms_lines.append("")
|
|
186
|
+
self.dbms_lines.append("// Relationships") # Ref: users.(id) < follows.(followed_user_id)
|
|
187
|
+
self.dbml_relationships()
|
|
155
188
|
|
|
156
189
|
expose_docs_path = Path(self.mod_gen.project_directory).joinpath('docs')
|
|
157
190
|
expose_docs_path.mkdir(parents=True, exist_ok=True)
|
|
@@ -162,20 +195,41 @@ class DBMLCreator(object):
|
|
|
162
195
|
|
|
163
196
|
|
|
164
197
|
|
|
165
|
-
def
|
|
166
|
-
"""
|
|
198
|
+
def create_mcp_json_file(self):
|
|
199
|
+
""" create docs/mcp_schema.json - create self.mcp_schema['resources'] entries like:
|
|
200
|
+
|
|
201
|
+
'''
|
|
202
|
+
{
|
|
203
|
+
"name": "Customer",
|
|
204
|
+
"path": "/Customer",
|
|
205
|
+
"methods": ["GET", "PATCH"],
|
|
206
|
+
"fields": ["id", "name", "balance", "credit_limit"],
|
|
207
|
+
"filterable": ["name", "credit_limit"],
|
|
208
|
+
"example": "List customers with credit over 5000"
|
|
209
|
+
}
|
|
210
|
+
'''
|
|
167
211
|
"""
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
212
|
+
|
|
213
|
+
resources : list = self.mcp_schema['resources']
|
|
214
|
+
for each_resource_name in self.mod_gen.resource_list:
|
|
215
|
+
if self.do_process_resource(each_resource_name):
|
|
216
|
+
each_inserted_resource = {}
|
|
217
|
+
each_resource : Resource = self.mod_gen.resource_list[each_resource_name]
|
|
218
|
+
each_inserted_resource['name'] = each_resource.name
|
|
219
|
+
each_inserted_resource['path'] = '/' + each_resource.name
|
|
220
|
+
each_inserted_resource['methods'] = ["GET", "PATCH", "POST", "DELETE"]
|
|
221
|
+
each_inserted_resource['fields'] = []
|
|
222
|
+
for each_attr in each_resource.attributes:
|
|
223
|
+
each_inserted_resource['fields'].append(each_attr.name)
|
|
224
|
+
each_inserted_resource['filterable'] = each_inserted_resource['fields']
|
|
225
|
+
resources.append(each_inserted_resource)
|
|
226
|
+
docs_path = Path(self.mod_gen.project_directory).joinpath('docs')
|
|
227
|
+
docs_path.mkdir(parents=True, exist_ok=True)
|
|
228
|
+
mcp_schema_path = Path(self.mod_gen.project_directory).joinpath('docs/mcp_schema.json')
|
|
229
|
+
# write self.mcp_schema dict to json file
|
|
230
|
+
with open(mcp_schema_path, 'w') as f:
|
|
231
|
+
json.dump(self.mcp_schema, f, indent=4)
|
|
232
|
+
|
|
179
233
|
|
|
180
234
|
|
|
181
235
|
def create(model_creation_services: create_from_model.ModelCreationServices):
|
|
@@ -183,4 +237,5 @@ def create(model_creation_services: create_from_model.ModelCreationServices):
|
|
|
183
237
|
"""
|
|
184
238
|
dbml_creator = DBMLCreator(model_creation_services)
|
|
185
239
|
dbml_creator.create_docs_dbml_file()
|
|
240
|
+
dbml_creator.create_mcp_json_file()
|
|
186
241
|
|