athena-python-pptx 0.16.0__tar.gz → 0.16.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 (92) hide show
  1. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/CHANGELOG.md +8 -0
  2. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/PKG-INFO +1 -1
  3. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/__init__.py +1 -1
  4. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/client.py +13 -11
  5. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/presentation.py +41 -13
  6. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pyproject.toml +1 -1
  7. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/.gitignore +0 -0
  8. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/AGENTS.md +0 -0
  9. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/API_PARITY_REPORT.md +0 -0
  10. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/CLAUDE.md +0 -0
  11. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/DEV-GUIDE.md +0 -0
  12. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/PARITY_QUESTIONS.md +0 -0
  13. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/README.md +0 -0
  14. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/docs/API_PARITY_EXCEPTIONS.md +0 -0
  15. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/docs/athena-api.json +0 -0
  16. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/docs/athena-api.md +0 -0
  17. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/_athena_extension.py +0 -0
  18. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/_citations.py +0 -0
  19. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/_ptc.py +0 -0
  20. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/_references.py +0 -0
  21. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/_unsupported.py +0 -0
  22. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/action.py +0 -0
  23. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/batching.py +0 -0
  24. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/chart/__init__.py +0 -0
  25. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/chart/axis.py +0 -0
  26. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/chart/category.py +0 -0
  27. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/chart/chart.py +0 -0
  28. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/chart/data.py +0 -0
  29. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/chart/datalabel.py +0 -0
  30. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/chart/legend.py +0 -0
  31. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/chart/marker.py +0 -0
  32. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/chart/plot.py +0 -0
  33. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/chart/point.py +0 -0
  34. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/chart/series.py +0 -0
  35. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/chart/xlsx.py +0 -0
  36. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/commands.py +0 -0
  37. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/decorators.py +0 -0
  38. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/dml/__init__.py +0 -0
  39. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/dml/chtfmt.py +0 -0
  40. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/dml/color.py +0 -0
  41. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/dml/effect.py +0 -0
  42. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/dml/fill.py +0 -0
  43. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/dml/line.py +0 -0
  44. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/docgen.py +0 -0
  45. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/enum/__init__.py +0 -0
  46. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/enum/action.py +0 -0
  47. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/enum/chart.py +0 -0
  48. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/enum/dml.py +0 -0
  49. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/enum/lang.py +0 -0
  50. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/enum/shapes.py +0 -0
  51. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/enum/text.py +0 -0
  52. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/errors.py +0 -0
  53. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/exc.py +0 -0
  54. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/generated/__init__.py +0 -0
  55. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/generated/autoshape_types.py +0 -0
  56. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/kit.py +0 -0
  57. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/media.py +0 -0
  58. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/oxml/__init__.py +0 -0
  59. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/oxml/ns.py +0 -0
  60. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/package.py +0 -0
  61. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/parts/__init__.py +0 -0
  62. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/parts/_base.py +0 -0
  63. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/parts/chart.py +0 -0
  64. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/parts/coreprops.py +0 -0
  65. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/parts/embeddedpackage.py +0 -0
  66. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/parts/image.py +0 -0
  67. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/parts/media.py +0 -0
  68. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/parts/presentation.py +0 -0
  69. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/parts/slide.py +0 -0
  70. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/shapes/__init__.py +0 -0
  71. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/shapes/autoshape.py +0 -0
  72. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/shapes/base.py +0 -0
  73. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/shapes/connector.py +0 -0
  74. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/shapes/freeform.py +0 -0
  75. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/shapes/graphfrm.py +0 -0
  76. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/shapes/group.py +0 -0
  77. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/shapes/picture.py +0 -0
  78. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/shapes/placeholder.py +0 -0
  79. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/shapes/shapetree.py +0 -0
  80. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/shared.py +0 -0
  81. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/slide.py +0 -0
  82. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/slides.py +0 -0
  83. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/spec.py +0 -0
  84. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/table.py +0 -0
  85. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/text/__init__.py +0 -0
  86. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/text/fonts.py +0 -0
  87. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/text/layout.py +0 -0
  88. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/text/text.py +0 -0
  89. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/types.py +0 -0
  90. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/typing.py +0 -0
  91. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/units.py +0 -0
  92. {athena_python_pptx-0.16.0 → athena_python_pptx-0.16.1}/pptx/util.py +0 -0
@@ -2,6 +2,14 @@
2
2
 
3
3
  All notable changes to `athena-python-pptx` are documented in this file.
4
4
 
5
+ ## 0.16.1 — `Presentation.upload()` and `create(pptx=...)` report the deck they create
6
+
7
+ - `Presentation.upload()` emits the `CreatePresentation` tool-call event with
8
+ the new deck's id, as `Presentation.create()` and the docx and xlsx uploads
9
+ do. It emitted nothing, so a deck uploaded from sandbox code, including one
10
+ seeded from a brand template with `Presentation.create(pptx=...)`, showed no
11
+ creation card and never joined the Athena session's created assets.
12
+
5
13
  ## 0.16.0 — `Presentation.create()` makes 13.333" × 7.5" decks; `create(name=, title=)` titles the deck
6
14
 
7
15
  - **Behaviour change:** `Presentation.create()` makes a deck at PowerPoint's
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: athena-python-pptx
3
- Version: 0.16.0
3
+ Version: 0.16.1
4
4
  Summary: Drop-in replacement for python-pptx that connects to PPTX Studio for real-time collaboration
5
5
  Project-URL: Homepage, https://github.com/pptx-studio/python-sdk
6
6
  Project-URL: Documentation, https://docs.pptx-studio.com/sdk/python
@@ -327,7 +327,7 @@ def validate_all_touched() -> dict[int, list[str]]:
327
327
  return results
328
328
 
329
329
 
330
- __version__ = "0.16.0"
330
+ __version__ = "0.16.1"
331
331
 
332
332
  __all__ = [
333
333
  # Main entry point
@@ -138,6 +138,17 @@ def _poll_delays(poll_interval: float, max_attempts: int) -> Iterator[float]:
138
138
  delay = min(delay * 1.5, poll_interval)
139
139
 
140
140
 
141
+ def _upload_deck_name(*, file_path: str, name: Optional[str]) -> str:
142
+ """The name an upload gives its deck: ``name``, else the file's name
143
+ without a ``.pptx`` / ``.potx`` extension."""
144
+ if name is not None:
145
+ return name
146
+ base = os.path.basename(file_path)
147
+ if base.endswith(".pptx") or base.endswith(".potx"):
148
+ return base[:-5]
149
+ return base
150
+
151
+
141
152
  def _is_read_timeout(exc: BaseException) -> bool:
142
153
  """A response that did not arrive in time. With retries configured,
143
154
  requests reports a read timeout as a ConnectionError wrapping urllib3's
@@ -926,12 +937,7 @@ class Client:
926
937
  if not os.path.exists(file_path):
927
938
  raise FileNotFoundError(f"File not found: {file_path}")
928
939
 
929
- # Use filename as name if not provided
930
- if name is None:
931
- name = os.path.basename(file_path)
932
- # Remove extension
933
- if name.endswith(".pptx") or name.endswith(".potx"):
934
- name = name[:-5]
940
+ name = _upload_deck_name(file_path=file_path, name=name)
935
941
 
936
942
  # Step 1: Create deck to get presigned URL
937
943
  deck_info = self.create_deck(name)
@@ -1007,11 +1013,7 @@ class Client:
1007
1013
  if not os.path.exists(file_path):
1008
1014
  raise FileNotFoundError(f"File not found: {file_path}")
1009
1015
 
1010
- # Use filename as name if not provided
1011
- if name is None:
1012
- name = os.path.basename(file_path)
1013
- if name.endswith(".pptx") or name.endswith(".potx"):
1014
- name = name[:-5]
1016
+ name = _upload_deck_name(file_path=file_path, name=name)
1015
1017
 
1016
1018
  # Step 1: Create deck to get presigned URL
1017
1019
  deck_info = self.create_deck(name)
@@ -17,7 +17,7 @@ import warnings
17
17
 
18
18
  from ._athena_extension import athena_extension
19
19
  from .batching import CommandBuffer, batch_context
20
- from .client import Client, _hand_session_to_next_client
20
+ from .client import Client, _hand_session_to_next_client, _upload_deck_name
21
21
  from .commands import SetCoreProperties, SetPresentationSize, CopySlideFromDeck
22
22
  from .errors import AuthenticationError, RemoteError, UnsupportedFeatureError
23
23
  from .slides import SlideLayouts, SlideMasters, Slides
@@ -894,23 +894,51 @@ class Presentation:
894
894
  # Save changes
895
895
  prs.save("modified.pptx")
896
896
  """
897
+ from pptx import _ptc
898
+
897
899
  client = Client(base_url=base_url, api_key=api_key, prefer_user_key=True)
898
900
 
899
901
  # The presentation's client takes over this connection (closed here
900
902
  # when the upload or the open fails first).
901
903
  with _hand_session_to_next_client(client):
902
- if wait:
903
- kwargs: dict[str, Any] = {}
904
- if max_wait_seconds is not None:
905
- # Match the client's poll_interval default (0.5s) so callers
906
- # can think in seconds without remembering attempt math.
907
- from .client import DEFAULT_POLL_INTERVAL
908
-
909
- kwargs["max_attempts"] = max(1, int(max_wait_seconds / DEFAULT_POLL_INTERVAL))
910
- deck_id = client.upload_file(str(path), name=name, **kwargs)
911
- else:
912
- # Upload without waiting
913
- deck_id = client.upload_file_async(str(path), name=name)
904
+ # PTC: the upload creates a deck asset, so it wears the same card
905
+ # as ``create()`` and the docx/xlsx uploads. Agora adds a deck to
906
+ # the session's created assets only from this event. Scoped to the
907
+ # upload as in ``create()``: the open below emits its own
908
+ # ``OpenPresentation``.
909
+ call_id = _ptc.emit_begin(
910
+ "CreatePresentation",
911
+ {"name": _upload_deck_name(file_path=str(path), name=name)},
912
+ )
913
+ try:
914
+ if wait:
915
+ kwargs: dict[str, Any] = {}
916
+ if max_wait_seconds is not None:
917
+ # Match the client's poll_interval default (0.5s) so callers
918
+ # can think in seconds without remembering attempt math.
919
+ from .client import DEFAULT_POLL_INTERVAL
920
+
921
+ kwargs["max_attempts"] = max(
922
+ 1, int(max_wait_seconds / DEFAULT_POLL_INTERVAL)
923
+ )
924
+ deck_id = client.upload_file(str(path), name=name, **kwargs)
925
+ else:
926
+ # Upload without waiting
927
+ deck_id = client.upload_file_async(str(path), name=name)
928
+ except Exception as exc:
929
+ _ptc.emit_end(
930
+ call_id=call_id,
931
+ tool_name="CreatePresentation",
932
+ result={"ok": False, "error": str(exc)},
933
+ is_error=True,
934
+ )
935
+ raise
936
+ _ptc.emit_end(
937
+ call_id=call_id,
938
+ tool_name="CreatePresentation",
939
+ result={"ok": True, "assetId": deck_id},
940
+ is_error=False,
941
+ )
914
942
 
915
943
  prs = cls(deck_id=deck_id, base_url=base_url, api_key=api_key, auto_refresh=wait)
916
944
  _release_opened_slides(prs)
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "athena-python-pptx"
7
- version = "0.16.0"
7
+ version = "0.16.1"
8
8
  description = "Drop-in replacement for python-pptx that connects to PPTX Studio for real-time collaboration"
9
9
  readme = "README.md"
10
10
  license = "MIT"