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.
Files changed (107) hide show
  1. api_logic_server_cli/add_cust/add_cust.py +283 -0
  2. api_logic_server_cli/api_logic_server.py +15 -237
  3. api_logic_server_cli/api_logic_server_info.yaml +3 -3
  4. api_logic_server_cli/cli.py +38 -28
  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__/dbml.cpython-312.pyc +0 -0
  7. api_logic_server_cli/create_from_model/__pycache__/ont_build.cpython-312.pyc +0 -0
  8. api_logic_server_cli/create_from_model/__pycache__/ont_create.cpython-312.pyc +0 -0
  9. api_logic_server_cli/create_from_model/api_logic_server_utils.py +47 -0
  10. api_logic_server_cli/create_from_model/dbml.py +113 -58
  11. api_logic_server_cli/create_from_model/ont_build.py +83 -60
  12. api_logic_server_cli/create_from_model/ont_create.py +2 -1
  13. api_logic_server_cli/database/basic_demo.sqlite +0 -0
  14. api_logic_server_cli/database/basic_demo.txt +1 -0
  15. api_logic_server_cli/database/basic_demo_wg.sqlite +0 -0
  16. api_logic_server_cli/manager.py +3 -2
  17. api_logic_server_cli/prototypes/base/.vscode/launch.json +3 -2
  18. api_logic_server_cli/prototypes/base/config/config.py +66 -11
  19. api_logic_server_cli/prototypes/base/config/default.env +7 -1
  20. api_logic_server_cli/prototypes/base/database/test_data/readme.md +2 -1
  21. api_logic_server_cli/prototypes/base/integration/kafka/kafka_producer.py +5 -2
  22. api_logic_server_cli/prototypes/base/integration/n8n/n8n_producer.py +68 -21
  23. api_logic_server_cli/prototypes/base/integration/n8n/n8n_readme.md +19 -0
  24. api_logic_server_cli/prototypes/base/test/basic/server_test.py +1 -1
  25. api_logic_server_cli/prototypes/basic_demo/README.md +29 -52
  26. api_logic_server_cli/prototypes/basic_demo/customizations/api/.DS_Store +0 -0
  27. api_logic_server_cli/prototypes/basic_demo/customizations/api/api_discovery/mcp_server_executor.py +138 -0
  28. api_logic_server_cli/prototypes/basic_demo/customizations/api/api_discovery/openapi.py +92 -0
  29. api_logic_server_cli/prototypes/basic_demo/customizations/api/api_discovery/proper_update_def.json +71 -0
  30. api_logic_server_cli/prototypes/basic_demo/customizations/config/default.env +13 -0
  31. api_logic_server_cli/prototypes/basic_demo/customizations/database/db.sqlite +0 -0
  32. api_logic_server_cli/prototypes/basic_demo/customizations/database/models.py +131 -0
  33. api_logic_server_cli/prototypes/basic_demo/customizations/integration/.DS_Store +0 -0
  34. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/.DS_Store +0 -0
  35. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/1_langchain_loader.py +71 -0
  36. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/README_mcp.md +13 -0
  37. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/mcp_client_executor.py +295 -0
  38. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/mcp_schema.txt +47 -0
  39. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/mcp_server_discovery.json +9 -0
  40. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/multi_mcp_flow/multi_mcp_flow.png +0 -0
  41. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/multi_mcp_flow/multi_mcp_orchestration.yaml +49 -0
  42. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/multi_mcp_flow/wny mcp flows.png +0 -0
  43. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/natlang_to_api.py +73 -0
  44. api_logic_server_cli/prototypes/{nw_no_cust → basic_demo/customizations}/integration/mcp/resources/curl.txt +2 -1
  45. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/images/MCP Overview.png +0 -0
  46. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/images/MCP_Arch.png +0 -0
  47. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/images/MCP_Overview_Executor.png +0 -0
  48. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/invoke_llm/1 - prompt_messages_array.json +10 -0
  49. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/invoke_llm/2 - completion_tool_context.json +12 -0
  50. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/llm_schema.txt +38 -0
  51. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/nw_swagger_2.yaml +17393 -0
  52. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/nw_swagger_3_relaxed.yaml +109 -0
  53. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/proxy_server.py +51 -0
  54. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/proxy_serverZ.py +72 -0
  55. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/resources/validate_jsonapi.py +64 -0
  56. api_logic_server_cli/prototypes/basic_demo/customizations/integration/mcp/swagger_converter.py +65 -0
  57. api_logic_server_cli/prototypes/{nw_no_cust/integration/mcp → basic_demo/customizations/integration/mcp/z_old}/3_executor_test_agent.py +20 -6
  58. api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/3_executor_test_agent.py +52 -0
  59. api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/README_functon.md +201 -0
  60. api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/ai_plugin.json +17 -0
  61. api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/nw-swagger_3.json +1731 -0
  62. api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/snippets.txt +5 -0
  63. api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/swagger_3 genai_demo_with_get.json +1731 -0
  64. api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/swagger_3.json +1782 -0
  65. api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/swagger_3_genai_demo.json +264 -0
  66. api_logic_server_cli/prototypes/basic_demo/customizations/integration/openai_function/swagger_3_genai_demo_with_update.json +1782 -0
  67. api_logic_server_cli/prototypes/basic_demo/customizations/logic/declare_logic.py +62 -44
  68. api_logic_server_cli/prototypes/basic_demo/customizations/security/declare_security.py +11 -12
  69. api_logic_server_cli/prototypes/basic_demo/customizations/ui/admin/admin.yaml +166 -0
  70. api_logic_server_cli/prototypes/basic_demo/iteration/api/{customize_api.py → api_discovery/order_b2b.py} +17 -23
  71. api_logic_server_cli/prototypes/basic_demo/iteration/database/db.sqlite +0 -0
  72. api_logic_server_cli/prototypes/basic_demo/iteration/integration/row_dict_maps/OrderB2B.py +6 -5
  73. api_logic_server_cli/prototypes/basic_demo/iteration/integration/row_dict_maps/OrderShipping.py +4 -4
  74. api_logic_server_cli/prototypes/basic_demo/iteration/logic/declare_logic.py +69 -43
  75. api_logic_server_cli/prototypes/basic_demo/iteration/ui/admin/admin.yaml +125 -50
  76. api_logic_server_cli/prototypes/manager/README.md +4 -0
  77. api_logic_server_cli/prototypes/manager/README_X.md +663 -0
  78. api_logic_server_cli/prototypes/nw_no_cust/Tutorial.md +45 -26
  79. api_logic_server_cli/prototypes/nw_no_cust/api/api_discovery/openapi.py +130 -0
  80. api_logic_server_cli/prototypes/nw_no_cust/api/api_discovery/proper_update_def.json +71 -0
  81. api_logic_server_cli/prototypes/nw_no_cust/config/default.env +13 -0
  82. api_logic_server_cli/prototypes/ont_app/ontimize_seed/package-lock.json +9725 -1180
  83. api_logic_server_cli/prototypes/ont_app/ontimize_seed/package.json +3 -6
  84. api_logic_server_cli/prototypes/ont_app/ontimize_seed/src/app/shared/app.services.config.ts +1 -1
  85. api_logic_server_cli/prototypes/ont_app/ontimize_seed/src/assets/css/app.scss +4 -0
  86. api_logic_server_cli/prototypes/ont_app/ontimize_seed/src/assets/i18n/en.json +1 -1
  87. api_logic_server_cli/prototypes/ont_app/ontimize_seed/src/assets/i18n/es.json +14 -12
  88. api_logic_server_cli/prototypes/ont_app/templates/app_config.jinja +1 -1
  89. api_logic_server_cli/prototypes/ont_app/templates/date_template.html +1 -1
  90. api_logic_server_cli/prototypes/ont_app/templates/textarea_template.html +1 -1
  91. api_logic_server_cli/prototypes/ont_app/templates/timestamp_template.html +1 -1
  92. api_logic_server_cli/prototypes/sample_ai/logic/declare_logic.py +30 -13
  93. {apilogicserver-14.4.0.dist-info → apilogicserver-14.5.0.dist-info}/METADATA +2 -2
  94. {apilogicserver-14.4.0.dist-info → apilogicserver-14.5.0.dist-info}/RECORD +101 -60
  95. {apilogicserver-14.4.0.dist-info → apilogicserver-14.5.0.dist-info}/WHEEL +1 -1
  96. api_logic_server_cli/prototypes/basic_demo/apply_customizations.ps1 +0 -17
  97. api_logic_server_cli/prototypes/basic_demo/apply_customizations.sh +0 -14
  98. api_logic_server_cli/prototypes/basic_demo/apply_iteration.ps1 +0 -20
  99. api_logic_server_cli/prototypes/basic_demo/apply_iteration.sh +0 -15
  100. api_logic_server_cli/prototypes/nw_no_cust/integration/mcp/1_langchain_loader.py +0 -19
  101. api_logic_server_cli/prototypes/nw_no_cust/integration/mcp/README.md +0 -17
  102. /api_logic_server_cli/prototypes/{nw_no_cust → basic_demo/customizations}/integration/mcp/2_gpt_mcp_prompt.txt +0 -0
  103. /api_logic_server_cli/prototypes/{nw_no_cust → basic_demo/customizations}/integration/mcp/resources/nw_swagger_3.yaml +0 -0
  104. /api_logic_server_cli/prototypes/{nw_no_cust → basic_demo/customizations}/integration/mcp/run_executor.py +0 -0
  105. {apilogicserver-14.4.0.dist-info → apilogicserver-14.5.0.dist-info}/entry_points.txt +0 -0
  106. {apilogicserver-14.4.0.dist-info → apilogicserver-14.5.0.dist-info}/licenses/LICENSE +0 -0
  107. {apilogicserver-14.4.0.dist-info → apilogicserver-14.5.0.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: Sample Application Tutorial
3
3
  Description: Create, Run and Customize the pre-installed sqlite Northwind database
4
- Version: 1.0 [proto]
4
+ Version: 1.02 dev
5
5
  ---
6
6
  # API Logic Server Sample Tutorial
7
7
 
@@ -11,11 +11,11 @@ This is the sample app. It was created from the pre-installed sqlite [Northwind
11
11
 
12
12
  In this tutorial, we will explore:
13
13
 
14
- * **create** - we will briefly review what actually happened during the create process.
14
+ 1. **Create** - we will briefly review what actually happened during the create process.
15
15
 
16
- * **run** - we will first run the Admin App and the JSON:API. These will illustrate how automation creates an app and API from a database. Use this to infer what you'd get for one of your databases.
16
+ 2. **Run** - we will first run the Admin App and the JSON:API. These will illustrate how automation creates an app and API from a database. Use this to infer what you'd get for one of your databases.
17
17
 
18
- * **customize** - we will then explore customizing and debugging the project.
18
+ 3. **Customize** - we will then explore customizing and debugging the project.
19
19
 
20
20
   
21
21
 
@@ -23,10 +23,13 @@ In this tutorial, we will explore:
23
23
  This tutorial illustrates some key concepts:
24
24
 
25
25
  #### _Declarative Models_, not code
26
- Observe that the files for the Admin App and API are models that describe _what, not how_. This is much easier to understand than large amounts of generated code.
26
+ Observe that the files for the Admin App and API are models that describe _what, not how_. This level of abstratction is much easier to understand than large amounts of generated code.
27
+
28
+ ##### Automated Automation
29
+ Not only do models automate functionality, the *models themselves* are automated, created instantly when you create a project. That means you have instant Working Software.
27
30
 
28
31
  #### Customize - using standard tools
29
- The system is designed for you to customize the UI, Logic, Security and API, using standard tools - your IDE for code editing/debugging, git, etc.
32
+ The system is designed for you to customize the UI, Logic, Security and API, using standard tools - your IDE for code editing / debugging, git, etc.
30
33
 
31
34
  #### Iterate - Preserve Customizations
32
35
  The system is designed to enable `rebuild`, so you can iterate the data model - _without losing your customizations._ In general, such customizations are kept in separate files from the model files. So, the model files can be rebuilt without affecting customization files.
@@ -38,7 +41,7 @@ A unique feature of API Logic Server is provision for spreadsheet-like rules, cu
38
41
 
39
42
  # Development Overview
40
43
 
41
- [![Using VS Code](https://github.com/valhuber/apilogicserver/wiki/images//creates-and-runs-video.jpg?raw=true?raw=true)](https://youtu.be/tOojjEAct4M "Using VS Code with the ApiLogicServer container - click for video")
44
+ [![Using VS Code](images/creates-and-runs-video.png)](https://youtu.be/tOojjEAct4M "Using VS Code with the ApiLogicServer container - click for video")
42
45
 
43
46
  The diagram above summarizes the create / run / customize process.
44
47
 
@@ -48,7 +51,9 @@ The diagram above summarizes the create / run / customize process.
48
51
 
49
52
  ## 1. Create: Instant Project
50
53
 
51
- The CLI command below creates an `ApiLogicProject` by reading your schema. Note: the `db_url` value is [an abbreviation](https://apilogicserver.github.io/Docs/Data-Model-Examples/); you would normally supply a SQLAlchemy URL.
54
+ The CLI command below creates an `ApiLogicProject` by reading your schema.
55
+
56
+ Note: the `db_url` value is defaulted to the pre-installed sample project; you would normally supply a SQLAlchemy URL.
52
57
 
53
58
  ```bash
54
59
  $ ApiLogicServer create --project_name= --db_url= # create ApiLogicProject
@@ -70,11 +75,11 @@ The system has created an API and an Admin App. Let's explore them.
70
75
 
71
76
  ### 2.a Self-Serve API: Ad hoc Integration
72
77
 
73
- The system creates an API with end points for each table, providing filtering, sorting, pagination, optimistic locking and related data access.
78
+ The system creates a JSON:API with end points for each table, providing filtering, sorting, pagination, optimistic locking and related data access.
74
79
 
75
80
  The API is [**self-serve**](https://apilogicserver.github.io/Docs/API-Self-Serve/): consumers can select their own attributes and related data, eliminating reliance on custom API development. Our self-serve API meets requirements for Ad Hoc Application Integration, and Custom UI Dev.
76
81
 
77
- <img src="https://github.com/ApiLogicServer/Docs/blob/main/docs/images/integration/api-swagger.jpeg?raw=true">
82
+ ![api-swagger](images/integration/api-swagger.png)
78
83
 
79
84
  ### 2.b Admin App: Multi-Page, Multi-Table, Automatic Joins
80
85
 
@@ -85,7 +90,7 @@ After starting the server and browser, explore the Admin App in your browser:
85
90
  1. Navigate to `Customer`
86
91
  * Depending on your screen size, you may need to hit the "hamburger menu" (top left) to see the left menu<br/><br/>
87
92
  2. Click the first Customer row to see Customer Details
88
- 3. Observe the `ORDERLIST` tab at the bottom
93
+ 3. Click the `ORDERLIST` tab at the bottom
89
94
  4. Click the first Order row
90
95
  5. Observe the `ORDERDETAILLIST` tab at the bottom
91
96
  6. Observe the elements shown in the diagram
@@ -94,10 +99,9 @@ After starting the server and browser, explore the Admin App in your browser:
94
99
  * Multi-Table - database relationships (typically from foreign keys) used to build master/detail pages
95
100
  * Automatic Joins - the Order Detail table contains `ProductId`, but the system has joined in the `Product Name`. You can edit the `admin.yaml` file to control such behavior.
96
101
 
102
+ ![run-admin-app](images/ui-admin/run-admin-app.png)
97
103
 
98
- <figure><img src="https://github.com/valhuber/apilogicserver/wiki/images/ui-admin/run-admin-app.png?raw=true"></figure>
99
-
100
- > **Key Takeaway: API/UI *Automation***<br>With 1 command, we have created an executable project with a self-serve API, for ad hoc application integration and custom UI development. Our Admin App can be used for agile business user collaboration.
104
+ > **Key Takeaway: *Microservice Automation***<br>With **1 command**, we have created an executable project with a **self-serve API**, for ad hoc application integration and custom UI development. Our **Admin App** can be used for agile business user collaboration.
101
105
 
102
106
  &nbsp;
103
107
 
@@ -132,6 +136,7 @@ To apply customizations, in a terminal window for your project:
132
136
 
133
137
  ```bash
134
138
  ApiLogicServer add-cust
139
+ ApiLogicServer add-auth --db_url=auth # version 10.3.14 or greater
135
140
  ```
136
141
 
137
142
  **3. Restart the server, login as `admin`**
@@ -149,7 +154,7 @@ In the sections below, we will explore:
149
154
 
150
155
  ### 3.a Customize UI: Declare UI Behavior
151
156
 
152
- The admin app is not built with complex html and javascript. Instead, it is configured with the `ui/admin/admin.yml`, automatically created from your data model by `ApiLogicServer create`.
157
+ The admin app is not built with complex html and javascript. Instead, it is *configured* with `ui/admin/admin.yml`, automatically created from your data model by `ApiLogicServer create`.
153
158
 
154
159
  You can customize this file in your IDE to control which fields are shown (including joins), hide/show conditions, help text etc. The `add-cust` process above has simulated such customizations.
155
160
 
@@ -175,7 +180,7 @@ To see customized Admin app in action, with the restarted server:
175
180
 
176
181
  One customization has been to hide several Order fields (search `ui/admin/admin.yml` for `show_when: isInserting == false`). This makes it convenient to use the Admin App to enter an Order and OrderDetails:
177
182
 
178
- <img src="https://github.com/ApiLogicServer/Docs/blob/main/docs/images/integration/order-entry-ui.jpg?raw=true">
183
+ ![order-entry-ui](images/integration/order-entry-ui.png)
179
184
 
180
185
  &nbsp;
181
186
 
@@ -198,7 +203,7 @@ Rules are declared in Python, simplified with IDE code completion. The `add-cus
198
203
 
199
204
  Observe rules can be debugged using standard logging and the debugger:
200
205
 
201
- <img src="https://github.com/ApiLogicServer/Docs/blob/main/docs/images/integration/logic-chaining.jpeg?raw=true">
206
+ ![logic-chaining](images/integration/logic-chaining.png)
202
207
 
203
208
  &nbsp;
204
209
 
@@ -222,7 +227,13 @@ Rules are a unique and significant innovation, providing meaningful improvements
222
227
 
223
228
  &nbsp;
224
229
 
225
- > Key Takeway - Logic: Multi-table Derivation and Constraint Rules, 40X More Concise. <br>For more on rules, [click here](https://apilogicserver.github.io/Docs/Logic-Why/).
230
+ > **Key Takeway - Logic:** Multi-table Derivations and Constraint Rules, Extensible with Python
231
+ <br><br>Rules are:
232
+ <br>1. **Declared** in your IDE - 40X more concise
233
+ <br>2. **Activated** on server start
234
+ <br>3. **Executed** - *automatically* - on updates (using SQLAlchemy events)
235
+ <br>4. **Debugged** in your IDE, and with the console log
236
+ <br><br>For more on rules, [click here](https://apilogicserver.github.io/Docs/Logic-Why/).
226
237
 
227
238
  &nbsp;
228
239
 
@@ -234,7 +245,9 @@ To see security in action:
234
245
 
235
246
  **1. Logout (upper right), and Login** as `AFLKI`, password `p`
236
247
 
237
- **2. Click Customer** - observe you now see only 1 customer
248
+ * This authorized user has 2 roles: `customer` and 'tenant`
249
+
250
+ **2. Click Customer** - observe you now see only 1 customer (per the `customer` role)
238
251
 
239
252
  <br>
240
253
 
@@ -242,7 +255,7 @@ To see security in action:
242
255
 
243
256
  Declarative row-level security ensures that users see only the rows authorized for their roles. Observe you now see only customer ALFKI, per the security declared below. Note the console log at the bottom shows how the filter worked.
244
257
 
245
- <img src="https://github.com/ApiLogicServer/Docs/blob/main/docs/images/integration/security-filters.jpg?raw=true">
258
+ ![security-filter](images/integration/security-filters.png)
246
259
 
247
260
  &nbsp;
248
261
 
@@ -277,7 +290,7 @@ The main task here is to ***map*** a B2B payload onto our logic-enabled SQLAlche
277
290
  * Use the `OrderB2B` class to transform a api request data to SQLAlchemy rows (`dict_to_row`)
278
291
  * The automatic commit initiates the same shared logic described above to check credit and reorder products
279
292
 
280
- ![dict to row](https://github.com/ApiLogicServer/Docs/blob/main/docs/images/integration/dict-to-row.jpg?raw=true)
293
+ ![dict-to-row](images/integration/dict-to-row.png)
281
294
 
282
295
 
283
296
  &nbsp;
@@ -304,19 +317,25 @@ Just as you can customize apis, you can complement rule-based logic using Python
304
317
 
305
318
  3. `send_order_to_shipping` uses the `OrderShipping` class, which maps our SQLAlchemy order row to a dict (`row_to_dict`).
306
319
 
307
- ![send order to shipping](https://github.com/ApiLogicServer/Docs/blob/main/docs/images/integration/order-to-shipping.jpg?raw=true)
308
-
320
+ ![order-to-shipping](images/integration/order-to-shipping.png)
309
321
 
310
322
  &nbsp;
311
323
  > **Key Takeway - Extensible Rules, Kafka Message Produced**<br>Rule-based logic is extensible with Python, here producing a Kafka message with 20 lines of code.
312
324
 
325
+
326
+ &nbsp;
327
+
328
+ ### 3.e Customize the Data Model
329
+
330
+ You can also alter the data model, while preserving customizations. For more information, see [Database Design Changes](https://apilogicserver.github.io/Docs/Database-Changes/).
331
+
313
332
  &nbsp;
314
333
 
315
334
  ## Testing
316
335
 
317
336
  ### Behave
318
337
 
319
- You can test using standard api and ui test tools. We recommend exploring the [Behave framework](https://valhuber.github.io/ApiLogicServer/Behave/). This can be used as part of an overall agile approach as described in the [Logic Tutorial](https://valhuber.github.io/ApiLogicServer/Logic-Tutorial/).
338
+ You can test using standard api and ui test tools. We recommend exploring the [Behave framework](https://apilogicserver.github.io/Docs/Behave/). This can be used as part of an overall agile approach as described in the [Logic Tutorial](https://apilogicserver.github.io/Docs/Logic-Tutorial/).
320
339
 
321
340
  TL;DR - features and test scripts are predefined in the sample; to run them (with the server running):
322
341
 
@@ -328,7 +347,7 @@ TL;DR - features and test scripts are predefined in the sample; to run them (wit
328
347
 
329
348
  > The sample Scenarios below were chosen to illustrate the basic patterns of using rules. Open the disclosure box ("Tests - and their logic...") to see the implementation and notes.
330
349
 
331
- For more information, see [Testing with Behave](https://valhuber.github.io/ApiLogicServer/Behave/).
350
+ For more information, see [Testing with Behave](https://apilogicserver.github.io/Docs/Behave/).
332
351
 
333
352
  &nbsp;
334
353
 
@@ -361,7 +380,7 @@ ApiLogicServer curl "'POST' 'http://localhost:5656/api/ServicesEndPoint/OrderB2B
361
380
 
362
381
  After the Tutorial, these are excellent next steps:
363
382
 
364
- * Further explore Application Integration - [open the Sample Integration tutorial](integration/Sample-Integration.md)
383
+ * Further explore Application Integration - [open the Sample Integration tutorial](Sample-Integration.md)
365
384
  * It will show how to activate Kafka so that the message above is actually sent
366
385
  * It will ilustrate to the _consume_ Kafka messages
367
386
  * You've already created most of it, so...
@@ -0,0 +1,130 @@
1
+ from flask import request, jsonify
2
+ from flask import Flask, redirect, send_from_directory, send_file
3
+ import logging
4
+ import os
5
+ import json
6
+ import io
7
+ from config.config import Args # circular import error if at top
8
+
9
+ app_logger = logging.getLogger("api_logic_server_app")
10
+
11
+ def add_service(app, api, project_dir, swagger_host: str, PORT: str, method_decorators = []):
12
+ pass
13
+
14
+ def get_server_url():
15
+ """ return the server URL for the OpenAPI spec """
16
+ result = f'http://{Args.instance.swagger_host}:{Args.instance.swagger_port}'
17
+ # get env variable API_LOGIC_SERVER_TUNNEL (or None)
18
+ if tunnel_url := os.getenv("API_LOGIC_SERVER_TUNNEL", None):
19
+ app_logger.info(f".. tunnel URL: {tunnel_url}")
20
+ result = tunnel_url
21
+ return result # + '/api'
22
+
23
+
24
+
25
+ @app.before_request
26
+ def before_any_request():
27
+ # print(f"[DEBUG] Incoming request: {request.method} {request.url}")
28
+ if activate_openapi_logging := True:
29
+ if request.content_type == 'application/json' and request.method in ['POST', 'PUT', 'PATCH']:
30
+ # openapi: Incoming request: PATCH http://localhost:5656/api/Customer/1/ {'data': {'attributes': {'credit_limit': 5555}, 'type': 'Customer', 'id': '1'}}
31
+ # openapi: Incoming request: PATCH http://6f6f-2601-644-4900-d6f0-ecc9-6df3-8863-c5b2.ngrok-free.app/api/Customer/1 {'credit_limit': 5555}
32
+
33
+ app_logger.info(f"openapi: Incoming request: {request.method} {request.url} {str(request.json)}")
34
+ else:
35
+ app_logger.info(f"openapi: Incoming request: {request.method} {request.url}")
36
+ # app_logger.info(f"openapi: Incoming request headers: {request.headers}")
37
+
38
+ chatgpt_request_json = {
39
+ "credit_limit": 25000,
40
+ }
41
+ standard_request_json = {
42
+ "data": {
43
+ "type": "Customer",
44
+ "id": "ALFKI",
45
+ "attributes": {
46
+ "name": "Alice",
47
+ "credit_limit": 25000,
48
+ "balance": 12345
49
+ }
50
+ }
51
+ }
52
+ swagger_request_json = {
53
+ 'data': {
54
+ 'attributes': {
55
+ 'credit_limit': 5555
56
+ },
57
+ 'type': 'Customer',
58
+ 'id': '1'
59
+ }
60
+ }
61
+ pass
62
+
63
+ @app.route('/mcp.json')
64
+ def mcp(path=None):
65
+ '''
66
+ test: curl -X GET http://localhost:5656/mcp.json
67
+ '''
68
+
69
+ mcp_json = {
70
+ "name": "MCP genai_demo test",
71
+ "description": "You are an AI Planner + Executor for a live JSON:API server.",
72
+ "instructions": [
73
+ "When a user gives you a natural language goal (e.g., 'list customers from Germany'), you:",
74
+ "Identify the resource (Customer, Order, Product).",
75
+ "Map filters (e.g., Country=Germany).",
76
+ "Construct a JSON:API call to the live endpoint (through a function called fetch_resource).",
77
+ "Execute the live API call through the function.",
78
+ "Format and display the results neatly."
79
+ ],
80
+ "serverUrl": "http://localhost:5656/api",
81
+ "openapiUrl": "http://localhost:5656/api/openapi.json",
82
+ "apiStandard": "JSON:API (application/vnd.api+json)"
83
+ }
84
+ mcp_json["serverUrl"] = get_server_url() + '/api'
85
+ mcp_json["openapiUrl"] = get_server_url() + '/api/openapi.json'
86
+ # return jsonify(mcp), 200, {'Content-Type': 'text/plain; charset=utf-8'}
87
+ return jsonify(mcp_json), 200, {'Content-Type': 'application/json; charset=utf-8'}
88
+
89
+
90
+ @app.route('/api/openapi.json')
91
+ def openapi(path=None):
92
+ """ return integration/openai_plugin/swagger_3.json
93
+ * with updated tunnel URL if API_LOGIC_SERVER_TUNNEL is set
94
+
95
+ test: curl -X GET http://localhost:5656/api/openapi.json
96
+ like: curl -X GET http://localhost:5656/api/swagger.json
97
+ """
98
+
99
+ # read dict from json file integration/openai_plugin/swagger_3.json
100
+ with open("integration/openai_function/swagger_3.json", "r") as json_file:
101
+ swagger_dict = json.load(json_file)
102
+ app_logger.info(f"openapi: Swagger JSON loaded: {swagger_dict}")
103
+
104
+ server_url = get_server_url()
105
+ swagger_dict["servers"][0]["url"] = server_url + '/api'
106
+
107
+ # convert dict to buffered stream
108
+ swagger_dict_mem = io.BytesIO(json.dumps(swagger_dict).encode('utf-8'))
109
+ return send_file(swagger_dict_mem, mimetype='text/json')
110
+
111
+
112
+ @app.route('/api/ai_plugin')
113
+ def ai_plugin(path=None):
114
+ """ return integration/openai_plugin/ai_plugin.json (disparaged)
115
+ * with updated tunnel URL if API_LOGIC_SERVER_TUNNEL is set
116
+
117
+ test: curl -X GET http://localhost:5656/api/ai_plugin
118
+ """
119
+
120
+ # read dict from json file integration/openai_plugin/swagger_3.json
121
+ with open("integration/openai_plugin/ai_plugin.json", "r") as json_file:
122
+ swagger_dict = json.load(json_file)
123
+ app_logger.info(f"openapi: ai_plugin JSON loaded: {swagger_dict}")
124
+
125
+ server_url = get_server_url()
126
+ swagger_dict["servers"][0]["url"] = server_url
127
+
128
+ # convert dict to buffered stream
129
+ swagger_dict_mem = io.BytesIO(json.dumps(swagger_dict).encode('utf-8'))
130
+ return send_file(swagger_dict_mem, mimetype='text/json')
@@ -0,0 +1,71 @@
1
+ {
2
+ "/Customer/{id}": {
3
+ "patch": {
4
+ "summary": "Update Customer by ID",
5
+ "operationId": "updateCustomer",
6
+ "parameters": [
7
+ {
8
+ "name": "id",
9
+ "in": "path",
10
+ "required": true,
11
+ "schema": {
12
+ "type": "string"
13
+ }
14
+ }
15
+ ],
16
+ "requestBody": {
17
+ "required": true,
18
+ "content": {
19
+ "application/vnd.api+json": {
20
+ "schema": {
21
+ "type": "object",
22
+ "required": ["data"],
23
+ "properties": {
24
+ "data": {
25
+ "type": "object",
26
+ "required": ["type", "id", "attributes"],
27
+ "properties": {
28
+ "type": {
29
+ "type": "string",
30
+ "enum": ["Customer"]
31
+ },
32
+ "id": {
33
+ "type": "string"
34
+ },
35
+ "attributes": {
36
+ "type": "object",
37
+ "properties": {
38
+ "name": {
39
+ "type": "string"
40
+ },
41
+ "credit_limit": {
42
+ "type": "number"
43
+ },
44
+ "balance": {
45
+ "type": "number"
46
+ }
47
+ }
48
+ }
49
+ }
50
+ }
51
+ }
52
+ }
53
+ }
54
+ }
55
+ },
56
+ "responses": {
57
+ "200": {
58
+ "description": "Customer updated",
59
+ "content": {
60
+ "application/vnd.api+json": {
61
+ "schema": {
62
+ "type": "object"
63
+ }
64
+ }
65
+ }
66
+ }
67
+ }
68
+ }
69
+ }
70
+ }
71
+
@@ -0,0 +1,13 @@
1
+ SECRET_KEY = "whatnothow"
2
+ SQLALCHEMY_TRACK_MODIFICATIONS = False
3
+ SQLAlCHEMY_ECHO = False
4
+ # AGGREGATE_DEFAULTS = True
5
+ # ALL_DEFAULTS = True
6
+ # APILOGICPROJECT_KAFKA_PRODUCER = "{\"bootstrap.servers\": \"localhost:9092\"}"
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"