athena-python-docx 0.44.0__tar.gz → 0.45.1__tar.gz

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.
Files changed (503) hide show
  1. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/PKG-INFO +1 -1
  2. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/__init__.py +1 -1
  3. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/_asset_token.py +46 -3
  4. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/_http.py +139 -2
  5. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/_http_doc.py +16 -1
  6. athena_python_docx-0.45.1/docx/_public_create.py +270 -0
  7. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/document.py +5 -1
  8. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/pyproject.toml +1 -1
  9. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_asset_tokens.py +99 -26
  10. athena_python_docx-0.45.1/tests/test_public_create.py +536 -0
  11. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/uv.lock +1 -1
  12. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/.gitignore +0 -0
  13. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/AGENTS.md +0 -0
  14. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/CLAUDE.md +0 -0
  15. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/DOCX_EXEC_LAB.md +0 -0
  16. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/README.md +0 -0
  17. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/_athena_extension.py +0 -0
  18. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/_batching.py +0 -0
  19. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/_buffer.py +0 -0
  20. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/_capabilities.py +0 -0
  21. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/_citations.py +0 -0
  22. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/_execution.py +0 -0
  23. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/_image_utils.py +0 -0
  24. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/_postproc.py +0 -0
  25. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/_proxy.py +0 -0
  26. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/_ptc.py +0 -0
  27. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/_references.py +0 -0
  28. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/_run_order.py +0 -0
  29. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/_table_styles.py +0 -0
  30. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/_timeouts.py +0 -0
  31. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/_tracked.py +0 -0
  32. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/_xml_text.py +0 -0
  33. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/api.py +0 -0
  34. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/blkcntnr.py +0 -0
  35. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/bookmarks.py +0 -0
  36. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/charts.py +0 -0
  37. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/client.py +0 -0
  38. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/commands.py +0 -0
  39. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/comments.py +0 -0
  40. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/drawing/__init__.py +0 -0
  41. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/enum/__init__.py +0 -0
  42. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/enum/base.py +0 -0
  43. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/enum/dml.py +0 -0
  44. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/enum/section.py +0 -0
  45. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/enum/shape.py +0 -0
  46. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/enum/style.py +0 -0
  47. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/enum/table.py +0 -0
  48. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/enum/text.py +0 -0
  49. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/errors.py +0 -0
  50. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/exceptions.py +0 -0
  51. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/fields.py +0 -0
  52. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/footnotes.py +0 -0
  53. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/image/__init__.py +0 -0
  54. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/image/exceptions.py +0 -0
  55. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/image/image.py +0 -0
  56. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/math.py +0 -0
  57. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/opc/__init__.py +0 -0
  58. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/opc/coreprops.py +0 -0
  59. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/oxml/__init__.py +0 -0
  60. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/revisions.py +0 -0
  61. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/sdt.py +0 -0
  62. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/section.py +0 -0
  63. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/session.py +0 -0
  64. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/settings.py +0 -0
  65. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/shape.py +0 -0
  66. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/shared.py +0 -0
  67. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/styles/__init__.py +0 -0
  68. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/styles/_table.py +0 -0
  69. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/styles/latent.py +0 -0
  70. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/styles/style.py +0 -0
  71. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/styles/styles.py +0 -0
  72. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/table.py +0 -0
  73. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/text/__init__.py +0 -0
  74. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/text/font.py +0 -0
  75. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/text/hyperlink.py +0 -0
  76. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/text/pagebreak.py +0 -0
  77. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/text/paragraph.py +0 -0
  78. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/text/parfmt.py +0 -0
  79. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/text/run.py +0 -0
  80. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/text/tabstops.py +0 -0
  81. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/toc.py +0 -0
  82. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/docx/typing.py +0 -0
  83. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/scripts/docx_exec_lab.py +0 -0
  84. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/scripts/docx_exec_lab_examples/fast_table_fill.py +0 -0
  85. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/scripts/docx_exec_lab_examples/find_replace_literal.py +0 -0
  86. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/scripts/docx_exec_lab_server.py +0 -0
  87. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/scripts/dump_wire_fixtures.py +0 -0
  88. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/scripts/release.sh +0 -0
  89. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/scripts/round_trip_smoke.py +0 -0
  90. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/scripts/smoke_test_block_not_found.py +0 -0
  91. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/scripts/validate_find_replace_asset.py +0 -0
  92. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/__init__.py +0 -0
  93. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/conftest.py +0 -0
  94. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/METHODOLOGY.md +0 -0
  95. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/README.md +0 -0
  96. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/__init__.py +0 -0
  97. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/ab_probe/__init__.py +0 -0
  98. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/ab_probe/agent_documents.py +0 -0
  99. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/ab_probe/default_style_run_formatting.py +0 -0
  100. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/ab_probe/header_footer_pictures.py +0 -0
  101. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/ab_probe/less_used_writes.py +0 -0
  102. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/ab_probe/merged_cell_identity.py +0 -0
  103. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/ab_probe/paragraph_text_setter.py +0 -0
  104. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/ab_probe/picture_runs.py +0 -0
  105. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/ab_probe/proxy_equality.py +0 -0
  106. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/ab_probe/return_types.py +0 -0
  107. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/ab_probe/xml_incompatible_text.py +0 -0
  108. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/ab_probe/zero_and_negative_indents.py +0 -0
  109. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/ab_probe_cases.py +0 -0
  110. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/ab_probe_runner.py +0 -0
  111. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/auto_gen_cases.py +0 -0
  112. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/binary_round_trip.py +0 -0
  113. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/cases.py +0 -0
  114. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/complex_cases.py +0 -0
  115. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/coverage_report.py +0 -0
  116. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/extract.py +0 -0
  117. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/extreme_cases.py +0 -0
  118. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/fake_session.py +0 -0
  119. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/firm_templates/README.md +0 -0
  120. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/firm_templates/__init__.py +0 -0
  121. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/firm_templates/_runner.py +0 -0
  122. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/firm_templates/extractor.py +0 -0
  123. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/firm_templates/test_pw_corpus.py +0 -0
  124. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/firm_templates/test_pw_research_digest.py +0 -0
  125. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/local_runner.py +0 -0
  126. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/mega_cases.py +0 -0
  127. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshot.py +0 -0
  128. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/01_basic_paragraph.json +0 -0
  129. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/02_multiple_headings.json +0 -0
  130. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/03_runs_with_formatting.json +0 -0
  131. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/04_font_name_and_size.json +0 -0
  132. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/05_font_color_rgb.json +0 -0
  133. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/06_font_character_properties.json +0 -0
  134. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/07_font_subscript_superscript.json +0 -0
  135. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/08_font_highlight.json +0 -0
  136. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/09_paragraph_alignment.json +0 -0
  137. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/100_table_negative_indexing.json +0 -0
  138. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/101_table_cells_flat_iteration.json +0 -0
  139. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/102_text_with_embedded_special_chars.json +0 -0
  140. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/104_core_properties_datetime.json +0 -0
  141. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/105_default_one_section.json +0 -0
  142. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/106_heading_paragraph_format.json +0 -0
  143. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/107_varying_row_heights.json +0 -0
  144. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/10_paragraph_indents.json +0 -0
  145. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/11_paragraph_spacing.json +0 -0
  146. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/12_paragraph_keep_options.json +0 -0
  147. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/13_paragraph_tab_stops.json +0 -0
  148. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/14_run_add_tab_and_break.json +0 -0
  149. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/15_run_add_break_page.json +0 -0
  150. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/16_paragraph_clear_and_insert_before.json +0 -0
  151. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/17_table_basic.json +0 -0
  152. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/18_table_cell_text.json +0 -0
  153. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/19_table_row_column_sizing.json +0 -0
  154. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/20_table_cell_vertical_alignment.json +0 -0
  155. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/21_table_alignment_and_autofit.json +0 -0
  156. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/22_table_cell_paragraphs_iteration.json +0 -0
  157. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/24_table_add_row_column.json +0 -0
  158. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/25_table_merge_cells.json +0 -0
  159. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/26_section_page_setup.json +0 -0
  160. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/27_section_margins.json +0 -0
  161. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/28_section_add_new.json +0 -0
  162. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/29_section_headers_linked.json +0 -0
  163. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/30_styles_iteration.json +0 -0
  164. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/31_styles_lookup_and_default.json +0 -0
  165. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/32_styles_add_paragraph_style.json +0 -0
  166. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/33_core_properties_set_and_get.json +0 -0
  167. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/34_inline_shapes_iterate_empty.json +0 -0
  168. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/35_full_report.json +0 -0
  169. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/36_replace_text_in_paragraph.json +0 -0
  170. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/37_iterate_runs_and_format_all_bold.json +0 -0
  171. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/38_font_all_properties.json +0 -0
  172. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/39_large_body_100_paragraphs.json +0 -0
  173. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/40_large_table_10x10.json +0 -0
  174. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/41_unicode_and_emoji.json +0 -0
  175. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/42_very_long_paragraph.json +0 -0
  176. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/43_paragraph_text_round_trip.json +0 -0
  177. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/44_paragraph_alignment_round_trip.json +0 -0
  178. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/45_cell_text_round_trip.json +0 -0
  179. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/46_run_text_setter_round_trip.json +0 -0
  180. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/47_font_size_round_trip.json +0 -0
  181. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/48_font_color_round_trip.json +0 -0
  182. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/49_resume_layout.json +0 -0
  183. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/50_multi_section_doc.json +0 -0
  184. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/52_iterate_everything.json +0 -0
  185. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/53_apply_style_to_paragraphs.json +0 -0
  186. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/54_empty_everything.json +0 -0
  187. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/55_single_character_runs.json +0 -0
  188. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/56_everything_in_one.json +0 -0
  189. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/57_runs_after_multiple_text_appends.json +0 -0
  190. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/58_modify_runs_in_place.json +0 -0
  191. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/59_indent_round_trip.json +0 -0
  192. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/60_space_round_trip.json +0 -0
  193. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/61_cell_paragraph_with_runs.json +0 -0
  194. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/62_many_cell_paragraphs.json +0 -0
  195. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/63_table_style_round_trip.json +0 -0
  196. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/64_many_sections.json +0 -0
  197. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/65_20x20_table_formatted.json +0 -0
  198. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/66_toc_like_structure.json +0 -0
  199. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/67_paragraph_insert_before_chain.json +0 -0
  200. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/68_invoice.json +0 -0
  201. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/69_newsletter.json +0 -0
  202. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/70_add_and_iterate_back.json +0 -0
  203. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/71_academic_paper.json +0 -0
  204. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/72_legal_contract.json +0 -0
  205. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/73_form_with_many_tables.json +0 -0
  206. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/74_paragraph_with_10_runs.json +0 -0
  207. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/75_paragraph_negative_first_line_indent.json +0 -0
  208. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/76_rgbcolor_from_string.json +0 -0
  209. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/77_length_unit_conversions.json +0 -0
  210. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/78_paragraph_copy_style.json +0 -0
  211. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/79_bulk_cell_formatting.json +0 -0
  212. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/80_apply_style_after_add_run.json +0 -0
  213. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/81_multi_page_with_breaks.json +0 -0
  214. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/82_add_text_on_existing_run.json +0 -0
  215. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/83_clear_then_repopulate_paragraph.json +0 -0
  216. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/84_table_reread_row_count.json +0 -0
  217. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/85_header_footer_access.json +0 -0
  218. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/86_font_read_unset_returns_none.json +0 -0
  219. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/87_500_paragraph_doc.json +0 -0
  220. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/88_mixed_content_iteration.json +0 -0
  221. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/89_alignment_clear_via_none.json +0 -0
  222. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/90_cell_add_paragraph_styled.json +0 -0
  223. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/91_many_small_tables.json +0 -0
  224. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/92_margins_every_section.json +0 -0
  225. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/93_font_bool_reads_after_set.json +0 -0
  226. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/94_page_break_before_paragraph.json +0 -0
  227. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/95_paragraph_hyperlinks_empty.json +0 -0
  228. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/96_paragraph_contains_page_break.json +0 -0
  229. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/97_document_styles_by_key.json +0 -0
  230. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/98_style_contains_check.json +0 -0
  231. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/99_run_add_picture_from_bytes.json +0 -0
  232. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/ex02_unicode_everywhere.json +0 -0
  233. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/ex03_1000_paragraphs.json +0 -0
  234. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/ex04_50x50_table.json +0 -0
  235. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/ex05_long_text_in_cell.json +0 -0
  236. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/ex06_hundred_tiny_runs.json +0 -0
  237. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/ex07_every_font_boolean.json +0 -0
  238. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/ex08_many_continuous_sections.json +0 -0
  239. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/ex09_many_tab_stops.json +0 -0
  240. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/ex10_complex_bom.json +0 -0
  241. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/ex11_banded_rows_formatting.json +0 -0
  242. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/ex12_section_reconfigure.json +0 -0
  243. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/ex13_cell_with_10_paragraphs.json +0 -0
  244. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/ex14_styled_report_table.json +0 -0
  245. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/ex15_paragraph_all_format_props.json +0 -0
  246. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/ex16_runs_interleaved_with_breaks.json +0 -0
  247. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/ex17_all_break_kinds.json +0 -0
  248. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/ex18_read_back_large_doc.json +0 -0
  249. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/ex19_mutate_all_runs.json +0 -0
  250. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/ex20_kitchen_sink_v2.json +0 -0
  251. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/mega01_book_chapter.json +0 -0
  252. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/mega02_research_proposal.json +0 -0
  253. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/mega03_financial_statement.json +0 -0
  254. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/mega04_recipe_card.json +0 -0
  255. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/mega05_user_manual.json +0 -0
  256. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/mega06_complex_newsletter.json +0 -0
  257. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/mega07_budget_spreadsheet.json +0 -0
  258. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/mega08_product_catalog.json +0 -0
  259. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/mega09_signed_contract.json +0 -0
  260. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/mega10_api_documentation.json +0 -0
  261. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/rw01_official_quickstart.json +0 -0
  262. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/rw02_paragraph_style_list.json +0 -0
  263. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/rw03_character_formatting.json +0 -0
  264. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/rw04_section_page_setup.json +0 -0
  265. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/rw05_toc_pattern.json +0 -0
  266. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/rw06_meeting_minutes.json +0 -0
  267. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/rw07_dense_formatting_demo.json +0 -0
  268. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/rw08_table_merged_header.json +0 -0
  269. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/rw09_bulk_run_iteration.json +0 -0
  270. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/rw10_colored_grid_table.json +0 -0
  271. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/rw11_header_text.json +0 -0
  272. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/rw12_first_page_footer.json +0 -0
  273. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/rw13_even_page_header.json +0 -0
  274. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/rw15_paragraph_style_instance.json +0 -0
  275. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/rw16_header_footer_tables.json +0 -0
  276. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/rw17_header_letterhead_filled.json +0 -0
  277. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/rw18_header_table_properties.json +0 -0
  278. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/rw19_header_table_rows_columns.json +0 -0
  279. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/op_snapshots/rw20_header_table_merges.json +0 -0
  280. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/ours_spec.json +0 -0
  281. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/parity_crawl.py +0 -0
  282. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/parity_diff.json +0 -0
  283. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/real_world_cases.py +0 -0
  284. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/round_trip_tests.py +0 -0
  285. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/stock_spec.json +0 -0
  286. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fidelity/test_e2e_against_staging.py +0 -0
  287. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fixtures/field_reads.json +0 -0
  288. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fixtures/note_reference_reads.json +0 -0
  289. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fixtures/ruby_reads.json +0 -0
  290. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/fixtures/symbol_reads.json +0 -0
  291. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/live/__init__.py +0 -0
  292. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/live/baseline.json +0 -0
  293. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/live/fixture_scripts.py +0 -0
  294. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/live/reader.py +0 -0
  295. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/live/runner.py +0 -0
  296. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/live/sdk_driver.py +0 -0
  297. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/live/stock_driver.py +0 -0
  298. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/live/test_live_runner.py +0 -0
  299. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/parity/README.md +0 -0
  300. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/parity/__init__.py +0 -0
  301. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/parity/baseline_gaps.json +0 -0
  302. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/parity/compare.py +0 -0
  303. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/parity/intentional_deviations.json +0 -0
  304. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/parity/introspect.py +0 -0
  305. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/parity/reports/GAP_ANALYSIS.md +0 -0
  306. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/parity/reports/gap_report.json +0 -0
  307. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/parity/run_parity.py +0 -0
  308. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/parity/snapshots/athena_latest.json +0 -0
  309. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/parity/snapshots/upstream_python_docx_1.2.0.json +0 -0
  310. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/parity/test_parity_gap.py +0 -0
  311. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_add_section.py +0 -0
  312. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_add_section_extract_items.py +0 -0
  313. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_alignment_values.py +0 -0
  314. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_athena_extension_creates_session_open.py +0 -0
  315. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_athena_extensions_contract.py +0 -0
  316. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_athena_extensions_registry.py +0 -0
  317. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_batch_chunking.py +0 -0
  318. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_batching_perf.py +0 -0
  319. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_battery_cases.py +0 -0
  320. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_block_not_found_error.py +0 -0
  321. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_buffer.py +0 -0
  322. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_cell_add_paragraph_wire_shape.py +0 -0
  323. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_cell_add_table_not_supported.py +0 -0
  324. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_cell_borders_spec.py +0 -0
  325. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_cell_fastpath_runs.py +0 -0
  326. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_cell_inner_add_hyperlink_stash.py +0 -0
  327. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_cell_inner_add_run_via_cell_insert.py +0 -0
  328. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_cell_inner_format_stash.py +0 -0
  329. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_cell_inner_run_format_stash.py +0 -0
  330. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_cell_inner_run_guard.py +0 -0
  331. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_cell_merge.py +0 -0
  332. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_cell_nested_tables.py +0 -0
  333. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_cell_paragraphs_listed.py +0 -0
  334. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_cell_text_plain_fastpath.py +0 -0
  335. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_cell_text_replace_semantics.py +0 -0
  336. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_citations.py +0 -0
  337. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_collapsed_range_format.py +0 -0
  338. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_color_format_theme.py +0 -0
  339. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_command_dataclasses.py +0 -0
  340. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_commands.py +0 -0
  341. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_comment_paragraphs.py +0 -0
  342. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_comments.py +0 -0
  343. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_comments_first_read.py +0 -0
  344. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_content_control_value.py +0 -0
  345. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_core_properties.py +0 -0
  346. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_create_workspace.py +0 -0
  347. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_document_asset_id_property.py +0 -0
  348. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_document_clear.py +0 -0
  349. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_document_create.py +0 -0
  350. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_document_create_from_template.py +0 -0
  351. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_document_factory_validation.py +0 -0
  352. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_document_settings_session_open.py +0 -0
  353. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_docx_exec_lab.py +0 -0
  354. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_docx_exec_lab_server.py +0 -0
  355. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_drawing_image.py +0 -0
  356. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_e2e_partial_failure_cascade.py +0 -0
  357. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_empty_hyperlinks.py +0 -0
  358. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_enum_parity.py +0 -0
  359. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_execution_scope.py +0 -0
  360. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_export_docx_clean.py +0 -0
  361. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_export_rescue_anchors.py +0 -0
  362. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_field_reads_python_docx_parity.py +0 -0
  363. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_field_refresh.py +0 -0
  364. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_field_runs.py +0 -0
  365. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_find_replace_session_open.py +0 -0
  366. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_flushed_write_failures.py +0 -0
  367. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_http_transport.py +0 -0
  368. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_hyperlink_coalescing.py +0 -0
  369. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_image_url_data_uri.py +0 -0
  370. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_inline_page_break.py +0 -0
  371. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_inline_shape_alt_text.py +0 -0
  372. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_inline_shape_size.py +0 -0
  373. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_inline_shape_type.py +0 -0
  374. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_inline_shapes_floating.py +0 -0
  375. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_insert_deferred.py +0 -0
  376. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_iter_inner_content.py +0 -0
  377. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_latent_style_writes.py +0 -0
  378. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_line_clear_break.py +0 -0
  379. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_list_styles.py +0 -0
  380. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_listed_paragraph_reads.py +0 -0
  381. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_literal_no_break_hyphens.py +0 -0
  382. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_literal_soft_hyphens.py +0 -0
  383. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_merged_cell_identity.py +0 -0
  384. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_merged_cell_secondary_slot.py +0 -0
  385. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_merged_cells.py +0 -0
  386. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_missing_modules.py +0 -0
  387. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_nested_table_refused.py +0 -0
  388. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_note_reference_reads_python_docx_parity.py +0 -0
  389. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_oxml_shim.py +0 -0
  390. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_page_break.py +0 -0
  391. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_paragraph_delete.py +0 -0
  392. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_paragraph_indent_reads.py +0 -0
  393. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_paragraph_runs_hyperlinks.py +0 -0
  394. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_paragraph_text_empty_run.py +0 -0
  395. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_paragraph_text_len_cache.py +0 -0
  396. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_parfmt_clears.py +0 -0
  397. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_parity_misc.py +0 -0
  398. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_parity_round2.py +0 -0
  399. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_partial_failure_cascade.py +0 -0
  400. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_pdf_export_and_page_renders.py +0 -0
  401. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_phase_a_behavior.py +0 -0
  402. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_phase_b_headers_footers.py +0 -0
  403. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_phase_c_tables.py +0 -0
  404. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_positional_cell_id.py +0 -0
  405. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_postproc_cell_format_rewrite.py +0 -0
  406. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_postproc_cell_run_format_rewrite.py +0 -0
  407. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_postproc_ref_restore.py +0 -0
  408. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_pr19766_review_fixes.py +0 -0
  409. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_proxy_equality.py +0 -0
  410. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_ptc.py +0 -0
  411. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_python_docx_api_parity.py +0 -0
  412. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_read_run_ranges.py +0 -0
  413. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_rendered_page_breaks.py +0 -0
  414. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_repeated_node_read.py +0 -0
  415. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_restart_numbering.py +0 -0
  416. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_revisions.py +0 -0
  417. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_round_trip_smoke_script.py +0 -0
  418. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_ruby_reads_python_docx_parity.py +0 -0
  419. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_run_add_picture_anchor.py +0 -0
  420. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_run_break_inner_content.py +0 -0
  421. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_run_edges.py +0 -0
  422. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_run_formatting_wire.py +0 -0
  423. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_run_identity.py +0 -0
  424. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_run_later_runs.py +0 -0
  425. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_run_mark_inheritance.py +0 -0
  426. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_run_page_number_blocks.py +0 -0
  427. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_run_table_style_objects.py +0 -0
  428. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_run_text_python_docx.py +0 -0
  429. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_run_text_refreshes_paragraph.py +0 -0
  430. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_run_unmodeled_toggles.py +0 -0
  431. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_sdk_reads_served.py +0 -0
  432. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_section_read_lengths.py +0 -0
  433. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_sections_empty_list.py +0 -0
  434. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_add_paragraph_style.py +0 -0
  435. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_add_picture.py +0 -0
  436. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_add_run.py +0 -0
  437. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_cell_add_paragraph.py +0 -0
  438. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_comments_add_comment.py +0 -0
  439. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_comments_get.py +0 -0
  440. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_document_audit.py +0 -0
  441. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_document_element.py +0 -0
  442. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_enum_section.py +0 -0
  443. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_font_audit.py +0 -0
  444. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_header_footer.py +0 -0
  445. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_hyperlink.py +0 -0
  446. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_inline_shape.py +0 -0
  447. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_insert_paragraph_before.py +0 -0
  448. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_misc.py +0 -0
  449. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_paragraph_strict.py +0 -0
  450. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_paragraph_style.py +0 -0
  451. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_paragraph_style_strict.py +0 -0
  452. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_parfmt.py +0 -0
  453. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_row_col_cell.py +0 -0
  454. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_run_add_break.py +0 -0
  455. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_run_bool_setters.py +0 -0
  456. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_run_style.py +0 -0
  457. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_run_style_strict.py +0 -0
  458. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_run_text.py +0 -0
  459. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_run_underline.py +0 -0
  460. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_section_audit.py +0 -0
  461. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_section_dimensions.py +0 -0
  462. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_section_onoff.py +0 -0
  463. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_settings.py +0 -0
  464. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_shared_audit.py +0 -0
  465. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_style.py +0 -0
  466. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_styles.py +0 -0
  467. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_table_audit.py +0 -0
  468. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_table_cell.py +0 -0
  469. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_table_dimensions.py +0 -0
  470. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_silent_stub_table_layout.py +0 -0
  471. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_smoke_integration.py +0 -0
  472. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_style_acceptance.py +0 -0
  473. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_style_delete.py +0 -0
  474. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_style_font.py +0 -0
  475. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_style_formatting_writes.py +0 -0
  476. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_style_metadata_writes.py +0 -0
  477. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_style_names.py +0 -0
  478. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_style_resolution.py +0 -0
  479. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_style_setters_contract.py +0 -0
  480. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_style_tab_stops.py +0 -0
  481. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_style_tab_stops_read.py +0 -0
  482. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_symbol_reads_python_docx_parity.py +0 -0
  483. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_tab_stop_writes.py +0 -0
  484. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_table_add_row_grid_row.py +0 -0
  485. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_table_anchors.py +0 -0
  486. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_table_clears.py +0 -0
  487. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_table_direction.py +0 -0
  488. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_table_length_reads.py +0 -0
  489. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_table_listing_reads.py +0 -0
  490. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_table_read_reuse.py +0 -0
  491. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_table_set_cell_perf.py +0 -0
  492. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_table_style_id_resolution.py +0 -0
  493. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_temporarily_unavailable.py +0 -0
  494. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_text_control_characters.py +0 -0
  495. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_tracked_revisions_offsets.py +0 -0
  496. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_unmapped_alignment_reads.py +0 -0
  497. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_uv_lock_version.py +0 -0
  498. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_validate_find_replace_asset_script.py +0 -0
  499. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_versioned_read_reuse.py +0 -0
  500. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_wire_contract.py +0 -0
  501. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_xml_attr_guard.py +0 -0
  502. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_xml_incompatible_text.py +0 -0
  503. {athena_python_docx-0.44.0 → athena_python_docx-0.45.1}/tests/test_zod_wire_contract.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: athena-python-docx
3
- Version: 0.44.0
3
+ Version: 0.45.1
4
4
  Summary: Drop-in replacement for python-docx that connects to Athena's DOCX Studio collaborative document stack
5
5
  Project-URL: Homepage, https://athenaintelligence.ai
6
6
  Author-email: Athena Intelligence <engineering@athenaintelligence.ai>
@@ -6,7 +6,7 @@ See CLAUDE.md for the API parity contract.
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
- __version__ = "0.44.0"
9
+ __version__ = "0.45.1"
10
10
 
11
11
  from docx.api import Document
12
12
  from docx._buffer import discard_all, flush_all
@@ -13,8 +13,17 @@ A call on an existing Word document reaches DOCX Studio with, in this order:
13
13
  4. otherwise ``ATHENA_API_KEY`` itself, as before.
14
14
 
15
15
  Creating a document (``Document.create``, its upload) keeps the key of 1, 2 or
16
- 4: a document that does not exist yet has no token. A token goes only to its
17
- own document's routes.
16
+ 4: a document that does not exist yet has no token. In case 3 Athena's public
17
+ API creates it instead (``docx._public_create``). A token goes only to its own
18
+ document's routes.
19
+
20
+ An Athena runtime credential (a computer's, a session VM's or a notebook
21
+ kernel's ``ATHENA_API_KEY``: ``athcomp_``, ``athsvm_``, ``athnb_``) is never
22
+ sent to DOCX Studio, which takes none, nor to Athena's older creation routes
23
+ outside its public API: a call that would send one (another document's routes,
24
+ an Athena without the studio-token route, no ``ATHENA_API_URL``, a create or an
25
+ upload Athena's public API cannot take) refuses before any request, naming what
26
+ to set (:func:`is_runtime_credential`).
18
27
 
19
28
  A token is minted once per (agora, key, asset, access) for the whole process,
20
29
  again 90 seconds before it expires, and once more when the studio answers 401.
@@ -28,7 +37,9 @@ or locally; both work.
28
37
 
29
38
  Athena's refusals (400, 401, 403, 404, 422) raise at once, without a retry. A
30
39
  deployment that signs no asset tokens answers 503: the client then uses the
31
- studio key when one is set, and otherwise raises an error that names it.
40
+ studio key when one is set, and otherwise raises an error that names it. An
41
+ Athena older than the route answers FastAPI's bare 404 (``{"detail": "Not
42
+ Found"}``): the client then sends ``ATHENA_API_KEY``, as before the route.
32
43
  """
33
44
 
34
45
  from __future__ import annotations
@@ -67,6 +78,16 @@ PUBLIC_API_PREFIX = "/api/v0"
67
78
  VIEW = "view"
68
79
  EDIT = "edit"
69
80
 
81
+ #: How the credentials Athena mints for a runtime begin: a computer's, a session
82
+ #: VM's and a notebook kernel's own ``ATHENA_API_KEY``. Only Athena's public API
83
+ #: takes one; a studio never does.
84
+ RUNTIME_CREDENTIAL_PREFIXES = ("athcomp_", "athsvm_", "athnb_")
85
+
86
+
87
+ def is_runtime_credential(key: str | None) -> bool:
88
+ """Whether ``key`` is a credential Athena minted for a runtime, which no studio takes."""
89
+ return bool(key) and str(key).startswith(RUNTIME_CREDENTIAL_PREFIXES)
90
+
70
91
  #: Minted again this long before Athena's ``expires_at_ms``.
71
92
  REFRESH_BEFORE_EXPIRY_SECONDS = 90.0
72
93
  #: The longest a token is held, whatever the local clock says (Athena's lifetime).
@@ -112,6 +133,26 @@ class SigningUnavailable(Exception):
112
133
  """Athena's 503: this deployment signs no asset tokens."""
113
134
 
114
135
 
136
+ class MintRouteMissing(Exception):
137
+ """A 404 with FastAPI's bare route-not-found body: the Athena at
138
+ ``ATHENA_API_URL`` predates the studio-token route (a self-hosted release
139
+ older than the SDK). The client then sends ``ATHENA_API_KEY``, as before."""
140
+
141
+
142
+ #: What FastAPI answers for a path no route matches. Athena's own 404 from the
143
+ #: studio-token route names the asset ("Asset not found."), so the two never mix.
144
+ _ROUTE_NOT_FOUND_BODY = {"detail": "Not Found"}
145
+
146
+
147
+ def _is_route_missing(response: requests.Response) -> bool:
148
+ if response.status_code != 404:
149
+ return False
150
+ try:
151
+ return bool(response.json() == _ROUTE_NOT_FOUND_BODY)
152
+ except ValueError:
153
+ return False
154
+
155
+
115
156
  class _TokenCache:
116
157
  """Process-wide tokens by (agora, key, asset, access), least recently used first."""
117
158
 
@@ -274,6 +315,8 @@ class TokenMinter:
274
315
  status = response.status_code
275
316
  if status == 503:
276
317
  raise SigningUnavailable(_detail(response) or "This deployment signs no asset tokens.")
318
+ if _is_route_missing(response):
319
+ raise MintRouteMissing(f"no studio-token route at {response.url}")
277
320
  detail = _detail(response)
278
321
  reason = f"(HTTP {status}{': ' + detail if detail else ''})"
279
322
  if status == 401:
@@ -45,13 +45,38 @@ def _resolve_api_key(api_key: str | None) -> str | None:
45
45
  makes. Both create paths land outside Athena's public API (docx-studio's
46
46
  ``/docs/empty``, agora's ``/api/docx-studio/assets``), and inside an Athena
47
47
  session VM or computer ``ATHENA_API_KEY`` is a credential only that public
48
- API (``/api/v0``) accepts. ``ATHENA_API_KEY`` stays the fallback for an
49
- environment that sets no studio key (local use with one personal key).
48
+ API (``/api/v0``) accepts: there (neither key set, ``ATHENA_API_URL`` set)
49
+ Athena's public API creates the document instead (``docx._public_create``).
50
+ ``ATHENA_API_KEY`` stays the fallback for an environment that sets no
51
+ studio key and no ``ATHENA_API_URL`` (local use with one personal key).
50
52
  The new document is owned by the user the key belongs to.
51
53
  """
52
54
  return api_key or os.environ.get(_API_KEY_ENV) or os.environ.get("ATHENA_API_KEY")
53
55
 
54
56
 
57
+ def _refuse_runtime_credential(*, key: str | None, action: str) -> None:
58
+ """Refuse, before any request, to send an Athena runtime credential where
59
+ Athena's public API could not take the call.
60
+
61
+ A computer's, session VM's or notebook's own ``ATHENA_API_KEY`` is accepted
62
+ only by Athena's public API (``/api/v0``). Reaching this point means that
63
+ API could not take the create (no ``ATHENA_API_URL``, or an Athena older
64
+ than its creation routes), and DOCX Studio and agora's older routes refuse
65
+ the credential.
66
+ """
67
+ from docx._asset_token import is_runtime_credential
68
+
69
+ if is_runtime_credential(key):
70
+ raise AuthenticationError(
71
+ f"Cannot {action}: ATHENA_API_KEY here is an Athena runtime credential (a "
72
+ "computer's, session's or notebook's own key), which only Athena's public "
73
+ "API accepts, and that API could not take this call (ATHENA_API_URL is "
74
+ "unset, or that Athena predates it). Set ATHENA_API_URL, or set "
75
+ "ATHENA_DOCX_API_KEY (or pass api_key=) to an Athena API key DOCX Studio "
76
+ "accepts.",
77
+ )
78
+
79
+
55
80
  def _derive_agora_base_url(docx_base_url: str) -> str | None:
56
81
  """Best-effort derive an Agora base URL from a docx-studio base URL.
57
82
 
@@ -137,12 +162,21 @@ def create_empty_document(
137
162
  "Pass base_url= to Document.create() or set the env var "
138
163
  '(e.g. ATHENA_DOCX_BASE_URL="https://docx-studio.prd.athenaintel.com").',
139
164
  )
165
+ created = _create_through_athena(
166
+ api_key=api_key,
167
+ name=name,
168
+ parent_folder_id=parent_folder_id,
169
+ workspace_id=workspace_id,
170
+ )
171
+ if created is not None:
172
+ return created
140
173
  if not resolved_key:
141
174
  raise AuthenticationError(
142
175
  f"Missing api_key and {_API_KEY_ENV} env var. "
143
176
  "Pass api_key= to Document.create() or set the env var "
144
177
  "(or set ATHENA_API_KEY as a fallback).",
145
178
  )
179
+ _refuse_runtime_credential(key=resolved_key, action="create the document on DOCX Studio")
146
180
 
147
181
  url: str = resolved_base.rstrip("/") + "/docs/empty"
148
182
  # The document is born as its creator's: its first write is signed as the
@@ -221,6 +255,44 @@ def create_empty_document(
221
255
  )
222
256
 
223
257
 
258
+ def _create_through_athena(
259
+ *,
260
+ api_key: str | None,
261
+ name: str | None,
262
+ parent_folder_id: str | None,
263
+ workspace_id: str | None,
264
+ ) -> CreateAssetResult | None:
265
+ """A new document Athena's public API made, or None for docx-studio's path.
266
+
267
+ Athena creates it when no ``api_key`` and no ``ATHENA_DOCX_API_KEY`` are set
268
+ and ``ATHENA_API_KEY`` and ``ATHENA_API_URL`` are (``docx._public_create``).
269
+ None otherwise, and when that Athena predates the public create.
270
+ """
271
+ from docx._public_create import (
272
+ PublicApi,
273
+ PublicCreateUnavailable,
274
+ create_word_document,
275
+ )
276
+
277
+ api = PublicApi.for_creation(api_key=api_key)
278
+ if api is None:
279
+ return None
280
+ try:
281
+ created = create_word_document(
282
+ api=api,
283
+ name=name,
284
+ parent_folder_id=parent_folder_id,
285
+ workspace_id=workspace_id or os.environ.get("ATHENA_WORKSPACE_ID"),
286
+ )
287
+ except PublicCreateUnavailable:
288
+ return None
289
+ return CreateAssetResult(
290
+ asset_id=created["asset_id"],
291
+ name=created["title"],
292
+ workspace_id=created["workspace_id"] or "",
293
+ )
294
+
295
+
224
296
  class UploadAssetResult(TypedDict):
225
297
  """Parsed response from the create-and-import upload flow."""
226
298
 
@@ -228,6 +300,58 @@ class UploadAssetResult(TypedDict):
228
300
  name: str
229
301
 
230
302
 
303
+ def _upload_through_athena(
304
+ *,
305
+ docx_path: str,
306
+ api_key: str | None,
307
+ name: str | None,
308
+ parent_folder_id: str | None,
309
+ workspace_id: str | None,
310
+ source_asset_id: str | None,
311
+ timeout: float,
312
+ ) -> UploadAssetResult | None:
313
+ """A document Athena made from the ``.docx`` at ``docx_path``, or None.
314
+
315
+ Athena's ``POST /api/v0/assets/create-from-file`` makes it in one request
316
+ when no ``api_key`` and no ``ATHENA_DOCX_API_KEY`` are set and
317
+ ``ATHENA_API_KEY`` and ``ATHENA_API_URL`` are (``docx._public_create``).
318
+ None otherwise, and when that Athena predates the route: the upload then
319
+ goes through agora's docx-studio bridge, as before.
320
+ """
321
+ from docx._public_create import (
322
+ PublicApi,
323
+ PublicCreateUnavailable,
324
+ create_word_document_from_file,
325
+ )
326
+
327
+ api = PublicApi.for_creation(api_key=api_key)
328
+ if api is None:
329
+ return None
330
+ if not os.path.exists(docx_path):
331
+ raise SessionError(f"DOCX file not found: {docx_path}")
332
+ if not docx_path.lower().endswith(".docx"):
333
+ raise SessionError(
334
+ f"Only .docx files are accepted by the upload endpoint (got {docx_path})",
335
+ )
336
+ title = name
337
+ if title is None:
338
+ base = os.path.basename(docx_path)
339
+ title = base[:-5] if base.lower().endswith(".docx") else base
340
+ try:
341
+ created = create_word_document_from_file(
342
+ api=api,
343
+ docx_path=docx_path,
344
+ title=title,
345
+ parent_folder_id=parent_folder_id,
346
+ workspace_id=workspace_id or os.environ.get("ATHENA_WORKSPACE_ID"),
347
+ source_asset_id=source_asset_id,
348
+ timeout=timeout,
349
+ )
350
+ except PublicCreateUnavailable:
351
+ return None
352
+ return UploadAssetResult(asset_id=created["asset_id"], name=created["title"])
353
+
354
+
231
355
  def upload_document(
232
356
  *,
233
357
  docx_path: str,
@@ -273,6 +397,18 @@ def upload_document(
273
397
  import base64
274
398
  import os
275
399
 
400
+ uploaded = _upload_through_athena(
401
+ docx_path=docx_path,
402
+ api_key=api_key,
403
+ name=name,
404
+ parent_folder_id=parent_folder_id,
405
+ workspace_id=workspace_id,
406
+ source_asset_id=source_asset_id,
407
+ timeout=timeout,
408
+ )
409
+ if uploaded is not None:
410
+ return uploaded
411
+
276
412
  resolved_docx_base: str | None = docx_base_url or os.environ.get(_BASE_URL_ENV)
277
413
  resolved_key: str | None = _resolve_api_key(api_key)
278
414
  resolved_agora_base: str | None = (
@@ -294,6 +430,7 @@ def upload_document(
294
430
  "Pass api_key= to Document.create() or set the env var "
295
431
  "(or set ATHENA_API_KEY as a fallback).",
296
432
  )
433
+ _refuse_runtime_credential(key=resolved_key, action="upload the document through agora")
297
434
 
298
435
  if not os.path.exists(docx_path):
299
436
  raise SessionError(f"DOCX file not found: {docx_path}")
@@ -47,9 +47,11 @@ from docx._asset_token import (
47
47
  EDIT,
48
48
  STUDIO_KEY_ENV,
49
49
  VIEW,
50
+ MintRouteMissing,
50
51
  SigningUnavailable,
51
52
  StudioToken,
52
53
  TokenMinter,
54
+ is_runtime_credential,
53
55
  )
54
56
  from docx._batching import call_abandoned, note_progress
55
57
  from docx._buffer import CommandBuffer, keep_reported_message
@@ -1127,6 +1129,10 @@ class HttpClient:
1127
1129
  token = minter.token(asset_id=asset_id, access=access)
1128
1130
  except SigningUnavailable as exc:
1129
1131
  return self._without_asset_tokens(asset_id=asset_id, reason=str(exc)), None
1132
+ except MintRouteMissing:
1133
+ # The Athena at ATHENA_API_URL predates the route: the key, as before.
1134
+ self._asset_tokens = None
1135
+ return self._api_key, None
1130
1136
  return token.token, (token, access)
1131
1137
 
1132
1138
  def _without_asset_tokens(self, *, asset_id: str, reason: str) -> str:
@@ -1150,6 +1156,15 @@ class HttpClient:
1150
1156
  is sent once more with a newly minted one: docx-studio refused it before
1151
1157
  acting on it, so nothing is applied twice."""
1152
1158
  bearer, grant = self._bearer(asset_id=asset_id, access=access)
1159
+ if grant is None and is_runtime_credential(bearer):
1160
+ raise AuthenticationError(
1161
+ f"DOCX Studio takes no Athena runtime credential, and this client "
1162
+ f"carries no token of {asset_id}. ATHENA_API_KEY here is a computer's, "
1163
+ "session's or notebook's own key, which only Athena's public API "
1164
+ "accepts. Open the document by its asset id (asset_...) with "
1165
+ "ATHENA_API_URL set, or set ATHENA_DOCX_API_KEY (or pass api_key=) to "
1166
+ "an Athena API key DOCX Studio accepts."
1167
+ )
1153
1168
  try:
1154
1169
  return send(bearer)
1155
1170
  except AuthenticationError as exc:
@@ -1160,7 +1175,7 @@ class HttpClient:
1160
1175
  minter.invalidate(token=refused, access=granted_access)
1161
1176
  try:
1162
1177
  fresh = minter.token(asset_id=asset_id, access=granted_access)
1163
- except SigningUnavailable:
1178
+ except (SigningUnavailable, MintRouteMissing):
1164
1179
  raise exc from None
1165
1180
  if fresh.token == refused.token:
1166
1181
  raise
@@ -0,0 +1,270 @@
1
+ """Creating a Word document through Athena's public API when no studio key is set.
2
+
3
+ ``Document.create()`` creates a document with the key every other call sends
4
+ (``api_key``, ``ATHENA_DOCX_API_KEY``, then ``ATHENA_API_KEY``), except when
5
+ neither of the first two is set and ``ATHENA_API_KEY`` and ``ATHENA_API_URL``
6
+ both are. That is a computer's or a session VM's scoped credential, which
7
+ Athena's public API (``/api/v0``) takes and neither docx-studio's ``/docs/empty``
8
+ nor agora's ``/api/docx-studio/assets`` does, so Athena creates the document:
9
+
10
+ * a document holding Athena's default template:
11
+ ``POST {ATHENA_API_URL}/api/v0/assets/create`` with
12
+ ``{"asset_type": "word_document", ...}``;
13
+ * a document holding a local ``.docx`` (``Document.create(docx=...)``):
14
+ ``POST {ATHENA_API_URL}/api/v0/assets/create-from-file`` (multipart ``file``,
15
+ query ``title``, ``parent_folder_id``, ``workspace_id``, ``source_asset_id``).
16
+
17
+ Both send ``X-API-KEY: $ATHENA_API_KEY`` and, inside an agent run, the run's
18
+ ``X-Athena-Session-Credential`` (``ATHENA_CLI_SESSION_KEY``), so the document's
19
+ first write records the run. Athena writes it with its own studio credential,
20
+ as the key's user, and answers once the document holds its content; its own
21
+ calls then carry a token minted for it (``docx._asset_token``).
22
+
23
+ An Athena older than these routes answers 422 naming the asset type, or
24
+ FastAPI's bare 404 or 405: the caller then creates through docx-studio and agora
25
+ with ``ATHENA_API_KEY``, as before (:class:`PublicCreateUnavailable`). Every
26
+ other refusal raises. A create is not resent once its request may have reached
27
+ Athena: a resend could make a second document.
28
+ """
29
+
30
+ from __future__ import annotations
31
+
32
+ import inspect
33
+ import os
34
+ from dataclasses import dataclass, field
35
+ from pathlib import Path
36
+ from typing import Any, TypedDict
37
+
38
+ import requests
39
+ from requests.adapters import HTTPAdapter
40
+ from urllib3.util.retry import Retry
41
+
42
+ from docx._asset_token import API_KEY_ENV, API_URL_ENV, STUDIO_KEY_ENV, public_api_base
43
+ from docx.errors import AuthenticationError, DocxError, SessionError
44
+
45
+ #: The credential the athena CLI's session VM exports for one ``execute`` call.
46
+ SESSION_CREDENTIAL_ENV = "ATHENA_CLI_SESSION_KEY"
47
+ #: The header Athena reads it from to name the agent run a write belongs to.
48
+ SESSION_CREDENTIAL_HEADER = "X-Athena-Session-Credential"
49
+ #: Athena waits for docx-studio's seed or import before it answers.
50
+ CREATE_TIMEOUT_SECONDS = 120.0
51
+ _DOCX_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
52
+ # What FastAPI answers for a path no route serves (404) or serves with other
53
+ # methods only (405: ``/assets/{asset_id}`` takes GET and PATCH).
54
+ _ROUTE_MISSING_BODIES = ({"detail": "Not Found"}, {"detail": "Method Not Allowed"})
55
+
56
+
57
+ class PublicCreateUnavailable(Exception):
58
+ """The Athena at ``ATHENA_API_URL`` predates creating a Word document through it."""
59
+
60
+
61
+ class CreatedDocument(TypedDict):
62
+ """What Athena answered: the new document's id, title and workspace."""
63
+
64
+ asset_id: str
65
+ title: str
66
+ workspace_id: str | None
67
+
68
+
69
+ @dataclass(frozen=True)
70
+ class PublicApi:
71
+ """Athena's public API, reached with ``ATHENA_API_KEY``."""
72
+
73
+ base: str
74
+ api_key: str = field(repr=False)
75
+
76
+ @classmethod
77
+ def for_creation(cls, *, api_key: str | None) -> PublicApi | None:
78
+ """The public API a new document is created through, or None.
79
+
80
+ None when the caller passed ``api_key`` or ``ATHENA_DOCX_API_KEY`` is
81
+ set (they create on docx-studio, as before), or when ``ATHENA_API_KEY``
82
+ or ``ATHENA_API_URL`` is unset.
83
+ """
84
+ if api_key or os.environ.get(STUDIO_KEY_ENV):
85
+ return None
86
+ athena_key = os.environ.get(API_KEY_ENV)
87
+ api_url = os.environ.get(API_URL_ENV)
88
+ if not athena_key or not api_url or not api_url.strip():
89
+ return None
90
+ return cls(base=public_api_base(api_url), api_key=athena_key)
91
+
92
+ def headers(self) -> dict[str, str]:
93
+ from docx import __version__
94
+
95
+ headers = {
96
+ "X-API-KEY": self.api_key,
97
+ "Accept": "application/json",
98
+ "User-Agent": f"athena-python-docx/{__version__}",
99
+ }
100
+ session_credential = os.environ.get(SESSION_CREDENTIAL_ENV)
101
+ if session_credential:
102
+ headers[SESSION_CREDENTIAL_HEADER] = session_credential
103
+ return headers
104
+
105
+
106
+ def _create_session() -> requests.Session:
107
+ """Connection retries only: a create that may have reached Athena is never resent."""
108
+ retry_kwargs: dict[str, Any] = {
109
+ "total": None,
110
+ "status": 0,
111
+ "connect": 2,
112
+ "read": 0,
113
+ "other": 0,
114
+ "backoff_factor": 0.5,
115
+ "allowed_methods": frozenset(["POST"]),
116
+ "raise_on_status": False,
117
+ }
118
+ if "backoff_max" in inspect.signature(Retry).parameters:
119
+ retry_kwargs["backoff_max"] = 5.0
120
+ session = requests.Session()
121
+ adapter = HTTPAdapter(max_retries=Retry(**retry_kwargs))
122
+ session.mount("http://", adapter)
123
+ session.mount("https://", adapter)
124
+ return session
125
+
126
+
127
+ def _json(response: requests.Response) -> Any:
128
+ try:
129
+ return response.json()
130
+ except ValueError:
131
+ return None
132
+
133
+
134
+ def _detail(body: Any, response: requests.Response) -> str:
135
+ """Athena's reason: ``detail`` as text, or the first validation message."""
136
+ detail = body.get("detail") if isinstance(body, dict) else None
137
+ if isinstance(detail, str):
138
+ return detail.strip()
139
+ if isinstance(detail, list) and detail and isinstance(detail[0], dict):
140
+ message = detail[0].get("msg")
141
+ if isinstance(message, str):
142
+ return message.strip()
143
+ return " ".join((response.text or "").split())[:200]
144
+
145
+
146
+ def _is_unavailable(*, status: int, body: Any) -> bool:
147
+ """An Athena that predates the route, or the ``word_document`` asset type."""
148
+ if status in (404, 405) and body in _ROUTE_MISSING_BODIES:
149
+ return True
150
+ if status != 422 or not isinstance(body, dict):
151
+ return False
152
+ errors = body.get("detail")
153
+ return isinstance(errors, list) and any(
154
+ isinstance(error, dict)
155
+ and "asset_type" in (error.get("loc") or [])
156
+ and "Unsupported asset type" in str(error.get("msg", ""))
157
+ for error in errors
158
+ )
159
+
160
+
161
+ def _created(response: requests.Response, *, what: str) -> CreatedDocument:
162
+ status = response.status_code
163
+ body = _json(response)
164
+ if _is_unavailable(status=status, body=body):
165
+ raise PublicCreateUnavailable(f"{response.url} answered HTTP {status}")
166
+ if status == 200 and isinstance(body, dict):
167
+ asset_id = body.get("asset_id")
168
+ title = body.get("title")
169
+ workspace_id = body.get("workspace_id")
170
+ if (
171
+ isinstance(asset_id, str)
172
+ and asset_id.startswith("asset_")
173
+ and isinstance(title, str)
174
+ and (workspace_id is None or isinstance(workspace_id, str))
175
+ ):
176
+ return CreatedDocument(asset_id=asset_id, title=title, workspace_id=workspace_id)
177
+ detail = _detail(body, response)
178
+ if status in (401, 403):
179
+ raise AuthenticationError(
180
+ f"Athena refused to create {what} with ATHENA_API_KEY (HTTP {status})"
181
+ f"{': ' + detail if detail else ''}",
182
+ )
183
+ if status == 200:
184
+ raise SessionError(f"Athena's answer to creating {what} is not one this SDK can use: {detail}")
185
+ raise DocxError(f"Athena could not create {what} (HTTP {status}){': ' + detail if detail else ''}")
186
+
187
+
188
+ def _post(
189
+ *,
190
+ session: requests.Session,
191
+ url: str,
192
+ what: str,
193
+ **kwargs: Any,
194
+ ) -> CreatedDocument:
195
+ try:
196
+ response = session.post(url, **kwargs)
197
+ except requests.RequestException as exc:
198
+ raise SessionError(f"Unable to reach Athena at {url} to create {what}: {exc}") from exc
199
+ try:
200
+ return _created(response, what=what)
201
+ finally:
202
+ response.close()
203
+
204
+
205
+ def create_word_document(
206
+ *,
207
+ api: PublicApi,
208
+ name: str | None,
209
+ parent_folder_id: str | None,
210
+ workspace_id: str | None,
211
+ ) -> CreatedDocument:
212
+ """Have Athena create a Word document holding its default template."""
213
+ payload: dict[str, str] = {"asset_type": "word_document"}
214
+ if name is not None:
215
+ payload["title"] = name
216
+ if parent_folder_id is not None:
217
+ payload["parent_folder_id"] = parent_folder_id
218
+ if workspace_id is not None:
219
+ payload["workspace_id"] = workspace_id
220
+ session = _create_session()
221
+ try:
222
+ return _post(
223
+ session=session,
224
+ url=f"{api.base}/assets/create",
225
+ what="a Word document",
226
+ json=payload,
227
+ headers=api.headers(),
228
+ timeout=CREATE_TIMEOUT_SECONDS,
229
+ )
230
+ finally:
231
+ session.close()
232
+
233
+
234
+ def create_word_document_from_file(
235
+ *,
236
+ api: PublicApi,
237
+ docx_path: str,
238
+ title: str,
239
+ parent_folder_id: str | None,
240
+ workspace_id: str | None,
241
+ source_asset_id: str | None,
242
+ timeout: float,
243
+ ) -> CreatedDocument:
244
+ """Have Athena create a Word document holding the ``.docx`` at ``docx_path``.
245
+
246
+ Athena answers once the file is imported, and leaves nothing behind when the
247
+ import fails.
248
+ """
249
+ params: dict[str, str] = {"title": title}
250
+ if parent_folder_id is not None:
251
+ params["parent_folder_id"] = parent_folder_id
252
+ if workspace_id is not None:
253
+ params["workspace_id"] = workspace_id
254
+ if source_asset_id is not None:
255
+ params["source_asset_id"] = source_asset_id
256
+ file_path = Path(docx_path)
257
+ session = _create_session()
258
+ try:
259
+ with file_path.open("rb") as handle:
260
+ return _post(
261
+ session=session,
262
+ url=f"{api.base}/assets/create-from-file",
263
+ what=f"a Word document from {file_path.name}",
264
+ params=params,
265
+ files={"file": (file_path.name, handle, _DOCX_CONTENT_TYPE)},
266
+ headers=api.headers(),
267
+ timeout=max(timeout, CREATE_TIMEOUT_SECONDS),
268
+ )
269
+ finally:
270
+ session.close()
@@ -282,7 +282,11 @@ class Document:
282
282
  api_key: Athena API key (PropelAuth user API key) or
283
283
  access token. Falls back to ``$ATHENA_DOCX_API_KEY``, then
284
284
  ``$ATHENA_API_KEY``, as every other call does; the upload path
285
- (``docx=``) sends the same key to agora.
285
+ (``docx=``) sends the same key to agora. With neither of the
286
+ first two set and both ``$ATHENA_API_KEY`` and
287
+ ``$ATHENA_API_URL`` set (a computer's or session VM's scoped
288
+ key), Athena's public API creates the document instead, from
289
+ the template or from ``docx`` (``docx._public_create``).
286
290
  parent_folder_id: Optional parent folder; defaults to
287
291
  the source document's folder when source_asset_id is set,
288
292
  otherwise workspace root.
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "athena-python-docx"
7
- version = "0.44.0"
7
+ version = "0.45.1"
8
8
  description = "Drop-in replacement for python-docx that connects to Athena's DOCX Studio collaborative document stack"
9
9
  readme = "README.md"
10
10
  license = "MIT"