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.
- {ApiLogicServer-12.0.4.dist-info → ApiLogicServer-12.1.0.dist-info}/METADATA +2 -1
- {ApiLogicServer-12.0.4.dist-info → ApiLogicServer-12.1.0.dist-info}/RECORD +39 -24
- {ApiLogicServer-12.0.4.dist-info → ApiLogicServer-12.1.0.dist-info}/WHEEL +1 -1
- api_logic_server_cli/api_logic_server.py +8 -201
- api_logic_server_cli/api_logic_server_info.yaml +3 -3
- api_logic_server_cli/cli.py +9 -79
- api_logic_server_cli/create_from_model/__pycache__/dbml.cpython-312.pyc +0 -0
- api_logic_server_cli/create_from_model/__pycache__/meta_model.cpython-312.pyc +0 -0
- api_logic_server_cli/create_from_model/__pycache__/model_creation_services.cpython-312.pyc +0 -0
- api_logic_server_cli/create_from_model/meta_model.py +1 -1
- api_logic_server_cli/create_from_model/model_creation_services.py +3 -1
- api_logic_server_cli/genai.py +273 -151
- api_logic_server_cli/genaiZ.py +752 -0
- api_logic_server_cli/prototypes/genai_demo/logic/declare_logic.py +11 -12
- api_logic_server_cli/prototypes/manager/.vscode/launch.json +78 -1
- api_logic_server_cli/prototypes/manager/README.md +16 -3
- api_logic_server_cli/prototypes/manager/system/genai/create_db_models_inserts/create_db_models_create_db.py +10 -0
- api_logic_server_cli/prototypes/manager/system/genai/create_db_models_inserts/create_db_models_imports.py +19 -0
- api_logic_server_cli/prototypes/manager/system/genai/create_db_models_inserts/create_db_models_test_data.py +7 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/emp_depts/emp_dept.prompt +4 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo.prompt +1 -1
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo.response_example +56 -130
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo.response_example_z +130 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_informal.prompt +10 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_iterative_logic/genai_demo_iterative_logic_000.response +1 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_iterative_logic/genai_demo_iterative_logic_001.prompt +171 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_iterative_logic/genai_demo_iterative_logic_002.prompt +21 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_iterative_logic/genai_demo_iterative_logic_003.response +94 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_iterative_logic/genai_demo_iterative_logic_004.prompt +6 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_iterative_logic/genai_demo_iterative_logic_005.response_example +122 -0
- api_logic_server_cli/prototypes/manager/system/genai/learning_requests/logic_bank_api.prompt +42 -5
- api_logic_server_cli/prototypes/manager/system/genai/prompt_inserts/logic_inserts.prompt +1 -0
- api_logic_server_cli/prototypes/manager/system/genai/prompt_inserts/response_format.prompt +6 -0
- api_logic_server_cli/prototypes/manager/system/genai/prompt_inserts/sqlite_inserts.prompt +11 -2
- api_logic_server_cli/prototypes/manager/system/genai/prompt_inserts/sqlite_inserts_iterations.prompt +25 -0
- api_logic_server_cli/prototypes/manager/system/genai/prompt_inserts/web_genai copy.prompt +15 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/emp_depts/emp_dept_explicit.prompt +0 -7
- api_logic_server_cli/prototypes/manager/system/genai/examples/emp_depts/emp_dept_implicit_fails.prompt +0 -5
- {ApiLogicServer-12.0.4.dist-info → ApiLogicServer-12.1.0.dist-info}/LICENSE +0 -0
- {ApiLogicServer-12.0.4.dist-info → ApiLogicServer-12.1.0.dist-info}/entry_points.txt +0 -0
- {ApiLogicServer-12.0.4.dist-info → ApiLogicServer-12.1.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
Here is the simplified API for LogicBank:
|
|
2
|
+
|
|
3
|
+
Create a function called declare_logic(), consisting of calls to Rule methods.
|
|
4
|
+
|
|
5
|
+
Do not generate import statements.
|
|
6
|
+
|
|
7
|
+
Use only the methods provided below.
|
|
8
|
+
|
|
9
|
+
class Rule:
|
|
10
|
+
"""Invoke these functions to declare rules in the created declare_logic function. """
|
|
11
|
+
|
|
12
|
+
@staticmethod
|
|
13
|
+
def sum(derive: Column, as_sum_of: any, where: any = None, child_role_name: str = "", insert_parent: bool=False):
|
|
14
|
+
"""
|
|
15
|
+
Derive parent column as sum of designated child column, optional where
|
|
16
|
+
|
|
17
|
+
Example
|
|
18
|
+
Prompt
|
|
19
|
+
Customer.Balance = Sum(Order.amount_total where date_shipped is null)
|
|
20
|
+
Response
|
|
21
|
+
Rule.sum(derive=Customer.Balance, as_sum_of=Order.AmountTotal,
|
|
22
|
+
where=lambda row: row.ShippedDate is None)
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
derive: name of parent <class.attribute> being derived
|
|
26
|
+
as_sum_of: name of child <class.attribute> being summed
|
|
27
|
+
child_role_name: parent's child accessor attribute (required only for disambiguation)
|
|
28
|
+
where: optional where clause, designates which child rows are summed
|
|
29
|
+
|
|
30
|
+
"""
|
|
31
|
+
return Sum(derive, as_sum_of, where, child_role_name, insert_parent)
|
|
32
|
+
|
|
33
|
+
@staticmethod
|
|
34
|
+
def count(derive: Column, as_count_of: object, where: any = None, child_role_name: str = "", insert_parent: bool=False):
|
|
35
|
+
"""
|
|
36
|
+
Derive parent column as count of designated child rows
|
|
37
|
+
|
|
38
|
+
Example
|
|
39
|
+
Prompt
|
|
40
|
+
Customer.UnPaidOrders = count(Orders where ShippedDate is None)
|
|
41
|
+
Response
|
|
42
|
+
Rule.count(derive=Customer.UnPaidOrders, as_count_of=Order,
|
|
43
|
+
where=Lambda row: row.ShippedDate is None)
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
derive: name of parent <class.attribute> being derived
|
|
47
|
+
as_count_of: name of child <class> being counted
|
|
48
|
+
child_role_name: parent's child accessor attribute (required only for disambiguation)
|
|
49
|
+
where: optional where clause, designates which child rows are counted
|
|
50
|
+
"""
|
|
51
|
+
return Count(derive, as_count_of, where, child_role_name, insert_parent)
|
|
52
|
+
|
|
53
|
+
@staticmethod
|
|
54
|
+
def constraint(validate: object,
|
|
55
|
+
calling: Callable = None,
|
|
56
|
+
as_condition: any = None,
|
|
57
|
+
error_msg: str = "(error_msg not provided)",
|
|
58
|
+
error_attributes=None):
|
|
59
|
+
"""
|
|
60
|
+
Constraints declare condition that must be true for all commits
|
|
61
|
+
|
|
62
|
+
Example
|
|
63
|
+
Prompt
|
|
64
|
+
Customer.balance <= credit_limit
|
|
65
|
+
Response
|
|
66
|
+
Rule.constraint(validate=Customer,
|
|
67
|
+
as_condition=lambda row: row.Balance <= row.CreditLimit,
|
|
68
|
+
error_msg="balance ({row.Balance}) exceeds credit ({row.CreditLimit})")
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
validate: name of mapped <class>
|
|
72
|
+
as_condition: lambda, passed row (simple constraints)
|
|
73
|
+
error_msg: string, with {row.attribute} replacements
|
|
74
|
+
error_attributes: list of attributes
|
|
75
|
+
|
|
76
|
+
"""
|
|
77
|
+
if error_attributes is None:
|
|
78
|
+
error_attributes = []
|
|
79
|
+
return Constraint(validate=validate, as_condition=as_condition,
|
|
80
|
+
error_attributes=error_attributes, error_msg=error_msg)
|
|
81
|
+
|
|
82
|
+
@staticmethod
|
|
83
|
+
def parent_check(validate: object,
|
|
84
|
+
error_msg: str = "(error_msg not provided)",
|
|
85
|
+
enable: bool = True):
|
|
86
|
+
"""
|
|
87
|
+
Parent Checks ensure that non-null foreign keys are present in parent class
|
|
88
|
+
|
|
89
|
+
Example
|
|
90
|
+
Rule.parent_check(validate=Customer, enable=True, error_msg="Missing Parent")
|
|
91
|
+
|
|
92
|
+
Parent_check failures raise ConstraintException, e.g.:
|
|
93
|
+
try:
|
|
94
|
+
session.commit()
|
|
95
|
+
except ConstraintException as ce:
|
|
96
|
+
print("Constraint raised: " + str(ce))
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
validate: name of mapped class
|
|
100
|
+
error_msg: message included in exception (can have {} syntax)
|
|
101
|
+
enable: True (default) = enable, False means disable (tolerate orphans)
|
|
102
|
+
|
|
103
|
+
Note: False not recommended - for existing databases with bad data
|
|
104
|
+
Behavior is undefined for other rules (sum, count, parent references, etc)
|
|
105
|
+
|
|
106
|
+
"""
|
|
107
|
+
return ParentCheck(validate=validate, error_msg=error_msg, enable=enable)
|
|
108
|
+
|
|
109
|
+
@staticmethod
|
|
110
|
+
def formula(derive: Column,
|
|
111
|
+
as_expression: Callable = None,
|
|
112
|
+
no_prune: bool = False):
|
|
113
|
+
"""
|
|
114
|
+
Formulas declare column value, based on current and parent rows
|
|
115
|
+
|
|
116
|
+
Example
|
|
117
|
+
Prompt
|
|
118
|
+
Item.amount = quantity * unit_price
|
|
119
|
+
Response
|
|
120
|
+
Rule.formula(derive=OrderDetail.Amount,
|
|
121
|
+
as_expression=lambda row: row.UnitPrice * row.Quantity)
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
derive: <class.attribute> being derived
|
|
125
|
+
as_expression: lambda, passed row (for syntax checking)
|
|
126
|
+
no_prune: disable pruning (rarely used, default False)
|
|
127
|
+
"""
|
|
128
|
+
return Formula(derive=derive,
|
|
129
|
+
as_expression=as_expression,
|
|
130
|
+
no_prune=no_prune)
|
|
131
|
+
|
|
132
|
+
@staticmethod
|
|
133
|
+
def copy(derive: Column, from_parent: any):
|
|
134
|
+
"""
|
|
135
|
+
Copy declares child column copied from parent column
|
|
136
|
+
|
|
137
|
+
Example
|
|
138
|
+
Prompt
|
|
139
|
+
Store the Item.unit_price as a copy from Product.unit_price
|
|
140
|
+
Response
|
|
141
|
+
Rule.copy(derive=OrderDetail.UnitPrice, from_parent=Product.UnitPrice)
|
|
142
|
+
|
|
143
|
+
Args:
|
|
144
|
+
derive: <class.attribute> being copied into
|
|
145
|
+
from_parent: <parent-class.attribute> source of copy
|
|
146
|
+
"""
|
|
147
|
+
return Copy(derive=derive, from_parent=from_parent)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
Expanded example:
|
|
151
|
+
|
|
152
|
+
Prompt:
|
|
153
|
+
|
|
154
|
+
Use Logic Bank to enforce the Check Credit requirement (do not generate check constraints):
|
|
155
|
+
1. Customer.balance <= credit_limit
|
|
156
|
+
2. Customer.balance = Sum(Order.amount_total where date_shipped is null)
|
|
157
|
+
3. Order.amount_total = Sum(Item.amount)
|
|
158
|
+
4. Item.amount = quantity * unit_price
|
|
159
|
+
5. Store the Item.unit_price as a copy from Product.unit_price
|
|
160
|
+
|
|
161
|
+
Response:
|
|
162
|
+
|
|
163
|
+
def declare_logic(): # created by Web/GenAI for ApiLogicServer, LogicBank
|
|
164
|
+
|
|
165
|
+
Rule.sum(derive=CustomerAccount.balance, as_sum_of=Order.amount_total, where=lambda row: row.date_shipped is None)
|
|
166
|
+
Rule.sum(derive=Order.amount_total, as_sum_of=Item.amount)
|
|
167
|
+
Rule.formula(derive=Item.amount, as_expression=lambda row: row.quantity * row.unit_price)
|
|
168
|
+
Rule.copy(derive=Item.unit_price, from_parent=Product.unit_price)
|
|
169
|
+
Rule.constraint(validate=CustomerAccount,
|
|
170
|
+
as_condition=lambda row: row.balance <= row.credit_limit,
|
|
171
|
+
error_msg="Customer balance ({row.balance}) exceeds credit limit ({row.credit_limit})")
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Use SQLAlchemy to create a sqlite database named system/genai/temp/create_db_models.sqlite, to
|
|
2
|
+
|
|
3
|
+
Create a system with customers, orders, items and products.
|
|
4
|
+
|
|
5
|
+
Do not generate any logic, including logic bank.
|
|
6
|
+
|
|
7
|
+
Do not generate derived attributes such as Customer.balance, Customer.credit_limit, Order.amount_total, Item.unit_price, or Item.amount.
|
|
8
|
+
|
|
9
|
+
Include a notes field for orders.
|
|
10
|
+
|
|
11
|
+
Hints: use autonum keys (for all tables - including for link/join/junction/intersection tables), allow nulls, foreign keys, no check constraints.
|
|
12
|
+
|
|
13
|
+
Remember that SQLite DateTime type only accepts Python datetime and date objects as input,
|
|
14
|
+
this means you can not enter string attributes where a date or datetime object is expected.
|
|
15
|
+
|
|
16
|
+
Don't install additional packages.
|
|
17
|
+
Don't use the faker pip package.
|
|
18
|
+
|
|
19
|
+
Create some test data, use foreign key columns instead of relationship names for the data. Do not print the test data. Be sure to initialize derived attributes, but do not rely on Logic Bank.
|
|
20
|
+
|
|
21
|
+
For each data model class, create a docstring describing the table, prefixed with 'description: '.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
Certainly! Here's how you might create a system with `customers`, `orders`, `items`, and `products` using SQLAlchemy. After defining the data model, I will generate test data and then proceed to use LogicBank for business rules in the `declare_logic()` function.
|
|
2
|
+
|
|
3
|
+
```python
|
|
4
|
+
from sqlalchemy import create_engine, Column, Integer, String, Float, ForeignKey, Date, DateTime
|
|
5
|
+
from sqlalchemy.ext.declarative import declarative_base
|
|
6
|
+
from sqlalchemy.orm import sessionmaker, relationship
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
|
|
9
|
+
Base = declarative_base()
|
|
10
|
+
|
|
11
|
+
class Customer(Base):
|
|
12
|
+
"""
|
|
13
|
+
description: Table for storing customer information.
|
|
14
|
+
"""
|
|
15
|
+
__tablename__ = 'customers'
|
|
16
|
+
|
|
17
|
+
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
18
|
+
name = Column(String, nullable=True)
|
|
19
|
+
credit_limit = Column(Float, nullable=True)
|
|
20
|
+
|
|
21
|
+
class Order(Base):
|
|
22
|
+
"""
|
|
23
|
+
description: Table for orders linked to customers.
|
|
24
|
+
"""
|
|
25
|
+
__tablename__ = 'orders'
|
|
26
|
+
|
|
27
|
+
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
28
|
+
customer_id = Column(Integer, ForeignKey('customers.id'), nullable=True)
|
|
29
|
+
date_shipped = Column(Date, nullable=True)
|
|
30
|
+
notes = Column(String, nullable=True)
|
|
31
|
+
# Placeholder for derived attribute (commented out but indicated)
|
|
32
|
+
# amount_total = Column(Float, default=0.0)
|
|
33
|
+
|
|
34
|
+
class Product(Base):
|
|
35
|
+
"""
|
|
36
|
+
description: Table for products.
|
|
37
|
+
"""
|
|
38
|
+
__tablename__ = 'products'
|
|
39
|
+
|
|
40
|
+
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
41
|
+
name = Column(String, nullable=True)
|
|
42
|
+
unit_price = Column(Float, nullable=True)
|
|
43
|
+
|
|
44
|
+
class Item(Base):
|
|
45
|
+
"""
|
|
46
|
+
description: Table for items linked to orders and products.
|
|
47
|
+
"""
|
|
48
|
+
__tablename__ = 'items'
|
|
49
|
+
|
|
50
|
+
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
51
|
+
order_id = Column(Integer, ForeignKey('orders.id'), nullable=True)
|
|
52
|
+
product_id = Column(Integer, ForeignKey('products.id'), nullable=True)
|
|
53
|
+
quantity = Column(Integer, nullable=True)
|
|
54
|
+
# Placeholder for derived attributes (commented out but indicated)
|
|
55
|
+
# unit_price = Column(Float, nullable=True)
|
|
56
|
+
# amount = Column(Float, default=0.0)
|
|
57
|
+
|
|
58
|
+
# Create an SQLite database
|
|
59
|
+
engine = create_engine('sqlite:///system/genai/temp/create_db_models.sqlite')
|
|
60
|
+
Base.metadata.create_all(engine)
|
|
61
|
+
|
|
62
|
+
Session = sessionmaker(bind=engine)
|
|
63
|
+
session = Session()
|
|
64
|
+
|
|
65
|
+
# Creating test data for tables
|
|
66
|
+
customer1 = Customer(name="John Doe", credit_limit=5000.0)
|
|
67
|
+
customer2 = Customer(name="Jane Smith", credit_limit=10000.0)
|
|
68
|
+
session.add_all([customer1, customer2])
|
|
69
|
+
session.commit()
|
|
70
|
+
|
|
71
|
+
order1 = Order(customer_id=customer1.id, date_shipped=None, notes="Express delivery")
|
|
72
|
+
order2 = Order(customer_id=customer2.id, date_shipped=datetime.now().date(), notes="Standard delivery")
|
|
73
|
+
session.add_all([order1, order2])
|
|
74
|
+
session.commit()
|
|
75
|
+
|
|
76
|
+
product1 = Product(name="Laptop", unit_price=1000.0)
|
|
77
|
+
product2 = Product(name="Smartphone", unit_price=500.0)
|
|
78
|
+
session.add_all([product1, product2])
|
|
79
|
+
session.commit()
|
|
80
|
+
|
|
81
|
+
item1 = Item(order_id=order1.id, product_id=product1.id, quantity=2)
|
|
82
|
+
item2 = Item(order_id=order1.id, product_id=product2.id, quantity=3)
|
|
83
|
+
item3 = Item(order_id=order2.id, product_id=product2.id, quantity=1)
|
|
84
|
+
session.add_all([item1, item2, item3])
|
|
85
|
+
session.commit()
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Expanded Explanation of Data Model and Logic
|
|
90
|
+
- **`Customer` Table**: Stores basic customer information including `name` and `credit_limit`.
|
|
91
|
+
- **`Order` Table**: Links orders to customers, and contains fields for shipment date (`date_shipped`) and additional comments or `notes`.
|
|
92
|
+
- **`Product` Table**: Contains product information like `name` and `unit_price`.
|
|
93
|
+
- **`Item` Table**: Represents purchased items within a particular order, tracking `quantity` and relating to `Product` and `Order`.
|
|
94
|
+
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
Use LogicBank to enforce the Check Credit requirement:
|
|
2
|
+
1. Customer.balance <= credit_limit
|
|
3
|
+
2. Customer.balance = Sum(Order.amount_total where date_shipped is null)
|
|
4
|
+
3. Order.amount_total = Sum(Item.amount)
|
|
5
|
+
4. Item.amount = quantity * unit_price
|
|
6
|
+
5. Store the Item.unit_price as a copy from Product.unit_price
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
Certainly! Let's incorporate the business logic using LogicBank, ensuring we add any necessary derived attributes to our model and adjust the test data accordingly. We'll also include the function `declare_logic` which utilizes LogicBank rules.
|
|
2
|
+
|
|
3
|
+
```python
|
|
4
|
+
from sqlalchemy import create_engine, Column, Integer, String, Float, ForeignKey, Date
|
|
5
|
+
from sqlalchemy.ext.declarative import declarative_base
|
|
6
|
+
from sqlalchemy.orm import sessionmaker
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
|
|
9
|
+
Base = declarative_base()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Customer(Base):
|
|
13
|
+
"""
|
|
14
|
+
description: Table for storing customer information.
|
|
15
|
+
"""
|
|
16
|
+
__tablename__ = 'customers'
|
|
17
|
+
|
|
18
|
+
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
19
|
+
name = Column(String, nullable=True)
|
|
20
|
+
credit_limit = Column(Float, nullable=True)
|
|
21
|
+
balance = Column(Float, default=0.0) # Added for logic rule
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class Order(Base):
|
|
25
|
+
"""
|
|
26
|
+
description: Table for orders linked to customers.
|
|
27
|
+
"""
|
|
28
|
+
__tablename__ = 'orders'
|
|
29
|
+
|
|
30
|
+
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
31
|
+
customer_id = Column(Integer, ForeignKey('customers.id'), nullable=True)
|
|
32
|
+
date_shipped = Column(Date, nullable=True)
|
|
33
|
+
notes = Column(String, nullable=True)
|
|
34
|
+
amount_total = Column(Float, default=0.0) # Added for logic rule
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class Product(Base):
|
|
38
|
+
"""
|
|
39
|
+
description: Table for products.
|
|
40
|
+
"""
|
|
41
|
+
__tablename__ = 'products'
|
|
42
|
+
|
|
43
|
+
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
44
|
+
name = Column(String, nullable=True)
|
|
45
|
+
unit_price = Column(Float, nullable=True)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class Item(Base):
|
|
49
|
+
"""
|
|
50
|
+
description: Table for items linked to orders and products.
|
|
51
|
+
"""
|
|
52
|
+
__tablename__ = 'items'
|
|
53
|
+
|
|
54
|
+
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
55
|
+
order_id = Column(Integer, ForeignKey('orders.id'), nullable=True)
|
|
56
|
+
product_id = Column(Integer, ForeignKey('products.id'), nullable=True)
|
|
57
|
+
quantity = Column(Integer, nullable=True)
|
|
58
|
+
unit_price = Column(Float, nullable=True) # Added for logic rule
|
|
59
|
+
amount = Column(Float, default=0.0) # Added for logic rule
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
# Create an SQLite database
|
|
63
|
+
engine = create_engine('sqlite:///system/genai/temp/create_db_models.sqlite')
|
|
64
|
+
Base.metadata.create_all(engine)
|
|
65
|
+
|
|
66
|
+
Session = sessionmaker(bind=engine)
|
|
67
|
+
session = Session()
|
|
68
|
+
|
|
69
|
+
# Creating test data for tables
|
|
70
|
+
customer1 = Customer(name="John Doe", credit_limit=5000.0, balance=0.0)
|
|
71
|
+
customer2 = Customer(name="Jane Smith", credit_limit=10000.0, balance=0.0)
|
|
72
|
+
session.add_all([customer1, customer2])
|
|
73
|
+
session.commit()
|
|
74
|
+
|
|
75
|
+
order1 = Order(customer_id=customer1.id, date_shipped=None, notes="Express delivery", amount_total=0.0)
|
|
76
|
+
order2 = Order(customer_id=customer2.id, date_shipped=datetime.now().date(), notes="Standard delivery", amount_total=0.0)
|
|
77
|
+
session.add_all([order1, order2])
|
|
78
|
+
session.commit()
|
|
79
|
+
|
|
80
|
+
product1 = Product(name="Laptop", unit_price=1000.0)
|
|
81
|
+
product2 = Product(name="Smartphone", unit_price=500.0)
|
|
82
|
+
session.add_all([product1, product2])
|
|
83
|
+
session.commit()
|
|
84
|
+
|
|
85
|
+
item1 = Item(order_id=order1.id, product_id=product1.id, quantity=2, unit_price=1000.0, amount=2000.0)
|
|
86
|
+
item2 = Item(order_id=order1.id, product_id=product2.id, quantity=3, unit_price=500.0, amount=1500.0)
|
|
87
|
+
item3 = Item(order_id=order2.id, product_id=product2.id, quantity=1, unit_price=500.0, amount=500.0)
|
|
88
|
+
session.add_all([item1, item2, item3])
|
|
89
|
+
session.commit()
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def declare_logic():
|
|
93
|
+
Rule.sum(derive=Customer.balance, as_sum_of=Order.amount_total, where=lambda row: row.date_shipped is None)
|
|
94
|
+
Rule.sum(derive=Order.amount_total, as_sum_of=Item.amount)
|
|
95
|
+
Rule.formula(derive=Item.amount, as_expression=lambda row: row.quantity * row.unit_price)
|
|
96
|
+
Rule.copy(derive=Item.unit_price, from_parent=Product.unit_price)
|
|
97
|
+
Rule.constraint(validate=Customer,
|
|
98
|
+
as_condition=lambda row: row.balance <= row.credit_limit,
|
|
99
|
+
error_msg="Customer balance ({row.balance}) exceeds credit limit ({row.credit_limit})")
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Explanation of Changes and Additions:
|
|
104
|
+
|
|
105
|
+
- **Data Model Updates**:
|
|
106
|
+
- Added `balance` to `Customer` to support business rules.
|
|
107
|
+
- Added `amount_total` to `Order` for summation logic.
|
|
108
|
+
- Added `unit_price` and `amount` to `Item` for business logic involving calculations and copying.
|
|
109
|
+
|
|
110
|
+
- **Test Data Updates**:
|
|
111
|
+
- Initialized `balance` and `amount_total` manually since we're relying on LogicBank for automatic updates.
|
|
112
|
+
- Set `unit_price` and `amount` for each item directly based on test data consistency with products and orders.
|
|
113
|
+
|
|
114
|
+
- **Business Logic (LogicBank)**:
|
|
115
|
+
- Implemented `declare_logic` function using LogicBank to define rules:
|
|
116
|
+
- Calculate `Customer.balance` as the sum of pending `Order.amount_total`.
|
|
117
|
+
- Sum `Order.amount_total` from `Item.amount`.
|
|
118
|
+
- Calculate `Item.amount` using `quantity * unit_price`.
|
|
119
|
+
- Copy `Product.unit_price` to `Item.unit_price`.
|
|
120
|
+
- Constraint to ensure `Customer.balance` does not exceed `credit_limit`.
|
|
121
|
+
|
|
122
|
+
By following these guidelines, the data model is prepared with a skeleton for logical integrity checks and value derivations, mirroring the application requirements without executing the logic directly in the database.
|
api_logic_server_cli/prototypes/manager/system/genai/learning_requests/logic_bank_api.prompt
CHANGED
|
@@ -152,11 +152,11 @@ Expanded example:
|
|
|
152
152
|
Prompt:
|
|
153
153
|
|
|
154
154
|
Use Logic Bank to enforce the Check Credit requirement (do not generate check constraints):
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
155
|
+
1. Customer.balance <= credit_limit
|
|
156
|
+
2. Customer.balance = Sum(Order.amount_total where date_shipped is null)
|
|
157
|
+
3. Order.amount_total = Sum(Item.amount)
|
|
158
|
+
4. Item.amount = quantity * unit_price
|
|
159
|
+
5. Store the Item.unit_price as a copy from Product.unit_price
|
|
160
160
|
|
|
161
161
|
Response:
|
|
162
162
|
|
|
@@ -169,3 +169,40 @@ def declare_logic(): # created by Web/GenAI for ApiLogicServer, LogicBank
|
|
|
169
169
|
Rule.constraint(validate=CustomerAccount,
|
|
170
170
|
as_condition=lambda row: row.balance <= row.credit_limit,
|
|
171
171
|
error_msg="Customer balance ({row.balance}) exceeds credit limit ({row.credit_limit})")
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
Equivalent expanded example using informal syntax:
|
|
175
|
+
|
|
176
|
+
Prompt:
|
|
177
|
+
|
|
178
|
+
Use Logic Bank to enforce the Check Credit requirement (do not generate check constraints):
|
|
179
|
+
1. The Customer's balance is less than the credit limit
|
|
180
|
+
2. The Customer's balance is the sum of the Order amount_total where date_shipped is null
|
|
181
|
+
3. The Order's amount_total is the sum of the Item amount
|
|
182
|
+
4. The Item amount is the quantity * unit_price
|
|
183
|
+
5. The Item unit_price is copied from the Product unit_price
|
|
184
|
+
|
|
185
|
+
Response is the same:
|
|
186
|
+
|
|
187
|
+
def declare_logic(): # created by Web/GenAI for ApiLogicServer, LogicBank
|
|
188
|
+
|
|
189
|
+
Rule.sum(derive=CustomerAccount.balance, as_sum_of=Order.amount_total, where=lambda row: row.date_shipped is None)
|
|
190
|
+
Rule.sum(derive=Order.amount_total, as_sum_of=Item.amount)
|
|
191
|
+
Rule.formula(derive=Item.amount, as_expression=lambda row: row.quantity * row.unit_price)
|
|
192
|
+
Rule.copy(derive=Item.unit_price, from_parent=Product.unit_price)
|
|
193
|
+
Rule.constraint(validate=CustomerAccount,
|
|
194
|
+
as_condition=lambda row: row.balance <= row.credit_limit,
|
|
195
|
+
error_msg="Customer balance ({row.balance}) exceeds credit limit ({row.credit_limit})")
|
|
196
|
+
|
|
197
|
+
Intermediate sum/count values require a new column, with a LogicBank sum/count rule. For example:
|
|
198
|
+
|
|
199
|
+
Prompt:
|
|
200
|
+
The sum of the child value cannot exceed the parent limit
|
|
201
|
+
|
|
202
|
+
Response is to create 2 rules - a derivation and a constraint, as follows:
|
|
203
|
+
First Rule to Create:
|
|
204
|
+
Rule.sum(derive=Parent.value_total, as_sum_of=Child.value)
|
|
205
|
+
And, be sure to create the second Rule:
|
|
206
|
+
Rule.constraint(validate=Parent,
|
|
207
|
+
as_condition=lambda row: row.value_total <= row.limit,
|
|
208
|
+
error_msg="Parent value total ({row.value_total}) exceeds limit ({row.limit})")
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Use LogicBank to create declare_logic() to enforce these requirements (do not generate check constraints); be sure to update the data model and *all* test data with any attributes used in the logic:
|
|
@@ -4,12 +4,21 @@ Use SQLAlchemy to create a sqlite database named system/genai/temp/create_db_mod
|
|
|
4
4
|
|
|
5
5
|
Hints: use autonum keys (for all tables - including for link/join/junction/intersection tables), allow nulls, foreign keys, no check constraints.
|
|
6
6
|
|
|
7
|
+
Be sure to create classes, never tables.
|
|
8
|
+
|
|
7
9
|
Remember that SQLite DateTime type only accepts Python datetime and date objects as input,
|
|
8
10
|
this means you can not enter string attributes where a date or datetime object is expected.
|
|
9
11
|
|
|
10
12
|
Don't install additional packages.
|
|
11
13
|
Don't use the faker pip package.
|
|
12
14
|
|
|
13
|
-
Create
|
|
15
|
+
Create multiple rows of test data for each table, and follow these guidelines carefully:
|
|
16
|
+
* Use foreign key columns instead of relationship names for the data.
|
|
17
|
+
* Create separate objects for each test data row, not in arrays.
|
|
18
|
+
* Be sure to initialize derived attributes for test data rows - including all sums and counts, but do not rely on LogicBank,
|
|
19
|
+
and do not generate db.execute statements.
|
|
20
|
+
* Do not create arrays of test data.
|
|
21
|
+
* Do not create a function to load test data.
|
|
22
|
+
* Do not print the test data.
|
|
14
23
|
|
|
15
|
-
For each data model class, create a docstring describing the table, prefixed with 'description: '.
|
|
24
|
+
For each data model class, create a docstring describing the table, prefixed with 'description: '.
|
api_logic_server_cli/prototypes/manager/system/genai/prompt_inserts/sqlite_inserts_iterations.prompt
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
|
|
2
|
+
{{prompt}}
|
|
3
|
+
|
|
4
|
+
Update the prior response - be sure not to lose classes and test data already created.
|
|
5
|
+
|
|
6
|
+
Hints: use autonum keys (for all tables - including for link/join/junction/intersection tables), allow nulls, foreign keys, no check constraints.
|
|
7
|
+
|
|
8
|
+
Be sure to create classes, never tables.
|
|
9
|
+
|
|
10
|
+
Remember that SQLite DateTime type only accepts Python datetime and date objects as input,
|
|
11
|
+
this means you can not enter string attributes where a date or datetime object is expected.
|
|
12
|
+
|
|
13
|
+
Don't install additional packages.
|
|
14
|
+
Don't use the faker pip package.
|
|
15
|
+
|
|
16
|
+
Create multiple rows of test data for each table, and follow these guidelines carefully:
|
|
17
|
+
* Use foreign key columns instead of relationship names for the data.
|
|
18
|
+
* Create separate objects for each test data row, not in arrays.
|
|
19
|
+
* Be sure to initialize derived attributes for test data rows - including all sums and counts, but do not rely on LogicBank,
|
|
20
|
+
and do not generate db.execute statements.
|
|
21
|
+
* Do not create arrays of test data.
|
|
22
|
+
* Do not create a function to load test data.
|
|
23
|
+
* Do not print the test data.
|
|
24
|
+
|
|
25
|
+
For each data model class, create a docstring describing the table, prefixed with 'description: '.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Use SQLAlchemy to create a sqlite database named system/genai/temp/model.sqlite .
|
|
2
|
+
the purpose of the database is:
|
|
3
|
+
|
|
4
|
+
{{prompt}}
|
|
5
|
+
|
|
6
|
+
Create at least 15 tables.
|
|
7
|
+
|
|
8
|
+
Hints: use autonum keys, allow nulls, foreign keys, no check constraints.
|
|
9
|
+
If you choose to use a date, only use python datetime datatype.
|
|
10
|
+
Remember that SQLite DateTime type only accepts Python datetime and date objects as input, this means you can not enter string attributes where a date or datetime object is expected.
|
|
11
|
+
Don't use python DECIMAL type.
|
|
12
|
+
Don't install additional packages.
|
|
13
|
+
Don't use the faker pip package.
|
|
14
|
+
|
|
15
|
+
Create a few rows of sample data, use foreign key columns instead of relationship names for the data .
|
api_logic_server_cli/prototypes/manager/system/genai/examples/emp_depts/emp_dept_explicit.prompt
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
Departments and Employees in departments, and on loan to departments.
|
|
2
|
-
|
|
3
|
-
Use Logic Bank to ensure
|
|
4
|
-
1. Department.TotalSalaries = sum(employee.salary)
|
|
5
|
-
2. Department.TotalSalaries < Department.Budget
|
|
6
|
-
3. Department.CountEmployees = count(employees)
|
|
7
|
-
4. Department.CountEmployees < 25
|
|
File without changes
|
|
File without changes
|
|
File without changes
|