ApiLogicServer 15.3.0__py3-none-any.whl → 15.3.6__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 +2 -1
- api_logic_server_cli/create_from_model/api_logic_server_utils.py +3 -1
- api_logic_server_cli/prototypes/base/.github/.copilot-instructions.md +60 -14
- 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/base/readme.md +1 -1
- api_logic_server_cli/prototypes/basic_demo/.github/.copilot-instructions.md +201 -25
- 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/docs/system-creation-vibe.md +2 -2
- api_logic_server_cli/prototypes/basic_demo/readme.md +1 -1
- api_logic_server_cli/prototypes/manager/.github/.copilot-instructions.md +164 -9
- api_logic_server_cli/prototypes/manager/README.md +1 -1
- api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/docs/system-creation-vibe.md +2 -2
- api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/logic/logic_discovery/check_credit.py +4 -1
- api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/readme.md +1 -1
- api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/readme_standard.md +1 -1
- api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/readme_vibe.md +2 -2
- {apilogicserver-15.3.0.dist-info → apilogicserver-15.3.6.dist-info}/METADATA +1 -1
- {apilogicserver-15.3.0.dist-info → apilogicserver-15.3.6.dist-info}/RECORD +24 -22
- {apilogicserver-15.3.0.dist-info → apilogicserver-15.3.6.dist-info}/WHEEL +0 -0
- {apilogicserver-15.3.0.dist-info → apilogicserver-15.3.6.dist-info}/entry_points.txt +0 -0
- {apilogicserver-15.3.0.dist-info → apilogicserver-15.3.6.dist-info}/licenses/LICENSE +0 -0
- {apilogicserver-15.3.0.dist-info → apilogicserver-15.3.6.dist-info}/top_level.txt +0 -0
|
@@ -12,9 +12,10 @@ 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.03.
|
|
15
|
+
__version__ = "15.03.06" # last public release: 15.03.02
|
|
16
16
|
recent_changes = \
|
|
17
17
|
f'\n\nRecent Changes:\n' +\
|
|
18
|
+
"\t11/06/2025 - 15.03.06: Nat lang Copilot data access, fix Manager/Copilot startup, finding venv in project \n"\
|
|
18
19
|
"\t10/29/2025 - 15.03.00: Stable Tutor 3.3 (working, vibe transtion) \n"\
|
|
19
20
|
"\t10/26/2025 - 15.02.07: Clarify order created for ship test, security fixes [105], tutor 2.1 \n"\
|
|
20
21
|
"\t10/22/2025 - 15.02.03: Copilot test creation from rules and custom APIs with issues [103, 104] \n"\
|
|
@@ -84,7 +84,7 @@ def copy_md(project, from_doc_file: str, to_project_file: str = "README.md"):
|
|
|
84
84
|
|
|
85
85
|
1. github (to acquire more recent version since release)
|
|
86
86
|
|
|
87
|
-
2. dev docs, iff exists (gold version in docs, not prototypes).
|
|
87
|
+
2. dev docs, iff exists (**gold version in docs, not prototypes**).
|
|
88
88
|
|
|
89
89
|
Used by Sample-AI; Sample-Integration (nw-), Tutorial, Tutorial-3 (3 projects), Sample-Basic-Demo; Manager
|
|
90
90
|
|
|
@@ -98,6 +98,8 @@ def copy_md(project, from_doc_file: str, to_project_file: str = "README.md"):
|
|
|
98
98
|
|
|
99
99
|
Doc Links are made absolute.
|
|
100
100
|
|
|
101
|
+
See: https://apilogicserver.github.io/Docs/Architecture-Internals/#docs-used-in-project-creation
|
|
102
|
+
|
|
101
103
|
Args:
|
|
102
104
|
project (ProjectRun or Path): project object (project name, etc)
|
|
103
105
|
from_doc_file (str): eg, Sample-Basic_Demo.md (no docs/)
|
|
@@ -3,10 +3,13 @@ title: Copilot Instructions for GenAI-Logic Projects
|
|
|
3
3
|
Description: Project-level instructions for working with generated projects
|
|
4
4
|
Source: ApiLogicServer-src/prototypes/base/.github/.copilot-instructions.md
|
|
5
5
|
Propagation: CLI create command → created projects (non-basic_demo)
|
|
6
|
+
Instrucions: Changes must be copied to api_logic_server_cli/prototypes/basic_demo/.github - see instructions there
|
|
6
7
|
Usage: AI assistants read this when user opens any created project
|
|
7
|
-
version: 2.
|
|
8
|
+
version: 2.4
|
|
8
9
|
changelog:
|
|
9
|
-
- 2.
|
|
10
|
+
- 2.4 (Nov 05, 2025 - Added MCP Integration section, Copilot as MCP client capability)
|
|
11
|
+
- 2.3 (Nov 04, 2025 - Clear 1st message about reading Welcome section verbatim, again for non basic_demo)
|
|
12
|
+
- 2.2 (Oct 29, 2025 - Clear 1st message about reading Welcome section verbatim)
|
|
10
13
|
- 2.1 (Oct 2025) - Streamlined OBX for non-tutorial projects, friendly collaborative tone
|
|
11
14
|
- 2.0 (Oct 2025) - Added front matter, updated for OBX improvements
|
|
12
15
|
- 1.0 (Initial) - Comprehensive technical reference
|
|
@@ -14,18 +17,8 @@ changelog:
|
|
|
14
17
|
|
|
15
18
|
# GitHub Copilot Instructions for GenAI-Logic (aka API Logic Server) Projects
|
|
16
19
|
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## ⚠️ CRITICAL INSTRUCTION FOR AI ASSISTANTS
|
|
20
|
-
|
|
21
|
-
**When user first opens this project or asks "what can you help me with", respond with the following text VERBATIM (copy-paste exactly as shown below):**
|
|
22
|
-
|
|
23
|
-
```
|
|
24
|
-
# GitHub Copilot Instructions for GenAI-Logic (aka API Logic Server) Projects
|
|
25
|
-
|
|
26
|
-
**INSTRUCTION**: When the user asks you to read 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.
|
|
27
20
|
|
|
28
|
-
---
|
|
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".
|
|
29
22
|
|
|
30
23
|
## Welcome
|
|
31
24
|
|
|
@@ -50,7 +43,7 @@ This is a complete, working microservice auto-generated from your database schem
|
|
|
50
43
|
4. **Add security** - Set up role-based access control with `genai-logic add-auth`
|
|
51
44
|
5. **Test your logic** - Create Behave tests with requirements traceability
|
|
52
45
|
6. **Configure Admin UI** - Customize the auto-generated admin interface
|
|
53
|
-
7. **
|
|
46
|
+
7. **Query via natural language** - I can act as MCP client to read/update data (see `docs/training/MCP_Copilot_Integration.md`)
|
|
54
47
|
8. **Create B2B APIs** - Complex integration endpoints with partner systems
|
|
55
48
|
9. **Add events** - Integrate with Kafka, webhooks, or other event systems
|
|
56
49
|
10. **Customize models** - Add tables, attributes, or derived fields
|
|
@@ -119,6 +112,17 @@ Want to get started? Press **F5** to start the server with debugger support, the
|
|
|
119
112
|
## Detailed Service Documentation
|
|
120
113
|
|
|
121
114
|
The sections below provide complete details on each service. I'll reference these as needed when we work together.
|
|
115
|
+
|
|
116
|
+
### `venv` is required
|
|
117
|
+
|
|
118
|
+
To establish the virtual environment:
|
|
119
|
+
|
|
120
|
+
1. Attempt to find a `venv` folder in the parent or grandparent directory
|
|
121
|
+
2. Or, create it using requirements.txt
|
|
122
|
+
|
|
123
|
+
### Starting the server
|
|
124
|
+
|
|
125
|
+
```bash
|
|
122
126
|
python api_logic_server_run.py
|
|
123
127
|
# Then open: http://localhost:5656
|
|
124
128
|
```
|
|
@@ -246,6 +250,48 @@ When users provide natural language with multiple use cases like:
|
|
|
246
250
|
|
|
247
251
|
**NEVER put everything in `use_case.py`** - that defeats the discovery system purpose.
|
|
248
252
|
|
|
253
|
+
### MCP Integration - Acting as Database Client
|
|
254
|
+
|
|
255
|
+
**You (GitHub Copilot) can serve as an MCP client** to read and update database entities using natural language queries!
|
|
256
|
+
|
|
257
|
+
**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.
|
|
258
|
+
|
|
259
|
+
**When users request database operations** (e.g., "list customers", "update credit limit", "what's the balance?"):
|
|
260
|
+
|
|
261
|
+
1. **Authenticate first** - Login to obtain JWT token:
|
|
262
|
+
```bash
|
|
263
|
+
curl -X POST http://localhost:5656/api/auth/login \
|
|
264
|
+
-H "Content-Type: application/json" \
|
|
265
|
+
-d '{"username":"admin","password":"p"}'
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
2. **Execute operations** - Use Bearer token for API calls:
|
|
269
|
+
```bash
|
|
270
|
+
# Read: List entities
|
|
271
|
+
curl -X GET http://localhost:5656/api/Customer/ \
|
|
272
|
+
-H "Authorization: Bearer {token}"
|
|
273
|
+
|
|
274
|
+
# Update: Change attributes (JSON:API format)
|
|
275
|
+
curl -X PATCH http://localhost:5656/api/Customer/ALFKI/ \
|
|
276
|
+
-H "Authorization: Bearer {token}" \
|
|
277
|
+
-H "Content-Type: application/vnd.api+json" \
|
|
278
|
+
-d '{"data": {"type": "Customer", "id": "ALFKI", "attributes": {"CreditLimit": 5000}}}'
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
3. **Handle constraint violations correctly** - Error code 2001 is SUCCESS!
|
|
282
|
+
- When LogicBank prevents invalid updates, report as: "✅ Business logic working - constraint prevented invalid operation"
|
|
283
|
+
- Example: "balance (2102.00) exceeds credit (1000.00)" = logic is protecting data integrity
|
|
284
|
+
|
|
285
|
+
**Natural Language Translation Examples**:
|
|
286
|
+
- "List customers" → `GET /api/Customer/`
|
|
287
|
+
- "Show customer ALFKI" → `GET /api/Customer/ALFKI/`
|
|
288
|
+
- "Set ALFKI credit to 5000" → `PATCH /api/Customer/ALFKI/` with CreditLimit
|
|
289
|
+
- "What's ALFKI's balance?" → `GET /api/Customer/ALFKI/` then extract Balance attribute
|
|
290
|
+
|
|
291
|
+
**Key Principle**: Constraint violations (code 2001) demonstrate that declarative business logic is working correctly - celebrate these as successes, not failures!
|
|
292
|
+
|
|
293
|
+
See `docs/training/MCP_Copilot_Integration.md` for comprehensive guide including JSON:API payload formats, authentication workflows, and architecture details.
|
|
294
|
+
|
|
249
295
|
### Automated Testing
|
|
250
296
|
|
|
251
297
|
**CRITICAL WORKFLOW - When User Says "Create Tests":**
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
# MCP Integration Guide for Copilot
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This GenAI-Logic project implements **MCP Server Executor** architecture - providing business logic services that AI assistants (like GitHub Copilot) can invoke to read and update database entities using natural language.
|
|
6
|
+
|
|
7
|
+
**Key Distinction**: GenAI-Logic is NOT a standard "MCP Protocol Server" (JSON-RPC over stdio). Instead, it's a **business logic microservice** that AI assistants interact with via authenticated REST API calls. This architecture is more scalable and enterprise-ready than stdio-based MCP servers.
|
|
8
|
+
|
|
9
|
+
## Architecture
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
┌─────────────────────────────────┐
|
|
13
|
+
│ GitHub Copilot / Claude │ Natural language interface
|
|
14
|
+
│ (MCP Client / AI Assistant) │
|
|
15
|
+
└────────────┬────────────────────┘
|
|
16
|
+
│ HTTP REST API (JSON:API format)
|
|
17
|
+
│ JWT Authentication
|
|
18
|
+
┌────────────▼────────────────────┐
|
|
19
|
+
│ GenAI-Logic Server │ MCP Server Executor
|
|
20
|
+
│ (Flask + LogicBank) │ - Business logic enforcement
|
|
21
|
+
│ │ - Constraint validation
|
|
22
|
+
│ Endpoints: │ - Declarative rules (44X reduction)
|
|
23
|
+
│ - /api/auth/login │ - Schema metadata
|
|
24
|
+
│ - /api/{Entity} │
|
|
25
|
+
│ - /.well-known/mcp.json │
|
|
26
|
+
│ - /mcp │
|
|
27
|
+
└────────────┬────────────────────┘
|
|
28
|
+
│
|
|
29
|
+
┌────────────▼────────────────────┐
|
|
30
|
+
│ Database (SQLAlchemy ORM) │
|
|
31
|
+
└─────────────────────────────────┘
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## How Copilot Acts as MCP Client
|
|
35
|
+
|
|
36
|
+
GitHub Copilot can serve as an interactive MCP client by:
|
|
37
|
+
|
|
38
|
+
1. **Authenticating** - Login to obtain JWT token
|
|
39
|
+
2. **Translating** - Convert natural language to API operations
|
|
40
|
+
3. **Executing** - Make authenticated HTTP calls
|
|
41
|
+
4. **Reporting** - Present results or explain constraint violations
|
|
42
|
+
|
|
43
|
+
## Copilot Usage Pattern
|
|
44
|
+
|
|
45
|
+
### Step 1: Authentication
|
|
46
|
+
|
|
47
|
+
When user requests database operations, Copilot should first authenticate:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
curl -X POST http://localhost:5656/api/auth/login \
|
|
51
|
+
-H "Content-Type: application/json" \
|
|
52
|
+
-d '{"username":"admin","password":"p"}'
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Response contains JWT token:
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
|
|
59
|
+
"token_type": "Bearer"
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Step 2: Execute Operations
|
|
64
|
+
|
|
65
|
+
Use token for authenticated requests:
|
|
66
|
+
|
|
67
|
+
#### Read Operations (GET)
|
|
68
|
+
```bash
|
|
69
|
+
# List customers
|
|
70
|
+
curl -X GET http://localhost:5656/api/Customer/ \
|
|
71
|
+
-H "Authorization: Bearer {token}"
|
|
72
|
+
|
|
73
|
+
# Get specific customer
|
|
74
|
+
curl -X GET http://localhost:5656/api/Customer/ALFKI/ \
|
|
75
|
+
-H "Authorization: Bearer {token}"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
#### Update Operations (PATCH)
|
|
79
|
+
```bash
|
|
80
|
+
# Update customer credit limit
|
|
81
|
+
curl -X PATCH http://localhost:5656/api/Customer/ALFKI/ \
|
|
82
|
+
-H "Authorization: Bearer {token}" \
|
|
83
|
+
-H "Content-Type: application/vnd.api+json" \
|
|
84
|
+
-d '{
|
|
85
|
+
"data": {
|
|
86
|
+
"type": "Customer",
|
|
87
|
+
"id": "ALFKI",
|
|
88
|
+
"attributes": {
|
|
89
|
+
"CreditLimit": 5000
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}'
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
#### Create Operations (POST)
|
|
96
|
+
```bash
|
|
97
|
+
# Create new customer
|
|
98
|
+
curl -X POST http://localhost:5656/api/Customer/ \
|
|
99
|
+
-H "Authorization: Bearer {token}" \
|
|
100
|
+
-H "Content-Type: application/vnd.api+json" \
|
|
101
|
+
-d '{
|
|
102
|
+
"data": {
|
|
103
|
+
"type": "Customer",
|
|
104
|
+
"attributes": {
|
|
105
|
+
"Id": "NEWCO",
|
|
106
|
+
"CompanyName": "New Company Inc",
|
|
107
|
+
"ContactName": "John Doe",
|
|
108
|
+
"CreditLimit": 1000
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}'
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Step 3: Handle Constraint Violations
|
|
115
|
+
|
|
116
|
+
**CRITICAL**: Constraint violations are SUCCESS demonstrations of business logic!
|
|
117
|
+
|
|
118
|
+
When an update violates business rules, the server returns error code 2001:
|
|
119
|
+
|
|
120
|
+
```json
|
|
121
|
+
{
|
|
122
|
+
"error": {
|
|
123
|
+
"code": 2001,
|
|
124
|
+
"message": "balance (2102.00) exceeds credit (1000.00)"
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**Copilot should report this as**: "✅ Business logic working correctly - constraint prevented invalid update: balance exceeds credit limit"
|
|
130
|
+
|
|
131
|
+
Common constraint codes:
|
|
132
|
+
- **2001** - Business rule violation (the valuable demonstration!)
|
|
133
|
+
- **401** - Unauthorized (need to authenticate)
|
|
134
|
+
- **404** - Entity not found
|
|
135
|
+
- **422** - Validation error
|
|
136
|
+
|
|
137
|
+
## Natural Language → API Translation Examples
|
|
138
|
+
|
|
139
|
+
| User Request | Copilot Action | API Call |
|
|
140
|
+
|--------------|----------------|----------|
|
|
141
|
+
| "List all customers" | GET collection | `GET /api/Customer/` |
|
|
142
|
+
| "Show customer ALFKI" | GET single entity | `GET /api/Customer/ALFKI/` |
|
|
143
|
+
| "Update ALFKI credit to 5000" | PATCH entity | `PATCH /api/Customer/ALFKI/` with CreditLimit |
|
|
144
|
+
| "What's ALFKI's balance?" | GET entity, extract attribute | `GET /api/Customer/ALFKI/` → read Balance |
|
|
145
|
+
| "Increase ALFKI credit by 1000" | GET then PATCH | GET current → calculate → PATCH new value |
|
|
146
|
+
| "Create customer NEWCO" | POST entity | `POST /api/Customer/` with attributes |
|
|
147
|
+
|
|
148
|
+
## MCP Discovery Endpoints
|
|
149
|
+
|
|
150
|
+
The server exposes schema metadata for AI assistants:
|
|
151
|
+
|
|
152
|
+
### Well-Known Endpoint
|
|
153
|
+
```bash
|
|
154
|
+
curl http://localhost:5656/.well-known/mcp.json
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Returns full schema including:
|
|
158
|
+
- Available entities (tables)
|
|
159
|
+
- Attributes and types
|
|
160
|
+
- Relationships
|
|
161
|
+
- Business rules documentation
|
|
162
|
+
|
|
163
|
+
### MCP Endpoint
|
|
164
|
+
```bash
|
|
165
|
+
curl http://localhost:5656/mcp
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Same schema as well-known endpoint, alternate path for compatibility.
|
|
169
|
+
|
|
170
|
+
## Key Implementation Files
|
|
171
|
+
|
|
172
|
+
- **`api/api_discovery/mcp_discovery.py`** - MCP discovery endpoints
|
|
173
|
+
- **`integration/mcp/mcp_client_executor.py`** - Example MCP client script
|
|
174
|
+
- **`docs/mcp_learning/mcp_schema.json`** - Schema metadata
|
|
175
|
+
- **`logic/declare_logic.py`** - Declarative business rules (LogicBank)
|
|
176
|
+
- **`config/default.env`** - Server configuration (SECURITY_ENABLED)
|
|
177
|
+
|
|
178
|
+
## Testing Workflow for Copilot
|
|
179
|
+
|
|
180
|
+
When user says: "Can you query the database for me?"
|
|
181
|
+
|
|
182
|
+
1. **Acknowledge**: "I'll act as MCP client and query the server"
|
|
183
|
+
2. **Authenticate**: Login via `/api/auth/login` to get JWT token
|
|
184
|
+
3. **Execute**: Make appropriate GET/PATCH/POST call with Bearer token
|
|
185
|
+
4. **Present**: Format results or explain constraint violations as logic success
|
|
186
|
+
5. **Iterate**: Accept follow-up natural language requests
|
|
187
|
+
|
|
188
|
+
Example interaction:
|
|
189
|
+
```
|
|
190
|
+
User: "List customers with balance over 1000"
|
|
191
|
+
Copilot:
|
|
192
|
+
1. Login to get token
|
|
193
|
+
2. GET /api/Customer/?filter[Balance]=>1000
|
|
194
|
+
3. Present: "Found 3 customers: ALFKI (2102.00), ANATR (1500.50), ..."
|
|
195
|
+
|
|
196
|
+
User: "Try to set ALFKI credit to 500"
|
|
197
|
+
Copilot:
|
|
198
|
+
1. PATCH /api/Customer/ALFKI/ with CreditLimit=500
|
|
199
|
+
2. Receive error 2001: "balance (2102.00) exceeds credit (500.00)"
|
|
200
|
+
3. Present: "✅ Business logic prevented this - ALFKI's balance of 2102.00
|
|
201
|
+
exceeds the proposed credit limit of 500.00. The system is correctly
|
|
202
|
+
enforcing the constraint that credit must be >= balance."
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Business Logic Layer (LogicBank)
|
|
206
|
+
|
|
207
|
+
The real power is in declarative business rules that auto-execute on all API operations:
|
|
208
|
+
|
|
209
|
+
```python
|
|
210
|
+
# From logic/declare_logic.py
|
|
211
|
+
|
|
212
|
+
# Constraint: Customer balance cannot exceed credit limit
|
|
213
|
+
Rule.constraint(validate=models.Customer,
|
|
214
|
+
as_condition=lambda row: row.Balance <= row.CreditLimit,
|
|
215
|
+
error_msg="balance ({row.Balance}) exceeds credit ({row.CreditLimit})")
|
|
216
|
+
|
|
217
|
+
# Sum rule: Customer balance = sum of unpaid order amounts
|
|
218
|
+
Rule.sum(derive=models.Customer.Balance,
|
|
219
|
+
as_sum_of=models.Order.AmountTotal,
|
|
220
|
+
where=lambda row: row.ShippedDate is None)
|
|
221
|
+
|
|
222
|
+
# Formula: Order amount = sum of items
|
|
223
|
+
Rule.sum(derive=models.Order.AmountTotal,
|
|
224
|
+
as_sum_of=models.OrderDetail.Amount)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
These rules:
|
|
228
|
+
- Execute automatically on INSERT/UPDATE/DELETE
|
|
229
|
+
- Provide **44X code reduction** vs. traditional procedural code
|
|
230
|
+
- Enforce multi-table constraints
|
|
231
|
+
- Chain automatically (Order → Customer balance)
|
|
232
|
+
|
|
233
|
+
## Why This Architecture?
|
|
234
|
+
|
|
235
|
+
**GenAI-Logic's HTTP-based approach** vs **stdio-based MCP servers**:
|
|
236
|
+
|
|
237
|
+
| Aspect | GenAI-Logic (HTTP) | Stdio MCP |
|
|
238
|
+
|--------|-------------------|-----------|
|
|
239
|
+
| Transport | HTTP REST API | JSON-RPC over stdin/stdout |
|
|
240
|
+
| Authentication | JWT Bearer tokens | Process isolation |
|
|
241
|
+
| Scalability | Horizontal scaling | One process per client |
|
|
242
|
+
| Network | Works across machines | Same machine only |
|
|
243
|
+
| Protocol | JSON:API standard | Custom JSON-RPC |
|
|
244
|
+
| Enterprise Ready | ✅ Yes | ⚠️ Limited |
|
|
245
|
+
|
|
246
|
+
For Microsoft demo: Position GenAI-Logic as the **business logic layer** that any MCP client can invoke, rather than trying to fit into stdio-based protocol constraints.
|
|
247
|
+
|
|
248
|
+
## Optional: JSON-RPC Wrapper
|
|
249
|
+
|
|
250
|
+
If standard MCP protocol compatibility is desired, you could add a thin JSON-RPC wrapper:
|
|
251
|
+
|
|
252
|
+
```python
|
|
253
|
+
# Optional enhancement - not required for Copilot usage
|
|
254
|
+
@app.route('/mcp/jsonrpc', methods=['POST'])
|
|
255
|
+
def mcp_jsonrpc():
|
|
256
|
+
"""Translate JSON-RPC 2.0 to internal API calls"""
|
|
257
|
+
request_data = request.json
|
|
258
|
+
method = request_data.get('method')
|
|
259
|
+
params = request_data.get('params', {})
|
|
260
|
+
|
|
261
|
+
if method == 'customers/list':
|
|
262
|
+
# Translate to GET /api/Customer/
|
|
263
|
+
response = internal_api_call('GET', '/api/Customer/', params)
|
|
264
|
+
return jsonify({'jsonrpc': '2.0', 'result': response, 'id': request_data['id']})
|
|
265
|
+
# ... more method translations
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
**Effort estimate**: Half-day for experienced developer. But this is optional - Copilot can work directly with REST API.
|
|
269
|
+
|
|
270
|
+
## Demo Strategy
|
|
271
|
+
|
|
272
|
+
For Microsoft presentation:
|
|
273
|
+
|
|
274
|
+
1. **Position correctly**: "GenAI-Logic implements MCP Server Executor - the valuable business logic layer"
|
|
275
|
+
2. **Show constraint violations**: "Error 2001 is the success - logic is working!"
|
|
276
|
+
3. **Demonstrate declarative rules**: "44X code reduction with automatic multi-table chaining"
|
|
277
|
+
4. **Use Copilot as client**: "AI assistant translates natural language to authenticated API calls"
|
|
278
|
+
5. **Highlight enterprise architecture**: "HTTP-based, JWT auth, horizontally scalable"
|
|
279
|
+
|
|
280
|
+
The MCP discovery endpoints (`/.well-known/mcp.json` and `/mcp`) allow AI assistants to understand the schema and available operations, but the real innovation is the declarative business logic layer that enforces rules automatically.
|
|
281
|
+
|
|
282
|
+
## Quick Reference for Copilot
|
|
283
|
+
|
|
284
|
+
**Authentication**:
|
|
285
|
+
```bash
|
|
286
|
+
curl -X POST http://localhost:5656/api/auth/login -d '{"username":"admin","password":"p"}'
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
**Common operations**:
|
|
290
|
+
- List: `GET /api/{Entity}/` with Bearer token
|
|
291
|
+
- Read: `GET /api/{Entity}/{id}/` with Bearer token
|
|
292
|
+
- Update: `PATCH /api/{Entity}/{id}/` with JSON:API payload and Bearer token
|
|
293
|
+
- Create: `POST /api/{Entity}/` with JSON:API payload and Bearer token
|
|
294
|
+
|
|
295
|
+
**Remember**: Constraint violations (code 2001) = business logic success! Report them positively.
|
|
@@ -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
|