ApiLogicServer 15.0.47__py3-none-any.whl → 15.0.52__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 (103) hide show
  1. api_logic_server_cli/api_logic_server.py +16 -5
  2. api_logic_server_cli/api_logic_server_info.yaml +3 -3
  3. api_logic_server_cli/cli.py +20 -16
  4. api_logic_server_cli/create_from_model/api_logic_server_utils.py +4 -1
  5. api_logic_server_cli/manager.py +24 -13
  6. api_logic_server_cli/prototypes/base/config/config.py +15 -0
  7. api_logic_server_cli/prototypes/base/venv_setup/requirements-no-cli.txt +5 -4
  8. api_logic_server_cli/prototypes/manager/.vscode/settings.json +1 -1
  9. api_logic_server_cli/prototypes/manager/{run_sample.sh → samples/docker_samples/run_sample_docker.sh} +4 -4
  10. api_logic_server_cli/prototypes/manager/samples/docker_samples/run_web_genai.sh +5 -0
  11. api_logic_server_cli/prototypes/manager/samples/readme_samples.md +22 -10
  12. api_logic_server_cli/prototypes/manager/system/app_model_editor/venv_setup/requirements-no-cli.txt +5 -4
  13. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/venv_setup/requirements-no-cli.txt +5 -4
  14. api_logic_server_cli/prototypes/manager/system/install-ApiLogicServer-dev/install-ApiLogicServer-dev.ps1 +7 -3
  15. api_logic_server_cli/prototypes/ont_app/ontimize_seed/package.json +2 -2
  16. api_logic_server_cli/sqlacodegen_wrapper/sqlacodegen/sqlacodegen/codegen.py +4 -2
  17. api_logic_server_cli/sqlacodegen_wrapper/sqlacodegen/sqlacodegen/main.py +25 -5
  18. api_logic_server_cli/sqlacodegen_wrapper/sqlacodegen_wrapper.py +25 -8
  19. {apilogicserver-15.0.47.dist-info → apilogicserver-15.0.52.dist-info}/METADATA +6 -5
  20. {apilogicserver-15.0.47.dist-info → apilogicserver-15.0.52.dist-info}/RECORD +24 -102
  21. api_logic_server_cli/create_from_model/__pycache__/__init__.cpython-312.pyc +0 -0
  22. api_logic_server_cli/create_from_model/__pycache__/api_expose_api_models_creator.cpython-312.pyc +0 -0
  23. api_logic_server_cli/create_from_model/__pycache__/api_logic_server_utils.cpython-312.pyc +0 -0
  24. api_logic_server_cli/create_from_model/__pycache__/create_db_from_model.cpython-312.pyc +0 -0
  25. api_logic_server_cli/create_from_model/__pycache__/dbml.cpython-312.pyc +0 -0
  26. api_logic_server_cli/create_from_model/__pycache__/meta_model.cpython-312.pyc +0 -0
  27. api_logic_server_cli/create_from_model/__pycache__/model_creation_services.cpython-312.pyc +0 -0
  28. api_logic_server_cli/create_from_model/__pycache__/ont_build.cpython-312.pyc +0 -0
  29. api_logic_server_cli/create_from_model/__pycache__/ont_create.cpython-312.pyc +0 -0
  30. api_logic_server_cli/create_from_model/__pycache__/ui_admin_creator.cpython-312.pyc +0 -0
  31. api_logic_server_cli/create_from_model/__pycache__/uri_info.cpython-312.pyc +0 -0
  32. api_logic_server_cli/prototypes/manager/run_web_genai.sh +0 -6
  33. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/__pycache__/api_logic_server_run.cpython-312.pyc +0 -0
  34. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/__pycache__/__init__.cpython-312.pyc +0 -0
  35. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/__pycache__/customize_api.cpython-312.pyc +0 -0
  36. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/__pycache__/expose_api_models.cpython-312.pyc +0 -0
  37. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/__pycache__/json_encoder.cpython-312.pyc +0 -0
  38. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/api_discovery/__pycache__/auto_discovery.cpython-312.pyc +0 -0
  39. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/api_discovery/__pycache__/new_service.cpython-312.pyc +0 -0
  40. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/api_discovery/__pycache__/newer_service.cpython-312.pyc +0 -0
  41. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/api_discovery/__pycache__/ontimize_api.cpython-312.pyc +0 -0
  42. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/api_discovery/__pycache__/system.cpython-312.pyc +0 -0
  43. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/system/__pycache__/api_utils.cpython-312.pyc +0 -0
  44. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/system/__pycache__/custom_endpoint.cpython-312.pyc +0 -0
  45. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/system/__pycache__/expression_parser.cpython-312.pyc +0 -0
  46. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/system/__pycache__/gen_csv_report.cpython-312.pyc +0 -0
  47. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/system/__pycache__/gen_pdf_report.cpython-312.pyc +0 -0
  48. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/system/opt_locking/__pycache__/opt_locking.cpython-312.pyc +0 -0
  49. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/config/__pycache__/__init__.cpython-312.pyc +0 -0
  50. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/config/__pycache__/activate_logicbank.cpython-312.pyc +0 -0
  51. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/config/__pycache__/config.cpython-312.pyc +0 -0
  52. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/config/__pycache__/server_setup.cpython-312.pyc +0 -0
  53. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/database/__pycache__/__init__.cpython-312.pyc +0 -0
  54. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/database/__pycache__/bind_dbs.cpython-312.pyc +0 -0
  55. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/database/__pycache__/customize_models.cpython-312.pyc +0 -0
  56. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/database/__pycache__/models.cpython-312.pyc +0 -0
  57. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/database/alembic/__pycache__/env.cpython-312.pyc +0 -0
  58. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/database/database_discovery/__pycache__/authentication_models.cpython-312.pyc +0 -0
  59. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/database/database_discovery/__pycache__/auto_discovery.cpython-312.pyc +0 -0
  60. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/database/db_debug/__pycache__/db_debug.cpython-312.pyc +0 -0
  61. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/database/system/__pycache__/SAFRSBaseX.cpython-312.pyc +0 -0
  62. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/database/test_data/__pycache__/alp_init.cpython-312.pyc +0 -0
  63. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/database/test_data/__pycache__/response2code.cpython-312.pyc +0 -0
  64. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/database/test_data/__pycache__/test_data_preamble.cpython-312.pyc +0 -0
  65. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/devops/keycloak/unused/__pycache__/auth_provider.cpython-312.pyc +0 -0
  66. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/devops/python-anywhere/__pycache__/python_anywhere_wsgi.cpython-312.pyc +0 -0
  67. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/integration/kafka/__pycache__/kafka_consumer.cpython-312.pyc +0 -0
  68. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/integration/kafka/__pycache__/kafka_producer.cpython-312.pyc +0 -0
  69. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/integration/n8n/__pycache__/n8n_producer.cpython-312.pyc +0 -0
  70. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/integration/system/__pycache__/FlaskKafka.cpython-312.pyc +0 -0
  71. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/integration/system/__pycache__/RowDictMapper.cpython-312.pyc +0 -0
  72. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/logic/__pycache__/declare_logic.cpython-312.pyc +0 -0
  73. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/logic/__pycache__/load_verify_rules.cpython-312.pyc +0 -0
  74. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/logic/logic_discovery/__pycache__/auto_discovery.cpython-312.pyc +0 -0
  75. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/security/__pycache__/__init__.cpython-312.pyc +0 -0
  76. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/security/__pycache__/declare_security.cpython-312.pyc +0 -0
  77. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/security/authentication_provider/__pycache__/__init__.cpython-312.pyc +0 -0
  78. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/security/authentication_provider/__pycache__/abstract_authentication_provider.cpython-312.pyc +0 -0
  79. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/security/authentication_provider/keycloak/__pycache__/auth_provider.cpython-312.pyc +0 -0
  80. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/security/authentication_provider/memory/__pycache__/auth_provider.cpython-312.pyc +0 -0
  81. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/security/authentication_provider/memory/__pycache__/auth_provider_no_swagger.cpython-312.pyc +0 -0
  82. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/security/authentication_provider/sql/__pycache__/auth_provider.cpython-312.pyc +0 -0
  83. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/security/system/__pycache__/authentication.cpython-312.pyc +0 -0
  84. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/security/system/__pycache__/authorization.cpython-312.pyc +0 -0
  85. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/test/__pycache__/__init__.cpython-312.pyc +0 -0
  86. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/test/api_logic_server_behave/__pycache__/__init__.cpython-312.pyc +0 -0
  87. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/test/api_logic_server_behave/__pycache__/behave_logic_report.cpython-312.pyc +0 -0
  88. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/test/api_logic_server_behave/__pycache__/behave_run.cpython-312.pyc +0 -0
  89. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/test/api_logic_server_behave/features/steps/__pycache__/about.cpython-312.pyc +0 -0
  90. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/test/api_logic_server_behave/features/steps/__pycache__/test_utils.cpython-312.pyc +0 -0
  91. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/test/basic/__pycache__/server_test.cpython-312.pyc +0 -0
  92. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/ui/__pycache__/__init__.cpython-312.pyc +0 -0
  93. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/ui/admin/__pycache__/admin_loader.cpython-312.pyc +0 -0
  94. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/venv_setup/__pycache__/py.cpython-312.pyc +0 -0
  95. api_logic_server_cli/sqlacodegen_wrapper/__pycache__/__init__.cpython-312.pyc +0 -0
  96. api_logic_server_cli/sqlacodegen_wrapper/__pycache__/sqlacodegen_wrapper.cpython-312.pyc +0 -0
  97. api_logic_server_cli/sqlacodegen_wrapper/sqlacodegen/__pycache__/__init__.cpython-312.pyc +0 -0
  98. api_logic_server_cli/sqlacodegen_wrapper/sqlacodegen/sqlacodegen/__pycache__/__init__.cpython-312.pyc +0 -0
  99. api_logic_server_cli/sqlacodegen_wrapper/sqlacodegen/sqlacodegen/__pycache__/codegen.cpython-312.pyc +0 -0
  100. {apilogicserver-15.0.47.dist-info → apilogicserver-15.0.52.dist-info}/WHEEL +0 -0
  101. {apilogicserver-15.0.47.dist-info → apilogicserver-15.0.52.dist-info}/entry_points.txt +0 -0
  102. {apilogicserver-15.0.47.dist-info → apilogicserver-15.0.52.dist-info}/licenses/LICENSE +0 -0
  103. {apilogicserver-15.0.47.dist-info → apilogicserver-15.0.52.dist-info}/top_level.txt +0 -0
@@ -12,10 +12,11 @@ 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__ = "15.00.47" # last public release: 15.00.41 (15.00.12)
15
+ __version__ = "15.00.52" # last public release: 15.00.47 (15.00.12)
16
16
  recent_changes = \
17
17
  f'\n\nRecent Changes:\n' +\
18
- "\t07/14/2024 - 15.00.47: venv fix, copilot vibe tweaks - creation, mcp logic, basic_demo autonums \n"\
18
+ "\t07/20/2024 - 15.00.52: Python 3.13 compatibility fixes - psycopg2→psycopg3, SQLAlchemy 2.0+, pkg_resources→importlib.metadata. mgr dbs \n"\
19
+ "\t07/17/2024 - 15.00.49: venv fix+, ext bldr * fix, copilot vibe tweaks - creation, mcp logic, basic_demo autonums \n"\
19
20
  "\t07/10/2024 - 15.00.41: copilot vibe support for logic, UI, MCP, bug[98] \n"\
20
21
  "\t06/30/2024 - 15.00.33: Tech Preview: genai-logic genai-add-app --vibe, bug [96, 97] \n"\
21
22
  "\t06/10/2024 - 15.00.12: MCP Security, win fixes for readme, graphics quotes \n"\
@@ -463,6 +464,13 @@ def create_project_and_overlay_prototypes(project: 'ProjectRun', msg: str) -> st
463
464
  copy_sqlite = True
464
465
  if copy_sqlite == False or "sqlite" not in project.abs_db_url:
465
466
  db_uri = get_windows_path_with_slashes(project.abs_db_url)
467
+
468
+ # Convert PostgreSQL URL for Python 3.13+ compatibility
469
+ import sys
470
+ if sys.version_info >= (3, 13) and db_uri.startswith('postgresql://'):
471
+ db_uri = db_uri.replace('postgresql://', 'postgresql+psycopg://')
472
+ log.debug(f'.. ..Converted PostgreSQL URL for Python 3.13+: {db_uri}')
473
+
466
474
  create_utils.replace_string_in_file(search_for="replace_db_url",
467
475
  replace_with=db_uri,
468
476
  in_file=f'{project.project_directory}/config/config.py')
@@ -915,7 +923,10 @@ def start_open_with(project: Project):
915
923
 
916
924
  def invoke_extended_builder(builder_path, db_url, project_directory, model_creation_services):
917
925
  # spec = importlib.util.spec_from_file_location("module.name", "/path/to/file.py")
918
- spec = importlib.util.spec_from_file_location("module.name", builder_path)
926
+ use_builder_path = builder_path
927
+ if builder_path == '*':
928
+ use_builder_path = Path('extended_builder.py')
929
+ spec = importlib.util.spec_from_file_location("module.name", use_builder_path)
919
930
  extended_builder = importlib.util.module_from_spec(spec)
920
931
  spec.loader.exec_module(extended_builder) # runs "bare" module code (e.g., initialization)
921
932
  extended_builder.extended_builder(db_url, project_directory, model_creation_services) # extended_builder.MyClass()
@@ -1194,8 +1205,8 @@ class ProjectRun(Project):
1194
1205
  log.debug(f'.. .. ..Copying sqlite database to: database/{self.bind_key}_db.sqlite')
1195
1206
  db_loc = self.abs_db_url.replace("sqlite:///", "")
1196
1207
  if os.name == "nt":
1197
- if db_loc.startswith("C:\C:"): # windows
1198
- db_loc = db_loc.replace("C:\C:", "C:") # remove unk junk
1208
+ if db_loc.startswith(r"C:\C:"): # windows
1209
+ db_loc = db_loc.replace(r"C:\C:", "C:") # remove unk junk
1199
1210
  target_db_loc_actual = str(self.project_directory_path.joinpath(f'database/{self.bind_key}_db.sqlite'))
1200
1211
  # target: /Users/val/dev/ApiLogicServer/ApiLogicServer-dev/org_git/servers/NW_NoCust/database/Todo_db.sqlite
1201
1212
  # e.g., /Users/val/dev/ApiLogicServer/ApiLogicServer-dev/servers/NW_NoCust/database
@@ -1,3 +1,3 @@
1
- last_created_date: July 14, 2025 19:56:50
2
- last_created_project_name: ApiLogicProject
3
- last_created_version: 15.00.46
1
+ last_created_date: July 20, 2025 08:02:02
2
+ last_created_project_name: samples/nw_sample_nocust
3
+ last_created_version: 15.00.52
@@ -188,14 +188,16 @@ def main(ctx):
188
188
  Creation is from your database (--db-url identifies a SQLAlchemy database)
189
189
 
190
190
  \b
191
- Doc: https://apilogicserver.github.io/Docs
191
+ Synonym to genai-logic: gail | gal
192
+ \b
193
+ Doc: https://apilogicserver.github.io/Docs/Doc-Home/
192
194
  And: https://apilogicserver.github.io/Docs/Database-Connectivity/
193
195
  \b
194
196
  Suggestions:
195
197
 
196
198
  \b
197
- ApiLogicServer start # create and manage projects
198
- ApiLogicServer create --db-url= --project-name= # defaults to Northwind sample
199
+ genai-logic start # create and manage projects
200
+ genai-logic create --db-url= --project-name= # defaults to Northwind sample
199
201
  """
200
202
  pass # all commands come through here
201
203
 
@@ -1083,13 +1085,13 @@ def genai_iterate(ctx, project_name: str, using: str):
1083
1085
  help="your_code.py for additional build automation")
1084
1086
  @click.option('--include_tables',
1085
1087
  default=f'',
1086
- help="yml for include: exclude:")
1088
+ help="yml for include, exclude")
1087
1089
  @click.option('--include-tables', 'include_tables',
1088
1090
  default=f'',
1089
- help="yml for include: exclude:")
1091
+ help="yml for include, exclude")
1090
1092
  @click.option('--infer_primary_key/--no_infer_primary_key',
1091
1093
  default=False, is_flag=True,
1092
- help="xInfer primary_key for unique cols")
1094
+ help="Infer primary_key for unique cols")
1093
1095
  @click.option('--infer-primary-key/--no-infer-primary-key', 'infer_primary_key',
1094
1096
  default=False, is_flag=True,
1095
1097
  help="Infer primary-key for unique cols")
@@ -1250,22 +1252,22 @@ def create(ctx, project_name: str, db_url: str, not_exposed: str, api_name: str,
1250
1252
  help="Swagger hostname (default is localhost)")
1251
1253
  @click.option('--extended_builder',
1252
1254
  default=f'',
1253
- help="your_code.py for additional build automation")
1255
+ help="your python for additional build automation")
1254
1256
  @click.option('--extended-builder', 'extended_builder',
1255
1257
  default=f'',
1256
- help="your_code.py for additional build automation")
1258
+ help="your python for additional build automation")
1257
1259
  @click.option('--include_tables',
1258
1260
  default=f'',
1259
- help="yml for include: exclude:")
1261
+ help="yml for include / exclude")
1260
1262
  @click.option('--include-tables', 'include_tables',
1261
1263
  default=f'',
1262
- help="yml for include: exclude:")
1264
+ help="yml for include / exclude")
1263
1265
  @click.option('--infer_primary_key/--no_infer_primary_key',
1264
1266
  default=False, is_flag=True,
1265
- help="Infer primary-key for unique cols")
1267
+ help="Infer primary key for unique cols")
1266
1268
  @click.option('--infer-primary-key/--no-infer-primary-key', 'infer_primary_key',
1267
1269
  default=False, is_flag=True,
1268
- help="Infer primary-key for unique cols")
1270
+ help="Unique cols infer primary key")
1269
1271
  @click.pass_context
1270
1272
  def create_and_run(ctx, project_name: str, db_url: str, not_exposed: str, api_name: str,
1271
1273
  from_git: str,
@@ -1280,11 +1282,13 @@ def create_and_run(ctx, project_name: str, db_url: str, not_exposed: str, api_na
1280
1282
  host: str,
1281
1283
  port: str,
1282
1284
  swagger_host: str,
1283
- favorites: str, non_favorites: str,
1285
+ favorites: str,
1286
+ non_favorites: str,
1284
1287
  extended_builder: str,
1285
1288
  include_tables: str,
1286
1289
  multi_api: click.BOOL,
1287
- opt_locking: str, opt_locking_attr: str,
1290
+ opt_locking: str,
1291
+ opt_locking_attr: str,
1288
1292
  id_column_alias: str,
1289
1293
  infer_primary_key: click.BOOL):
1290
1294
  """
@@ -2122,7 +2126,7 @@ if __name__ == '__main__': # debugger & python command line start here
2122
2126
  "show-args" in api_logic_server_info_file_dict:
2123
2127
  print_args(commands, f'\nCommand Line Arguments:')
2124
2128
  python_version = sys.version_info
2125
- assert python_version[0] >= 3 and python_version[1] in [10,11,12], \
2126
- "... Requires Python >=3.10, !=3.11.0, !=3.11.1, 3.12"
2129
+ assert python_version[0] >= 3 and python_version[1] in [10,11,12, 13], \
2130
+ "... Requires Python >=3.10, !=3.11.0, !=3.11.1, 3.12, 3.13"
2127
2131
  main()
2128
2132
 
@@ -293,10 +293,13 @@ def get_abs_db_url(msg, project: Project, is_auth: bool = False):
293
293
  else:
294
294
  rtn_abs_db_url = f'sqlite:///{str(project.api_logic_server_dir_path.joinpath("prototypes/sample_ai/database/chatgpt/sample_ai_items.sqlite"))}'
295
295
  # log.info('.. using installed nw sample database')
296
- else:
296
+ else: # for win, might be: sqlite:////C:\\Users\\val\\dev\\ApiLogicServer\\ApiLogicServer-dev\\org_git\\ApiLogicServer-src\\api_logic_server_cli\\database\\mcp.sqlite
297
297
  url = url_to_process[10: len(url_to_process)]
298
+ if url_to_process.startswith('sqlite:////c:'):
299
+ url = url_to_process[11: len(url_to_process)]
298
300
  rtn_abs_db_url = abspath(url)
299
301
  rtn_abs_db_url = 'sqlite:///' + rtn_abs_db_url
302
+ pass
300
303
  elif url_to_process == 'sqlsvr-sample': # work-around - VSCode run config arg parsing
301
304
  rtn_abs_db_url = 'mssql+pyodbc://sa:Posey3861@localhost:1433/SampleDB?driver=ODBC+Driver+18+for+SQL+Server&trusted_connection=no&Encrypt=no'
302
305
  elif url_to_process == 'sqlsvr-nwlogic': # work-around - VSCode run config arg parsing
@@ -36,9 +36,9 @@ def create_manager(clean: bool, open_with: str, api_logic_server_path: Path,
36
36
  samples (bool, optional): Whether to create large samples (prevent win max file length)
37
37
  """
38
38
 
39
- def create_sym_links(cli_path: Path, mgr_path: Path):
39
+ def copy_sqlite_dbs(cli_path: Path, mgr_path: Path):
40
40
  """
41
- Creates symbolic links to sample dbs and prompts (clearer than db abbreviations).
41
+ Copy sample sqlite databases to mgr/samples/dbs (clearer than db abbreviations).
42
42
 
43
43
  Args:
44
44
  cli_path (Path): loc of cli.py in the manager's venv
@@ -48,16 +48,27 @@ def create_manager(clean: bool, open_with: str, api_logic_server_path: Path,
48
48
  Creates a symbolic link from 'cli_path/database/basic_demo.sqlite' to 'mgr_path/samples/dbs/basic_demo'.
49
49
 
50
50
  """
51
-
52
- # create symbolic link - thanks https://www.geeksforgeeks.org/python/python-os-symlink-method/
53
- try:
54
- os.symlink(cli_path.parent / 'database/basic_demo.sqlite', mgr_path / 'samples/dbs/basic_demo.sqlite')
55
- os.symlink(cli_path.parent / 'database/nw-gold.sqlite', mgr_path / 'samples/dbs/nw.sqlite')
56
- os.symlink(cli_path.parent / 'database/Chinook_Sqlite.sqlite', mgr_path / 'samples/dbs/chinook.sqlite')
57
- os.symlink(cli_path.parent / 'database/classicmodels.sqlite', mgr_path / 'samples/dbs/classicmodels.sqlite')
58
- log.debug("✅ Manager Creation - SymLink created: samples/dbs/")
59
- except Exception as e:
60
- log.debug(f"❌ Manager Creation - SymLink creation failed: {str(e)}")
51
+ if use_syn_link := False:
52
+ # could create symbolic link - thanks https://www.geeksforgeeks.org/python/python-os-symlink-method/
53
+ # but this fails on windows due to permissions
54
+ try:
55
+ os.symlink(cli_path.parent / 'database/basic_demo.sqlite', mgr_path / 'samples/dbs/basic_demo.sqlite')
56
+ os.symlink(cli_path.parent / 'database/nw-gold.sqlite', mgr_path / 'samples/dbs/nw.sqlite')
57
+ os.symlink(cli_path.parent / 'database/Chinook_Sqlite.sqlite', mgr_path / 'samples/dbs/chinook.sqlite')
58
+ os.symlink(cli_path.parent / 'database/classicmodels.sqlite', mgr_path / 'samples/dbs/classicmodels.sqlite')
59
+ log.debug("✅ Manager Creation - SymLink created: samples/dbs/")
60
+ except Exception as e:
61
+ log.debug(f"❌ Manager Creation - Copy samples/dbs SymLink creation failed: {str(e)}")
62
+ else:
63
+ try:
64
+ copyfile(cli_path.parent / 'database/basic_demo.sqlite', mgr_path / 'samples/dbs/basic_demo.sqlite')
65
+ copyfile(cli_path.parent / 'database/nw-gold.sqlite', mgr_path / 'samples/dbs/nw.sqlite')
66
+ copyfile(cli_path.parent / 'database/Chinook_Sqlite.sqlite', mgr_path / 'samples/dbs/chinook.sqlite')
67
+ copyfile(cli_path.parent / 'database/classicmodels.sqlite', mgr_path / 'samples/dbs/classicmodels.sqlite')
68
+ copyfile(cli_path.parent / 'database/todos.sqlite', mgr_path / 'samples/dbs/todos.sqlite')
69
+ log.debug("✅ Manager Creation - Created: samples/dbs/")
70
+ except Exception as e:
71
+ log.debug(f"❌ Manager Creation - Copy samples/dbs creation failed: {str(e)}")
61
72
 
62
73
 
63
74
  log = logging.getLogger(__name__)
@@ -218,7 +229,7 @@ def create_manager(clean: bool, open_with: str, api_logic_server_path: Path,
218
229
  create_utils.replace_string_in_file(search_for = 'cli_path',
219
230
  replace_with=str(cli_str),
220
231
  in_file=vscode_launch_path)
221
- create_sym_links(cli_path=cli_path, mgr_path=to_dir)
232
+ copy_sqlite_dbs(cli_path=cli_path, mgr_path=to_dir)
222
233
 
223
234
  if env_path.exists():
224
235
  create_utils.replace_string_in_file(search_for = 'APILOGICSERVER_AUTO_OPEN=code',
@@ -133,6 +133,12 @@ class Config:
133
133
  SQLALCHEMY_DATABASE_URI : typing.Optional[str] = f"replace_db_url"
134
134
  # override SQLALCHEMY_DATABASE_URI here as required
135
135
 
136
+ # Python 3.13+ compatibility: Convert PostgreSQL URLs to use psycopg3
137
+ import sys
138
+ if sys.version_info >= (3, 13) and SQLALCHEMY_DATABASE_URI.startswith('postgresql://'):
139
+ SQLALCHEMY_DATABASE_URI = SQLALCHEMY_DATABASE_URI.replace('postgresql://', 'postgresql+psycopg://')
140
+ app_logger.debug(f'config.py - converted PostgreSQL URL for Python 3.13+: {SQLALCHEMY_DATABASE_URI}')
141
+
136
142
  BACKTIC_AS_QUOTE = False # use backtic as quote for table names for API Bridge
137
143
  if SQLALCHEMY_DATABASE_URI.startswith("mysql") or SQLALCHEMY_DATABASE_URI.startswith("mariadb"):
138
144
  BACKTIC_AS_QUOTE = True
@@ -145,6 +151,11 @@ class Config:
145
151
  if os.getenv('SQLALCHEMY_DATABASE_URI'): # e.g. export SECURITY_ENABLED=true
146
152
  SQLALCHEMY_DATABASE_URI = os.getenv('SQLALCHEMY_DATABASE_URI')
147
153
  app_logger.debug(f'.. overridden from env variable: {SQLALCHEMY_DATABASE_URI}')
154
+
155
+ # Python 3.13+ compatibility: Convert PostgreSQL URLs to use psycopg3 (for env override)
156
+ if sys.version_info >= (3, 13) and SQLALCHEMY_DATABASE_URI.startswith('postgresql://'):
157
+ SQLALCHEMY_DATABASE_URI = SQLALCHEMY_DATABASE_URI.replace('postgresql://', 'postgresql+psycopg://')
158
+ app_logger.debug(f'config.py - converted PostgreSQL URL for Python 3.13+: {SQLALCHEMY_DATABASE_URI}')
148
159
 
149
160
 
150
161
  # KEYCLOAK Args
@@ -178,6 +189,10 @@ class Config:
178
189
  # Begin Multi-Database URLs (from ApiLogicServer add-db...)
179
190
  auth_db_path = str(project_path.joinpath('database/authentication_db.sqlite'))
180
191
  SQLALCHEMY_DATABASE_URI_AUTHENTICATION = f'sqlite:///{auth_db_path}'
192
+ # Python 3.13+ compatibility: Convert PostgreSQL URLs to use psycopg3 (for env override)
193
+ if sys.version_info >= (3, 13) and SQLALCHEMY_DATABASE_URI_AUTHENTICATION.startswith('postgresql://'):
194
+ SQLALCHEMY_DATABASE_URI_AUTHENTICATION = SQLALCHEMY_DATABASE_URI_AUTHENTICATION.replace('postgresql://', 'postgresql+psycopg://')
195
+ app_logger.debug(f'config.py - converted PostgreSQL URL for Python 3.13+: {SQLALCHEMY_DATABASE_URI_AUTHENTICATION}')
181
196
  app_logger.info(f'config.py - SQLALCHEMY_DATABASE_URI_AUTHENTICATION: {SQLALCHEMY_DATABASE_URI_AUTHENTICATION}\n')
182
197
 
183
198
  # as desired, use env variable: export SQLALCHEMY_DATABASE_URI='sqlite:////Users/val/dev/servers/docker_api_logic_project/database/db.sqliteXX'
@@ -1,9 +1,9 @@
1
1
  PyJWT==2.6.0
2
2
  python-dateutil==2.8.2
3
3
  six==1.16.0
4
- SQLAlchemy==1.4.29
5
- Flask-SQLAlchemy==2.5.1
6
- SQLAlchemy-Utils==0.38.2
4
+ SQLAlchemy>=2.0.0
5
+ Flask-SQLAlchemy>=3.0.0
6
+ SQLAlchemy-Utils>=0.38.2
7
7
  Werkzeug==2.2.3
8
8
  logicbankutils==0.6.0
9
9
  inflect==5.0.2
@@ -25,7 +25,8 @@ PyMySQL==1.0.2
25
25
  cryptography==36.0.1
26
26
  requests==2.27.1
27
27
  gunicorn==20.1.0
28
- psycopg2-binary==2.9.5
28
+ psycopg2-binary>=2.9.5; python_version < '3.13'
29
+ psycopg[binary]>=3.1.0; python_version >= '3.13'
29
30
  DotMap==1.3.25
30
31
  WTForms==2.3.3
31
32
  behave==1.2.6
@@ -20,5 +20,5 @@
20
20
  "workbench.editorAssociations": {
21
21
  "*.md": "vscode.markdown.preview.editor"
22
22
  },
23
- "workbench.colorTheme": "Visual Studio Light"
23
+ "workbench.colorTheme": "Arduino Light"
24
24
  }
@@ -14,8 +14,8 @@ if [ $# -eq 0 ]
14
14
  # echo "shell: $SHELL"
15
15
  echo " eg:"
16
16
  echo " "
17
- echo " > cd webgenai # or ApiLogicServer"
18
- echo " > sh run_sample.sh nw_sample_nocust"
17
+ echo " > cd ApiLogicServer # ONLY if already running under docker"
18
+ echo " > sh samples/docker_samples/run_sample_docker.sh nw_sample_nocust"
19
19
  echo " "
20
20
  exit 0
21
21
  fi
@@ -26,5 +26,5 @@ if [ "$1" = "$" ]
26
26
  sample="nw_sample"
27
27
  fi
28
28
 
29
- cd samples/$sample
30
- docker run -it --rm --name api_logic_project -p 5656:5656 --env-file ./devops/docker-standard-image/env.list -v ./:/app apilogicserver/web_genai python3 /app/api_logic_server_run.py
29
+ pushd samples/$sample
30
+ docker run -it --rm --name api_logic_project_${sample}_$(date +%s) -p 5656:5656 --env-file ./devops/docker-standard-image/env.list -v ./:/app apilogicserver/web_genai python3 /app/api_logic_server_run.py
@@ -0,0 +1,5 @@
1
+ # Run WebGenAI docker container
2
+
3
+ # sh samples/docker_samples/run_web_genai.sh
4
+
5
+ docker compose -f webgenai/docker-compose.yml up
@@ -6,7 +6,7 @@ The created `samples/nw_sample` illustrates important customization sample code
6
6
 
7
7
  ## Sqlite Sample Databases
8
8
 
9
- The `samples/db` files are symbolic links to pre-installed sqlite databases. These allow you to explore creating projects from existing databases.
9
+ The `samples/db` files are pre-installed sqlite databases. These allow you to explore creating projects from existing databases.
10
10
 
11
11
  For example, create Northwind like this:
12
12
 
@@ -14,24 +14,36 @@ For example, create Northwind like this:
14
14
  genai-logic create --project_name=nw --db_url=sqlite:///samples/dbs/nw.sqlite
15
15
  ```
16
16
 
17
- > Note: If the symbolic links are missing, it is probably due to permission issues, e.g., on windows you must run the Shell with Admin privileges. You can continue using the abbeviations instead of a standard SQLAlchemy database uri.
18
-
19
17
  ## Database Connectivity
20
18
 
21
19
  Sample project creation commands:
22
20
 
23
21
  ```bash
24
- genai-logic create
25
- genai-logic create-and-run
26
- genai-logic create --db_url=sqlite:////Users/val/dev/todo_example/todos.db --project_name=todo
22
+ # local sqlite
27
23
  genai-logic create --db_url=sqlite:///c:\genai-logic\nw.sqlite --project_name=nw
28
- genai-logic create --db_url=sqlite:///ai.sqlite --project_name=ai --open_with=code
29
- genai-logic create --db_url=mysql+pymysql://root:p@mysql-container:3306/classicmodels --project_name=/localhost/docker_db_project
30
- genai-logic create --db_url='mssql+pyodbc://sa:Posey3861@localhost:1433/NORTHWND?driver=ODBC+Driver+18+for+SQL+Server&trusted_connection=no&Encrypt=no'
24
+ genai-logic create --db_url=sqlite:///samples/dbs/todos.sqlite --project_name=todo
25
+ genai-logic create --db_url=sqlite:////Users/val/dev/ApiLogicServer/ApiLogicServer-dev/clean/ApiLogicServer/samples/dbs/todos.sqlite --project_name=todo
26
+
27
+ # from localhost to mysql container
28
+ genai-logic create --db_url=mysql+pymysql://root:p@localhost:3306/classicmodels --project_name=docker_classicmodels
29
+ genai-logic create --db_url=mysql+pymysql://root:p@localhost:3306/Chinook --project_name=docker_chinook
30
+
31
+ # from container to mysql container replace localhost with....
32
+ genai-logic create --db_url=mysql+pymysql://root:p@mysql-container:3306/Chinook --project_name=/localhost/docker_chinook
33
+
34
+ # microsoft sql server (setup: https://apilogicserver.github.io/Docs/Install-pyodbc/)
35
+ genai-logic create --db_url='mssql+pyodbc://sa:Posey3861@localhost:1433/NORTHWND?driver=ODBC+Driver+18+for+SQL+Server&trusted_connection=no&Encrypt=no' --project-name=NORTHWND
36
+
37
+ # oracle
31
38
  genai-logic create --project_name=oracle_hr --db_url='oracle+oracledb://hr:tiger@localhost:1521/?service_name=ORCL'
39
+
40
+ # postgres
41
+ genai-logic create --db_url=postgresql://postgres:p@localhost/northwind --project-name=nw-postgres
32
42
  genai-logic create --db_url=postgresql://postgres:p@10.0.0.234/postgres
33
43
  genai-logic create --project_name=my_schema --db_url=postgresql://postgres:p@localhost/my_schema
34
- genai-logic create --db_url=postgresql+psycopg2://postgres:password@localhost:5432/postgres?options=-csearch_path%3Dmy_db_schema
44
+ genai-logic create --db_url=postgresql://postgres:password@localhost:5432/postgres?options=-csearch_path%3Dmy_db_schema
45
+
46
+ # pythonanywhere
35
47
  genai-logic create --project_name=Chinook \
36
48
  --host=ApiLogicServer.pythonanywhere.com --port= \
37
49
  --db_url=mysql+pymysql://ApiLogicServer:@ApiLogicServer.mysql.pythonanywhere-services.com/ApiLogicServer\$Chinook
@@ -1,9 +1,9 @@
1
1
  PyJWT==2.6.0
2
2
  python-dateutil==2.8.2
3
3
  six==1.16.0
4
- SQLAlchemy==1.4.29
5
- Flask-SQLAlchemy==2.5.1
6
- SQLAlchemy-Utils==0.38.2
4
+ SQLAlchemy>=2.0.0
5
+ Flask-SQLAlchemy>=3.0.0
6
+ SQLAlchemy-Utils>=0.38.2
7
7
  Werkzeug==2.2.3
8
8
  logicbankutils==0.6.0
9
9
  inflect==5.0.2
@@ -25,7 +25,8 @@ PyMySQL==1.0.2
25
25
  cryptography==36.0.1
26
26
  requests==2.27.1
27
27
  gunicorn==20.1.0
28
- psycopg2-binary==2.9.5
28
+ psycopg2-binary>=2.9.5; python_version < '3.13'
29
+ psycopg[binary]>=3.1.0; python_version >= '3.13'
29
30
  DotMap==1.3.25
30
31
  WTForms==2.3.3
31
32
  behave==1.2.6
@@ -1,9 +1,9 @@
1
1
  PyJWT==2.6.0
2
2
  python-dateutil==2.8.2
3
3
  six==1.16.0
4
- SQLAlchemy==1.4.29
5
- Flask-SQLAlchemy==2.5.1
6
- SQLAlchemy-Utils==0.38.2
4
+ SQLAlchemy>=2.0.0
5
+ Flask-SQLAlchemy>=3.0.0
6
+ SQLAlchemy-Utils>=0.38.2
7
7
  Werkzeug==2.2.3
8
8
  logicbankutils==0.6.0
9
9
  inflect==5.0.2
@@ -25,7 +25,8 @@ PyMySQL==1.0.2
25
25
  cryptography==36.0.1
26
26
  requests==2.27.1
27
27
  gunicorn==20.1.0
28
- psycopg2-binary==2.9.5
28
+ psycopg2-binary>=2.9.5; python_version < '3.13'
29
+ psycopg[binary]>=3.1.0; python_version >= '3.13'
29
30
  DotMap==1.3.25
30
31
  WTForms==2.3.3
31
32
  behave==1.2.6
@@ -4,7 +4,10 @@ param(
4
4
  [String]$IDE
5
5
  )
6
6
 
7
- SRA="venv/lib/python3.12/site-packages/api_logic_server_cli/create_from_model/safrs-react-admin-npm-build"
7
+ # $SRA="venv/lib/python3.12/site-packages/api_logic_server_cli/create_from_model/safrs-react-admin-npm-build"
8
+
9
+ $venvPath = "venv\Lib\site-packages"
10
+ $SRA = Join-Path $venvPath "api_logic_server_cli\create_from_model\safrs-react-admin-npm-build"
8
11
 
9
12
  if (Test-Path -Path $SRA) {
10
13
  Write-Output " "
@@ -12,7 +15,7 @@ if (Test-Path -Path $SRA) {
12
15
  Write-Output " "
13
16
  } else {
14
17
  Write-Output " "
15
- Write-Output "Safrs React Admin (SRA) not found - please fix line above"
18
+ Write-Output "Safrs React Admin (SRA) not found - please fix line above for $SRA"
16
19
  Write-Output " "
17
20
  Exit 1
18
21
  }
@@ -28,8 +31,9 @@ if($IDE -eq "") {
28
31
  Write-Output " "
29
32
  Write-Output " IMPORTANT - create a folder, then install:"
30
33
  Write-Output " > mkdir ApiLogicServer"
34
+ Write-Output " > pip install ApiLogicServer"
31
35
  Write-Output " "
32
- Write-Output " > .\Install-ApiLogicServer-Dev [ vscode | charm | x ]"
36
+ Write-Output " > .\system\install-ApiLogicServer-dev\install-ApiLogicServer-dev.ps1 vscode"
33
37
  Write-Output " "
34
38
  Exit
35
39
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ontimize-app",
3
- "version": "15.6.0-NEXT-2",
3
+ "version": "15.6.0-NEXT-7",
4
4
  "scripts": {
5
5
  "ng": "ng",
6
6
  "start": "ng serve --port 4299",
@@ -30,7 +30,7 @@
30
30
  "@angular/router": "^15.2.10",
31
31
  "@angular/service-worker": "^15.2.10",
32
32
  "@angular/upgrade": "^15.2.10",
33
- "ontimize-web-ngx": "15.6.0-next.4",
33
+ "ontimize-web-ngx": "15.6.0-next.7",
34
34
  "ontimize-web-ngx-charts": "15.2.0-next.3",
35
35
  "ontimize-web-ngx-filemanager": "^15.1.0-next.0",
36
36
  "ontimize-web-ngx-map": "15.0.0",
@@ -8,6 +8,7 @@ from collections import defaultdict
8
8
  from importlib import import_module
9
9
  from inspect import FullArgSpec # val-311
10
10
  from keyword import iskeyword
11
+ from typing import TYPE_CHECKING
11
12
 
12
13
  import sqlalchemy
13
14
  import sqlalchemy.exc
@@ -22,7 +23,8 @@ import yaml
22
23
  import datetime
23
24
 
24
25
  # The generic ARRAY type was introduced in SQLAlchemy 1.1
25
- from api_logic_server_cli.create_from_model.model_creation_services import ModelCreationServices
26
+ if TYPE_CHECKING:
27
+ from api_logic_server_cli.create_from_model.model_creation_services import ModelCreationServices
26
28
  from api_logic_server_cli.create_from_model.meta_model import Resource, ResourceRelationship, ResourceAttribute
27
29
 
28
30
  log = logging.getLogger(__name__)
@@ -818,7 +820,7 @@ class CodeGenerator(object):
818
820
  """ not used by API Logic Server """
819
821
  self.noinflect = noinflect
820
822
  self.noclasses = noclasses
821
- self.model_creation_services = model_creation_services # type: ModelCreationServices
823
+ self.model_creation_services = model_creation_services # type: "ModelCreationServices"
822
824
  self.generate_relationships_on = "parent" # "child"
823
825
  """ FORMERLY, relns were genned ONLY on parent (== 'parent') """
824
826
  self.indentation = indentation
@@ -4,11 +4,23 @@ import argparse
4
4
  import io
5
5
  import sys
6
6
 
7
- import pkg_resources
7
+ try:
8
+ from importlib import metadata
9
+ except ImportError:
10
+ # Python < 3.8
11
+ import pkg_resources as metadata_fallback
12
+
13
+ class MetadataWrapper:
14
+ @staticmethod
15
+ def version(name):
16
+ return metadata_fallback.get_distribution(name).version
17
+
18
+ metadata = MetadataWrapper()
19
+
8
20
  from sqlalchemy.engine import create_engine
9
21
  from sqlalchemy.schema import MetaData
10
22
 
11
- from sqlacodegen_wrapper.sqlacodegen_wrapper import CodeGenerator
23
+ from .codegen import CodeGenerator
12
24
 
13
25
 
14
26
  def main(calling_args=None):
@@ -30,8 +42,11 @@ def main(calling_args=None):
30
42
  args = parser.parse_args()
31
43
 
32
44
  if args.version:
33
- version = pkg_resources.get_distribution('sqlacodegen').parsed_version
34
- print(version.public)
45
+ try:
46
+ version = metadata.version('sqlacodegen')
47
+ print(version)
48
+ except Exception:
49
+ print("sqlacodegen version unknown")
35
50
  return
36
51
  if not args.url:
37
52
  print('You must supply a url\n', file=sys.stderr)
@@ -39,7 +54,12 @@ def main(calling_args=None):
39
54
  return
40
55
 
41
56
  # Use reflection to fill in the metadata
42
- engine = create_engine(args.url)
57
+ # For Python 3.13+, force PostgreSQL URLs to use psycopg3 dialect
58
+ engine_url = args.url
59
+ if sys.version_info >= (3, 13) and engine_url.startswith('postgresql://'):
60
+ engine_url = engine_url.replace('postgresql://', 'postgresql+psycopg://', 1)
61
+
62
+ engine = create_engine(engine_url)
43
63
  try:
44
64
  # dirty hack for sqlite TODO review ApiLogicServer
45
65
  engine.execute("""PRAGMA journal_mode = OFF""")
@@ -29,6 +29,11 @@ The ctor then calls `create_resource_list`, to create the `resource_list`
29
29
 
30
30
  import sys, logging, inspect, builtins, os, argparse, tempfile, atexit, shutil, io
31
31
  import traceback
32
+ try:
33
+ from importlib.metadata import version as get_version
34
+ except ImportError:
35
+ # Python < 3.8 fallback
36
+ from importlib_metadata import version as get_version
32
37
 
33
38
  import safrs
34
39
  from sqlalchemy import CHAR, Column, DateTime, Float, ForeignKey, Index, Integer, String, TIMESTAMP, Table, Text, UniqueConstraint, text
@@ -44,8 +49,11 @@ from io import StringIO
44
49
  from sqlalchemy.engine import create_engine
45
50
  from sqlalchemy.schema import MetaData
46
51
  from flask_cors import CORS
47
- from sqlacodegen_wrapper.sqlacodegen.sqlacodegen.codegen import CodeGenerator
48
- from api_logic_server_cli.create_from_model.model_creation_services import ModelCreationServices
52
+ from .sqlacodegen.sqlacodegen.codegen import CodeGenerator
53
+ from .sqlacodegen.sqlacodegen.main import main as codegen
54
+ from typing import TYPE_CHECKING
55
+ if TYPE_CHECKING:
56
+ from api_logic_server_cli.create_from_model.model_creation_services import ModelCreationServices
49
57
  from pathlib import Path
50
58
  from shutil import copyfile
51
59
  import os, sys
@@ -91,8 +99,11 @@ def get_args():
91
99
  args = parser.parse_args()
92
100
 
93
101
  if args.version:
94
- version = pkg_resources.get_distribution("sqlacodegen").parsed_version # noqa: F821
95
- log.debug(version.public)
102
+ try:
103
+ version_str = get_version("sqlacodegen")
104
+ log.debug(version_str)
105
+ except Exception:
106
+ log.debug("sqlacodegen version not found")
96
107
  exit()
97
108
  if not args.url:
98
109
  log.debug("You must supply a url\n", file=sys.stderr)
@@ -133,7 +144,7 @@ uri_info = """Examples:
133
144
  ApiLogicServer create-and-run --db_url=mssql+pyodbc://sa:Posey3861@localhost:1433/NORTHWND?driver=ODBC+Driver+17+for+SQL+Server&trusted_connection=no
134
145
  ApiLogicServer create-and-run --db_url=postgresql://postgres:p@10.0.0.234/postgres
135
146
  ApiLogicServer create --project_name=my_schema --db_url=postgresql://postgres:p@localhost/my_schema
136
- ApiLogicServer create --db_url=postgresql+psycopg2://postgres:password@localhost:5432/postgres?options=-csearch_path%3Dmy_db_schema
147
+ ApiLogicServer create --db_url=postgresql://postgres:password@localhost:5432/postgres?options=-csearch_path%3Dmy_db_schema
137
148
  ApiLogicServer create --project_name=Chinook \
138
149
  --host=ApiLogicServer.pythonanywhere.com --port= \
139
150
  --db_url=mysql+pymysql://ApiLogicServer:***@ApiLogicServer.mysql.pythonanywhere-services.com/ApiLogicServer$Chinook
@@ -199,7 +210,13 @@ def create_models_memstring(args) -> str:
199
210
 
200
211
  if os.getenv('APILOGICSERVER_ORACLE_THICK'):
201
212
  oracledb.init_oracle_client(lib_dir=os.getenv('APILOGICSERVER_ORACLE_THICK'))
202
- engine = create_engine(args.url) # type _engine.Engine
213
+
214
+ # For Python 3.13+, force PostgreSQL URLs to use psycopg3 dialect
215
+ engine_url = args.url
216
+ if sys.version_info >= (3, 13) and engine_url.startswith('postgresql://'):
217
+ engine_url = engine_url.replace('postgresql://', 'postgresql+psycopg://', 1)
218
+
219
+ engine = create_engine(engine_url) # type _engine.Engine
203
220
 
204
221
  metadata = MetaData()
205
222
  if os.getenv('APILOGICSERVER_ORACLE_THICK'):
@@ -292,7 +309,7 @@ if on_import:
292
309
  models_f.write(models)
293
310
  # atexit.register(lambda : shutil.rmtree(MODEL_DIR))
294
311
 
295
- import models
312
+ import models # type: ignore # dynamically created module
296
313
 
297
314
 
298
315
  def start_api(HOST="0.0.0.0", PORT=5000):
@@ -338,7 +355,7 @@ if __name__ == "__main__":
338
355
 
339
356
 
340
357
 
341
- def create_models_py(model_creation_services: ModelCreationServices, abs_db_url: str, project_directory: str):
358
+ def create_models_py(model_creation_services: "ModelCreationServices", abs_db_url: str, project_directory: str):
342
359
  """
343
360
  Create `models.py` (using sqlacodegen, via this wrapper at create_models_py() ).
344
361