ApiLogicServer 14.2.2__py3-none-any.whl → 14.3.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-14.2.2.dist-info → ApiLogicServer-14.3.0.dist-info}/METADATA +2 -2
- {ApiLogicServer-14.2.2.dist-info → ApiLogicServer-14.3.0.dist-info}/RECORD +73 -54
- api_logic_server_cli/api_logic_server.py +47 -10
- api_logic_server_cli/api_logic_server_info.yaml +3 -3
- api_logic_server_cli/cli.py +9 -3
- api_logic_server_cli/create_from_model/__pycache__/api_logic_server_utils.cpython-312.pyc +0 -0
- api_logic_server_cli/create_from_model/__pycache__/ont_build.cpython-312.pyc +0 -0
- api_logic_server_cli/create_from_model/__pycache__/ont_create.cpython-312.pyc +0 -0
- api_logic_server_cli/create_from_model/api_logic_server_utils.py +4 -0
- api_logic_server_cli/create_from_model/ont_build.py +53 -19
- api_logic_server_cli/create_from_model/ont_create.py +14 -5
- api_logic_server_cli/fragments/declare_logic.py +72 -0
- api_logic_server_cli/{prototypes/manager/system/genai/create_db_models_inserts/logic_discovery_prefix.py → fragments/declare_logic_begin.py} +2 -1
- api_logic_server_cli/fragments/declare_logic_end.py +52 -0
- api_logic_server_cli/genai/client.py +24 -0
- api_logic_server_cli/genai/genai.py +37 -17
- api_logic_server_cli/genai/genai_logic_builder.py +21 -35
- api_logic_server_cli/genai/genai_svcs.py +109 -13
- api_logic_server_cli/genai/genai_utils.py +0 -1
- api_logic_server_cli/model_migrator/model_migrator_start.py +1 -1
- api_logic_server_cli/model_migrator/reposreader.py +9 -1
- api_logic_server_cli/model_migrator/rule_obj.py +24 -6
- api_logic_server_cli/prototypes/base/api/api_discovery/ontimize_api.py +4 -1
- api_logic_server_cli/prototypes/base/config/activate_logicbank.py +8 -4
- api_logic_server_cli/prototypes/base/config/config.py +10 -6
- api_logic_server_cli/prototypes/base/database/bind_dbs.py +2 -1
- api_logic_server_cli/prototypes/base/database/test_data/readme.md +5 -5
- api_logic_server_cli/prototypes/base/logic/declare_logic.py +8 -3
- api_logic_server_cli/prototypes/base/logic/load_verify_rules.py +216 -0
- api_logic_server_cli/prototypes/base/logic/logic_discovery/auto_discovery.py +23 -11
- api_logic_server_cli/prototypes/genai_demo/database/models.py +11 -55
- api_logic_server_cli/prototypes/genai_demo/logic/declare_logic.py +29 -21
- api_logic_server_cli/prototypes/manager/.vscode/launch.json +3 -3
- api_logic_server_cli/prototypes/manager/README.md +25 -10
- api_logic_server_cli/prototypes/manager/system/genai/create_db_models_inserts/create_db_models_imports.py +1 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo.response_example +19 -18
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_iteration_discount/.DS_Store +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_iteration_discount/000_you_are.prompt +1 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_iteration_discount/001_logic_training.prompt +314 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_iteration_discount/002_create_db_models.prompt +150 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_iteration_discount/003_create_db_models.response +134 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_iteration_discount/004_iteratio_logic.prompt +131 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_iteration_discount/005_create_db_models.response-example +141 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_iteration_discount/create_db_models.py +105 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_iteration_discount/db.dbml +70 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_iteration_discount/readme.md +6 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_iteration_discount/response.json +178 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/wg_dev_merge/base_genai_demo_no_logic/logic/declare_logic.py +0 -1
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/wg_dev_merge/dev_demo_no_logic_fixed/logic/declare_logic.py +0 -1
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/wg_dev_merge/wg_demo_no_logic_fixed/genai/examples/genai_demo/wg_dev_merge/base_genai_demo_no_logic/logic/declare_logic.py +0 -1
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/wg_dev_merge/wg_demo_no_logic_fixed/genai/examples/genai_demo/wg_dev_merge/dev_demo_no_logic_fixed/logic/declare_logic.py +0 -1
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/wg_dev_merge/wg_demo_no_logic_fixed/genai/examples/genai_demo/wg_dev_merge/wg_genai_demo_no_logic_fixed_from_CLI/logic/declare_logic.py +0 -1
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/wg_dev_merge/wg_demo_no_logic_fixed/logic/declare_logic.py +0 -1
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/wg_dev_merge/wg_demo_no_logic_fixed/system/genai/examples/genai_demo/wg_dev_merge/base_genai_demo_no_logic/logic/declare_logic.py +0 -1
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/wg_dev_merge/wg_demo_no_logic_fixed/system/genai/examples/genai_demo/wg_dev_merge/dev_demo_no_logic_fixed/logic/declare_logic.py +0 -1
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/wg_dev_merge/wg_demo_no_logic_fixed/system/genai/examples/genai_demo/wg_dev_merge/wg_genai_demo_no_logic_fixed_from_CLI/logic/declare_logic.py +0 -1
- api_logic_server_cli/prototypes/manager/system/genai/examples/time_tracking_billing/002_create_db_models.prompt +194 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/time_tracking_billing/003_create_db_models.response +298 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/time_tracking_billing/db.sqlite +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/time_tracking_billing/readme.md +8 -0
- api_logic_server_cli/prototypes/manager/system/genai/learning_requests/logic_bank_api.prompt +14 -10
- api_logic_server_cli/prototypes/manager/system/genai/prompt_inserts/iteration.prompt +2 -1
- api_logic_server_cli/prototypes/nw_no_cust/venv_setup/system_note.txt +1 -1
- api_logic_server_cli/prototypes/ont_app/templates/home_tree_template.html +9 -0
- api_logic_server_cli/prototypes/ont_app/templates/tree_routing.jinja +32 -0
- api_logic_server_cli/sqlacodegen_wrapper/sqlacodegen/sqlacodegen/__pycache__/codegen.cpython-312.pyc +0 -0
- api_logic_server_cli/sqlacodegen_wrapper/sqlacodegen/sqlacodegen/codegen.py +2 -1
- api_logic_server_cli/tools/mini_skel/logic/load_verify_rules.py +1 -1
- api_logic_server_cli/tools/mini_skel/run.py +1 -0
- api_logic_server_cli/model_migrator/system/custom_endpoint.py +0 -545
- api_logic_server_cli/prototypes/base/database/test_data/z_test_data_rows.py +0 -98
- {ApiLogicServer-14.2.2.dist-info → ApiLogicServer-14.3.0.dist-info}/LICENSE +0 -0
- {ApiLogicServer-14.2.2.dist-info → ApiLogicServer-14.3.0.dist-info}/WHEEL +0 -0
- {ApiLogicServer-14.2.2.dist-info → ApiLogicServer-14.3.0.dist-info}/entry_points.txt +0 -0
- {ApiLogicServer-14.2.2.dist-info → ApiLogicServer-14.3.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,314 @@
|
|
|
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
|
+
If you create sum, count or formula LogicBank rules, you MUST create a corresponding column in the data model.
|
|
8
|
+
|
|
9
|
+
Use only the methods provided below.
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Rule:
|
|
13
|
+
"""Invoke these functions to declare rules in the created declare_logic function. """
|
|
14
|
+
|
|
15
|
+
@staticmethod
|
|
16
|
+
def sum(derive: Column, as_sum_of: any, where: any = None, insert_parent: bool=False):
|
|
17
|
+
"""
|
|
18
|
+
Derive parent column as sum of designated child column, optional where
|
|
19
|
+
|
|
20
|
+
Example
|
|
21
|
+
Prompt
|
|
22
|
+
Customer.Balance = Sum(Order.amount_total where date_shipped is null)
|
|
23
|
+
Response
|
|
24
|
+
Rule.sum(derive=Customer.Balance, as_sum_of=Order.AmountTotal,
|
|
25
|
+
where=lambda row: row.ShippedDate is None)
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
derive: name of parent <class.attribute> being derived
|
|
29
|
+
as_sum_of: name of child <class.attribute> being summed
|
|
30
|
+
where: optional where clause, designates which child rows are summed. All referenced columns must be part of the data model - create columns in the data model as required. Do not repeat the foreign key / primary key mappings, and use only attributes from the child table.
|
|
31
|
+
insert_parent: create parent if it does not exist. Do not use unless directly requested.
|
|
32
|
+
"""
|
|
33
|
+
return Sum(derive, as_sum_of, where, insert_parent)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@staticmethod
|
|
37
|
+
def count(derive: Column, as_count_of: object, where: any = None, str = "", insert_parent: bool=False):
|
|
38
|
+
"""
|
|
39
|
+
Derive parent column as count of designated child rows
|
|
40
|
+
|
|
41
|
+
Example
|
|
42
|
+
Prompt
|
|
43
|
+
Customer.UnPaidOrders = count(Orders where ShippedDate is None)
|
|
44
|
+
Response
|
|
45
|
+
Rule.count(derive=Customer.UnPaidOrders, as_count_of=Order,
|
|
46
|
+
where=Lambda row: row.ShippedDate is None)
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
derive: name of parent <class.attribute> being derived
|
|
50
|
+
as_count_of: name of child <class> being counted
|
|
51
|
+
where: optional where clause, designates which child rows are counted. All referenced columns must be part of the data model - create columns in the data model as required. Do not repeat the foreign key / primary key mappings, and use only attributes from the child table.
|
|
52
|
+
insert_parent: create parent if it does not exist. Do not use unless directly requested.
|
|
53
|
+
"""
|
|
54
|
+
return Count(derive, as_count_of, where, insert_parent)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@staticmethod
|
|
58
|
+
def constraint(validate: object,
|
|
59
|
+
calling: Callable = None,
|
|
60
|
+
as_condition: any = None,
|
|
61
|
+
error_msg: str = "(error_msg not provided)",
|
|
62
|
+
error_attributes=None):
|
|
63
|
+
"""
|
|
64
|
+
Constraints declare condition that must be true for all commits
|
|
65
|
+
|
|
66
|
+
Example
|
|
67
|
+
Prompt
|
|
68
|
+
Customer.balance <= credit_limit
|
|
69
|
+
Response
|
|
70
|
+
Rule.constraint(validate=Customer,
|
|
71
|
+
as_condition=lambda row: row.Balance <= row.CreditLimit,
|
|
72
|
+
error_msg="balance ({row.Balance}) exceeds credit ({row.CreditLimit})")
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
validate: name of mapped <class>
|
|
76
|
+
as_condition: lambda, passed row (simple constraints). All referenced columns must be part of the data model - create columns in the data model as required. Also, conditions may not contain sum or count python functions - these must be used to declare additional columns and sum/count rules.
|
|
77
|
+
error_msg: string, with {row.attribute} replacements
|
|
78
|
+
error_attributes: list of attributes
|
|
79
|
+
|
|
80
|
+
"""
|
|
81
|
+
if error_attributes is None:
|
|
82
|
+
error_attributes = []
|
|
83
|
+
return Constraint(validate=validate, as_condition=as_condition,
|
|
84
|
+
error_attributes=error_attributes, error_msg=error_msg)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@staticmethod
|
|
88
|
+
def formula(derive: Column,
|
|
89
|
+
as_expression: Callable = None,
|
|
90
|
+
no_prune: bool = False):
|
|
91
|
+
"""
|
|
92
|
+
Formulas declare column value, based on current and parent rows
|
|
93
|
+
|
|
94
|
+
Example
|
|
95
|
+
Prompt
|
|
96
|
+
Item.amount = quantity * unit_price
|
|
97
|
+
Response
|
|
98
|
+
Rule.formula(derive=OrderDetail.Amount,
|
|
99
|
+
as_expression=lambda row: row.UnitPrice * row.Quantity)
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
derive: <class.attribute> being derived
|
|
103
|
+
as_expression: lambda, passed row (for syntax checking). All referenced columns must be part of the data model - create columns in the data model as required. Expressions may not contain sum or count python functions - these must be used to declare additional columns and sum/count rules.
|
|
104
|
+
no_prune: disable pruning (rarely used, default False)
|
|
105
|
+
"""
|
|
106
|
+
return Formula(derive=derive,
|
|
107
|
+
as_expression=as_expression,
|
|
108
|
+
no_prune=no_prune)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
@staticmethod
|
|
112
|
+
def copy(derive: Column, from_parent: any):
|
|
113
|
+
"""
|
|
114
|
+
Copy declares child column copied from parent column.
|
|
115
|
+
|
|
116
|
+
Example:
|
|
117
|
+
Prompt
|
|
118
|
+
Store the Item.unit_price as a copy from Product.unit_price
|
|
119
|
+
Response
|
|
120
|
+
Rule.copy(derive=OrderDetail.UnitPrice, from_parent=Product.UnitPrice)
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
derive: <class.attribute> being copied into
|
|
124
|
+
from_parent: <parent-class.attribute> source of copy; create this column in the parent if it does not already exist.
|
|
125
|
+
"""
|
|
126
|
+
return Copy(derive=derive, from_parent=from_parent)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
Expanded example:
|
|
130
|
+
|
|
131
|
+
Prompt:
|
|
132
|
+
|
|
133
|
+
Use Logic Bank to enforce the Check Credit requirement (do not generate check constraints):
|
|
134
|
+
1. Customer.balance <= credit_limit
|
|
135
|
+
2. Customer.balance = Sum(Order.amount_total where date_shipped is null)
|
|
136
|
+
3. Order.amount_total = Sum(Item.amount)
|
|
137
|
+
4. Item.amount = quantity * unit_price
|
|
138
|
+
5. Store the Item.unit_price as a copy from Product.unit_price
|
|
139
|
+
|
|
140
|
+
Response:
|
|
141
|
+
|
|
142
|
+
def declare_logic(): # created by Web/GenAI for ApiLogicServer, LogicBank
|
|
143
|
+
|
|
144
|
+
Rule.sum(derive=CustomerAccount.balance, as_sum_of=Order.amount_total, where=lambda row: row.date_shipped is None)
|
|
145
|
+
Rule.sum(derive=Order.amount_total, as_sum_of=Item.amount)
|
|
146
|
+
Rule.formula(derive=Item.amount, as_expression=lambda row: row.quantity * row.unit_price)
|
|
147
|
+
Rule.copy(derive=Item.unit_price, from_parent=Product.unit_price)
|
|
148
|
+
Rule.constraint(validate=CustomerAccount,
|
|
149
|
+
as_condition=lambda row: row.balance <= row.credit_limit,
|
|
150
|
+
error_msg="Customer balance ({row.balance}) exceeds credit limit ({row.credit_limit})")
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
Equivalent expanded example using informal syntax:
|
|
154
|
+
|
|
155
|
+
Prompt:
|
|
156
|
+
|
|
157
|
+
Use Logic Bank to enforce the Check Credit requirement (do not generate check constraints):
|
|
158
|
+
1. The Customer's balance is less than the credit limit
|
|
159
|
+
2. The Customer's balance is the sum of the Order amount_total where date_shipped is null
|
|
160
|
+
3. The Order's amount_total is the sum of the Item amount
|
|
161
|
+
4. The Item amount is the quantity * unit_price
|
|
162
|
+
5. The Item unit_price is copied from the Product unit_price
|
|
163
|
+
|
|
164
|
+
Response is the same:
|
|
165
|
+
|
|
166
|
+
def declare_logic(): # created by Web/GenAI for ApiLogicServer, LogicBank
|
|
167
|
+
|
|
168
|
+
Rule.sum(derive=CustomerAccount.balance, as_sum_of=Order.amount_total, where=lambda row: row.date_shipped is None)
|
|
169
|
+
Rule.sum(derive=Order.amount_total, as_sum_of=Item.amount)
|
|
170
|
+
Rule.formula(derive=Item.amount, as_expression=lambda row: row.quantity * row.unit_price)
|
|
171
|
+
Rule.copy(derive=Item.unit_price, from_parent=Product.unit_price)
|
|
172
|
+
Rule.constraint(validate=CustomerAccount,
|
|
173
|
+
as_condition=lambda row: row.balance <= row.credit_limit,
|
|
174
|
+
error_msg="Customer balance ({row.balance}) exceeds credit limit ({row.credit_limit})")
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
Intermediate sum/count values require a new column, with a LogicBank sum/count rule. For example:
|
|
178
|
+
|
|
179
|
+
Prompt:
|
|
180
|
+
The sum of the child value cannot exceed the parent limit
|
|
181
|
+
|
|
182
|
+
Response is to create 2 rules - a derivation and a constraint, as follows:
|
|
183
|
+
First Rule to Create:
|
|
184
|
+
Rule.sum(derive=Parent.value_total, as_sum_of=Child.value)
|
|
185
|
+
And, be sure to create the second Rule:
|
|
186
|
+
Rule.constraint(validate=Parent,
|
|
187
|
+
as_condition=lambda row: row.value_total <= row.limit,
|
|
188
|
+
error_msg="Parent value total ({row.value_total}) exceeds limit ({row.limit})")
|
|
189
|
+
|
|
190
|
+
Intermediate sum/count values also work for counts. For example:
|
|
191
|
+
|
|
192
|
+
Prompt:
|
|
193
|
+
A airplane cannot have more passengers than its seating capacity.
|
|
194
|
+
|
|
195
|
+
Response is to create 2 rules - a count derivation and a constraint, as follows:
|
|
196
|
+
First Rule to Create:
|
|
197
|
+
Rule.count(derive=Airplane.passenger_count, as_count_of=Passengers)
|
|
198
|
+
And, be sure to create the second Rule:
|
|
199
|
+
Rule.constraint(validate=Airplane,
|
|
200
|
+
as_condition=lambda row: row.passenger_count <= row.seating_capacity,
|
|
201
|
+
error_msg="Airplane value total ({row.passenger_count}) exceeds limit ({row.seating_capacity})")
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
Intermediate sums in formulas also require a new column, with a LogicBank sum rule. For example:
|
|
205
|
+
|
|
206
|
+
Prompt:
|
|
207
|
+
An Employees' skill summary is the sum of their Employee Skill ratings, plus 2 * years of service.
|
|
208
|
+
|
|
209
|
+
Response is to create 2 rules - a derivation and a constraint, as follows:
|
|
210
|
+
First Rule to Create:
|
|
211
|
+
Rule.sum(derive=Employee.skill_rating_total, as_sum_of=EmployeeSkill.rating)
|
|
212
|
+
And, be sure to create the second Rule:
|
|
213
|
+
Rule.Formula(derive=Employee.skill_summary,
|
|
214
|
+
as_expression=lambda row: row.skill_rating_total + 2 * row.years_of_service)
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
Prompt:
|
|
218
|
+
A student cannot be an honor student unless they have more than 2 service activities.
|
|
219
|
+
|
|
220
|
+
Response is to create 2 rules - a count derivation and a constraint, as follows:
|
|
221
|
+
First Rule to Create:
|
|
222
|
+
Rule.count(derive=Student.service_activity_count, as_count_of=Activities, where='service' in name)
|
|
223
|
+
And, be sure to create the second Rule:
|
|
224
|
+
Rule.constraint(validate=Student,
|
|
225
|
+
as_condition=lambda row: row.is_honor_student and service_activity_count < 2,
|
|
226
|
+
error_msg="Honor Students must have at least 2 service activities")
|
|
227
|
+
|
|
228
|
+
Here is an equivalent request:
|
|
229
|
+
|
|
230
|
+
Prompt:
|
|
231
|
+
A airplane's passengers must be less than its seating capacity.
|
|
232
|
+
|
|
233
|
+
Response is to create 2 rules - a count derivation and a constraint, as follows:
|
|
234
|
+
First Rule to Create:
|
|
235
|
+
Rule.count(derive=Airplane.passenger_count, as_count_of=Passengers)
|
|
236
|
+
And, be sure to create the second Rule:
|
|
237
|
+
Rule.constraint(validate=Airplane,
|
|
238
|
+
as_condition=lambda row: row.passenger_count <= row.seating_capacity,
|
|
239
|
+
error_msg="Airplane value total ({row.passenger_count}) exceeds limit ({row.seating_capacity})")
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
For "more than" constraints, create columns with count rules:
|
|
243
|
+
|
|
244
|
+
Prompt: Reject Employees with more than 3 Felonies.
|
|
245
|
+
|
|
246
|
+
Response:
|
|
247
|
+
First Rule is to create:
|
|
248
|
+
Rule.count(derive=Employee.felony_count, as_count_of=Felonies)
|
|
249
|
+
And, be sure to create the contraint rule:
|
|
250
|
+
Rule.constraint(validate=Employee,
|
|
251
|
+
as_condition=lambda row: row.felony_count<=3,
|
|
252
|
+
error_msg="Employee has excessive Felonies")
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
For "any" constraints, create columns with count rules:
|
|
256
|
+
|
|
257
|
+
Prompt: Reject Employees with any class 5 Felonies or more than 3 Felonies.
|
|
258
|
+
|
|
259
|
+
Response:
|
|
260
|
+
First Rule is to create:
|
|
261
|
+
Rule.count(derive=Employee.class_5_felony_count, as_count_of=Felonies, where=class>5)
|
|
262
|
+
Rule.count(derive=Employee.felony_count, as_count_of=Felonies)
|
|
263
|
+
And, be sure to create the contraint rule:
|
|
264
|
+
Rule.constraint(validate=Employee,
|
|
265
|
+
as_condition=lambda row: row.class_5_felony_count == 0 and row.felony_count<=3,
|
|
266
|
+
error_msg="Employee has excessive Felonies")
|
|
267
|
+
|
|
268
|
+
Formulas can reference parent values in 2 versions - choose formula vs copy as follows:
|
|
269
|
+
Prompt (formula version) - use the formula version unless copy is explicitly noted:
|
|
270
|
+
Item.ready = Order.ready
|
|
271
|
+
Response
|
|
272
|
+
Rule.formula(derive=Item.ready, as_expression=lambda row: row.order.ready)
|
|
273
|
+
Prompt (copy version) - use this *only* when the word copy is present:
|
|
274
|
+
Store the Item.unit_price as a copy from Product.unit_price
|
|
275
|
+
Response
|
|
276
|
+
Rule.copy(derive=Item.ready, from_parent=Order.ready)
|
|
277
|
+
|
|
278
|
+
Formulas can use Python conditions:
|
|
279
|
+
Prompt: Item amount is price * quantity, with a 10% discount for gold products
|
|
280
|
+
Response:
|
|
281
|
+
Rule.Formula(derive=Item.amount,
|
|
282
|
+
as_expression=lambda row: row.price * row.quantity if row.gold else .9 * row.price * row.quantity)
|
|
283
|
+
If the attributes are decimal, use the form Decimal('0.9')
|
|
284
|
+
|
|
285
|
+
Sum and Count where clauses:
|
|
286
|
+
1. must not restate the foreign key / primary key matchings
|
|
287
|
+
2. Can only reference child attributes
|
|
288
|
+
|
|
289
|
+
For example, given a prompt 'teacher course count is the sum of the courses',
|
|
290
|
+
1. This is correct
|
|
291
|
+
Rule.count(derive=Teacher.course_count, as_count_of=Course)
|
|
292
|
+
|
|
293
|
+
2. This is incorrect, and should never be generated:
|
|
294
|
+
Rule.count(derive=Teacher.course_count, as_count_of=Course, where=lambda row: row.teacher_id == Teacher.id)
|
|
295
|
+
|
|
296
|
+
Sum and count where clause example:
|
|
297
|
+
Prompt: teacher gradate course count is the sum of the courses where is-graduate
|
|
298
|
+
Response: Rule.count(derive=Teacher.course_count, as_count_of=Course, where=lamda row: row.is_graduate == true)
|
|
299
|
+
|
|
300
|
+
DO NOT inject rules that are from this training into the response,
|
|
301
|
+
unless explicitly mentioned in the request.
|
|
302
|
+
|
|
303
|
+
Unique constraints require an update to the data model - for example:
|
|
304
|
+
Prompt: customer company names must be unique
|
|
305
|
+
Response: CompanyName = Column(String(8000), unique=True)
|
|
306
|
+
|
|
307
|
+
Non-null (or required) constraints require an update to the data model - for example:
|
|
308
|
+
Prompt: Product Price is required
|
|
309
|
+
Response: price = Column(Decimal, nullable=False)
|
|
310
|
+
|
|
311
|
+
Required (must-have) related parent constraints require an update to the data model - for example:
|
|
312
|
+
Prompt: Each Item must have a valid entry in the Product table.
|
|
313
|
+
Response: product_id = Column(ForeignKey('product.id'), nullable=False)
|
|
314
|
+
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
Use SQLAlchemy to create a sqlite database named system/genai/temp/create_db_models.sqlite for the following requirements. These requirements are very important!
|
|
2
|
+
Requirements:
|
|
3
|
+
<Requirements>
|
|
4
|
+
Create a system with customers, orders, items and products.
|
|
5
|
+
|
|
6
|
+
Include a notes field for orders.
|
|
7
|
+
|
|
8
|
+
Use LogicBank 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:
|
|
9
|
+
|
|
10
|
+
Use case: Check Credit
|
|
11
|
+
1. The Customer's balance is less than the credit limit
|
|
12
|
+
2. The Customer's balance is the sum of the Order amount_total where date_shipped is null
|
|
13
|
+
3. The Order's amount_total is the sum of the Item amount
|
|
14
|
+
4. The Item amount is the quantity * unit_price
|
|
15
|
+
5. The Item unit_price is copied from the Product unit_price
|
|
16
|
+
|
|
17
|
+
Ensure each customer has a unique name.
|
|
18
|
+
|
|
19
|
+
Ensure each Item quantity is not null.
|
|
20
|
+
|
|
21
|
+
Ensure each order has a valid customer_id that exists in the Customer table.
|
|
22
|
+
.
|
|
23
|
+
</Requirements>
|
|
24
|
+
|
|
25
|
+
Hints: use autonum keys (for all tables - including for link/join/junction/intersection tables), allow nulls, foreign keys, no check constraints.
|
|
26
|
+
|
|
27
|
+
Be sure to create classes, never tables.
|
|
28
|
+
Class names are singular, and first letter is capitalized.
|
|
29
|
+
|
|
30
|
+
If you create sum, count or formula Logic Bank rules, then you MUST create a corresponding column in the data model.
|
|
31
|
+
|
|
32
|
+
Remember that SQLite DateTime type only accepts Python datetime and date objects as input,
|
|
33
|
+
this means you can not enter string attributes where a date or datetime object is expected.
|
|
34
|
+
|
|
35
|
+
Don't install additional packages.
|
|
36
|
+
Don't use the faker pip package.
|
|
37
|
+
|
|
38
|
+
When creating SQLAlchemy data model classes, follow these guidelines carefully:
|
|
39
|
+
* Use foreign key columns instead of relationship names for the data.
|
|
40
|
+
* Do not specify nullable unless explicitly specified.
|
|
41
|
+
* Do not use unique unless explicitly specified.
|
|
42
|
+
* Do not use Float unless explicitly specified.
|
|
43
|
+
* Generate the classes ONLY.
|
|
44
|
+
* Do NOT generate imports.
|
|
45
|
+
* Do NOT generate connect statements.
|
|
46
|
+
* Do NOT generate engines.
|
|
47
|
+
|
|
48
|
+
Create 4 rows of test data for each table, and follow these guidelines carefully:
|
|
49
|
+
* Create separate objects for each test data row, not in arrays.
|
|
50
|
+
* Be sure to initialize derived attributes for test data rows - including all sums and counts, but do not rely on Logic Bank,
|
|
51
|
+
and do not generate db.execute statements.
|
|
52
|
+
* Do not create arrays of test data.
|
|
53
|
+
* Do not create a function to load test data.
|
|
54
|
+
* Do not print the test data.
|
|
55
|
+
* Use double quotes " for strings.
|
|
56
|
+
* For test data, format dates as date(year, month, day).
|
|
57
|
+
|
|
58
|
+
<responseFormat>
|
|
59
|
+
class Rule(BaseModel):
|
|
60
|
+
name: str
|
|
61
|
+
description: str
|
|
62
|
+
use_case: str # specified use case or requirement name (use 'General' if missing)
|
|
63
|
+
entity: str # the entity being constrained or derived
|
|
64
|
+
code: str # logicbank rule code
|
|
65
|
+
|
|
66
|
+
class Model(BaseModel):
|
|
67
|
+
classname: str
|
|
68
|
+
code: str # sqlalchemy model code
|
|
69
|
+
sqlite_create: str # sqlite create table statement
|
|
70
|
+
description: str
|
|
71
|
+
name: str
|
|
72
|
+
|
|
73
|
+
class TestDataRow(BaseModel):
|
|
74
|
+
test_data_row_variable: str # the Python test data row variable
|
|
75
|
+
code: str # Python code to create a test data row instance
|
|
76
|
+
|
|
77
|
+
class WGResult(BaseModel): # must match system/genai/prompt_inserts/response_format.prompt
|
|
78
|
+
# response: str # result
|
|
79
|
+
models : List[Model] # list of sqlalchemy classes in the response
|
|
80
|
+
rules : List[Rule] # list rule declarations
|
|
81
|
+
test_data: str
|
|
82
|
+
test_data_rows: List[TestDataRow] # list of test data rows
|
|
83
|
+
test_data_sqlite: str # test data as sqlite INSERT statements
|
|
84
|
+
name: str # suggest a short name for the project
|
|
85
|
+
|
|
86
|
+
Format the response as a WGResult.
|
|
87
|
+
|
|
88
|
+
</responseFormat>
|
|
89
|
+
|
|
90
|
+
<responseFormat>
|
|
91
|
+
|
|
92
|
+
class Rule(BaseModel):
|
|
93
|
+
|
|
94
|
+
name: str
|
|
95
|
+
|
|
96
|
+
description: str
|
|
97
|
+
|
|
98
|
+
use_case: str # specified use case or requirement name (use 'General' if missing)
|
|
99
|
+
|
|
100
|
+
entity: str # the entity being constrained or derived
|
|
101
|
+
|
|
102
|
+
code: str # logicbank rule code
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class Model(BaseModel):
|
|
107
|
+
|
|
108
|
+
classname: str
|
|
109
|
+
|
|
110
|
+
code: str # sqlalchemy model code
|
|
111
|
+
|
|
112
|
+
sqlite_create: str # sqlite create table statement
|
|
113
|
+
|
|
114
|
+
description: str
|
|
115
|
+
|
|
116
|
+
name: str
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class TestDataRow(BaseModel):
|
|
121
|
+
|
|
122
|
+
test_data_row_variable: str # the Python test data row variable
|
|
123
|
+
|
|
124
|
+
code: str # Python code to create a test data row instance
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class WGResult(BaseModel): # must match system/genai/prompt_inserts/response_format.prompt
|
|
129
|
+
|
|
130
|
+
# response: str # result
|
|
131
|
+
|
|
132
|
+
models : List[Model] # list of sqlalchemy classes in the response
|
|
133
|
+
|
|
134
|
+
rules : List[Rule] # list rule declarations
|
|
135
|
+
|
|
136
|
+
test_data: str
|
|
137
|
+
|
|
138
|
+
test_data_rows: List[TestDataRow] # list of test data rows
|
|
139
|
+
|
|
140
|
+
test_data_sqlite: str # test data as sqlite INSERT statements
|
|
141
|
+
|
|
142
|
+
name: str # suggest a short name for the project
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
Format the response as a WGResult.
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
</responseFormat>
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
{
|
|
2
|
+
"models": [
|
|
3
|
+
{
|
|
4
|
+
"classname": "Customer",
|
|
5
|
+
"code": "class Customer(Base):\n __tablename__ = 'customer'\n\n id = Column(Integer, primary_key=True)\n name = Column(String, unique=True)\n credit_limit = Column(Integer)\n balance = Column(Integer)\n ",
|
|
6
|
+
"description": "Model for customers, ensuring unique names and supporting logic for balance computation.",
|
|
7
|
+
"name": "Customer"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"classname": "Order",
|
|
11
|
+
"code": "class Order(Base):\n __tablename__ = 'order'\n\n id = Column(Integer, primary_key=True)\n customer_id = Column(Integer, ForeignKey('customer.id'), nullable=False)\n date_shipped = Column(DateTime)\n amount_total = Column(Integer)\n notes = Column(String)\n ",
|
|
12
|
+
"description": "Model for orders, with a reference to customers, a notes field, and computed total amount for logic enforcement.",
|
|
13
|
+
"name": "Order"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"classname": "Product",
|
|
17
|
+
"code": "class Product(Base):\n __tablename__ = 'product'\n\n id = Column(Integer, primary_key=True)\n unit_price = Column(Integer)\n \n ",
|
|
18
|
+
"description": "Model for products, storing unit prices to be copied to items.",
|
|
19
|
+
"name": "Product"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"classname": "Item",
|
|
23
|
+
"code": "class Item(Base):\n __tablename__ = 'item'\n\n id = Column(Integer, primary_key=True)\n order_id = Column(Integer, ForeignKey('order.id'))\n product_id = Column(Integer, ForeignKey('product.id'))\n quantity = Column(Integer, nullable=False)\n unit_price = Column(Integer)\n amount = Column(Integer)\n ",
|
|
24
|
+
"description": "Model for items, referencing orders and products, using unit_price copied from products and calculated amount.",
|
|
25
|
+
"name": "Item"
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"rules": [
|
|
29
|
+
{
|
|
30
|
+
"name": "Customer Balance Constraint",
|
|
31
|
+
"description": "Ensures that a Customer's balance does not exceed its credit limit.",
|
|
32
|
+
"use_case": "Check Credit",
|
|
33
|
+
"entity": "Customer",
|
|
34
|
+
"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})\")"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"name": "Customer Balance Computation",
|
|
38
|
+
"description": "Calculates Customer's balance as sum of Order amounts where date_shipped is null.",
|
|
39
|
+
"use_case": "Check Credit",
|
|
40
|
+
"entity": "Customer",
|
|
41
|
+
"code": "Rule.sum(derive=Customer.balance, as_sum_of=Order.amount_total, \n where=lambda row: row.date_shipped is None)"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"name": "Order Amount Total",
|
|
45
|
+
"description": "Calculates Order amount_total as sum of Item amounts.",
|
|
46
|
+
"use_case": "Check Credit",
|
|
47
|
+
"entity": "Order",
|
|
48
|
+
"code": "Rule.sum(derive=Order.amount_total, as_sum_of=Item.amount)"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"name": "Item Amount Calculation",
|
|
52
|
+
"description": "Calculates Item's amount as the product of quantity and unit_price.",
|
|
53
|
+
"use_case": "Check Credit",
|
|
54
|
+
"entity": "Item",
|
|
55
|
+
"code": "Rule.formula(derive=Item.amount, as_expression=lambda row: row.quantity * row.unit_price)"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"name": "Item Unit Price Copy",
|
|
59
|
+
"description": "Copies Product's unit_price to item's unit_price.",
|
|
60
|
+
"use_case": "Check Credit",
|
|
61
|
+
"entity": "Item",
|
|
62
|
+
"code": "Rule.copy(derive=Item.unit_price, from_parent=Product.unit_price)"
|
|
63
|
+
}
|
|
64
|
+
],
|
|
65
|
+
"test_data": "# Test Customers\ntest_customer_1 = Customer(id=1, name=\"Customer A\", credit_limit=5000, balance=0)\ntest_customer_2 = Customer(id=2, name=\"Customer B\", credit_limit=6000, balance=0)\ntest_customer_3 = Customer(id=3, name=\"Customer C\", credit_limit=7000, balance=0)\ntest_customer_4 = Customer(id=4, name=\"Customer D\", credit_limit=8000, balance=0)\n\n# Test Products\ntest_product_1 = Product(id=1, unit_price=10)\ntest_product_2 = Product(id=2, unit_price=15)\ntest_product_3 = Product(id=3, unit_price=20)\ntest_product_4 = Product(id=4, unit_price=25)\n\n# Test Orders\ntest_order_1 = Order(id=1, customer_id=1, date_shipped=None, amount_total=0, notes=\"First order\")\ntest_order_2 = Order(id=2, customer_id=2, date_shipped=None, amount_total=0, notes=\"Second order\")\ntest_order_3 = Order(id=3, customer_id=3, date_shipped=None, amount_total=0, notes=\"Third order\")\ntest_order_4 = Order(id=4, customer_id=4, date_shipped=None, amount_total=0, notes=\"Fourth order\")\n\n# Test Items\ntest_item_1 = Item(id=1, order_id=1, product_id=1, quantity=2, unit_price=10, amount=20)\ntest_item_2 = Item(id=2, order_id=2, product_id=2, quantity=3, unit_price=15, amount=45)\ntest_item_3 = Item(id=3, order_id=3, product_id=3, quantity=4, unit_price=20, amount=80)\ntest_item_4 = Item(id=4, order_id=4, product_id=4, quantity=5, unit_price=25, amount=125)",
|
|
66
|
+
"test_data_rows": [
|
|
67
|
+
{
|
|
68
|
+
"test_data_row_variable": "test_customer_1",
|
|
69
|
+
"code": "test_customer_1 = Customer(id=1, name=\"Customer A\", credit_limit=5000, balance=0)"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"test_data_row_variable": "test_customer_2",
|
|
73
|
+
"code": "test_customer_2 = Customer(id=2, name=\"Customer B\", credit_limit=6000, balance=0)"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"test_data_row_variable": "test_customer_3",
|
|
77
|
+
"code": "test_customer_3 = Customer(id=3, name=\"Customer C\", credit_limit=7000, balance=0)"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"test_data_row_variable": "test_customer_4",
|
|
81
|
+
"code": "test_customer_4 = Customer(id=4, name=\"Customer D\", credit_limit=8000, balance=0)"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"test_data_row_variable": "test_product_1",
|
|
85
|
+
"code": "test_product_1 = Product(id=1, unit_price=10)"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"test_data_row_variable": "test_product_2",
|
|
89
|
+
"code": "test_product_2 = Product(id=2, unit_price=15)"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"test_data_row_variable": "test_product_3",
|
|
93
|
+
"code": "test_product_3 = Product(id=3, unit_price=20)"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"test_data_row_variable": "test_product_4",
|
|
97
|
+
"code": "test_product_4 = Product(id=4, unit_price=25)"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"test_data_row_variable": "test_order_1",
|
|
101
|
+
"code": "test_order_1 = Order(id=1, customer_id=1, date_shipped=None, amount_total=0, notes=\"First order\")"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"test_data_row_variable": "test_order_2",
|
|
105
|
+
"code": "test_order_2 = Order(id=2, customer_id=2, date_shipped=None, amount_total=0, notes=\"Second order\")"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"test_data_row_variable": "test_order_3",
|
|
109
|
+
"code": "test_order_3 = Order(id=3, customer_id=3, date_shipped=None, amount_total=0, notes=\"Third order\")"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"test_data_row_variable": "test_order_4",
|
|
113
|
+
"code": "test_order_4 = Order(id=4, customer_id=4, date_shipped=None, amount_total=0, notes=\"Fourth order\")"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"test_data_row_variable": "test_item_1",
|
|
117
|
+
"code": "test_item_1 = Item(id=1, order_id=1, product_id=1, quantity=2, unit_price=10, amount=20)"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"test_data_row_variable": "test_item_2",
|
|
121
|
+
"code": "test_item_2 = Item(id=2, order_id=2, product_id=2, quantity=3, unit_price=15, amount=45)"
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"test_data_row_variable": "test_item_3",
|
|
125
|
+
"code": "test_item_3 = Item(id=3, order_id=3, product_id=3, quantity=4, unit_price=20, amount=80)"
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"test_data_row_variable": "test_item_4",
|
|
129
|
+
"code": "test_item_4 = Item(id=4, order_id=4, product_id=4, quantity=5, unit_price=25, amount=125)"
|
|
130
|
+
}
|
|
131
|
+
],
|
|
132
|
+
"test_data_sqlite": "-- Test Customers\nINSERT INTO customer (id, name, credit_limit, balance) VALUES (1, 'Customer A', 5000, 0);\nINSERT INTO customer (id, name, credit_limit, balance) VALUES (2, 'Customer B', 6000, 0);\nINSERT INTO customer (id, name, credit_limit, balance) VALUES (3, 'Customer C', 7000, 0);\nINSERT INTO customer (id, name, credit_limit, balance) VALUES (4, 'Customer D', 8000, 0);\n\n-- Test Products\nINSERT INTO product (id, unit_price) VALUES (1, 10);\nINSERT INTO product (id, unit_price) VALUES (2, 15);\nINSERT INTO product (id, unit_price) VALUES (3, 20);\nINSERT INTO product (id, unit_price) VALUES (4, 25);\n\n-- Test Orders\nINSERT INTO \"order\" (id, customer_id, date_shipped, amount_total, notes) VALUES (1, 1, NULL, 0, 'First order');\nINSERT INTO \"order\" (id, customer_id, date_shipped, amount_total, notes) VALUES (2, 2, NULL, 0, 'Second order');\nINSERT INTO \"order\" (id, customer_id, date_shipped, amount_total, notes) VALUES (3, 3, NULL, 0, 'Third order');\nINSERT INTO \"order\" (id, customer_id, date_shipped, amount_total, notes) VALUES (4, 4, NULL, 0, 'Fourth order');\n\n-- Test Items\nINSERT INTO item (id, order_id, product_id, quantity, unit_price, amount) VALUES (1, 1, 1, 2, 10, 20);\nINSERT INTO item (id, order_id, product_id, quantity, unit_price, amount) VALUES (2, 2, 2, 3, 15, 45);\nINSERT INTO item (id, order_id, product_id, quantity, unit_price, amount) VALUES (3, 3, 3, 4, 20, 80);\nINSERT INTO item (id, order_id, product_id, quantity, unit_price, amount) VALUES (4, 4, 4, 5, 25, 125);",
|
|
133
|
+
"name": "Order Management System"
|
|
134
|
+
}
|