ApiLogicServer 15.3.2__py3-none-any.whl → 15.4.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/api_logic_server.py +3 -2
- api_logic_server_cli/api_logic_server_info.yaml +3 -3
- api_logic_server_cli/create_from_model/api_logic_server_utils.py +3 -1
- api_logic_server_cli/prototypes/base/.github/.copilot-instructions.md +147 -4
- api_logic_server_cli/prototypes/base/docs/training/MCP_Copilot_Integration.md +295 -0
- api_logic_server_cli/prototypes/base/logic/readme_logic.md +38 -25
- api_logic_server_cli/prototypes/basic_demo/.github/.copilot-instructions.md +291 -26
- api_logic_server_cli/prototypes/basic_demo/.github/welcome.md +26 -0
- api_logic_server_cli/prototypes/basic_demo/customizations/logic/declare_logic.py +5 -0
- api_logic_server_cli/prototypes/basic_demo/logic/procedural/declarative-vs-procedural-comparison.md +301 -198
- api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/logic/logic_discovery/check_credit.py +4 -1
- {apilogicserver-15.3.2.dist-info → apilogicserver-15.4.0.dist-info}/METADATA +1 -1
- {apilogicserver-15.3.2.dist-info → apilogicserver-15.4.0.dist-info}/RECORD +17 -15
- {apilogicserver-15.3.2.dist-info → apilogicserver-15.4.0.dist-info}/WHEEL +0 -0
- {apilogicserver-15.3.2.dist-info → apilogicserver-15.4.0.dist-info}/entry_points.txt +0 -0
- {apilogicserver-15.3.2.dist-info → apilogicserver-15.4.0.dist-info}/licenses/LICENSE +0 -0
- {apilogicserver-15.3.2.dist-info → apilogicserver-15.4.0.dist-info}/top_level.txt +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
This describes how to use Logic; for more information, [see here](https://apilogicserver.github.io/Docs/Logic-Why).
|
|
2
2
|
|
|
3
|
-
> What is Logic: Multi-table Derivation and Constraint Rules, Extensible with Python
|
|
4
|
-
<br>Rules are:
|
|
5
|
-
<br>1. **Declared** in your IDE - 40X more concise
|
|
6
|
-
<br>2. **Activated** on server start
|
|
7
|
-
<br>3. **Executed** - *automatically* - on updates (using SQLAlchemy events)
|
|
8
|
-
<br>4. **Debugged** in your IDE, and with the console log
|
|
9
|
-
<br>For more on rules, [click here](https://apilogicserver.github.io/Docs/Logic-Why/).
|
|
3
|
+
> What is Logic: Multi-table Derivation and Constraint Rules, Extensible with Python
|
|
4
|
+
> <br>Rules are:
|
|
5
|
+
> <br>1. **Declared** in your IDE - 40X more concise
|
|
6
|
+
> <br>2. **Activated** on server start
|
|
7
|
+
> <br>3. **Executed** - *automatically* - on updates (using SQLAlchemy events)
|
|
8
|
+
> <br>4. **Debugged** in your IDE, and with the console log
|
|
9
|
+
> <br>For more on rules, [click here](https://apilogicserver.github.io/Docs/Logic-Why/).
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
@@ -27,11 +27,13 @@ Use case: App Integration
|
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
Basic process:
|
|
30
|
+
|
|
30
31
|
1. Create a file such as `logic/logic_discovery/check_credit.py` (e.g., copy from `use_case.py`).
|
|
31
|
-
2. Paste the prompt above into CoPilot -
|
|
32
|
+
2. Paste the prompt above into CoPilot - it uses `docs/training` to generate logic
|
|
32
33
|
3. Paste the generated logic into `logic/logic_discovery/check_credit.py`
|
|
33
34
|
|
|
34
35
|
From the Natural Language, Copilot will create Python rules (you can also create these directly using code completion):
|
|
36
|
+
|
|
35
37
|
```python
|
|
36
38
|
if os.environ.get("WG_PROJECT"):
|
|
37
39
|
# Inside WG: Load rules from docs/expprt/export.json
|
|
@@ -67,7 +69,7 @@ From the Natural Language, Copilot will create Python rules (you can also create
|
|
|
67
69
|
|
|
68
70
|
## Natural Language vs. IDE
|
|
69
71
|
|
|
70
|
-
If you are using WebGenAI, you can specify rules in Natural Language. You can also augment them in the IDE using code completion. There are some important usage guidelines.
|
|
72
|
+
If you are using WebGenAI, you can specify rules in Natural Language. You can also augment them in the IDE using code completion. There are some important usage guidelines.
|
|
71
73
|
|
|
72
74
|
> You should generally not alter any files in the `wg_rules` directory. For more information, see [WebGenAI](https://apilogicserver.github.io/Docs/WebGenAI/), and [WebGenAI Logic](https://apilogicserver.github.io/Docs/WebGenAI-CLI.md#natural-language-logic).
|
|
73
75
|
|
|
@@ -79,7 +81,7 @@ You can declare logic in `declare_logic.py`,
|
|
|
79
81
|
but that can lead to a lot of rules in 1 file.
|
|
80
82
|
|
|
81
83
|
A *best practice* is to create logic files in `logic/logic_discovery`,
|
|
82
|
-
named after the use case (e.g., `check_credit.py`).
|
|
84
|
+
named after the use case (e.g., `check_credit.py`).
|
|
83
85
|
|
|
84
86
|
The easiest way to to copy/paste `use_case.py` to a new file, then
|
|
85
87
|
add your logic either by Natural Language (use your Coding Assistant, such as CoPilot),
|
|
@@ -87,8 +89,10 @@ or your IDE's code completion.
|
|
|
87
89
|
|
|
88
90
|
<br>
|
|
89
91
|
|
|
90
|
-
## Examples
|
|
92
|
+
## Examples
|
|
93
|
+
|
|
91
94
|
Examples from tutorial project:
|
|
95
|
+
|
|
92
96
|
* Examples drawn from [tutorial project](https://github.com/ApiLogicServer/demo/blob/main/logic/declare_logic.py)
|
|
93
97
|
* Use Shift + "." to view in project mode
|
|
94
98
|
|
|
@@ -105,11 +109,13 @@ This declares the Customer.Balance as the sum of the unshipped Order.AmountTotal
|
|
|
105
109
|
as_sum_of=models.Order.AmountTotal,
|
|
106
110
|
where=lambda row: row.ShippedDate is None)
|
|
107
111
|
```
|
|
112
|
+
|
|
108
113
|
It means the rule engine **watches** for these changes:
|
|
114
|
+
|
|
109
115
|
* Order inserted/deleted, or
|
|
110
116
|
* AmountTotal or ShippedDate or CustomerID changes
|
|
111
117
|
|
|
112
|
-
Iff changes are detected, the engine **reacts** by *adjusting* the Customer.Balance. SQLs are [optimized](#declarative-logic-important-notes).
|
|
118
|
+
Iff changes are detected, the engine **reacts** by *adjusting* the Customer.Balance. SQLs are [optimized - see Important Notes, below](#declarative-logic-important-notes).
|
|
113
119
|
|
|
114
120
|
This would **chain** to check the Customers' Constraint rule, described below.
|
|
115
121
|
|
|
@@ -120,6 +126,7 @@ This would **chain** to check the Customers' Constraint rule, described below.
|
|
|
120
126
|
Constraints are multi-field conditions which must be true for transactions to succeed (else an exception is raised). You can express the condition as a lambda or a function:
|
|
121
127
|
|
|
122
128
|
**As a lambda:**
|
|
129
|
+
|
|
123
130
|
```python
|
|
124
131
|
Rule.constraint(validate=models.Customer,
|
|
125
132
|
as_condition=lambda row: row.Balance <= row.CreditLimit, # parent references are supported
|
|
@@ -127,6 +134,7 @@ Constraints are multi-field conditions which must be true for transactions to su
|
|
|
127
134
|
```
|
|
128
135
|
|
|
129
136
|
**Or, as a function:**
|
|
137
|
+
|
|
130
138
|
```python
|
|
131
139
|
def check_balance(row: models.Customer, old_row: models.Customer, logic_row: LogicRow):
|
|
132
140
|
if logic_row.ins_upd_dlt != "dlt": # see also: logic_row.old_row
|
|
@@ -144,12 +152,14 @@ Constraints are multi-field conditions which must be true for transactions to su
|
|
|
144
152
|
### 3. Row Events: Extensible with Python
|
|
145
153
|
|
|
146
154
|
Events are procedural Python code, providing extensibility for declarative rules:
|
|
155
|
+
|
|
147
156
|
```python
|
|
148
157
|
def congratulate_sales_rep(row: models.Order, old_row: models.Order, logic_row: LogicRow):
|
|
149
158
|
pass # event code here - sending email, messages, etc.
|
|
150
159
|
|
|
151
160
|
Rule.commit_row_event(on_class=models.Order, calling=congratulate_sales_rep)
|
|
152
161
|
```
|
|
162
|
+
|
|
153
163
|
Note there are multiple kinds of events, so you can control whether they run before or after rule execution. For more information, [see here](https://apilogicserver.github.io/Docs/Logic-Type-Constraint).
|
|
154
164
|
|
|
155
165
|
|
|
@@ -159,9 +169,7 @@ Note there are multiple kinds of events, so you can control whether they run bef
|
|
|
159
169
|
A key argument to functions is `logic_row`:
|
|
160
170
|
|
|
161
171
|
* **Wraps row and old_row,** plus methods for insert, update and delete - rule enforcement
|
|
162
|
-
|
|
163
172
|
* **Additional instance variables:** ins_upd_dlt, nest_level, session, etc.
|
|
164
|
-
|
|
165
173
|
* **Helper Methods:** are_attributes_changed, set_same_named_attributes, get_parent_logic_row(role_name), get_derived_attributes, log, is_inserted, etc
|
|
166
174
|
|
|
167
175
|
Here is an example:
|
|
@@ -194,13 +202,11 @@ logic_row.log("no manager for this order's salesrep")
|
|
|
194
202
|
Logic *declarative*, which differs from conventional *procedural* logic:
|
|
195
203
|
|
|
196
204
|
1. **Automatic Invocation:** you don't call the rules; they execute in response to updates (via SQLAlchemy events).
|
|
197
|
-
|
|
198
205
|
2. **Automatic Ordering:** you don't order the rules; execution order is based on system-discovered depencencies.
|
|
199
|
-
|
|
200
206
|
3. **Automatic Optimizations:** logic is optimized to reduce SQLs.
|
|
201
207
|
|
|
202
|
-
|
|
203
|
-
|
|
208
|
+
* Rule execution is *pruned* if dependent attributes are not altered
|
|
209
|
+
* SQL is optimized, e.g., `sum` rules operate by *adjustment*, not expensive SQL `select sum`
|
|
204
210
|
|
|
205
211
|
These simplify maintenance / iteration: you can be sure new logic is always called, in the correct order.
|
|
206
212
|
|
|
@@ -226,14 +232,15 @@ Logging is performed using standard Python logging, with a logger named `logic_l
|
|
|
226
232
|
|
|
227
233
|
In addition, the system logs all rules that fire, to aid in debugging. Referring the the screen shot above:
|
|
228
234
|
|
|
229
|
-
*
|
|
230
|
-
*
|
|
235
|
+
* Each line represents a rule execution, showing row state (old/new values), and the _{reason}_ that caused the update (e.g., client, sum adjustment)
|
|
236
|
+
* Log indention shows multi-table chaining
|
|
231
237
|
|
|
232
238
|
|
|
233
239
|
|
|
234
240
|
## How Logic works
|
|
235
241
|
|
|
236
242
|
*Activation* occurs in `api_logic_server_run.py`:
|
|
243
|
+
|
|
237
244
|
```python
|
|
238
245
|
LogicBank.activate(session=session, activator=declare_logic, constraint_event=constraint_handler)
|
|
239
246
|
```
|
|
@@ -242,8 +249,14 @@ This installs the rule engine as a SQLAlchemy event listener (`before_flush`).
|
|
|
242
249
|
|
|
243
250
|
Rules plug into SQLAlchemy events, and execute as follows:
|
|
244
251
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
|
248
|
-
| **
|
|
249
|
-
| **
|
|
252
|
+
|
|
253
|
+
| Logic Phase | Why It Matters |
|
|
254
|
+
| :--------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------- |
|
|
255
|
+
| **Watch** for changes at the attribute level | Performance - Automatic Attribute-level Pruning |
|
|
256
|
+
| **React** by recomputing value | Ensures Reuse - Invocation is automatic<br>Derivations are optimized (e.g. *adjustment updates* - not aggregate queries) |
|
|
257
|
+
| **Chain** to other referencing data | Simplifies Maintenance - ordering is automatic<br>Multi-table logic automation |
|
|
258
|
+
|
|
259
|
+
This pattern is sometimes called Reactive Dependency Propagation. Automatic dependency management accounts is why 5 *declarative* lines represent the same logic as 200 lines of *declarative* Python
|
|
260
|
+
|
|
261
|
+
1. To view a AI procedural/declarative comparison, [click here](https://github.com/ApiLogicServer/ApiLogicServer-src/blob/main/api_logic_server_cli/prototypes/basic_demo/logic/procedural/declarative-vs-procedural-comparison.md)
|
|
262
|
+
2. Rules typically automate over 95% of your logic, so the results can be significant. Consider a 100 table system: 1,000 rules vs. 40,000 lines of code
|
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: Copilot Instructions for
|
|
3
|
-
Description: Project-level instructions for
|
|
4
|
-
Source: ApiLogicServer-src/prototypes/
|
|
5
|
-
Propagation: CLI create command → created projects
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
title: Copilot Instructions for GenAI-Logic Projects
|
|
3
|
+
Description: Project-level instructions for working with generated projects
|
|
4
|
+
Source: ApiLogicServer-src/prototypes/base/.github/.copilot-instructions.md
|
|
5
|
+
Propagation: CLI create command → created projects (non-basic_demo)
|
|
6
|
+
Instrucions: Changes must be merged from api_logic_server_cli/prototypes/basic_demo/.github - see instructions there
|
|
7
|
+
Usage: AI assistants read this when user opens any created project
|
|
8
|
+
version: 2.5
|
|
8
9
|
changelog:
|
|
9
|
-
- 2.
|
|
10
|
-
- 2.
|
|
11
|
-
- 2.
|
|
12
|
-
- 2.
|
|
13
|
-
- 2.
|
|
10
|
+
- 2.5 (Nov 08, 2025 - API Best Practices
|
|
11
|
+
- 2.4 (Nov 05, 2025 - Added MCP Integration section, Copilot as MCP client capability)
|
|
12
|
+
- 2.3 (Nov 04, 2025 - Clear 1st message about reading Welcome section verbatim, again for non basic_demo)
|
|
13
|
+
- 2.2 (Oct 29, 2025 - Clear 1st message about reading Welcome section verbatim)
|
|
14
|
+
- 2.1 (Oct 2025) - Streamlined OBX for non-tutorial projects, friendly collaborative tone
|
|
15
|
+
- 2.0 (Oct 2025) - Added front matter, updated for OBX improvements
|
|
16
|
+
- 1.0 (Initial) - Comprehensive technical reference
|
|
14
17
|
---
|
|
15
18
|
|
|
16
19
|
# GitHub Copilot Instructions for GenAI-Logic (aka API Logic Server) Projects
|
|
17
20
|
|
|
18
|
-
**INSTRUCTION**: When the user asks you to
|
|
21
|
+
**INSTRUCTION**: When the user asks you to load these instructions, respond with the Welcome section content below as your greeting. Do not add preamble like "I've read the instructions" - just present the Welcome content directly. The Welcome section ends at the "---" marker before "🔑 Key Technical Points".
|
|
19
22
|
|
|
20
23
|
## Welcome
|
|
21
24
|
|
|
@@ -34,25 +37,100 @@ This is a complete, working microservice auto-generated from a database schema -
|
|
|
34
37
|
|
|
35
38
|
**First, we'll briefly explore what's automatically created. Then I'll show you how I can help you customize it - adding logic, security, and API endpoints.**
|
|
36
39
|
|
|
40
|
+
**Ready to explore?** Say **"guide me through"** to begin the interactive tutorial.
|
|
37
41
|
|
|
38
|
-
**
|
|
42
|
+
**Or, self-demo?** open `basic_demo/readme_ai_mcp.md` or `basic_demo/readme_vibe.md`.
|
|
39
43
|
|
|
40
44
|
---
|
|
41
45
|
|
|
42
|
-
|
|
46
|
+
**DO NOT include the content below in the welcome greeting. It is reference material only.**
|
|
43
47
|
|
|
44
|
-
|
|
48
|
+
## Here are some things I can help you with
|
|
49
|
+
|
|
50
|
+
1. **Add business logic** - Describe your requirements in natural language, I'll generate declarative rules
|
|
51
|
+
2. **Customize the API** - Add custom endpoints for your specific needs
|
|
52
|
+
3. **Create custom UIs** - Build React apps with `genai-logic genai-add-app --vibe`
|
|
53
|
+
4. **Add security** - Set up role-based access control with `genai-logic add-auth`
|
|
54
|
+
5. **Test your logic** - Create Behave tests with requirements traceability
|
|
55
|
+
6. **Configure Admin UI** - Customize the auto-generated admin interface
|
|
56
|
+
7. **Query via natural language** - I can act as MCP client to read/update data (see `docs/training/MCP_Copilot_Integration.md`)
|
|
57
|
+
8. **Create B2B APIs** - Complex integration endpoints with partner systems
|
|
58
|
+
9. **Add events** - Integrate with Kafka, webhooks, or other event systems
|
|
59
|
+
10. **Customize models** - Add tables, attributes, or derived fields
|
|
60
|
+
11. **Discovery systems** - Auto-load logic and APIs from discovery folders
|
|
61
|
+
|
|
62
|
+
Want to get started? Press **F5** to start the server with debugger support, then open `http://localhost:5656`. (There are also run configurations for running tests and other tasks.) Or just ask me what you'd like to work on.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## 🔑 Key Technical Points
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**DO NOT create your own summary. DO NOT rephrase. Copy the text above exactly.**
|
|
70
|
+
|
|
71
|
+
The technical reference sections below are for later consultation when working on specific tasks.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Welcome (Reference Copy)
|
|
76
|
+
|
|
77
|
+
| # | Service | Description |
|
|
78
|
+
|---|---------|-------------|
|
|
79
|
+
| 1️⃣ | **Add business logic** | Describe your requirements in natural language, I'll generate declarative rules |
|
|
80
|
+
| 2️⃣ | **Customize the API** | Add custom endpoints for your specific needs |
|
|
81
|
+
| 3️⃣ | **Create custom UIs** | Build React apps with `genai-logic genai-add-app --vibe` |
|
|
82
|
+
| 4️⃣ | **Add security** | Set up role-based access control with `genai-logic add-auth` |
|
|
83
|
+
| 5️⃣ | **Test your logic** | Create Behave tests with requirements traceability |
|
|
84
|
+
| 6️⃣ | **Configure Admin UI** | Customize the auto-generated admin interface |
|
|
85
|
+
| 7️⃣ | **Add MCP integration** | Enable Model Context Protocol for external AI access |
|
|
86
|
+
| 8️⃣ | **Create B2B APIs** | Complex integration endpoints with partner systems |
|
|
87
|
+
| 9️⃣ | **Add events** | Integrate with Kafka, webhooks, or other event systems |
|
|
88
|
+
| 🔟 | **Customize models** | Add tables, attributes, or derived fields |
|
|
89
|
+
| 1️⃣1️⃣ | **Discovery systems** | Auto-load logic and APIs from discovery folders |
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
Want to get started? Press **F5** to start the server with debugger support, then open `http://localhost:5656`. (There are also run configurations for running tests and other tasks.) Or just ask me what you'd like to work on.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## 🔑 Key Technical Points
|
|
98
|
+
|
|
99
|
+
**Critical Implementation Details:**
|
|
100
|
+
|
|
101
|
+
1. **Discovery Systems**:
|
|
102
|
+
- **Logic Discovery**: Business rules automatically loaded from `logic/logic_discovery/use_case.py` via `logic/logic_discovery/auto_discovery.py`
|
|
103
|
+
- **API Discovery**: Custom APIs automatically loaded from `api/api_discovery/[service_name].py` via `api/api_discovery/auto_discovery.py`
|
|
104
|
+
- Do NOT manually duplicate rule calls or API registrations
|
|
105
|
+
|
|
106
|
+
2. **API Record ID Pattern**: When creating records via custom APIs, use `session.flush()` before accessing the ID to ensure it's generated:
|
|
107
|
+
```python
|
|
108
|
+
session.add(sql_alchemy_row)
|
|
109
|
+
session.flush() # Ensures ID is generated
|
|
110
|
+
record_id = sql_alchemy_row.id
|
|
111
|
+
return {"message": "Success", "record_id": record_id}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
3. **Automatic Business Logic**: All APIs (standard and custom) automatically inherit LogicBank rules without additional code.
|
|
115
|
+
|
|
116
|
+
4. **CLI Commands**: Use `genai-logic --help` to see all available commands. When CLI commands exist for a task (e.g., `add-auth`, `genai-add-mcp-client`, `genai-add-app`), ALWAYS use them instead of manual configuration - they handle all setup correctly.
|
|
117
|
+
|
|
118
|
+
> **📋 Testing:** For comprehensive testing conventions, patterns, and examples, see `docs/training/testing.md` (555 lines - I'll read this before we create any tests)
|
|
45
119
|
|
|
46
120
|
---
|
|
47
121
|
|
|
48
|
-
|
|
122
|
+
## Detailed Service Documentation
|
|
49
123
|
|
|
50
|
-
|
|
51
|
-
If it's not already set, we can often find a `venv` in the GenAI-Logic Manager - a parent or grandparent directory.
|
|
124
|
+
The sections below provide complete details on each service. I'll reference these as needed when we work together.
|
|
52
125
|
|
|
53
|
-
###
|
|
126
|
+
### `venv` is required
|
|
54
127
|
|
|
55
|
-
|
|
128
|
+
To establish the virtual environment:
|
|
129
|
+
|
|
130
|
+
1. Attempt to find a `venv` folder in the parent or grandparent directory
|
|
131
|
+
2. Or, create it using requirements.txt
|
|
132
|
+
|
|
133
|
+
### Starting the server
|
|
56
134
|
|
|
57
135
|
```bash
|
|
58
136
|
python api_logic_server_run.py
|
|
@@ -182,6 +260,135 @@ When users provide natural language with multiple use cases like:
|
|
|
182
260
|
|
|
183
261
|
**NEVER put everything in `use_case.py`** - that defeats the discovery system purpose.
|
|
184
262
|
|
|
263
|
+
### MCP Integration - Acting as Database Client
|
|
264
|
+
|
|
265
|
+
**You (GitHub Copilot) can serve as an MCP client** to read and update database entities using natural language queries!
|
|
266
|
+
|
|
267
|
+
**Architecture**: This project implements **MCP Server Executor** - a business logic microservice that AI assistants interact with via authenticated REST API calls. See `docs/training/MCP_Copilot_Integration.md` for complete details.
|
|
268
|
+
|
|
269
|
+
**When users request database operations** (e.g., "list customers", "update credit limit", "what's the balance?"):
|
|
270
|
+
|
|
271
|
+
1. **Authenticate first** - Login to obtain JWT token:
|
|
272
|
+
```bash
|
|
273
|
+
curl -X POST http://localhost:5656/api/auth/login \
|
|
274
|
+
-H "Content-Type: application/json" \
|
|
275
|
+
-d '{"username":"admin","password":"p"}'
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
2. **Execute operations** - Use Bearer token for API calls:
|
|
279
|
+
```bash
|
|
280
|
+
# Read: List entities
|
|
281
|
+
curl -X GET http://localhost:5656/api/Customer/ \
|
|
282
|
+
-H "Authorization: Bearer {token}"
|
|
283
|
+
|
|
284
|
+
# Update: Change attributes (JSON:API format)
|
|
285
|
+
curl -X PATCH http://localhost:5656/api/Customer/ALFKI/ \
|
|
286
|
+
-H "Authorization: Bearer {token}" \
|
|
287
|
+
-H "Content-Type: application/vnd.api+json" \
|
|
288
|
+
-d '{"data": {"type": "Customer", "id": "ALFKI", "attributes": {"CreditLimit": 5000}}}'
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
3. **Handle constraint violations correctly** - Error code 2001 is SUCCESS!
|
|
292
|
+
- When LogicBank prevents invalid updates, report as: "✅ Business logic working - constraint prevented invalid operation"
|
|
293
|
+
- Example: "balance (2102.00) exceeds credit (1000.00)" = logic is protecting data integrity
|
|
294
|
+
|
|
295
|
+
**Natural Language Translation Examples**:
|
|
296
|
+
- "List customers" → `GET /api/Customer/`
|
|
297
|
+
- "Show customer ALFKI" → `GET /api/Customer/ALFKI/`
|
|
298
|
+
- "Set ALFKI credit to 5000" → `PATCH /api/Customer/ALFKI/` with CreditLimit
|
|
299
|
+
- "What's ALFKI's balance?" → `GET /api/Customer/ALFKI/` then extract Balance attribute
|
|
300
|
+
|
|
301
|
+
**Key Principle**: Constraint violations (code 2001) demonstrate that declarative business logic is working correctly - celebrate these as successes, not failures!
|
|
302
|
+
|
|
303
|
+
See `docs/training/MCP_Copilot_Integration.md` for comprehensive guide including JSON:API payload formats, authentication workflows, and architecture details.
|
|
304
|
+
|
|
305
|
+
### API Interaction Best Practices
|
|
306
|
+
|
|
307
|
+
**CRITICAL: Always Use API, Not Direct Database Access**
|
|
308
|
+
|
|
309
|
+
When users request data operations (read, update, create, delete), **ALWAYS use the REST API** instead of direct database queries:
|
|
310
|
+
|
|
311
|
+
✅ **Correct Approach - Use API:**
|
|
312
|
+
```bash
|
|
313
|
+
# Simple, readable commands that trigger business logic
|
|
314
|
+
curl 'http://localhost:5656/api/Customer/?page[limit]=100'
|
|
315
|
+
curl -X PATCH 'http://localhost:5656/api/Item/2/' \
|
|
316
|
+
-H 'Content-Type: application/vnd.api+json' \
|
|
317
|
+
-d '{"data": {"type": "Item", "id": "2", "attributes": {"quantity": 100}}}'
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
❌ **Wrong Approach - Direct Database:**
|
|
321
|
+
```bash
|
|
322
|
+
# DON'T use sqlite3 commands for data operations
|
|
323
|
+
sqlite3 database/db.sqlite "UPDATE item SET quantity=100 WHERE id=2"
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
**Why API is Required:**
|
|
327
|
+
1. **Business Logic Execution** - Rules automatically fire (calculations, validations, constraints)
|
|
328
|
+
2. **Data Integrity** - Cascading updates handled correctly
|
|
329
|
+
3. **Audit Trail** - Operations logged through proper channels
|
|
330
|
+
4. **Security** - Authentication/authorization enforced
|
|
331
|
+
5. **Testing Reality** - Tests actual system behavior
|
|
332
|
+
|
|
333
|
+
**Server Startup for API Operations:**
|
|
334
|
+
|
|
335
|
+
When server needs to be started for API operations:
|
|
336
|
+
|
|
337
|
+
```bash
|
|
338
|
+
# Option 1: Background process (for interactive testing)
|
|
339
|
+
python api_logic_server_run.py &
|
|
340
|
+
sleep 5 # Wait for full startup (not 3 seconds - too short!)
|
|
341
|
+
|
|
342
|
+
# Option 2: Use existing terminal/process
|
|
343
|
+
# Check if already running: lsof -i :5656
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
**Common Mistakes to Avoid:**
|
|
347
|
+
|
|
348
|
+
1. ❌ **Insufficient startup wait**: `sleep 3` often fails
|
|
349
|
+
- ✅ Use: `sleep 5` or check with `curl` in retry loop
|
|
350
|
+
|
|
351
|
+
2. ❌ **Complex inline Python**: Piping JSON to `python3 -c` with complex list comprehensions
|
|
352
|
+
- ✅ Use: Simple `curl` commands, pipe to `jq` for filtering, or save to file first
|
|
353
|
+
|
|
354
|
+
3. ❌ **Database queries for CRUD**: Using `sqlite3` commands
|
|
355
|
+
- ✅ Use: API endpoints that trigger business logic
|
|
356
|
+
|
|
357
|
+
**Simple API Query Patterns:**
|
|
358
|
+
|
|
359
|
+
```bash
|
|
360
|
+
# Get all records (simple, reliable)
|
|
361
|
+
curl 'http://localhost:5656/api/Customer/'
|
|
362
|
+
|
|
363
|
+
# Get specific record by ID
|
|
364
|
+
curl 'http://localhost:5656/api/Customer/1/'
|
|
365
|
+
|
|
366
|
+
# Get related records (follow relationships)
|
|
367
|
+
curl 'http://localhost:5656/api/Customer/1/OrderList'
|
|
368
|
+
|
|
369
|
+
# Filter results (use bracket notation)
|
|
370
|
+
curl 'http://localhost:5656/api/Customer/?filter[name]=Alice'
|
|
371
|
+
|
|
372
|
+
# Limit results
|
|
373
|
+
curl 'http://localhost:5656/api/Customer/?page[limit]=10'
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
**Parsing JSON Responses:**
|
|
377
|
+
|
|
378
|
+
```bash
|
|
379
|
+
# Simple: Pipe to python -m json.tool for pretty printing
|
|
380
|
+
curl 'http://localhost:5656/api/Customer/' | python3 -m json.tool
|
|
381
|
+
|
|
382
|
+
# Better: Use jq if available
|
|
383
|
+
curl 'http://localhost:5656/api/Customer/' | jq '.data[] | {id, name: .attributes.name}'
|
|
384
|
+
|
|
385
|
+
# Alternative: Save to file first, then parse
|
|
386
|
+
curl 'http://localhost:5656/api/Customer/' > customers.json
|
|
387
|
+
python3 -c "import json; data=json.load(open('customers.json')); print(data['data'][0])"
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
**Key Principle**: The API is not just a convenience - it's the **only correct way** to interact with data because it ensures business logic executes properly.
|
|
391
|
+
|
|
185
392
|
### Automated Testing
|
|
186
393
|
|
|
187
394
|
**CRITICAL WORKFLOW - When User Says "Create Tests":**
|
|
@@ -398,20 +605,20 @@ Customize using CoPilot chat, with `docs/training`.
|
|
|
398
605
|
|
|
399
606
|
Configure:
|
|
400
607
|
```
|
|
401
|
-
|
|
402
|
-
|
|
608
|
+
genai-logic add-auth --provider-type=sql --db-url=
|
|
609
|
+
genai-logic add-auth --provider-type=sql --db_url=postgresql://postgres:p@localhost/authdb
|
|
403
610
|
|
|
404
|
-
|
|
405
|
-
|
|
611
|
+
genai-logic add-auth --provider-type=keycloak --db-url=localhost
|
|
612
|
+
genai-logic add-auth --provider-type=keycloak --db-url=hardened
|
|
406
613
|
|
|
407
|
-
|
|
614
|
+
genai-logic add-auth --provider-type=None # to disable
|
|
408
615
|
```
|
|
409
616
|
|
|
410
617
|
Keycloak quick start [(more information here:)](https://apilogicserver.github.io/Docs/Security-Keycloak/)
|
|
411
618
|
```bash
|
|
412
619
|
cd devops/keycloak
|
|
413
620
|
docker compose up
|
|
414
|
-
|
|
621
|
+
genai-logic add-auth --provider-type=keycloak --db-url=localhost
|
|
415
622
|
```
|
|
416
623
|
|
|
417
624
|
For more on KeyCloak: https://apilogicserver.github.io/Docs/Security-Keycloak/
|
|
@@ -422,6 +629,64 @@ Declaration:
|
|
|
422
629
|
Grant(on_entity=Customer, to_role=sales, filter=lambda: Customer.SalesRep == current_user())
|
|
423
630
|
```
|
|
424
631
|
|
|
632
|
+
|
|
633
|
+
#### Testing with Security Enabled
|
|
634
|
+
|
|
635
|
+
**CRITICAL:** When `SECURITY_ENABLED=True`, test code must obtain and include JWT authentication tokens.
|
|
636
|
+
|
|
637
|
+
**Pattern for test steps:**
|
|
638
|
+
```python
|
|
639
|
+
from pathlib import Path
|
|
640
|
+
import os
|
|
641
|
+
from dotenv import load_dotenv
|
|
642
|
+
|
|
643
|
+
# Load config to check SECURITY_ENABLED
|
|
644
|
+
config_path = Path(__file__).parent.parent.parent.parent.parent / 'config' / 'default.env'
|
|
645
|
+
load_dotenv(config_path)
|
|
646
|
+
|
|
647
|
+
# Cache for auth token (obtained once per test session)
|
|
648
|
+
_auth_token = None
|
|
649
|
+
|
|
650
|
+
def get_auth_token():
|
|
651
|
+
"""Login and get JWT token if security is enabled"""
|
|
652
|
+
global _auth_token
|
|
653
|
+
|
|
654
|
+
if _auth_token is not None:
|
|
655
|
+
return _auth_token
|
|
656
|
+
|
|
657
|
+
# Login with default admin credentials
|
|
658
|
+
login_url = f'{BASE_URL}/api/auth/login'
|
|
659
|
+
login_data = {'username': 'admin', 'password': 'p'}
|
|
660
|
+
|
|
661
|
+
response = requests.post(login_url, json=login_data)
|
|
662
|
+
if response.status_code == 200:
|
|
663
|
+
_auth_token = response.json().get('access_token')
|
|
664
|
+
return _auth_token
|
|
665
|
+
else:
|
|
666
|
+
raise Exception(f"Login failed: {response.status_code}")
|
|
667
|
+
|
|
668
|
+
def get_headers():
|
|
669
|
+
"""Get headers including auth token if security is enabled"""
|
|
670
|
+
security_enabled = os.getenv('SECURITY_ENABLED', 'false').lower() not in ['false', 'no']
|
|
671
|
+
|
|
672
|
+
headers = {'Content-Type': 'application/json'}
|
|
673
|
+
|
|
674
|
+
if security_enabled:
|
|
675
|
+
token = get_auth_token()
|
|
676
|
+
if token:
|
|
677
|
+
headers['Authorization'] = f'Bearer {token}'
|
|
678
|
+
|
|
679
|
+
return headers
|
|
680
|
+
|
|
681
|
+
# Use in all API requests
|
|
682
|
+
response = requests.post(url=api_url, json=data, headers=get_headers())
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
**Key points:**
|
|
686
|
+
- Tests DO NOT automatically include auth headers - you must code this pattern
|
|
687
|
+
- Token is cached to avoid repeated logins during test session
|
|
688
|
+
- Pattern works for both `SECURITY_ENABLED=True` and `SECURITY_ENABLED=False`
|
|
689
|
+
- See `test/api_logic_server_behave/features/steps/order_processing_steps.py` for complete example
|
|
425
690
|
### Adding Custom API Endpoints
|
|
426
691
|
|
|
427
692
|
For simple endpoints:
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
use: welcome for basic_demo - please start the tour
|
|
3
|
+
instuctions: copy api_logic_server_cli/prototypes/base/.github/.copilot-instructions.md, then paste as the Welcome section
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Welcome
|
|
7
|
+
|
|
8
|
+
**Welcome! This is your basic_demo project.**
|
|
9
|
+
|
|
10
|
+
This is a complete, working microservice auto-generated from a database schema - **uncustomized**, so you can see what to expect when you create projects from your own databases.
|
|
11
|
+
|
|
12
|
+
**What's already created from introspecting the database schema:**
|
|
13
|
+
- **Admin Web Application** - Live at `http://localhost:5656`
|
|
14
|
+
- **REST API Endpoints** - All database tables exposed at `/api/*`
|
|
15
|
+
- **Database Models** - Complete SQLAlchemy ORM in `database/models.py`
|
|
16
|
+
- **Authentication System** - JWT-based auth framework
|
|
17
|
+
- **Business Logic Engine** - Declarative rules system
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
**First, we'll briefly explore what's automatically created. Then I'll show you how I can help you customize it - adding logic, security, and API endpoints.**
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
**Ready to explore?** Open `tutor.md` and tell me "guide me through" to begin the interactive tutorial.
|
|
25
|
+
|
|
26
|
+
---
|
|
@@ -47,7 +47,12 @@ def declare_logic():
|
|
|
47
47
|
|
|
48
48
|
Use case: App Integration
|
|
49
49
|
1. Send the Order to Kafka topic 'order_shipping' if the date_shipped is not None.
|
|
50
|
+
|
|
50
51
|
Also, using logic/logic_discovery is a Best Practice - see logic/readme_logic.md
|
|
52
|
+
|
|
53
|
+
The 5 *declarative* lines below represent the same logic as 200 lines of *declarative* Python
|
|
54
|
+
1. To view the AI procedural/declarative comparison, [click here](https://github.com/ApiLogicServer/ApiLogicServer-src/blob/main/api_logic_server_cli/prototypes/basic_demo/logic/procedural/declarative-vs-procedural-comparison.md)
|
|
55
|
+
2. Consider a 100 table system: 1,000 rules vs. 40,000 lines of code
|
|
51
56
|
'''
|
|
52
57
|
from database.models import Product, Order, Item, Customer, SysEmail
|
|
53
58
|
|