AssemblyLine.al_document
- AssemblyLine.al_document
- json
- mimetypes
- os
- re
- escape
- Any
- Dict
- List
- Literal
- Union
- Callable
- Optional
- TypedDict
- Address
- LatitudeLongitude
- log
- DADict
- DAList
- DAObject
- DAFile
- DAFileCollection
- DAFileList
- DALazyTemplate
- defined
- pdf_concatenate
- zip_file
- DAOrderedDict
- background_action
- action_button_html
- include_docx_template
- user_logged_in
- user_info
- send_email
- docx_concatenate
- get_config
- space_to_underscore
- DAStaticFile
- alpha
- showifdef
- word
- DAError
- pdf_to_pdfa
- wrap
- floor
- subprocess
- pikepdf
- Tuple
- secrets
- string
- __all__
- DEBUG_MODE
- _CacheableDocumentTitle
- CacheableDocument
- random_suffix
- base_name
- label
- key
- safeattr
- html_safe_str
- _javascript_href
- table_row
- pdf_page_parity
- add_blank_page
- ALAddendumField
- ALAddendumFieldDict
- DALazyAttribute
- ALDocument
- ALStaticDocument
- ALDocumentBundle
- init
- _set_default_attributes
- as_pdf
- __str__
- as_zip
- preview
- has_enabled_documents
- enabled_documents
- as_flat_list
- get_titles
- as_pdf_list
- as_docx_list
- as_editable_list
- get_cacheable_documents
- has_broken_documents
- broken_exhibit_titles
- broken_documents_warning_html
- download_list_html
- download_html
- send_email_table_row
- send_button_to_html
- send_button_html
- send_email
- _is_self_enabled
- is_enabled
- _is_docx
- as_docx
- as_list
- ALExhibit
- ocrmypdf_task
- ALExhibitList
- ALExhibitDocument
- include_exhibit_cover_pages
- include_table_of_contents
- add_page_numbers
- has_addendum
- auto_labeler
- auto_ocr
- bates_prefix
- maximum_size
- maximum_size_per_doc
- suffix_to_append
- exhibits
- table_of_contents
- page_number_prefix
- page_number_digits
- page_number_area
- page_number_font_size
- page_number_offset_horizontal
- page_number_offset_vertical
- init
- _set_default_attributes
- has_overflow
- ocr_ready
- __getitem__
- as_list
- as_pdf
- has_broken_exhibits
- broken_exhibits
- as_docx
- ALTableDocument
- ALUntransformedDocument
- ALDocumentUpload
- unpack_dafilelist
json
mimetypes
os
re
escape
Any
Dict
List
Literal
Union
Callable
Optional
TypedDict
Address
LatitudeLongitude
log
DADict
DAList
DAObject
DAFile
DAFileCollection
DAFileList
DALazyTemplate
defined
pdf_concatenate
zip_file
DAOrderedDict
background_action
action_button_html
include_docx_template
user_logged_in
user_info
send_email
docx_concatenate
get_config
space_to_underscore
DAStaticFile
alpha
showifdef
word
DAError
pdf_to_pdfa
wrap
floor
subprocess
pikepdf
Tuple
secrets
string
__all__
DEBUG_MODE
_CacheableDocumentTitle Objects
class _CacheableDocumentTitle(TypedDict)
title: str
CacheableDocument Objects
class CacheableDocument(_CacheableDocumentTitle)
Rendered title and the available download formats for a document.
download_filename: str
pdf: DAFile
docx: DAFile
original: Union[DAFile, DAFileList, DAFileCollection]
random_suffix
def random_suffix(length: int = 8) -> str
Return a random string for use in unique IDs.
Note: this is powerful enough for the expected usecase of distinguishing a few HTML elements from each other, but not cryptographically secure or as strong as a true GUID.
Arguments
lengthint - The length of the random string to generate. Defaults to 8.
Returns
str- A random string of lowercase letters and digits.
Example
Import random_suffix explicitly from
docassemble.AssemblyLine.al_document before using this example.
In an interview code block:
code: |
download_id = random_suffix(length=8)
base_name
def base_name(filename: str) -> str
Extracts the base name of a file without its extension.
Arguments
filenamestr - The full name of the file.
Returns
str- The base name of the file without its extension.
Example
Import base_name explicitly from
docassemble.AssemblyLine.al_document before using this example.
In an interview code block:
code: |
document_name = base_name("petition.pdf")
label
def label(dictionary: dict) -> str
Return the value of the first dictionary item.
Given a dictionary like: {"some_attribute":"Some label"}, this function returns the value of the first
dictionary item. Useful for working with the columns method of an ALAddendumField.
Arguments
dictionarydict - The dictionary to extract the value from.
Returns
str- The value of the first dictionary item or an empty string if not found.
Example
In an interview code block:
code: |
column_heading = label({"name": "Full name"})
key
def key(dictionary: dict) -> str
Return the key of the first dictionary item.
Given a dictionary like: {"some_attribute":"Some label"}, this function returns the key of the first
dictionary item. Useful for working with the columns method of an ALAddendumField.
Arguments
dictionarydict - The dictionary to extract the key from.
Returns
str- The key of the first dictionary item or an empty string if not found.
Example
In an interview code block:
code: |
column_attribute = key({"name": "Full name"})
safeattr
def safeattr(object: Any, key: str) -> str
Safely retrieve an attribute or key value from an object.
Arguments
objectAny - The object (which could be a dict, DADict, or DAObject) from which to retrieve the value.keystr - The key or attribute name.
Returns
str- The retrieved value or an empty string if not found or if an error occurred.
Notes
The location attribute of an Address object or any LatitudeLongitude attribute of a DAObject is always skipped.
Example
Show an email address only if it is already defined:
In question or Markdown attachment text (Mako):
${ safeattr(users[0], "email") }
In a DOCX template (Jinja2):
{{ safeattr(users[0], "email") }}
html_safe_str
def html_safe_str(the_string: str) -> str
Convert a string into a format that's safe for use as an HTML class or ID.
Arguments
the_stringstr - The string to be converted.
Returns
str- A string that's safe for use as an HTML class or ID.
Example
Import html_safe_str explicitly from
docassemble.AssemblyLine.al_document before using this example.
In an interview code block:
code: |
html_id = html_safe_str("Your documents")
_javascript_href
def _javascript_href(function_name: str, *args: Any) -> str
Build a JavaScript URL that is safe to use in an HTML href attribute.
table_row
def table_row(title: str, button_htmls: List[str] = []) -> str
Generate an HTML row string for an AL document-styled table.
Arguments
titlestr - The title to display in the row.button_htmlsList[str], optional - A list of HTML strings representing buttons. Defaults to an empty list.
Returns
str- An HTML string representing a row in an AL document-styled table.
Example
Import table_row explicitly from
docassemble.AssemblyLine.al_document before using this example.
Add a row with a download button in question text (Mako):
${ table_row("Petition", [action_button_html(petition.as_pdf().url_for(attachment=True), label="Download", icon="download")]) }
pdf_page_parity
def pdf_page_parity(pdf_path: str) -> Literal["even", "odd"]
Count the number of pages in the PDF and return "even" if it is divisible by 2 and "odd" if it is not divisible by 2.
Arguments
pdf_pathstr - Path to the PDF in the filesystem.
Returns
Literal["even", "odd"]: The parity of the number of pages in the PDF.
Example
Import pdf_page_parity explicitly from
docassemble.AssemblyLine.al_document before using this example.
In an interview code block:
code: |
page_parity = pdf_page_parity(petition.as_pdf().path())
add_blank_page
def add_blank_page(pdf_path: str) -> None
Add a blank page to the end of a PDF.
Arguments
pdf_pathstr - Path to the PDF in the filesystem.
Example
Import add_blank_page explicitly from
docassemble.AssemblyLine.al_document before using this example.
In an interview code block:
code: |
combined_pdf = al_user_bundle.as_pdf()
add_blank_page(combined_pdf.path())
ALAddendumField Objects
class ALAddendumField(DAObject)
Represents a field with attributes determining its display in an addendum, typically for PDF templates.
The field can manage items that are either strings or list-like structures. Handling of dictionary overflow is not currently supported.
Attributes
-
field_namestr - The name of a docassemble variable that this object represents. -
overflow_triggerUnion[int, bool] - Specifies the limit after which the text is truncated and moved. to an addendum. If set toTrue, it will always overflow. If set toFalse, it will never overflow. An integer value represents the maximum character count before overflow. -
headersOptional[Dict[str, str]] - Mapping of attributes to their display labels for a table representation. Planned for future implementation. -
field_styleOptional[str] - Style of the field, can be one of ["list", "table", "string"]. Defaults to "string". Planned for future implementation.
Notes
The attributes headers and field_style are planned for future releases and are not currently implemented.
Example
On an ALDocument named petition with has_addendum=True, configure
the interview variable reasons to overflow after 640 characters:
code: |
petition.overflow_fields["reasons"].overflow_trigger = 640
petition.overflow_fields["reasons"].label = "Reasons for the request"
petition.overflow_fields.gathered = True
init
def init(*pargs, **kwargs) -> None
Standard DAObject init method.
Arguments
*pargs- Positional arguments.**kwargs- Keyword arguments.
Example
Docassemble calls init() automatically during object creation.
See the class example for the rest of the setup.
code: |
petition.overflow_fields["reasons"].overflow_trigger = 640
overflow_value
def overflow_value(preserve_newlines: bool = False,
input_width: int = 80,
overflow_message: str = "",
preserve_words: bool = True) -> Any
Retrieve the overflow portion of a variable that exceeds the content of safe_value().
This function addresses both list-like objects and strings, ensuring that the returned overflow content adheres to whitespace preferences specified by the parameters.
Arguments
-
preserve_newlinesbool, optional - Determines the treatment of newline characters. If True, the returned string can contain single newline characters. Sequences of newline characters, including Windows-style "rn", will be reduced to a single "n". Double spaces will be replaced with a single space. If False, all whitespace, including newlines and tabs, will be replaced with a single space. Defaults to False. -
input_widthint, optional - The width of the input field or display area, used for determining overflow. Defaults to 80. -
overflow_messagestr, optional - Message indicating overflow in the safe value. Defaults to "". -
preserve_wordsbool, optional - If True, ensures words are not split between the main content and the overflow. Defaults to True.
Returns
Any- The portion of the variable exceeding the content safe for display, considered as overflow.
Example
With reasons = "I need more time to move." and
petition.overflow_fields["reasons"].overflow_trigger = 16:
Calling the field directly uses an empty overflow marker by default.
Input (Mako)
${ petition.overflow_fields["reasons"].overflow_value() }
Input (Jinja2)
{{ petition.overflow_fields["reasons"].overflow_value() }}
Output
to move.
max_lines
def max_lines(input_width: int = 80) -> int
Compute the maximum number of lines that can fit in the input given the specified input width.
Arguments
input_widthint, optional - The width of the input or display area. Defaults to 80.
Returns
int- The maximum number of lines accommodated by the input width.
Example
In an interview code block:
code: |
lines_that_fit = petition.overflow_fields["reasons"].max_lines()
value
def value() -> Any
Retrieve the complete value without considering overflow constraints.
This can be especially helpful in appendices where there's a desire to showcase the entire value without the necessity of toggling between various sections or pages.
Returns
Any- The whole value of the field, irrespective of overflow.
Example
Use after configuring the field in petition.overflow_fields.
In question or Markdown attachment text (Mako):
${ petition.overflow_fields["reasons"].value() }
In a DOCX template (Jinja2):
{{ petition.overflow_fields["reasons"].value() }}
has_overflow
def has_overflow(overflow_message: str = "",
input_width: int = 80,
preserve_newlines: bool = False,
_original_value: Optional[str] = None,
preserve_words: bool = True) -> bool
Return True only if the value's length exceeds the overflow trigger.
Arguments
overflow_messagestr - A short message to go on the page where text is cutoff.input_widthint - The width, in characters, of the input box. Defaults to 80.preserve_newlinesbool - Determines whether newlines are preserved in the "safe" text. Defaults to False, which means all newlines are removed. This allows more text to appear before being sent to the addendum._original_valueAny - for speed reasons, you can provide the full text and just use this. method to determine if the overflow trigger is exceeded. If no _original_value is provided, this method will determine it using the value_if_defined() method.preserve_wordsbool - If True, the algorithm will try to preserve whole words when. truncating the text. If False, the algorithm will truncate the text at the overflow trigger, regardless of whether it is in the middle of a word.
Returns
bool- True if the value's length exceeds the overflow trigger, False otherwise.
Example
In an interview code block:
code: |
document_has_overflow = petition.overflow_fields["reasons"].has_overflow()
original_or_overflow_message
def original_or_overflow_message(
overflow_message: str = "",
input_width: int = 80,
preserve_newlines: bool = False,
_original_value: Optional[str] = None,
preserve_words: bool = True) -> Union[str, List[Any]]
Return the original value if it is less than the overflow trigger (once processed), otherwise return the overflow message.
Unlike safe_value(), this will never output a partial value.
Arguments
overflow_messagestr - A short message to go on the page where text is cutoff.input_widthint - The width, in characters, of the input box. Defaults to 80.preserve_newlinesbool - Determines whether newlines are preserved in the "safe" text. Defaults to False, which means all newlines are removed. This allows more text to appear before being sent to the addendum._original_valueAny - for speed reasons, you can provide the full text and just use this. method to determine if the overflow trigger is exceeded. If no _original_value is provided, this method will determine it using the value_if_defined() method.preserve_wordsbool - If True, the algorithm will try to preserve whole words when. truncating the text. If False, the algorithm will truncate the text at the overflow trigger, regardless of whether it is in the middle of a word.
Returns
Union[str, List[Any]]: Either a string representing the overflow message or the original value.
Example
With reasons = "I need more time to move." and
petition.overflow_fields["reasons"].overflow_trigger = 16:
Calling the field directly uses an empty overflow marker by default.
Input (Mako)
${ petition.overflow_fields["reasons"].original_or_overflow_message(overflow_message="See addendum.") }
Input (Jinja2)
{{ petition.overflow_fields["reasons"].original_or_overflow_message(overflow_message="See addendum.") }}
Output
See addendum.
safe_value
def safe_value(overflow_message: str = "",
input_width: int = 80,
preserve_newlines: bool = False,
_original_value: Optional[str] = None,
preserve_words: bool = True) -> Union[str, List[Any]]
Return just the portion of the variable that heuristics suggest will fit in the specified overflow_trigger limit. If the value is not defined, return an empty string.
When preserve_newlines is True, the output will be limited to a number of lines, not a number
of characters. The max number of lines will be calculated as floor(self.overflow_trigger/input_width).
Therefore, it is important that input_width is a divisor of overflow_trigger.
Whitespace will be altered. If preserve_newlines is true, the return value may have newlines,
but double newlines and Windows style (rn) will be replaced with n. Double spaces will be replaced
with a single space.
If preserve_newlines is false, all whitespace, including newlines and tabs, will be replaced
with a single space.
Arguments
overflow_messagestr - A short message to go on the page where text is cutoff.input_widthint - The width, in characters, of the input box. Defaults to 80.preserve_newlinesbool - Determines whether newlines are preserved in the "safe" text. Defaults to False, which means all newlines are removed. This allows more text to appear before being sent to the addendum._original_valueOptional[str] - For speed reasons, you can provide the full text and just use this. method to determine if the overflow trigger is exceeded. If no_original_valueis provided, this method will determine it using thevalue_if_defined()method.preserve_wordsbool - Indicates whether words should be preserved in their entirety without being split.
Returns
Union[str, List[Any]]: The portion of the variable that fits within the overflow trigger.
Example
With reasons = "I need more time to move." and
petition.overflow_fields["reasons"].overflow_trigger = 16:
Calling the field directly uses an empty overflow marker by default.
Input (Mako)
${ petition.overflow_fields["reasons"].safe_value() }
Input (Jinja2)
{{ petition.overflow_fields["reasons"].safe_value() }}
Output
I need more time
value_if_defined
def value_if_defined() -> Any
Fetch the value of the designated field if it exists; otherwise, return an empty string.
This method ensures that the addendum does not inadvertently trigger docassemble's variable gathering.
Returns
Any- The value of the field if it exists, otherwise an empty string.
Example
Use after configuring the field in petition.overflow_fields.
In question or Markdown attachment text (Mako):
${ petition.overflow_fields["reasons"].value_if_defined() }
In a DOCX template (Jinja2):
{{ petition.overflow_fields["reasons"].value_if_defined() }}
__str__
def __str__()
Represent the ALAddendumField instance as a string.
Returns
str- The string representation of the value contained within the field.
columns
def columns(skip_empty_attributes: bool = True,
skip_attributes: Optional[set] = None) -> Optional[list]
Return a list of the attributes present within the object that would make sense to go in the table of an addendum.
If the headers attribute exists, this will be prioritized. Otherwise, the method will infer columns
from the first value in the list. Empty attributes and the complete attribute are typically ignored.
Arguments
skip_empty_attributesbool, optional - Determines whether empty attributes are included in the list. Defaults to True.skip_attributesOptional[set], optional - A set of attributes to ignore. Defaults to {"complete"}.
Returns
Optional[list]- A list of columns or None if no meaningful columns can be determined.
Notes
The "location" attribute of an Address object is always skipped in the column list.
Example
After configuring users as an overflow field on petition:
code: |
addendum_columns = petition.overflow_fields["users"].columns()
type
def type() -> str
Determine the data type of the contained value.
Categories:
- 'list': A simple list.
- 'object_list': A list containing dictionaries or objects.
- 'other': Any other type.
Returns
str- The type category of the value.
Example
After configuring users as an overflow field on petition:
code: |
field_kind = petition.overflow_fields["users"].type()
is_list
def is_list() -> bool
Check if the field contains a list value, whether it consists of objects, dictionaries, or standard values.
Returns
bool- True if the field contains a list, otherwise False.
Example
After configuring users as an overflow field on petition:
code: |
field_is_list = petition.overflow_fields["users"].is_list()
is_object_list
def is_object_list() -> bool
Determine if the field contains a list of dictionaries or objects.
Returns
bool- True if the field contains a list of dictionaries or objects, otherwise False.
Example
After configuring users as an overflow field on petition:
code: |
field_contains_people = petition.overflow_fields["users"].is_object_list()
overflow_markdown
def overflow_markdown() -> str
Generate a markdown representation of the overflow values.
The method returns either a markdown table or a bulleted list based on the structure of the values. This utility offers a standardized way to represent overflow content, though users might prefer to manually control the output's format.
Returns
str- A markdown representation of the overflow values.
Example
In question or Markdown attachment text (Mako):
${ petition.overflow_fields["users"].overflow_markdown() }
overflow_docx
def overflow_docx(
path: str = "docassemble.ALDocumentDict:data/templates/addendum_table.docx"
) -> Any
Insert a formatted table into a docx file, representing the overflow values.
This method provides a convenient way to add overflow content into a docx file, although it
doesn't offer formatting control. If more formatting flexibility is required, consider directly
fetching the overflow values using the overflow_value() method.
Arguments
pathstr, optional - Path to the template docx file to be used. Defaults to a predetermined path.
Returns
A docx template with the inserted table.
Example
In a DOCX addendum, give the path to your table template:
{{p petition.overflow_fields["users"].overflow_docx(path="addendum_table.docx") }}
ALAddendumFieldDict Objects
class ALAddendumFieldDict(DAOrderedDict)
A specialized dictionary for managing fields that may overflow in a document.
This class assists in organizing and controlling fields that might exceed a specified character limit in a document. It provides utilities to determine if an overflow condition exists and to correctly display fields in various contexts, ensuring only the necessary text is shown.
Adding a new entry will implicitly set the field_name attribute of the field
Attributes
stylestr - Determines the display behavior. If set to "overflow_only",. only the overflow text will be displayed.
Example
Configure the overflow fields on an ALDocument named petition:
code: |
petition.overflow_fields.from_list([
{"field_name": "reasons", "overflow_trigger": 640},
{"field_name": "users", "overflow_trigger": 2},
])
petition.overflow_fields.gathered = True
init
def init(*pargs, **kwargs) -> None
Standard DAObject init method.
Arguments
*pargs- Positional arguments.**kwargs- Keyword arguments.
Example
Docassemble calls init() automatically during object creation. The petition.overflow_fields attribute is an ALAddendumFieldDict.
See the class example for the rest of the setup.
objects:
- petition: ALDocument.using(title="Petition", filename="petition", enabled=True, has_addendum=True)
initializeObject
def initializeObject(*pargs, **kwargs) -> Any
Initializes a new dictionary entry and sets its field_name attribute.
When an entry is implicitly created, this method ensures the item knows
its own field name by setting the field_name attribute.
Arguments
*pargs- List of arguments to use to create the dict entry. The 0th arg is. also used to set thefield_nameattribute.**kwargs- List of keyword arguments used to create the dict entry.
Returns
The new dictionary entry created
Example
In an interview code block:
code: |
petition.overflow_fields.initializeObject("reasons", ALAddendumField)
petition.overflow_fields["reasons"].overflow_trigger = 640
from_list
def from_list(data: List[Dict]) -> None
Populate the dictionary using a list of field data.
Arguments
datalist - List of dictionaries containing ield data with keys "field_name". and "overflow_trigger".
Example
In an interview code block:
code: |
petition.overflow_fields.from_list([
{"field_name": "reasons", "overflow_trigger": 640},
{"field_name": "users", "overflow_trigger": 2},
])
petition.overflow_fields.gathered = True
defined_fields
def defined_fields(style: str = "overflow_only") -> list
Fetch a list of fields that are defined.
Arguments
stylestr, optional - If set to "overflow_only", only the fields with overflow values. will be returned. Defaults to "overflow_only".
Returns
list- List of defined fields based on the specified style.
Example
In an interview code block:
code: |
addendum_fields = petition.overflow_fields.defined_fields()
overflow
def overflow() -> list
Retrieve fields that have overflowed their character limits.
Returns
list- A list of fields with overflow values.
Example
In an interview code block:
code: |
overflow_fields = petition.overflow_fields.overflow()
has_overflow
def has_overflow() -> bool
Determine if any field within the dictionary exceeds its overflow limit.
Returns
bool- True if at least one field overflows, False otherwise.
Example
In an interview code block:
code: |
document_has_overflow = petition.overflow_fields.has_overflow()
DALazyAttribute Objects
class DALazyAttribute(DAObject)
Extends the DAObject to support attributes that are re-evaluated with every page load.
This is particularly helpful when there's a need to cache information on a per-page basis.
The implementation leverages Docassemble's object pickling process by customizing the
__getstate__ method that Pickle uses for serialization.
Attributes
instanceNamestr - A unique identifier for the object instance, if available.
__getstate__
def __getstate__() -> dict
Overrides the default method used by Pickle for object serialization.
If the object has an instanceName attribute, it is retained during serialization.
Otherwise, an empty dictionary is returned, ensuring that other attributes are not
persisted across page loads.
Returns
dict- A dictionary containing only theinstanceNameif it exists, or empty otherwise.
ALDocument Objects
class ALDocument(DADict)
A dictionary of attachments, either created by a DAFile or an attachment block. Typically there are three:
- The final version of a document with a signature. E.g., my_doc['final'].
- The preview version of a document with no signature. E.g., my_doc['preview'].
- An addendum of a document contained in the attribute
addendum. E.g.my_doc.addendum.
There is no limit to the number of keys, but the ALDocumentBundle class
expects at least a "final" key to exist, and the addendum attribute is
required if you desire to use PDF documents with text overflow. It is best
practice to use exactly the two keys "final" and "preview" and the attribute
"addendum". The "final" and "preview" documents will normally be the same
template, but with logic controlling the display of a particular section, such
as the signature.
Each form that an interview generates should get its own ALDocument object.
The "addendum" attribute can be handled in a generic object block. Multiple documents can use the same addendum template, with just the case caption varying.
ALDocuments are designed to be used contingently as part of ALDocumentBundle objects. Each ALDocument is considered to be "enabled" or "disabled" for a particular interview user's session. This allows you to always work with a single object representing all of the possible documents an interview can generate, and use encapsulated logic to trigger individual documents inclusion on the final download screen.
Attributes
filenamestr - name used for output PDF.titlestr - display name for the output PDF.enabledbool - if this document should be created. See examples.addendumDAFile | DAFileCollection - (optional) an attachment block.overflow_fieldsALAddendumField - (optional) ALAddendumFieldDict. instance. These values will be used to detect and handle overflow.has_addendumbool - (optional) Defaults to False. Set to True if the. document could have overflow, like for a PDF template.default_overflow_messagestr - The message appended to truncated text when it overflows. to the addendum. Defaults to"...". This is used as the fallback wheneveroverflow_message=Noneis passed to :meth:safe_value,. :meth:overflow_value, or :meth:original_or_overflow_message. Override per-document by settingmy_doc.default_overflow_message.suffix_to_appendstr - When the document key matches this value, it is appended to. the output filename to distinguish it from other versions. Defaults to"preview"so the preview version is saved as e.g.myDoc_preview.pdfwhile the final version is saved asmyDoc.pdf.
Notes
The enabled attribute should always be defined by a code block or the
objects block, because by default it is considered fresh on each page
load. If your interview logic requires that you directly ask the user
whether or not to include a document, you can use a single intermediate
variable that is posed to the interview user to work around this
limitation.
Examples
Define an always-enabled petition with preview and final versions. With
assembly_line.yml included, users[0] is the first ALIndividual in
the users ALPeopleList. This attachment uses Mako:
objects:
- petition: ALDocument.using(filename="petition.pdf", title="Petition", enabled=True)
event: review_petition
question: |
Review your petition before signing
subquestion: |
${ petition.as_pdf(key="preview") }
question: |
Do you want to include an additional statement?
fields:
- Include a statement: include_extra_document
datatype: yesnoradio
attachment:
variable name: extra_document[i]
docx template file: extra_document.docx
For a PDF template with a limited-size text field, configure overflow
and define an addendum. In this example, reasons is a gathered text
answer, and reasons_field is the field name in petition.pdf, stored
in your package's data/templates directory:
objects:
- petition: ALDocument.using(filename="petition.pdf", title="Petition", enabled=True, has_addendum=True)
attachment:
variable name: petition[i]
pdf template file: petition.pdf
fields:
- reasons_field: ${ petition.safe_value("reasons") }
event: download
question: |
Download your instructions
subquestion: |
${ al_user_bundle.download_list_html() }
init
def init(*pargs, **kwargs) -> None
Standard DAObject init method.
Arguments
*pargs- Positional arguments.**kwargs- Keyword arguments.
Example
Docassemble calls init() automatically during object creation.
See the class example for the rest of the setup.
objects:
- instructions: ALStaticDocument.using(title="Instructions", filename="instructions.pdf", enabled=True)
__getitem__
def __getitem__(key)
Override to ensure 'final' and 'private' keys always exist and reference the same file.
Returns
ALStaticDocument- Returns self.
as_list
def as_list(key: str = "final", refresh: bool = True) -> List[DAStaticFile]
Get the document as a list.
Arguments
keystr - Key to access the document. Defaults to "final".refreshbool - Whether to refresh the document. Defaults to True.
Returns
List[DAStaticFile]- A list containing this document.
Example
In an interview code block:
code: |
document_files = instructions.as_list()
as_pdf
def as_pdf(key: str = "final",
pdfa: bool = False,
filename: str = "",
append_matching_suffix: bool = True,
refresh: bool = False) -> Union[DAStaticFile, DAFile]
Convert the document into PDF format.
Arguments
keystr - Key to access the document. Defaults to "final".pdfabool - Whether to return the document in PDF/A format. Defaults to False.filenamestr - Name for the converted file. Defaults to the original filename.append_matching_suffixbool - Whether to append a matching suffix to the filename. Defaults to True.refreshbool - Whether to refresh the document. Defaults to False.
Returns
Union[DAStaticFile, DAFile]: The document in PDF format.
Example
In question text (Mako):
${ instructions.as_pdf() }
as_docx
def as_docx(
key: str = "final",
refresh: bool = True,
append_matching_suffix: bool = False) -> Union[DAStaticFile, DAFile]
Convert the document into DOCX format, if possible. If not, return as PDF.
Arguments
keystr - Key to access the document. Defaults to "final".refreshbool - Whether to refresh the document. Defaults to True.append_matching_suffixbool - Not used for static documents. They remain unchanged.
Returns
Union[DAStaticFile, DAFile]: The document in DOCX or PDF format.
Example
In question text (Mako):
${ instructions.as_docx() }
_is_docx
def _is_docx(key: str = "final") -> bool
Check if the document is in DOCX format.
Arguments
keystr - Key to access the document. Defaults to "final".
Returns
bool- True if the document is in DOCX format, otherwise False.
show
def show(**kwargs) -> DAFile
Display the document.
This method provides a workaround for problems generating thumbnails.
Arguments
**kwargs- Args to pass to DAFile's show function.
Returns
DAFile- Displayable version of the document.
Example
In question text (Mako):
${ instructions.show() }
is_enabled
def is_enabled(**kwargs) -> bool
Check if the document is enabled.
Arguments
**kwargs- Unused (for signature compatibility only).
Returns
bool- True if the document is enabled, otherwise False.
Example
In an interview code block:
code: |
document_is_enabled = instructions.is_enabled()
ALDocumentBundle Objects
class ALDocumentBundle(DAList)
A collection of ALDocuments or nested ALDocumentBundles, represented as a DAList.
This class provides functionalities for grouping multiple documents or nested bundles in a specific order. For instance, you might want to bundle documents differently for the court, the user, and the opposing party. Each ALDocument within this bundle can be individually "enabled" or "disabled", which will determine its inclusion in the generated bundle.
A bundle can be output as a single merged PDF or as a list of individual documents. For nested bundles, each can be rendered as a merged PDF or a list of documents.
Attributes
filenamestr - The name of the output file (without extension).titlestr - The title of the bundle.enabledbool, optional - Determines if the bundle is active. Defaults to True.auto_gatherbool, optional - Automatically gathers attributes. Defaults to False.gatheredbool, optional - Specifies if attributes have been gathered. Defaults to True.default_parityOptional[Literal["even", "odd"]] - Default parity to enforce on the PDF. When set, :meth:as_pdfwill append a blank page if necessary to reach the desired. parity. Defaults toNone(no enforcement).suffix_to_appendstr - When the document key matches this value, it is appended to the. output filename to distinguish it from other versions. Defaults to"preview"so the preview bundle is saved as e.g.bundle_preview.pdfwhile the final is saved asbundle.pdf.view_labelDALazyTemplate - Template providing the label for "View" buttons in. :meth:download_list_html. Defined generically inql_baseline.yml; resolves to."View"(or its translation). Override by assigning a new template toyour_bundle.view_labelin your interview YAML.download_labelDALazyTemplate - Template providing the label for "Download" buttons in. :meth:download_list_html. Defined generically inql_baseline.yml; resolves to."Download"(or its translation).send_labelDALazyTemplate - Template providing the label for "Send" buttons in. :meth:download_list_html, :meth:send_email_table_row, and. :meth:send_button_to_html. Defined generically inql_baseline.yml; resolves to."Send"(or its translation).zip_labelDALazyTemplate - Template providing the label for the "Download all" zip. button in :meth:download_list_html. Defined generically inal_document.yml;. resolves to"Download all"(or its translation).full_pdf_labelDALazyTemplate - Template providing the label for the "Download as one. PDF" button in :meth:download_list_html. Defined generically in.al_document.yml; resolves to"Download as one PDF"(or its translation).send_email_templateDALazyTemplate - Template used as the default email subject and. body in :meth:send_emailwhentemplate=None. Defined generically in.al_document.yml. The subject defaults to"Your <document> document from <app> is ready"and the body to"Your document is attached. Visit <homepage> to learn more."Override by assigning a new template block toyour_bundle.send_email_templatein your interview YAML.get_email_copyDALazyTemplate - Template providing the header text for the email input. section rendered by :meth:send_button_html. Defined generically in.al_document.yml; resolves to"Get a copy of the documents in email"(or its translation).email_input_labelDALazyTemplate - Template providing the label for the email input field in :meth:send_button_html. Defined generically inql_baseline.yml; resolves to"Email"(or its translation).email_alt_textDALazyTemplate - Template providing the alt text for the email input field. Defined generically inql_baseline.yml; resolves to"Email address for document"(or its translation).include_editable_documentsDALazyTemplate - Template providing the label for the. "include editable copy" checkbox in :meth:send_button_html. Defined generically. inal_document.yml; resolves to"Include an editable copy"(or its translation).add_page_numbersbool - IfTrue, Bates-style page numbers are stamped onto the. merged PDF produced by :meth:as_pdf. Defaults toFalse.page_number_prefixstr - Text prepended to each stamped page number (e.g."EX-"). Defaults to"".page_number_startint - The first page number used when stamping page numbers. Defaults to1.page_number_digitsint - Minimum number of digits in each stamped page number;. shorter numbers are left-padded with zeros. Defaults to5.page_number_areaOptional[str] - Location on the page where numbers are stamped. Accepted values:"TOP_LEFT","TOP_RIGHT","BOTTOM_LEFT",."BOTTOM_RIGHT". Defaults toNone(bottom-right).page_number_font_sizefloat - Font size in points for stamped page numbers. Defaults to10.page_number_offset_horizontalfloat - Horizontal inset in pixels from the nearest. page edge for stamped page numbers. Defaults to15.page_number_offset_verticalfloat - Vertical inset in pixels from the nearest page. edge for stamped page numbers. Defaults to15.
Example
After defining petition and instructions as documents, add them
to the bundle and display download and email controls:
objects:
- al_user_bundle: ALDocumentBundle.using(elements=[petition, instructions], filename="user_bundle.pdf", title="Your documents", enabled=True)
objects:
- exhibit_attachment: ALExhibitDocument.using(title="Exhibits", filename="exhibits" )
objects:
- al_user_bundle: ALDocumentBundle.using(elements=[my_instructions, my_main_attachment, exhibit_attachment], filename="user_bundle.pdf", title="All forms to download for your records")
Example of using a custom label function, https://docassemble.org/docs/functions.html#item_label:
table: people_table.table
rows: users
columns:
- Name: row_item.name_full()
- Address: row_item.address.on_one_line()
code: |
supporting_document["final"] = uploaded_file
init
def init(*pargs, **kwargs) -> None
Standard DAObject init method.
Arguments
*pargs- Positional arguments.**kwargs- Keyword arguments.
Example
Docassemble calls init() automatically during object creation.
See the class example for the rest of the setup.
objects:
- supporting_document: ALUntransformedDocument.using(title="Supporting document", filename="supporting_document", enabled=True)
has_overflow
def has_overflow() -> bool
Check for overflow in the document.
For compatibility with ALDocument. Untransformed documents inherently don't have overflow.
Returns
bool- Always False for this implementation.
Example
In an interview code block:
code: |
document_has_overflow = supporting_document.has_overflow()
as_list
def as_list(key: str = "final",
refresh: bool = True,
**kwargs) -> List[DAFile]
Retrieve the document as a list.
Arguments
keystr - Identifier key for the document. Default is "final".refreshbool - If True, the document list will be refreshed. Default is True.
Returns
List[DAFile]- A list containing the document.
Example
In an interview code block:
code: |
document_files = supporting_document.as_list()
as_pdf
def as_pdf(key: str = "final",
refresh: bool = True,
pdfa: bool = False,
append_matching_suffix: bool = True,
**kwargs) -> DAFile
Fetch the document in its original form, without any transformations.
This method is primarily for duck-typing compatibility with ALDocument.
Arguments
keystr - Identifier key for the document. Unused, but included for compatibility.refreshbool - If True, fetches the latest version of the document. Default is True.pdfabool - Unused argument for compatibility.append_matching_suffixbool - Unused argument for compatibility.
Returns
DAFile- The original, untransformed document.
Example
In question text (Mako):
${ supporting_document.as_pdf() }
as_docx
def as_docx(key: str = "final",
refresh: bool = True,
append_matching_suffix: bool = True) -> DAFile
Fetch the document in its original form, without any transformations.
This method is primarily for duck-typing compatibility with ALDocument.
Arguments
keystr - Identifier key for the document. Default is "final".refreshbool - If True, fetches the latest version of the document. Default is True.append_matching_suffixbool - Unused argument for compatibility.
Returns
DAFile- The original, untransformed document.
Example
In question text (Mako):
${ supporting_document.as_docx() }
ALDocumentUpload Objects
class ALDocumentUpload(ALUntransformedDocument)
Simplified class to handle uploaded documents, without any of the complexity of the ALExhibitDocument class.
Example
In an interview:
objects:
- supporting_document: ALDocumentUpload.using(title="Supporting document", filename="supporting_document", enabled=True)