Celery tasks
MEG Docs
- (celery task)megdocs.tasks.parse_document_content(version_id: int)
Proxy that evaluates object once.
Proxywill evaluate the object each time, while the promise will only evaluate it once.
- (celery task)megdocs.tasks.download_cloud_version(log_uid: str) None
Download file from OneDrive and attach it to a
Version.- Parameters:
log_uid – UID of the
CloudVersionDownloadLog.
- megdocs.tasks.get_review_notification_recipients(document: Document) set[Auditor]
Return the owner, reviewer, and their direct delegates for a review notification. Direct delegates only — delegators and co-delegates are not notified for review reminders. Relies on prefetched
owner__delegatesandcurrent_version__reviewer__delegates.- Parameters:
document – The document whose owner and reviewer should be notified.
- Returns:
Set of auditors to notify.
- (celery task)megdocs.tasks.send_review_notifications()
Proxy that evaluates object once.
Proxywill evaluate the object each time, while the promise will only evaluate it once.
- (celery task)megdocs.tasks.send_attestation_notifications_batch(checkbox_id: int, auditor_ids: list[int]) None
Sends attestation notifications for a batch of auditors for a given DocumentCheckbox Batches auditor notifications to reduce number of celery tasks queued
- Parameters:
checkbox_id – The ID of the checkbox object to filter users for
auditor_ids – List of auditor IDs to send notifications for
Emails a user to notify them that another user has shared a document with them.
- Parameters:
recipient_id – The recipient auditor’s id.
sharer_name – Name of the user who shared the document.
document_id – The document’s id.
note – The note to be sent to the user
- (celery task)megdocs.tasks.submit_draft_as_new_version(draft_id: int, auditor_id: int, version_data: dict, *, publish=False) int
Renders draft into a PDF file and submits a new version
- Parameters:
draft_id – pk of the draft object
auditor_id – the id of the user who is creating the version
version_data – dict of any additional kwargs for the new
Versionpublish – whether to approve and publish the version automatically
- Returns:
pk of the new version object
- (celery task)megdocs.tasks.update_version_draft(version_id: int)
Updates version in review with the latest contents from draft:
pdf version
documents plaintext contents
This job runs if
DRAFT_UPDATE_REVIEWis set
- (celery task)megdocs.tasks.generate_pdf_preview(html: str) str
Generate a pdf document from given input HTML string. Uses
html_to_pdf()to write preview to a temporary pdf file and returns its url (for example/media/CACHE/pdf_preview/0F0F0F0F0F0F0F.pdf). The preview file is deleted after time defined inPDF_PREVIEW_EXPIRY_MINS.Uses file contents as the hash to determine filename, and if already exists, existing file is returned instead of rendering the pdf again.
- Parameters:
html – The source HTML string
- Returns:
the url to the generated PDF file
- (celery task)megdocs.tasks.import_word_document_ckeditor(document_id: int, user_id: int) int
Imports document’s word version and creates or updates document’s draft with its contents. Creates draft object if one does not exist. If exists, overrides draft’s contents
The document’s current version must have a current version with “source” being a word docx file. The user must have access to the document
- Parameters:
document_id – pk of the
Documentuser_id – pk of the User
- Returns:
pk of the draft object
- (celery task)megdocs.tasks.import_word_document_from_file_ckeditor(document_id: int, user_id: int, file_path: str) int
Parses The MS Word docx file and creates or updates Document’s draft with its contents. Creates draft object if one does not exist. If exists, overrides draft’s contents After successful import, the docx file is deleted.
- Parameters:
document_id – pk of the
Documentuser_id – pk of the User - The user must have access to the document
file_path – absolute path to the Word DOCX file, must be in an accessible directory such as the /media/ folder
- Returns:
pk of the draft object
- (celery task)megdocs.tasks.create_user_notifications_version_pending_review(reviewer_id: int) None
Task to bulk create pending-review notifications for versions awaiting the reviewer’s action. Excludes versions belonging to archived documents. Given the unique constraint on UserNotification, conflicts will be ignored in bulk create and duplicates will not be created.
- Parameters:
reviewer_id – the id of the reviewer the notifications will be created for
- (celery task)megdocs.tasks.create_user_notifications_document_due_review(reviewer_id: int) None
Task to bulk create periodic due-review notifications for documents whose review interval has elapsed. Given the unique constraint on UserNotification, conflicts will be ignored in bulk create and duplicates will not be created.
- Parameters:
reviewer_id – the id of the reviewer the notifications will be created for
- (celery task)megdocs.tasks.create_user_notifications_version_awaiting_publish(reviewer_id: int) None
Task to bulk create document publish notifications for the versions reviewer Given the unique constraint on UserNotification, conflicts will be ignored in bulk create and duplicates will not be created
- Param:
reviewer_id: the id of the documents versions reviewer that the notification will be created for
- (celery task)megdocs.tasks.create_user_notifications_version_publication_process(version_id: int) None
Task to bulk create document publication process notifications for those users in the version approval config’s current step that have not yet approved Given the unique constraint on UserNotification, conflicts will be ignored in bulk create and duplicates will not be created
- Param:
version_id: the ids of the document version that will be queried to get the approval config and approvers
- (celery task)megdocs.tasks.create_user_notifications_approval_config_publication_process(approval_config_id: int) None
Task to bulk create document publication process notifications for those users in the version approval config’s current step that have not yet approved Given the unique constraint on UserNotification, conflicts will be ignored in bulk create and duplicates will not be created
- Param:
approval_config_id: the id of the approval config object by which the task was triggered
- (celery task)megdocs.tasks.create_user_notifications_version_decline(version_id: int) None
Create bell notifications for the document owner and controller when a version is declined.
The notification points to the declined document and is created once per decline for each recipient. The owner-side recipients utilize the institution’s
use_owner_fieldconfig. The unique constraint on UserNotification ensures repeat declines do not duplicate a recipient’s notification.- Parameters:
version_id – the id of the declined version
- (celery task)megdocs.tasks.create_user_notifications_attestation_required(document_id: int) None
Create user notifications for documents that need to be attestation Queries the checkbox model associated with the document and annotates the auditor_ids on the model Loops through all relevant auditor ids for both teams and standalone auditors and creates a notification for each
- Parameters:
document_id – The ID of the document that was recently updated with a new current version (published)
- (celery task)megdocs.tasks.publish_document_version_from_schedule(version_id: int, auditor_id: int) None
Task to publish a document version checking if the auditor who invoked the task is indeed the reviewer Will fail if the version is no approved (for example if the review has been revoked)
- Parameters:
version_id – the id of the version to be published
auditor_id – the id of the auditor who triggered the task
- (celery task)megdocs.tasks.delete_current_version_due_review_notifications(version_id: int)
Delete relevant notifcation when a version is marked as reviewed according to its interval
- (celery task)megdocs.tasks.delete_relevant_version_notifications(version_id: int, current_step: int)
Update user notification by deleting the relevant notification based on the notification type
- Parameters:
version_id – the version id for which the notification will be filtered by
current_step – the current step of the publication process
- (celery task)megdocs.tasks.delete_previous_version_notifications(version_id: int) None
Task to cleanup any redundant notifications relevant to the version’s document Queries all previous versions of the document except the current version on publish and deletes stale notifications
- Parameters:
version_id – The id of the version to exclude (document’s current version)
- (celery task)megdocs.tasks.delete_existing_notification_approval_config(approval_config_id: int, document_id: int | None = None) None
Task to delete any redundant notifications relevant to the approval config’s documents. When
document_idis provided, only notifications for that document’s versions are deleted.- Parameters:
approval_config_id – the id of the approval config whose notifications should be deleted
document_id – optional document id to scope deletion to a single document
- megdocs.tasks.get_comment_mention_notification_filter(document_id: int) Q
Builds a Q filter matching comment mention notifications for a document. Handles both CKEditor inline comments (DocumentComment on draft) and side-panel comments (Comment on version).
- Parameters:
document_id – ID of the document
- Returns:
Q filter for matching notifications, or a Q that matches nothing if none found
- (celery task)megdocs.tasks.delete_comment_mention_notifications_for_document(document_id: int) int
Deletes all comment mention notifications linked to comments on a document. Called when a document’s workflow step (review/approval) completes.
- Parameters:
document_id – ID of the document whose comment mention notifications should be cleared
- Returns:
Number of deleted notifications
- (celery task)megdocs.tasks.generate_llm_response_for_document_chat_message(auditor_id: int, ai_message_id: int, ai_chat_id: int, version_id: int) dict[str, bool]
Given an existing placeholder message and an AI chat, creates a LLM reply and updates the placeholder with the reply.
- Steps:
Feeds chat history to LLM and requests a new response
If response contains a title adds the title to the chat.
Updates placeholder-message content field object with LLM reply.
- (celery task)megdocs.tasks.delete_attestation_required_notification(document_id: int, auditor_ids: list[int] | None = None) None
Delete attestation required notifications for specific auditors and document.
This task removes user notifications of type NOTIFICATION_TYPE_DOCUMENT_ATTESTATION_REQUIRED for the given auditors and document. It is typically called when: - A user completes an attestation (checks the checkbox) - A checkbox is deleted
- Parameters:
document_id – The ID of the document for which to delete notifications
auditor_ids – List of auditor IDs whose notifications should be deleted
- (celery task)megdocs.tasks.expire_checkbox_attestations(checkbox_id: int) None
Unpublish all DocumentCheckboxState records for a given checkbox when the review_interval has expired. This forces users to re-attest.
After expiring attestations, schedules the next expiration and reminder to maintain the review cycle.
- Parameters:
checkbox_id – The ID of the DocumentCheckbox whose attestations should expire
- (celery task)megdocs.tasks.send_attestation_reminder_emails(checkbox_id: int) None
Send reminder emails to users who have not yet attested to a document checkbox and reschedule the next reminder at the configured interval until every relevant user has attested.
- Parameters:
checkbox_id – The ID of the DocumentCheckbox to send reminders for
Files
- (celery task)files.tasks.delete_media_file(path: str)
Deletes a file in the media folder. The task will fail if the file does not exist, of path leads outside the media folder. Use this task to lazily delete a file using celery or put it on a timer.
- Parameters:
path – relative path to the preview file within media directory (for example CACHE/test.jpeg)
- Raises:
FileNotFoundError – if the file does not exist
Audit builder
- (celery task)audit_builder.tasks.calculate_llm_topics_for_fields(session_id: 'int')
Query llm to determine topics in text of text custom fields and output the result to a multiple choice field.
- Parameters:
session_id – pk of the AuditSession obj
- (celery task)audit_builder.tasks.calculate_observations(schedule_id: 'int') 'int'
Runs field re-calculation in form and fields defined by given schedule
- (celery task)audit_builder.tasks.calculate_sentiment_for_fields(session_id: 'int')
Runs sentiment analysis on text custom fields and outputs the result to a choice field.
- Parameters:
session_id – pk of the AuditSession obj
- (celery task)audit_builder.tasks.calculate_session_fields(session_id: 'int', user_id: 'int | None' = None)
Trigger calculation for dynamic fields in given session
- Parameters:
session_id – pk of the AuditSession obj
user_id – optional user id if the action was triggered by user. When provided, the action will be logged against that user.
- audit_builder.tasks.convert_openai_to_google_format(messages: list[ChatCompletionMessageParam]) tuple[str | None, list[genai_types.Content]]
Converts text-only OpenAI messages to Google GenAI format, separating the system instruction .
- (celery task)audit_builder.tasks.daily_calculate_observations()
Triggers fields calculation for all forms where calculation is scheduled
- (celery task)audit_builder.tasks.decompress_observation_sessions(session_ids: 'list[int]', user_id: 'int | None' = None)
Decompresses the given audit sessions using
decompress_observations().Every session shares a single transaction, so the whole batch is either migrated or rolled back, leaving no partially converted selection. Each session that changed is recorded in the admin log.
- Parameters:
session_ids – pks of the AuditSession objects to decompress
user_id – optional user id if the action was triggered by user. When provided, the action will be logged against that user.
- audit_builder.tasks.generate_llm_response(messages_for_llm: list[ChatCompletionMessageParam], safety_identifier: str | None = None) str
Takes Openai style prompt and feeds it to ChatGPT or Gemini or does nothing, depending on env vars. Handles errors and produces reusable simple errors.
- Parameters:
messages_for_llm – Openai-style chat messages to send to the LLM.
safety_identifier – Tenant-scoped identifier forwarded to the OpenAI backend for abuse monitoring.
- (celery task)audit_builder.tasks.generate_titles_for_fields(session_id: 'int')
Generates titles from text custom fields and outputs to another text field.
- Parameters:
session_id – pk of the AuditSession obj
- audit_builder.tasks.get_custom_topics_from_llm(text: str, topics: list[str], examples: list[list[str]], extra_prompt: str | None = None, safety_identifier: str | None = None) str
Prompts a LLM to determine if any of the predefined topics/classes are present in the text.
- Parameters:
text – string to be auto classified
topics – list of topics/classes
examples – list of lists of examples (format [question, answer]
extra_prompt – string or None, gives LLM more context about the task
safety_identifier – Tenant-scoped identifier forwarded to the OpenAI backend for abuse monitoring.
- Returns:
string containing topics/classes extracted
- audit_builder.tasks.get_empty_answers(subform: CustomSubform) dict
Creates empty answers dictionary for the subform’s fields. Ensures choice fields are initialized with None to preserve options.
- audit_builder.tasks.get_llm_client() AzureOpenAI | genai.Client | None
Connects to Open AI Azure API or Google Genie API
- Returns:
Azure client object or Google Genie client object
- audit_builder.tasks.get_request_topics_messages_for_llm(text: str, topics: list[str], examples: list[list[str]], extra_prompt: str | None = None) list[dict[str, str]]
Creates messages to send to LLM to request it to select topics/classes from a text.
- Parameters:
text – string to be auto classified
topics – list of topics/classes
examples – list of lists of examples (format [question, answer]
extra_prompt – string or None, gives LLM more context about the task
- Returns:
list of dictionaries containing messages to send to LLM
- audit_builder.tasks.get_sentiment_llm_prompt(text: str, extra_examples: list[list[str]], question: str | None = None) list[dict[str, str]]
Creates messages to send to LLM to request it to select topics/classes from a text. We ask the result to be placed in brackets as sometimes the LLM produces an explanation with the answer (easier to extract answer).
- Parameters:
text – The answer text to analyze
extra_examples – Extra examples for few-shot learning
question – Optional question context to provide semantic understanding
- audit_builder.tasks.get_temp_wav_file(audio_path: str) Generator[tuple[str, int], None, None]
Creates a temporary WAV file from an audio file with standardized format and handles cleanup.
- Parameters:
audio_path – Path to the source audio file (can be any audio format)
- Returns:
Path to temporary WAV file converted to mono 16kHz WAV format that will be automatically cleaned up
- Raises:
OSError – If file operations fail
AudioSegmentException – If audio conversion fails
The file is converted to a standardized format required by Azure Speech Services: - Mono channel audio - 16kHz sample rate - 16-bit PCM WAV encoding
- audit_builder.tasks.get_title_generation_prompt(text: str, extra_examples: list[list[str]]) list[dict[str, str]]
Creates messages to send to LLM to generate a concise title from text.
- audit_builder.tasks.handle_llm_errors(func)
A decorator to handle common API errors for both Google and OpenAI LLM clients. It captures exceptions and raises standardized, user-friendly errors.
- (celery task)audit_builder.tasks.import_form_json(institution_id: 'int', *, path: 'str', user_id: 'int | None', **kwargs) 'Sequence[int]'
Celery job that imports a form from a json file and populates it with dummy data
- Parameters:
institution_id
path – path to the json file - must be available to celery worker (i.e. be part of the docker image, or located in a shared folder, like media files)
user_id – id of the used to associate the dummy observations with
- audit_builder.tasks.increment_sequence_id(config: AuditFormConfig) int
Increment and return next sequential id for a locked config object. This function expects the config object to already be locked with select_for_update() within a transaction.atomic() context. It does not acquire its own lock.
- Parameters:
config – A locked AuditFormConfig instance (must be locked with select_for_update)
- Raises:
ValueError – If the form is not sequence enabled
- Returns:
The incremented sequential id
- (celery task)audit_builder.tasks.link_session_observations(session_id: 'int', created: 'bool' = True) 'None'
Iterates through all observations in the session and processes related observations for each. Checks if the form implements custom subforms and if so, gets the related subobservations. Otherwise gets the related custom observations.
- Parameters:
session_id – The pk of the session containing observations to be linked.
created – Is true if the session was just created.
Only custom forms are supported.
- (celery task)audit_builder.tasks.migrate_observations(*, source_form_id: 'int', target_form_id: 'int', move: 'bool', dry_run: 'bool' = False, report_email_address: 'str')
Proxy that evaluates object once.
Proxywill evaluate the object each time, while the promise will only evaluate it once.
- (celery task)audit_builder.tasks.parse_lacas_forms(imported_forms: 'list[int]', run_calculations=True) 'int'
Processes the LACAS form imported from JSON file by correcting the related form ids and observation answers
- Parameters:
imported_forms – ids of the forms (first id should related to the summary form) returned by
import_form_jsonjob
- audit_builder.tasks.perform_sentiment_analysis(text: str, extra_examples: list[list[str]], question: str | None = None, safety_identifier: str | None = None) Literal['positive', 'neutral', 'negative', 'unknown']
Runs sentiment analysis on given text using Chat-GPT or Gemini model
- Parameters:
text – string to be passed to the model
extra_examples – extra example, use for multilingual examples if needed
question – optional question context to provide semantic understanding of the answer
safety_identifier – Tenant-scoped identifier forwarded to the OpenAI backend for abuse monitoring.
- Returns:
sentiment analysis result
- (celery task)audit_builder.tasks.process_default_values(session_id: 'int')
Process default values for fields where ‘show_in_app’ is False
First finds subforms using default value logic and checks if they dont have a sub observation. If they are missing a sub obs its added then default values are added to these.
- (celery task)audit_builder.tasks.process_sequence_ids(session_id: 'int')
If sequential ids are enabled for the form, set sequence ids for all observations in a given session
- Parameters:
session_id – Session to set sequence ids for
- (celery task)audit_builder.tasks.reset_audit_form_sequence_ids(form_id: 'int')
Reset audit form sequence ids
- Parameters:
form_id – Audit form to reset sequence ids for
- audit_builder.tasks.safe_llm_task(func: Callable[[...], Any]) Callable[[...], Any]
Decorator for Celery tasks to handle retries and soft-failures for LLM operations.
Catches standardized LLM errors (LLMAuthError, LLMAPIError) and triggers Celery’s built-in retry mechanism. If maximum retries are exceeded and the allow_failures kwarg is True, the error is swallowed, logged to Sentry.
Note: The decorated task must use @app.task(bind=True).
- (celery task)audit_builder.tasks.schedule_observation_reviews(session_id: 'int')
For forms that have enabled the feature, schedule automatic observation reviews.
- (celery task)audit_builder.tasks.schedule_workflow_tasks(session_id: 'int')
Schedule workflow tasks for a given audit session. This task schedules workflow tasks based on two triggers: creation and observation answer dates. It processes all session observations to schedule tasks accordingly.
- Parameters:
session_id – The ID of the AuditSession for which workflow tasks are to be scheduled.
Emails a user to notify them that another user has shared an observation with them.
- Parameters:
recipient_id – The recipient auditor’s id.
sharer_name – Name of the user who shared the document.
observation_id – The observation id.
note – The note to be sent to the user
- (celery task)audit_builder.tasks.transcribe_audio_fields(session_id: 'int')
Transcribes audio custom fields and outputs the result to a text field.
- Parameters:
session_id – pk of the AuditSession obj
- (celery task)audit_builder.tasks.update_observation_auditors_task(observation_id: 'int', auditor_fields: 'list[tuple[int | None, list[tuple[str, int]]]]') 'int'
Async job wrapper for
update_observation_auditors().- Parameters:
observation_id – Custom observation id
auditor_fields – list of subform ids, and the field names within that subform.
Nonerepresents observation-level questions. Must be an exhaustive list of all auditor fields. This list will be converted to a dict before passing it toupdate_observation_auditors()- the dict is not json-serializable due to int and null keys.
- (celery task)audit_builder.tasks.update_observation_generated_title_fields(observation_id: 'int', user_id: 'int', is_sub_observation: 'bool | None' = False) 'None'
Updates AI-generated titles for an observation
- Parameters:
observation_id – ID of observation to update
user_id – ID of user who made the change
is_sub_observation – whether observation is a sub observation or not
save – whether to save to db or not (set to false if using in bulk update)
- (celery task)audit_builder.tasks.update_observation_transcribe_audio_fields(observation_id: 'int', user_id: 'int', is_sub_observation: 'bool | None' = False)
Updates AI-generated audio transcriptions for an observation when source fields change.
param: observation_id: ID of observation to update param: user_id: ID of user who made the change param: is_sub_observation: whether observation is a sub observation or not param: save: whether to save to db or not (set to false if using in bulk update)