Skip to content

Commit ef67e33

Browse files
committed
Added: [untested] caching wrapper functions for form stages (#62)
1 parent e6c5c30 commit ef67e33

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

libreforms_fastapi/app/__init__.py

+75
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@
142142

143143
from libreforms_fastapi.utils.custom_tinydb import CustomEncoder
144144

145+
# This import is used for caching with selective invalidation
146+
from libreforms_fastapi.utils.parameterized_caching import parameterized_lru_cache
147+
145148
# Import to render more powerful email content
146149
from libreforms_fastapi.utils.jinja_emails import (
147150
render_email_message_from_jinja,
@@ -155,6 +158,78 @@
155158
_env = os.environ.get('ENVIRONMENT', 'development')
156159

157160

161+
162+
# The following functions will be used to cache form stage data,
163+
# see https://github.com/signebedi/libreforms-fastapi/issues/62
164+
@parameterized_lru_cache(maxsize=128)
165+
def cache_form_stage_data(
166+
form_name: str,
167+
form_stages: dict,
168+
doc_db: ManageDocumentDB,
169+
):
170+
"""
171+
This function wraps ManageDocumentDB.get_all_documents_by_stage() so we can cache values
172+
outside the class scope, since we are using it largely as a dependency injection...
173+
"""
174+
175+
# We begin be instantiating an empty container to store document_id values for each stage
176+
stage_dict = {}
177+
178+
# Then we iterate through each stage and collect each of the items
179+
for stage_name, _stage_conf in form_stages.items(): # _stage_conf is not important in this function
180+
181+
document_ids = [] # Reset this variable... perhaps redundant
182+
document_ids = doc.db.get_all_documents_by_stage(form_name, stage_name) # Get all values with the current stage
183+
184+
# Add these values to stage_dict
185+
stage_dict[stage_name] = document_ids
186+
187+
return stage_dict
188+
189+
# @parameterized_lru_cache(maxsize=128)
190+
@lru_cache() # Opt for a standard cache because we probably need to rebuild this entire cache when there are changes
191+
def cache_form_stage_data_for_specified_user(
192+
form_name: str,
193+
form_stages: dict,
194+
current_user, # This is a sqlalchemy row
195+
doc_db: ManageDocumentDB,
196+
):
197+
"""
198+
This function wraps extends cache_form_stage_data to get a list of documents that a given
199+
user is eligible to approve.
200+
"""
201+
202+
# Get the list of documents in each stage from cached data
203+
all_stage_data = cache_form_stage_data(form_name, form_stages, doc_db)
204+
205+
user_specific_data = []
206+
207+
# Iterate through each form stage in form_stages
208+
for stage_name, stage_conf in form_stages.items():
209+
210+
stage_specific_data = all_stage_data[stage_name]
211+
212+
# Start with the static form approval method
213+
if stage_conf.method == "static":
214+
# If this user is the specified approver, then append all the stage-
215+
# specific data to the user's list of documents needing their action
216+
if user.email == stage_conf.target:
217+
user_specific_data.extend(stage_specific_data)
218+
219+
# Then do group based approval
220+
if stage_conf.method == "group":
221+
# If the user is a member of the approving group, then add all the stage-
222+
# specific data to the user's list of docs needing their action
223+
if stage_conf.target in user.groups:
224+
user_specific_data.extend(stage_specific_data)
225+
226+
# Relationship-based approval is... complex, to say the least. This will remain unimplemented
227+
# for now, see https://github.com/signebedi/libreforms-fastapi/issues/332
228+
229+
return user_specific_data
230+
231+
232+
158233
class ConfigFileChangeHandler(FileSystemEventHandler):
159234
"""
160235
I am adding this class to help manage caching for the application configuration,

0 commit comments

Comments
 (0)