ApiLogicServer 12.0.4__py3-none-any.whl → 12.1.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 (41) hide show
  1. {ApiLogicServer-12.0.4.dist-info → ApiLogicServer-12.1.0.dist-info}/METADATA +2 -1
  2. {ApiLogicServer-12.0.4.dist-info → ApiLogicServer-12.1.0.dist-info}/RECORD +39 -24
  3. {ApiLogicServer-12.0.4.dist-info → ApiLogicServer-12.1.0.dist-info}/WHEEL +1 -1
  4. api_logic_server_cli/api_logic_server.py +8 -201
  5. api_logic_server_cli/api_logic_server_info.yaml +3 -3
  6. api_logic_server_cli/cli.py +9 -79
  7. api_logic_server_cli/create_from_model/__pycache__/dbml.cpython-312.pyc +0 -0
  8. api_logic_server_cli/create_from_model/__pycache__/meta_model.cpython-312.pyc +0 -0
  9. api_logic_server_cli/create_from_model/__pycache__/model_creation_services.cpython-312.pyc +0 -0
  10. api_logic_server_cli/create_from_model/meta_model.py +1 -1
  11. api_logic_server_cli/create_from_model/model_creation_services.py +3 -1
  12. api_logic_server_cli/genai.py +273 -151
  13. api_logic_server_cli/genaiZ.py +752 -0
  14. api_logic_server_cli/prototypes/genai_demo/logic/declare_logic.py +11 -12
  15. api_logic_server_cli/prototypes/manager/.vscode/launch.json +78 -1
  16. api_logic_server_cli/prototypes/manager/README.md +16 -3
  17. api_logic_server_cli/prototypes/manager/system/genai/create_db_models_inserts/create_db_models_create_db.py +10 -0
  18. api_logic_server_cli/prototypes/manager/system/genai/create_db_models_inserts/create_db_models_imports.py +19 -0
  19. api_logic_server_cli/prototypes/manager/system/genai/create_db_models_inserts/create_db_models_test_data.py +7 -0
  20. api_logic_server_cli/prototypes/manager/system/genai/examples/emp_depts/emp_dept.prompt +4 -0
  21. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo.prompt +1 -1
  22. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo.response_example +56 -130
  23. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo.response_example_z +130 -0
  24. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_informal.prompt +10 -0
  25. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_iterative_logic/genai_demo_iterative_logic_000.response +1 -0
  26. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_iterative_logic/genai_demo_iterative_logic_001.prompt +171 -0
  27. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_iterative_logic/genai_demo_iterative_logic_002.prompt +21 -0
  28. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_iterative_logic/genai_demo_iterative_logic_003.response +94 -0
  29. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_iterative_logic/genai_demo_iterative_logic_004.prompt +6 -0
  30. api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_iterative_logic/genai_demo_iterative_logic_005.response_example +122 -0
  31. api_logic_server_cli/prototypes/manager/system/genai/learning_requests/logic_bank_api.prompt +42 -5
  32. api_logic_server_cli/prototypes/manager/system/genai/prompt_inserts/logic_inserts.prompt +1 -0
  33. api_logic_server_cli/prototypes/manager/system/genai/prompt_inserts/response_format.prompt +6 -0
  34. api_logic_server_cli/prototypes/manager/system/genai/prompt_inserts/sqlite_inserts.prompt +11 -2
  35. api_logic_server_cli/prototypes/manager/system/genai/prompt_inserts/sqlite_inserts_iterations.prompt +25 -0
  36. api_logic_server_cli/prototypes/manager/system/genai/prompt_inserts/web_genai copy.prompt +15 -0
  37. api_logic_server_cli/prototypes/manager/system/genai/examples/emp_depts/emp_dept_explicit.prompt +0 -7
  38. api_logic_server_cli/prototypes/manager/system/genai/examples/emp_depts/emp_dept_implicit_fails.prompt +0 -5
  39. {ApiLogicServer-12.0.4.dist-info → ApiLogicServer-12.1.0.dist-info}/LICENSE +0 -0
  40. {ApiLogicServer-12.0.4.dist-info → ApiLogicServer-12.1.0.dist-info}/entry_points.txt +0 -0
  41. {ApiLogicServer-12.0.4.dist-info → ApiLogicServer-12.1.0.dist-info}/top_level.txt +0 -0
@@ -37,17 +37,19 @@ def declare_logic():
37
37
 
38
38
  from logic_bank.logic_bank import Rule
39
39
 
40
- # 1. Customer.Balance <= CreditLimit
41
- Rule.constraint(validate=Customer,
42
- error_msg="balance exceeds credit limit",
43
- as_condition=lambda row: row.Balance <= row.CreditLimit)
44
-
45
- # 2. Customer.Balance = Sum(Order.AmountTotal where date shipped is null)
46
- Rule.sum(derive=Customer.Balance, as_sum_of=Order.AmountTotal,
47
- where=lambda row: row.ShipDate is None)
40
+ from logic.logic_discovery.auto_discovery import discover_logic
41
+ discover_logic()
48
42
 
49
- # 3. Order.AmountTotal = Sum(Items.Amount)
43
+ # Logic from GenAI: (or, use your IDE w/ code completion)n
44
+ Rule.sum(derive=Customer.Balance, as_sum_of=Order.AmountTotal, where=lambda row: row.ShipDate is None)
50
45
  Rule.sum(derive=Order.AmountTotal, as_sum_of=Item.Amount)
46
+ # Rule.formula(derive=Item.amount, as_expression=lambda row: row.quantity * row.unit_price)
47
+ Rule.copy(derive=Item.UnitPrice, from_parent=Product.UnitPrice)
48
+ Rule.constraint(validate=Customer,
49
+ as_condition=lambda row: row.Balance <= row.CreditLimit,
50
+ error_msg="Customer balance ({row.balance}) exceeds credit limit ({row.credit_limit})")
51
+
52
+ # End Logic from GenAI
51
53
 
52
54
  def derive_amount(row: Item, old_row: Item, logic_row: LogicRow):
53
55
  amount = row.Quantity * row.UnitPrice
@@ -58,9 +60,6 @@ def declare_logic():
58
60
  # 4. Items.Amount = Quantity * UnitPrice
59
61
  Rule.formula(derive=Item.Amount, calling=derive_amount)
60
62
 
61
- # 5. Store the Items.UnitPrice as a copy from Product.UnitPrice
62
- Rule.copy(Item.UnitPrice, from_parent=Product.UnitPrice)
63
-
64
63
  #als: Demonstrate that logic == Rules + Python (for extensibility)
65
64
 
66
65
  def send_order_to_shipping(row: Order, old_row: Order, logic_row: LogicRow):
@@ -5,7 +5,7 @@
5
5
  "version": "0.2.0",
6
6
  "configurations": [
7
7
  {
8
- "name": "GENAI",
8
+ "name": " * GENAI",
9
9
  "type": "debugpy",
10
10
  "request": "launch",
11
11
  "program": "${workspaceFolder}/venv/lib/python3.12/site-packages/api_logic_server_cli/cli.py",
@@ -218,6 +218,83 @@
218
218
  "NODE_ENV": "development"
219
219
  }
220
220
  },
221
+ {
222
+ "name": "Internal - GenAI smoke test - genai_demo",
223
+ "type": "debugpy",
224
+ "request": "launch",
225
+ "program": "${workspaceFolder}/venv/lib/python3.12/site-packages/api_logic_server_cli/cli.py",
226
+ "redirectOutput": true,
227
+ "cwd": "${workspaceFolder}",
228
+ "env": {
229
+ "PYTHONPATH": "",
230
+ "SECURITY_ENABLED": "False",
231
+ "PYTHONHASHSEED": "0",
232
+ "APILOGICSERVER_DEBUG": "False",
233
+ "OPT_LOCKING": "optional"},
234
+ "justMyCode": false,
235
+ "args": [ "genai", "--retries=-1",
236
+ "--using=${workspaceFolder}/system/genai/examples/genai_demo/genai_demo.prompt"],
237
+ "console": "internalConsole",
238
+ "internalConsoleOptions": "openOnSessionStart"
239
+ },
240
+ {
241
+ "name": " - GenAI informal logic - genai_demo",
242
+ "type": "debugpy",
243
+ "request": "launch",
244
+ "program": "${workspaceFolder}/venv/lib/python3.12/site-packages/api_logic_server_cli/cli.py",
245
+ "redirectOutput": true,
246
+ "cwd": "${workspaceFolder}",
247
+ "env": {
248
+ "PYTHONPATH": "",
249
+ "SECURITY_ENABLED": "False",
250
+ "PYTHONHASHSEED": "0",
251
+ "APILOGICSERVER_DEBUG": "False",
252
+ "OPT_LOCKING": "optional"},
253
+ "justMyCode": false,
254
+ "args": [ "genai", "--retries=-1",
255
+ "--using=${workspaceFolder}/system/genai/examples/genai_demo/genai_demo_informal.prompt"],
256
+ "console": "internalConsole",
257
+ "internalConsoleOptions": "openOnSessionStart"
258
+ },
259
+ {
260
+ "name": " - GenAI informal logic - emp_depts",
261
+ "type": "debugpy",
262
+ "request": "launch",
263
+ "program": "${workspaceFolder}/venv/lib/python3.12/site-packages/api_logic_server_cli/cli.py",
264
+ "redirectOutput": true,
265
+ "cwd": "${workspaceFolder}",
266
+ "env": {
267
+ "PYTHONPATH": "",
268
+ "SECURITY_ENABLED": "False",
269
+ "PYTHONHASHSEED": "0",
270
+ "APILOGICSERVER_DEBUG": "False",
271
+ "OPT_LOCKING": "optional"},
272
+ "justMyCode": false,
273
+ "args": [ "genai", "--retries=-1",
274
+ "--using=${workspaceFolder}/system/genai/examples/emp_depts/emp_dept.prompt"],
275
+ "console": "internalConsole",
276
+ "internalConsoleOptions": "openOnSessionStart"
277
+ },
278
+ {
279
+ "name": " - retry repaired-response",
280
+ "type": "debugpy",
281
+ "request": "launch",
282
+ "program": "${workspaceFolder}/venv/lib/python3.12/site-packages/api_logic_server_cli/cli.py",
283
+ "redirectOutput": true,
284
+ "cwd": "${workspaceFolder}",
285
+ "env": {
286
+ "PYTHONPATH": "",
287
+ "SECURITY_ENABLED": "False",
288
+ "PYTHONHASHSEED": "0",
289
+ "APILOGICSERVER_DEBUG": "False",
290
+ "OPT_LOCKING": "optional"},
291
+ "justMyCode": false,
292
+ "args": [ "genai", "--retries=-1",
293
+ "--using=genai_demo",
294
+ "--repaired-response=system/genai/examples/genai_demo/genai_demo.response_example"],
295
+ "console": "internalConsole",
296
+ "internalConsoleOptions": "openOnSessionStart"
297
+ },
221
298
  {
222
299
  "name": "Python: Module",
223
300
  "type": "debugpy",
@@ -1,5 +1,5 @@
1
1
  ---
2
- version info: 0.7 (9/15/2024)
2
+ version info: 0.8 (10/24/2024)
3
3
  ---
4
4
  ## Welcome to API Logic Server
5
5
 
@@ -152,7 +152,7 @@ als genai --using=system/genai/examples/genai_demo/genai_demo.prompt
152
152
 
153
153
 
154
154
  ```bash
155
- als genai --using=genai_demo.prompt --repaired-response=system/genai/temp/chatgpt_retry.response
155
+ als genai --using=genai_demo.prompt --repaired-response=system/genai/examples/genai_demo/genai_demo_conversation/genai_demo_conversation_005.response-example
156
156
  ```
157
157
  </br>
158
158
 
@@ -197,6 +197,19 @@ als genai --project-name='genai_demo_conversation' --using=system/genai/examples
197
197
 
198
198
  <details markdown>
199
199
 
200
+ <summary> You can iterate with logic</summary>
201
+
202
+ <br>You can add new columns/tables, while keeping the prior model intact:
203
+
204
+ ```bash title="Iterate With Logic"
205
+ als genai --project-name='genai_demo_iterative_logic' --using=system/genai/examples/genai_demo/genai_demo_iterative_logic
206
+ # open Docs/db.dbml
207
+ ```
208
+ </details>
209
+ </br>
210
+
211
+ <details markdown>
212
+
200
213
  <summary> You can also execute directly, and iterate</summary>
201
214
 
202
215
  <br>You can add new columns/tables, while keeping the prior model intact:
@@ -225,7 +238,7 @@ als create --project-name=genai_demo --from-model=system/genai/temp/create_db_mo
225
238
  Or, correct the chatgpt response, and
226
239
 
227
240
  ```bash
228
- als genai --using=genai_demo.prompt --repaired-response=system/genai/temp/chatgpt_retry.response
241
+ als genai --using=genai_demo.prompt --repaired-response=system/genai/examples/genai_demo/genai_demo.response_example
229
242
  ```
230
243
 
231
244
  We have seen failures such as:
@@ -0,0 +1,10 @@
1
+
2
+
3
+ # ALS/GenAI: Create an SQLite database
4
+ engine = create_engine('sqlite:///system/genai/temp/create_db_models.sqlite')
5
+ Base.metadata.create_all(engine)
6
+
7
+ Session = sessionmaker(bind=engine)
8
+ session = Session()
9
+ # ALS/GenAI: Prepare for sample data
10
+
@@ -0,0 +1,19 @@
1
+ # created from response - used to create database and project
2
+ # should run without error
3
+ # if not, check for decimal, indent, or import issues
4
+
5
+ import decimal
6
+ import logging
7
+ import sqlalchemy
8
+ from sqlalchemy.sql import func # end imports from system/genai/create_db_models_inserts/create_db_models_prefix.py
9
+ from logic_bank.logic_bank import Rule
10
+ from sqlalchemy import create_engine, Column, Integer, String, Float, ForeignKey, Date, DateTime, Numeric, Boolean, Text
11
+ from sqlalchemy.ext.declarative import declarative_base
12
+ from sqlalchemy.orm import sessionmaker
13
+ from datetime import datetime
14
+ from sqlalchemy.orm import relationship
15
+ from datetime import date
16
+
17
+ logging.getLogger('sqlalchemy.engine.Engine').disabled = True # remove for additional logging
18
+
19
+ Base = declarative_base()
@@ -0,0 +1,7 @@
1
+ # Create an SQLite database
2
+ engine = create_engine('sqlite:///system/genai/temp/create_db_models.sqlite')
3
+ Base.metadata.create_all(engine)
4
+
5
+ Session = sessionmaker(bind=engine)
6
+ session = Session()
7
+
@@ -0,0 +1,4 @@
1
+ System for Departments and Employees.
2
+
3
+ LogicBank:
4
+ 1. Sum of employee salaries cannot exceed department budget
@@ -2,7 +2,7 @@ Create a system with customers, orders, items and products.
2
2
 
3
3
  Include a notes field for orders.
4
4
 
5
- Use LogicBank to create declare_logic() to enforce the Check Credit requirement (do not generate check constraints):
5
+ Use LogicBank to enforce the Check Credit requirement:
6
6
  1. Customer.balance <= credit_limit
7
7
  2. Customer.balance = Sum(Order.amount_total where date_shipped is null)
8
8
  3. Order.amount_total = Sum(Item.amount)
@@ -1,130 +1,56 @@
1
- To achieve the given requirements using SQLAlchemy, follow these steps to create a SQLAlchemy ORM model for a SQLite database, create the database, and insert some test data.
2
-
3
- ### 1. Setup and Import Libraries
4
-
5
- First install SQLAlchemy if you haven't already:
6
- ```bash
7
- pip install sqlalchemy
8
- ```
9
-
10
- Then, you can write the code:
11
-
12
- ```python
13
- from sqlalchemy import create_engine, Column, Integer, String, DateTime, ForeignKey, DECIMAL
14
- from sqlalchemy.ext.declarative import declarative_base
15
- from sqlalchemy.orm import sessionmaker, relationship
16
- import datetime
17
-
18
- # Create an instance of the declarative base class
19
- Base = declarative_base()
20
-
21
- # Define the Customer model
22
- class Customer(Base):
23
- """
24
- description: This table stores customer information, including a balance and credit limit.
25
- """
26
- __tablename__ = 'customers'
27
- id = Column(Integer, primary_key=True, autoincrement=True)
28
- name = Column(String, nullable=False)
29
- balance = Column(DECIMAL, nullable=False, default=0)
30
- credit_limit = Column(DECIMAL, nullable=False, default=0)
31
-
32
- # Define the Order model
33
- class Order(Base):
34
- """
35
- description: This table stores information about each order, including total amount and notes.
36
- """
37
- __tablename__ = 'orders'
38
- id = Column(Integer, primary_key=True, autoincrement=True)
39
- customer_id = Column(Integer, ForeignKey('customers.id'), nullable=False)
40
- date_placed = Column(DateTime, default=datetime.datetime.utcnow)
41
- date_shipped = Column(DateTime, nullable=True)
42
- amount_total = Column(DECIMAL, nullable=False)
43
- notes = Column(String, nullable=True)
44
-
45
- # Define the Product model
46
- class Product(Base):
47
- """
48
- description: This table stores product information, including unit prices.
49
- """
50
- __tablename__ = 'products'
51
- id = Column(Integer, primary_key=True, autoincrement=True)
52
- name = Column(String, nullable=False)
53
- unit_price = Column(DECIMAL, nullable=False)
54
-
55
- # Define the Item model
56
- class Item(Base):
57
- """
58
- description: This table stores each item in an order, including quantity, and unit price.
59
- """
60
- __tablename__ = 'items'
61
- id = Column(Integer, primary_key=True, autoincrement=True)
62
- order_id = Column(Integer, ForeignKey('orders.id'), nullable=False)
63
- product_id = Column(Integer, ForeignKey('products.id'), nullable=False)
64
- quantity = Column(Integer, nullable=False, default=1)
65
- unit_price = Column(DECIMAL, nullable=False)
66
- amount = Column(DECIMAL, nullable=False)
67
-
68
- # SQLite Database
69
- engine = create_engine('sqlite:///system/genai/temp/create_db_models.sqlite')
70
- Base.metadata.create_all(engine)
71
-
72
- Session = sessionmaker(bind=engine)
73
- session = Session()
74
-
75
- # Create some test data
76
- # Add test products
77
- product1 = Product(name='Product 1', unit_price=10.50)
78
- product2 = Product(name='Product 2', unit_price=15.75)
79
-
80
- # Add test customers
81
- customer1 = Customer(name='Customer 1', balance=0, credit_limit=500)
82
- customer2 = Customer(name='Customer 2', balance=0, credit_limit=1000)
83
-
84
- # Add test orders and items for customer1
85
- order1 = Order(customer_id=1, amount_total=0, notes='First Order')
86
- item1 = Item(order_id=1, product_id=1, quantity=2, unit_price=10.50, amount=21.00)
87
- item2 = Item(order_id=1, product_id=2, quantity=1, unit_price=15.75, amount=15.75)
88
-
89
- # Calculate order total
90
- order1.amount_total = item1.amount + item2.amount
91
-
92
- # Add order2
93
- order2 = Order(customer_id=1, amount_total=0, notes='Second Order')
94
- item3 = Item(order_id=2, product_id=1, quantity=1, unit_price=10.50, amount=10.50)
95
-
96
- # Calculate order2 total
97
- order2.amount_total = item3.amount
98
-
99
- # Set balance for customer1
100
- customer1.balance = order1.amount_total + order2.amount_total
101
-
102
- # Add test orders and items for customer2
103
- order3 = Order(customer_id=2, amount_total=0, notes='First Order for customer 2')
104
- item4 = Item(order_id=3, product_id=2, quantity=3, unit_price=15.75, amount=47.25)
105
-
106
- # Calculate order3 total
107
- order3.amount_total = item4.amount
108
-
109
- # Set balance for customer2
110
- customer2.balance = order3.amount_total
111
-
112
- # Add records to the session
113
- session.add_all([product1, product2, customer1, customer2, order1, item1, item2, order2, item3, order3, item4])
114
-
115
- # Commit the session
116
- session.commit()
117
-
118
- # Close the session
119
- session.close()
120
- ```
121
-
122
- ### Explanation:
123
-
124
- 1. **Database Models**: There are four main models: Customer, Order, Product, and Item. Each has its own table and columns defined.
125
-
126
- 2. **No Check Constraints**: Instead of using constraints for calculations, calculations are made in Python and are reflected in the ORM models (like order totals, item amounts, etc.).
127
-
128
- 3. **Adding Data**: Insert test data for products, customers, orders, and items. This includes calculating the amounts manually before adding them to ensure the database consistency requirements are met.
129
-
130
- Make sure to adapt the paths and environment as needed. This code should create the SQLite database, define the relationships, insert some records, and enforce the credit requirements logically within Python.
1
+ {
2
+ "models": [
3
+ {
4
+ "classname": "Customer",
5
+ "code": "from sqlalchemy import Column, Integer, String, Float\nfrom sqlalchemy.orm import declarative_base\n\nBase = declarative_base()\n\nclass Customer(Base):\n \"\"\"description: Stores customer details, such as balance and credit limit.\"\"\"\n __tablename__ = 'customer'\n \n id = Column(Integer, primary_key=True, autoincrement=True)\n name = Column(String, nullable=False)\n balance = Column(Float, default=0.0)\n credit_limit = Column(Float, nullable=False)",
6
+ "description": "Stores customer details, such as balance and credit limit.",
7
+ "name": "Customer"
8
+ },
9
+ {
10
+ "classname": "Order",
11
+ "code": "from sqlalchemy import Column, Integer, String, Float, DateTime, ForeignKey\nfrom sqlalchemy.orm import declarative_base\n\nBase = declarative_base()\n\nclass Order(Base):\n \"\"\"description: Represents a customer's order, with total amount and optional shipping date.\"\"\"\n __tablename__ = 'order'\n \n id = Column(Integer, primary_key=True, autoincrement=True)\n customer_id = Column(Integer, ForeignKey('customer.id'))\n amount_total = Column(Float, default=0.0)\n date_shipped = Column(DateTime, nullable=True)\n notes = Column(String, nullable=True)",
12
+ "description": "Represents a customer's order, with total amount and optional shipping date.",
13
+ "name": "Order"
14
+ },
15
+ {
16
+ "classname": "Item",
17
+ "code": "from sqlalchemy import Column, Integer, Float, ForeignKey\nfrom sqlalchemy.orm import declarative_base\n\nBase = declarative_base()\n\nclass Item(Base):\n \"\"\"description: Stores details about items within an order, including quantity and unit price.\"\"\"\n __tablename__ = 'item'\n \n id = Column(Integer, primary_key=True, autoincrement=True)\n order_id = Column(Integer, ForeignKey('order.id'))\n product_id = Column(Integer, ForeignKey('product.id'))\n amount = Column(Float, default=0.0)\n quantity = Column(Integer, nullable=False)\n unit_price = Column(Float, nullable=False)",
18
+ "description": "Stores details about items within an order, including quantity and unit price.",
19
+ "name": "Item"
20
+ },
21
+ {
22
+ "classname": "Product",
23
+ "code": "from sqlalchemy import Column, Integer, String, Float\nfrom sqlalchemy.orm import declarative_base\n\nBase = declarative_base()\n\nclass Product(Base):\n \"\"\"description: Catalog of products available for purchase.\"\"\"\n __tablename__ = 'product'\n \n id = Column(Integer, primary_key=True, autoincrement=True)\n name = Column(String, nullable=False)\n unit_price = Column(Float, nullable=False)",
24
+ "description": "Catalog of products available for purchase.",
25
+ "name": "Product"
26
+ }
27
+ ],
28
+ "rules": [
29
+ {
30
+ "name": "Customer Balance Constraint",
31
+ "description": "Ensures that a customer's balance does not exceed their credit limit.",
32
+ "code": "Rule.constraint(validate=Customer,\n as_condition=lambda row: row.balance <= row.credit_limit,\n error_msg=\"Customer balance ({row.balance}) exceeds credit limit ({row.credit_limit})\")"
33
+ },
34
+ {
35
+ "name": "Customer Balance Calculation",
36
+ "description": "Calculates the customer's balance as the sum of their orders' total amounts where orders have not been shipped.",
37
+ "code": "Rule.sum(derive=Customer.balance, as_sum_of=Order.amount_total, where=lambda row: row.date_shipped is None)"
38
+ },
39
+ {
40
+ "name": "Order Amount Total Calculation",
41
+ "description": "Calculates the order's amount total as the sum of all item amounts in the order.",
42
+ "code": "Rule.sum(derive=Order.amount_total, as_sum_of=Item.amount)"
43
+ },
44
+ {
45
+ "name": "Item Amount Calculation",
46
+ "description": "Calculates the item amount as the product of quantity and unit price.",
47
+ "code": "Rule.formula(derive=Item.amount, as_expression=lambda row: row.quantity * row.unit_price)"
48
+ },
49
+ {
50
+ "name": "Item Unit Price Copy",
51
+ "description": "Copies the unit price from the product to the item.",
52
+ "code": "Rule.copy(derive=Item.unit_price, from_parent=Product.unit_price)"
53
+ }
54
+ ],
55
+ "test_data": "## Test Data\n\n# Products\nproduct1 = Product(id=1, name='Product 1', unit_price=10.0)\nproduct2 = Product(id=2, name='Product 2', unit_price=15.0)\n\n# Customers\ncustomer1 = Customer(id=1, name='Alice', balance=0.0, credit_limit=100.0)\ncustomer2 = Customer(id=2, name='Bob', balance=0.0, credit_limit=150.0)\n\n# Orders\norder1 = Order(id=1, customer_id=1, amount_total=0.0, notes='Order 1 for Alice')\norder2 = Order(id=2, customer_id=2, amount_total=0.0, notes='Order 2 for Bob')\norder3 = Order(id=3, customer_id=1, amount_total=0.0, notes='Another order for Alice', date_shipped=None)\n\n# Items\nitem1 = Item(id=1, order_id=1, product_id=1, quantity=2, unit_price=10.0, amount=20.0)\nitem2 = Item(id=2, order_id=1, product_id=2, quantity=1, unit_price=15.0, amount=15.0)\nitem3 = Item(id=3, order_id=2, product_id=2, quantity=3, unit_price=15.0, amount=45.0)\nitem4 = Item(id=4, order_id=3, product_id=1, quantity=5, unit_price=10.0, amount=50.0)\n\n# Since the logic is not enforced via LogicBank for this demo, we manually calculate derived values:\n# Order 1 Total for Alice: 20.0 + 15.0 = 35.0\norder1.amount_total = item1.amount + item2.amount\n# Order 2 Total for Bob: 45.0\norder2.amount_total = item3.amount\n# Order 3 Total for Alice, not shipped yet: 50.0\norder3.amount_total = item4.amount\n# Customer Balance for Alice: 35.0 (order 1) + 50.0 (order 3, not shipped)\ncustomer1.balance = order1.amount_total + order3.amount_total\n# Customer Balance for Bob: 45.0\ncustomer2.balance = order2.amount_total"
56
+ }
@@ -0,0 +1,130 @@
1
+ To achieve the given requirements using SQLAlchemy, follow these steps to create a SQLAlchemy ORM model for a SQLite database, create the database, and insert some test data.
2
+
3
+ ### 1. Setup and Import Libraries
4
+
5
+ First install SQLAlchemy if you haven't already:
6
+ ```bash
7
+ pip install sqlalchemy
8
+ ```
9
+
10
+ Then, you can write the code:
11
+
12
+ ```python
13
+ from sqlalchemy import create_engine, Column, Integer, String, DateTime, ForeignKey, DECIMAL
14
+ from sqlalchemy.ext.declarative import declarative_base
15
+ from sqlalchemy.orm import sessionmaker, relationship
16
+ import datetime
17
+
18
+ # Create an instance of the declarative base class
19
+ Base = declarative_base()
20
+
21
+ # Define the Customer model
22
+ class Customer(Base):
23
+ """
24
+ description: This table stores customer information, including a balance and credit limit.
25
+ """
26
+ __tablename__ = 'customers'
27
+ id = Column(Integer, primary_key=True, autoincrement=True)
28
+ name = Column(String, nullable=False)
29
+ balance = Column(DECIMAL, nullable=False, default=0)
30
+ credit_limit = Column(DECIMAL, nullable=False, default=0)
31
+
32
+ # Define the Order model
33
+ class Order(Base):
34
+ """
35
+ description: This table stores information about each order, including total amount and notes.
36
+ """
37
+ __tablename__ = 'orders'
38
+ id = Column(Integer, primary_key=True, autoincrement=True)
39
+ customer_id = Column(Integer, ForeignKey('customers.id'), nullable=False)
40
+ date_placed = Column(DateTime, default=datetime.datetime.utcnow)
41
+ date_shipped = Column(DateTime, nullable=True)
42
+ amount_total = Column(DECIMAL, nullable=False)
43
+ notes = Column(String, nullable=True)
44
+
45
+ # Define the Product model
46
+ class Product(Base):
47
+ """
48
+ description: This table stores product information, including unit prices.
49
+ """
50
+ __tablename__ = 'products'
51
+ id = Column(Integer, primary_key=True, autoincrement=True)
52
+ name = Column(String, nullable=False)
53
+ unit_price = Column(DECIMAL, nullable=False)
54
+
55
+ # Define the Item model
56
+ class Item(Base):
57
+ """
58
+ description: This table stores each item in an order, including quantity, and unit price.
59
+ """
60
+ __tablename__ = 'items'
61
+ id = Column(Integer, primary_key=True, autoincrement=True)
62
+ order_id = Column(Integer, ForeignKey('orders.id'), nullable=False)
63
+ product_id = Column(Integer, ForeignKey('products.id'), nullable=False)
64
+ quantity = Column(Integer, nullable=False, default=1)
65
+ unit_price = Column(DECIMAL, nullable=False)
66
+ amount = Column(DECIMAL, nullable=False)
67
+
68
+ # SQLite Database
69
+ engine = create_engine('sqlite:///system/genai/temp/create_db_models.sqlite')
70
+ Base.metadata.create_all(engine)
71
+
72
+ Session = sessionmaker(bind=engine)
73
+ session = Session()
74
+
75
+ # Create some test data
76
+ # Add test products
77
+ product1 = Product(name='Product 1', unit_price=10.50)
78
+ product2 = Product(name='Product 2', unit_price=15.75)
79
+
80
+ # Add test customers
81
+ customer1 = Customer(name='Customer 1', balance=0, credit_limit=500)
82
+ customer2 = Customer(name='Customer 2', balance=0, credit_limit=1000)
83
+
84
+ # Add test orders and items for customer1
85
+ order1 = Order(customer_id=1, amount_total=0, notes='First Order')
86
+ item1 = Item(order_id=1, product_id=1, quantity=2, unit_price=10.50, amount=21.00)
87
+ item2 = Item(order_id=1, product_id=2, quantity=1, unit_price=15.75, amount=15.75)
88
+
89
+ # Calculate order total
90
+ order1.amount_total = item1.amount + item2.amount
91
+
92
+ # Add order2
93
+ order2 = Order(customer_id=1, amount_total=0, notes='Second Order')
94
+ item3 = Item(order_id=2, product_id=1, quantity=1, unit_price=10.50, amount=10.50)
95
+
96
+ # Calculate order2 total
97
+ order2.amount_total = item3.amount
98
+
99
+ # Set balance for customer1
100
+ customer1.balance = order1.amount_total + order2.amount_total
101
+
102
+ # Add test orders and items for customer2
103
+ order3 = Order(customer_id=2, amount_total=0, notes='First Order for customer 2')
104
+ item4 = Item(order_id=3, product_id=2, quantity=3, unit_price=15.75, amount=47.25)
105
+
106
+ # Calculate order3 total
107
+ order3.amount_total = item4.amount
108
+
109
+ # Set balance for customer2
110
+ customer2.balance = order3.amount_total
111
+
112
+ # Add records to the session
113
+ session.add_all([product1, product2, customer1, customer2, order1, item1, item2, order2, item3, order3, item4])
114
+
115
+ # Commit the session
116
+ session.commit()
117
+
118
+ # Close the session
119
+ session.close()
120
+ ```
121
+
122
+ ### Explanation:
123
+
124
+ 1. **Database Models**: There are four main models: Customer, Order, Product, and Item. Each has its own table and columns defined.
125
+
126
+ 2. **No Check Constraints**: Instead of using constraints for calculations, calculations are made in Python and are reflected in the ORM models (like order totals, item amounts, etc.).
127
+
128
+ 3. **Adding Data**: Insert test data for products, customers, orders, and items. This includes calculating the amounts manually before adding them to ensure the database consistency requirements are met.
129
+
130
+ Make sure to adapt the paths and environment as needed. This code should create the SQLite database, define the relationships, insert some records, and enforce the credit requirements logically within Python.
@@ -0,0 +1,10 @@
1
+ Create a system with customers, orders, items and products.
2
+
3
+ Include a notes field for orders.
4
+
5
+ Use LogicBank to enforce the Check Credit requirement:
6
+ 1. The Customer's balance is less than the credit limit
7
+ 2. The Customer's balance is the sum of the Order amount_total where date_shipped is null
8
+ 3. The Order's amount_total is the sum of the Item amount
9
+ 4. The Item amount is the quantity * unit_price
10
+ 5. The Item unit_price is copied from the Product unit_price
@@ -0,0 +1 @@
1
+ You are a data modelling expert and python software architect who expands on user input ideas. You create data models with at least 4 tables