pdfdancer-client-python 0.2.6__tar.gz → 0.2.8__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.

Potentially problematic release.


This version of pdfdancer-client-python might be problematic. Click here for more details.

Files changed (44) hide show
  1. {pdfdancer_client_python-0.2.6/src/pdfdancer_client_python.egg-info → pdfdancer_client_python-0.2.8}/PKG-INFO +1 -1
  2. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/pyproject.toml +1 -1
  3. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/src/pdfdancer/pdfdancer_v1.py +22 -10
  4. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/src/pdfdancer/types.py +0 -7
  5. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8/src/pdfdancer_client_python.egg-info}/PKG-INFO +1 -1
  6. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/src/pdfdancer_client_python.egg-info/SOURCES.txt +1 -0
  7. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/tests/e2e/test_page.py +2 -2
  8. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/tests/e2e/test_paragraph.py +1 -1
  9. pdfdancer_client_python-0.2.8/tests/e2e/test_pdfdancer.py +33 -0
  10. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/.github/workflows/ci.yml +0 -0
  11. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/.gitignore +0 -0
  12. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/CLAUDE.md +0 -0
  13. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/README.md +0 -0
  14. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/docs/openapi.yml +0 -0
  15. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/release.py +0 -0
  16. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/requirements-dev.txt +0 -0
  17. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/requirements.txt +0 -0
  18. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/setup.cfg +0 -0
  19. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/src/pdfdancer/__init__.py +0 -0
  20. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/src/pdfdancer/exceptions.py +0 -0
  21. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/src/pdfdancer/image_builder.py +0 -0
  22. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/src/pdfdancer/models.py +0 -0
  23. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/src/pdfdancer/paragraph_builder.py +0 -0
  24. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/src/pdfdancer_client_python.egg-info/dependency_links.txt +0 -0
  25. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/src/pdfdancer_client_python.egg-info/requires.txt +0 -0
  26. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/src/pdfdancer_client_python.egg-info/top_level.txt +0 -0
  27. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/tests/__init__.py +0 -0
  28. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/tests/conftest.py +0 -0
  29. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/tests/e2e/__init__.py +0 -0
  30. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/tests/e2e/test_acroform.py +0 -0
  31. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/tests/e2e/test_form_x_objects.py +0 -0
  32. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/tests/e2e/test_image.py +0 -0
  33. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/tests/e2e/test_line.py +0 -0
  34. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/tests/e2e/test_path.py +0 -0
  35. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/tests/fixtures/DancingScript-Regular.ttf +0 -0
  36. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/tests/fixtures/JetBrainsMono-Regular.ttf +0 -0
  37. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/tests/fixtures/ObviouslyAwesome.pdf +0 -0
  38. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/tests/fixtures/basic-paths.pdf +0 -0
  39. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/tests/fixtures/form-xobject-example.pdf +0 -0
  40. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/tests/fixtures/logo-80.png +0 -0
  41. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/tests/fixtures/mixed-form-types.pdf +0 -0
  42. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/tests/test_authentication.py +0 -0
  43. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/tests/test_models.py +0 -0
  44. {pdfdancer_client_python-0.2.6 → pdfdancer_client_python-0.2.8}/tests/test_openapi_compliance.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pdfdancer-client-python
3
- Version: 0.2.6
3
+ Version: 0.2.8
4
4
  Summary: Python client for PDFDancer API
5
5
  Author-email: "The Famous Cat Ltd." <hi@thefamouscat.com>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pdfdancer-client-python"
7
- version = "0.2.6"
7
+ version = "0.2.8"
8
8
  description = "Python client for PDFDancer API"
9
9
  readme = "README.md"
10
10
  authors = [
@@ -26,13 +26,16 @@ from .models import (
26
26
  FindRequest, DeleteRequest, MoveRequest, AddRequest, ModifyRequest, ModifyTextRequest, ChangeFormFieldRequest,
27
27
  ShapeType, PositionMode
28
28
  )
29
- from .types import PathObject, ParagraphObject, TextLineObject, ImageObject, FormObject, FormFieldObject, PageObject
29
+ from .types import PathObject, ParagraphObject, TextLineObject, ImageObject, FormObject, FormFieldObject
30
30
 
31
31
 
32
32
  class PageClient:
33
33
  def __init__(self, page_index: int, root: "PDFDancer"):
34
34
  self.page_index = page_index
35
35
  self.root = root
36
+ self.object_type = ObjectType.PAGE
37
+ self.position = Position.at_page(page_index)
38
+ self.internal_id = f"PAGE-{page_index}"
36
39
 
37
40
  def select_paths_at(self, x: float, y: float) -> List[PathObject]:
38
41
  # noinspection PyProtectedMember
@@ -99,8 +102,17 @@ class PageClient:
99
102
  # noinspection PyProtectedMember
100
103
  return self.root._to_form_field_objects(self.root._find_form_fields(position))
101
104
 
102
- def get(self) -> PageObject:
103
- return self.root._to_page_object(self.root._get_page(self.page_index))
105
+ @classmethod
106
+ def from_ref(cls, root: 'PDFDancer', object_ref: ObjectRef) -> 'PageClient':
107
+ page_client = PageClient(page_index=object_ref.position.page_index, root=root)
108
+ return page_client
109
+
110
+ def delete(self) -> bool:
111
+ # noinspection PyProtectedMember
112
+ return self.root._delete_page(self._ref())
113
+
114
+ def _ref(self):
115
+ return ObjectRef(internal_id=self.internal_id, position=self.position, type=self.object_type)
104
116
 
105
117
 
106
118
  class PDFDancer:
@@ -472,7 +484,7 @@ class PDFDancer:
472
484
 
473
485
  # Page Operations
474
486
 
475
- def pages(self) -> List[PageObject]:
487
+ def pages(self) -> List[PageClient]:
476
488
  return self._to_page_objects(self._get_pages())
477
489
 
478
490
  def _get_pages(self) -> List[ObjectRef]:
@@ -767,7 +779,7 @@ class PDFDancer:
767
779
 
768
780
  # Document Operations
769
781
 
770
- def get_pdf_file(self) -> bytes:
782
+ def get_bytes(self) -> bytes:
771
783
  """
772
784
  Downloads the current state of the PDF document with all modifications applied.
773
785
 
@@ -792,7 +804,7 @@ class PDFDancer:
792
804
  raise ValidationException("File path cannot be null or empty")
793
805
 
794
806
  try:
795
- pdf_data = self.get_pdf_file()
807
+ pdf_data = self.get_bytes()
796
808
  output_path = Path(file_path)
797
809
 
798
810
  # Create parent directories if they don't exist
@@ -898,8 +910,8 @@ class PDFDancer:
898
910
  return [FormFieldObject(self, ref.internal_id, ref.type, ref.position, ref.name, ref.value) for ref in
899
911
  path_refs]
900
912
 
901
- def _to_page_objects(self, path_refs: List[ObjectRef]) -> List[PageObject]:
902
- return [PageObject(self, ref.internal_id, ref.type, ref.position) for ref in path_refs]
913
+ def _to_page_objects(self, path_refs: List[ObjectRef]) -> List[PageClient]:
914
+ return [PageClient.from_ref(self, ref) for ref in path_refs]
903
915
 
904
- def _to_page_object(self, ref: ObjectRef) -> PageObject:
905
- return PageObject(self, ref.internal_id, ref.type, ref.position)
916
+ def _to_page_object(self, ref: ObjectRef) -> PageClient:
917
+ return PageClient.from_ref(self, ref)
@@ -239,10 +239,3 @@ class FormFieldObject(PDFObjectBase):
239
239
  ref.name = self.name
240
240
  ref.value = self.value
241
241
  return ref
242
-
243
-
244
- class PageObject(PDFObjectBase):
245
-
246
- def delete(self) -> bool:
247
- # noinspection PyProtectedMember
248
- return self._client._delete_page(self.object_ref())
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pdfdancer-client-python
3
- Version: 0.2.6
3
+ Version: 0.2.8
4
4
  Summary: Python client for PDFDancer API
5
5
  Author-email: "The Famous Cat Ltd." <hi@thefamouscat.com>
6
6
  License: MIT
@@ -32,6 +32,7 @@ tests/e2e/test_line.py
32
32
  tests/e2e/test_page.py
33
33
  tests/e2e/test_paragraph.py
34
34
  tests/e2e/test_path.py
35
+ tests/e2e/test_pdfdancer.py
35
36
  tests/fixtures/DancingScript-Regular.ttf
36
37
  tests/fixtures/JetBrainsMono-Regular.ttf
37
38
  tests/fixtures/ObviouslyAwesome.pdf
@@ -16,7 +16,7 @@ def test_get_page():
16
16
  base_url, token, pdf_path = _require_env_and_fixture("ObviouslyAwesome.pdf")
17
17
 
18
18
  with PDFDancer.open(pdf_path, token=token, base_url=base_url, timeout=30.0) as pdf:
19
- page = pdf.page(2).get()
19
+ page = pdf.page(2)
20
20
  assert page is not None
21
21
  assert page.position.page_index == 2
22
22
  assert page.internal_id is not None
@@ -26,7 +26,7 @@ def test_delete_page():
26
26
  base_url, token, pdf_path = _require_env_and_fixture("ObviouslyAwesome.pdf")
27
27
 
28
28
  with PDFDancer.open(pdf_path, token=token, base_url=base_url, timeout=30.0) as pdf:
29
- page3 = pdf.page(3).get()
29
+ page3 = pdf.page(3)
30
30
  page3.delete()
31
31
 
32
32
  pages_after = pdf.pages()
@@ -161,7 +161,7 @@ def test_add_paragraph_with_custom_font3():
161
161
  with PDFDancer.open(pdf_path, token=token, base_url=base_url, timeout=30.0) as pdf:
162
162
  pdf.new_paragraph() \
163
163
  .text("Awesomely\nObvious!") \
164
- .font_file(str(ttf_path), 24) \
164
+ .font_file(ttf_path, 24) \
165
165
  .line_spacing(1.8) \
166
166
  .color(Color(0, 0, 255)) \
167
167
  .at(0, 300.1, 500) \
@@ -0,0 +1,33 @@
1
+ import os
2
+
3
+ import pytest
4
+
5
+ from e2e import _require_env_and_fixture
6
+ from pdfdancer import PDFDancer, ValidationException, HttpClientException
7
+
8
+
9
+ def test_env_vars():
10
+ base_url, _, pdf_path = _require_env_and_fixture("ObviouslyAwesome.pdf")
11
+ os.environ.pop("PDFDANCER_TOKEN", None)
12
+
13
+ with pytest.raises(ValidationException) as exc_info:
14
+ with PDFDancer.open(pdf_path, base_url=base_url) as pdf:
15
+ pass
16
+ assert "Missing PDFDancer API token. Pass a token via the `token` argument or set the PDFDANCER_TOKEN environment variable." == str(
17
+ exc_info.value)
18
+
19
+ os.environ["PDFDANCER_TOKEN"] = "42"
20
+ with PDFDancer.open(pdf_path, base_url=base_url) as pdf:
21
+ pass
22
+
23
+ os.environ["PDFDANCER_BASE_URL"] = "http://www.google.com"
24
+ with pytest.raises(HttpClientException) as exc_info:
25
+ with PDFDancer.open(pdf_path) as pdf:
26
+ pass
27
+
28
+ os.environ["PDFDANCER_BASE_URL"] = "https://api.pdfdancer.com"
29
+ with pytest.raises(ValidationException) as exc_info:
30
+ with PDFDancer.open(pdf_path) as pdf:
31
+ pass
32
+ assert "Authentication with the PDFDancer API failed. Confirm that your API token is valid, has not expired" in str(
33
+ exc_info.value)