pdfdancer-client-python 0.3.12__py3-none-any.whl → 0.3.13__py3-none-any.whl
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.
- pdfdancer/__init__.py +5 -1
- pdfdancer/models.py +82 -0
- pdfdancer/pdfdancer_v1.py +75 -3
- pdfdancer/types.py +92 -1
- {pdfdancer_client_python-0.3.12.dist-info → pdfdancer_client_python-0.3.13.dist-info}/METADATA +1 -1
- {pdfdancer_client_python-0.3.12.dist-info → pdfdancer_client_python-0.3.13.dist-info}/RECORD +10 -10
- {pdfdancer_client_python-0.3.12.dist-info → pdfdancer_client_python-0.3.13.dist-info}/WHEEL +0 -0
- {pdfdancer_client_python-0.3.12.dist-info → pdfdancer_client_python-0.3.13.dist-info}/licenses/LICENSE +0 -0
- {pdfdancer_client_python-0.3.12.dist-info → pdfdancer_client_python-0.3.13.dist-info}/licenses/NOTICE +0 -0
- {pdfdancer_client_python-0.3.12.dist-info → pdfdancer_client_python-0.3.13.dist-info}/top_level.txt +0 -0
pdfdancer/__init__.py
CHANGED
|
@@ -28,6 +28,7 @@ from .models import (
|
|
|
28
28
|
ImageTransformRequest,
|
|
29
29
|
ImageTransformType,
|
|
30
30
|
Line,
|
|
31
|
+
ModifyPathRequest,
|
|
31
32
|
ObjectRef,
|
|
32
33
|
ObjectType,
|
|
33
34
|
Orientation,
|
|
@@ -36,6 +37,7 @@ from .models import (
|
|
|
36
37
|
Paragraph,
|
|
37
38
|
Path,
|
|
38
39
|
PathGroupInfo,
|
|
40
|
+
PathObjectRef,
|
|
39
41
|
PathSegment,
|
|
40
42
|
Point,
|
|
41
43
|
Position,
|
|
@@ -55,7 +57,7 @@ from .paragraph_builder import ParagraphBuilder
|
|
|
55
57
|
from .path_builder import BezierBuilder, LineBuilder, PathBuilder
|
|
56
58
|
from .text_line_builder import TextLineBuilder
|
|
57
59
|
|
|
58
|
-
__version__ = "0.3.
|
|
60
|
+
__version__ = "0.3.13"
|
|
59
61
|
__all__ = [
|
|
60
62
|
"PDFDancer",
|
|
61
63
|
"ParagraphBuilder",
|
|
@@ -65,6 +67,8 @@ __all__ = [
|
|
|
65
67
|
"LineBuilder",
|
|
66
68
|
"BezierBuilder",
|
|
67
69
|
"ObjectRef",
|
|
70
|
+
"PathObjectRef",
|
|
71
|
+
"ModifyPathRequest",
|
|
68
72
|
"Position",
|
|
69
73
|
"ObjectType",
|
|
70
74
|
"Font",
|
pdfdancer/models.py
CHANGED
|
@@ -1895,3 +1895,85 @@ class ImageTransformRequest:
|
|
|
1895
1895
|
result["fillColor"] = self.fill_color
|
|
1896
1896
|
|
|
1897
1897
|
return result
|
|
1898
|
+
|
|
1899
|
+
|
|
1900
|
+
@dataclass
|
|
1901
|
+
class ModifyPathRequest:
|
|
1902
|
+
"""Request to modify path stroke and fill colors.
|
|
1903
|
+
|
|
1904
|
+
Parameters:
|
|
1905
|
+
- object_ref: Reference to the path to modify.
|
|
1906
|
+
- stroke_color: New stroke color (optional - null means don't change).
|
|
1907
|
+
- fill_color: New fill color (optional - null means don't change).
|
|
1908
|
+
|
|
1909
|
+
Example:
|
|
1910
|
+
```python
|
|
1911
|
+
req = ModifyPathRequest(object_ref=path_ref, stroke_color=Color(255, 0, 0), fill_color=None)
|
|
1912
|
+
payload = req.to_dict()
|
|
1913
|
+
```
|
|
1914
|
+
"""
|
|
1915
|
+
|
|
1916
|
+
object_ref: ObjectRef
|
|
1917
|
+
stroke_color: Optional[Color] = None
|
|
1918
|
+
fill_color: Optional[Color] = None
|
|
1919
|
+
|
|
1920
|
+
def to_dict(self) -> dict:
|
|
1921
|
+
"""Convert to dictionary for JSON serialization."""
|
|
1922
|
+
result: Dict[str, Any] = {
|
|
1923
|
+
"ref": self.object_ref.to_dict(),
|
|
1924
|
+
}
|
|
1925
|
+
|
|
1926
|
+
if self.stroke_color is not None:
|
|
1927
|
+
result["strokeColor"] = {
|
|
1928
|
+
"red": self.stroke_color.r,
|
|
1929
|
+
"green": self.stroke_color.g,
|
|
1930
|
+
"blue": self.stroke_color.b,
|
|
1931
|
+
"alpha": self.stroke_color.a,
|
|
1932
|
+
}
|
|
1933
|
+
|
|
1934
|
+
if self.fill_color is not None:
|
|
1935
|
+
result["fillColor"] = {
|
|
1936
|
+
"red": self.fill_color.r,
|
|
1937
|
+
"green": self.fill_color.g,
|
|
1938
|
+
"blue": self.fill_color.b,
|
|
1939
|
+
"alpha": self.fill_color.a,
|
|
1940
|
+
}
|
|
1941
|
+
|
|
1942
|
+
return result
|
|
1943
|
+
|
|
1944
|
+
|
|
1945
|
+
class PathObjectRef(ObjectRef):
|
|
1946
|
+
"""
|
|
1947
|
+
Reference to a path object with stroke and fill color information.
|
|
1948
|
+
|
|
1949
|
+
Parameters (typically provided by the server):
|
|
1950
|
+
- internal_id: Identifier of the path object.
|
|
1951
|
+
- position: Position of the path.
|
|
1952
|
+
- object_type: Should be ObjectType.PATH.
|
|
1953
|
+
- stroke_color: Stroke/outline color of the path (optional).
|
|
1954
|
+
- fill_color: Fill color of the path (optional).
|
|
1955
|
+
|
|
1956
|
+
Usage:
|
|
1957
|
+
- Returned by find/snapshot APIs when querying paths.
|
|
1958
|
+
- Pass to ModifyPathRequest to update path colors.
|
|
1959
|
+
"""
|
|
1960
|
+
|
|
1961
|
+
def __init__(
|
|
1962
|
+
self,
|
|
1963
|
+
internal_id: str,
|
|
1964
|
+
position: Position,
|
|
1965
|
+
object_type: ObjectType,
|
|
1966
|
+
stroke_color: Optional[Color] = None,
|
|
1967
|
+
fill_color: Optional[Color] = None,
|
|
1968
|
+
):
|
|
1969
|
+
super().__init__(internal_id, position, object_type)
|
|
1970
|
+
self.stroke_color = stroke_color
|
|
1971
|
+
self.fill_color = fill_color
|
|
1972
|
+
|
|
1973
|
+
def get_stroke_color(self) -> Optional[Color]:
|
|
1974
|
+
"""Get the stroke/outline color of the path."""
|
|
1975
|
+
return self.stroke_color
|
|
1976
|
+
|
|
1977
|
+
def get_fill_color(self) -> Optional[Color]:
|
|
1978
|
+
"""Get the fill color of the path."""
|
|
1979
|
+
return self.fill_color
|
pdfdancer/pdfdancer_v1.py
CHANGED
|
@@ -47,6 +47,7 @@ from .models import (
|
|
|
47
47
|
FontType,
|
|
48
48
|
FormFieldRef,
|
|
49
49
|
Image,
|
|
50
|
+
ModifyPathRequest,
|
|
50
51
|
ModifyRequest,
|
|
51
52
|
ModifyTextRequest,
|
|
52
53
|
MoveRequest,
|
|
@@ -58,6 +59,7 @@ from .models import (
|
|
|
58
59
|
PageSize,
|
|
59
60
|
PageSnapshot,
|
|
60
61
|
Paragraph,
|
|
62
|
+
PathObjectRef,
|
|
61
63
|
Position,
|
|
62
64
|
PositionMode,
|
|
63
65
|
RedactRequest,
|
|
@@ -2755,6 +2757,38 @@ class PDFDancer:
|
|
|
2755
2757
|
self._invalidate_snapshots()
|
|
2756
2758
|
return result
|
|
2757
2759
|
|
|
2760
|
+
def _modify_path(
|
|
2761
|
+
self,
|
|
2762
|
+
object_ref: ObjectRef,
|
|
2763
|
+
stroke_color: Optional[Color],
|
|
2764
|
+
fill_color: Optional[Color],
|
|
2765
|
+
) -> CommandResult:
|
|
2766
|
+
"""
|
|
2767
|
+
Modifies the stroke and fill colors of a path object.
|
|
2768
|
+
|
|
2769
|
+
Args:
|
|
2770
|
+
object_ref: Reference to the path to modify.
|
|
2771
|
+
stroke_color: New stroke color (None means don't change).
|
|
2772
|
+
fill_color: New fill color (None means don't change).
|
|
2773
|
+
|
|
2774
|
+
Returns:
|
|
2775
|
+
CommandResult indicating success or failure.
|
|
2776
|
+
"""
|
|
2777
|
+
if object_ref is None:
|
|
2778
|
+
raise ValidationException("Object reference cannot be null")
|
|
2779
|
+
|
|
2780
|
+
request_data = ModifyPathRequest(
|
|
2781
|
+
object_ref=object_ref,
|
|
2782
|
+
stroke_color=stroke_color,
|
|
2783
|
+
fill_color=fill_color,
|
|
2784
|
+
).to_dict()
|
|
2785
|
+
response = self._make_request("PUT", "/pdf/modify/path", data=request_data)
|
|
2786
|
+
result = CommandResult.from_dict(response.json())
|
|
2787
|
+
|
|
2788
|
+
# Invalidate snapshot caches after mutation
|
|
2789
|
+
self._invalidate_snapshots()
|
|
2790
|
+
return result
|
|
2791
|
+
|
|
2758
2792
|
# Font Operations
|
|
2759
2793
|
|
|
2760
2794
|
def find_fonts(self, font_name: str, font_size: int) -> List[Font]:
|
|
@@ -3159,6 +3193,43 @@ class PDFDancer:
|
|
|
3159
3193
|
value=obj_data["value"] if "value" in obj_data else None,
|
|
3160
3194
|
)
|
|
3161
3195
|
|
|
3196
|
+
def _parse_path_object_ref(self, obj_data: dict) -> PathObjectRef:
|
|
3197
|
+
"""Parse JSON object data into PathObjectRef instance with color information."""
|
|
3198
|
+
position_data = obj_data.get("position", {})
|
|
3199
|
+
position = self._parse_position(position_data) if position_data else None
|
|
3200
|
+
|
|
3201
|
+
object_type = ObjectType(obj_data["type"])
|
|
3202
|
+
|
|
3203
|
+
# Parse stroke color if present
|
|
3204
|
+
stroke_color = None
|
|
3205
|
+
stroke_color_data = obj_data.get("strokeColor")
|
|
3206
|
+
if isinstance(stroke_color_data, dict):
|
|
3207
|
+
red = stroke_color_data.get("red")
|
|
3208
|
+
green = stroke_color_data.get("green")
|
|
3209
|
+
blue = stroke_color_data.get("blue")
|
|
3210
|
+
alpha = stroke_color_data.get("alpha", 255)
|
|
3211
|
+
if all(isinstance(v, int) for v in [red, green, blue]):
|
|
3212
|
+
stroke_color = Color(red, green, blue, alpha)
|
|
3213
|
+
|
|
3214
|
+
# Parse fill color if present
|
|
3215
|
+
fill_color = None
|
|
3216
|
+
fill_color_data = obj_data.get("fillColor")
|
|
3217
|
+
if isinstance(fill_color_data, dict):
|
|
3218
|
+
red = fill_color_data.get("red")
|
|
3219
|
+
green = fill_color_data.get("green")
|
|
3220
|
+
blue = fill_color_data.get("blue")
|
|
3221
|
+
alpha = fill_color_data.get("alpha", 255)
|
|
3222
|
+
if all(isinstance(v, int) for v in [red, green, blue]):
|
|
3223
|
+
fill_color = Color(red, green, blue, alpha)
|
|
3224
|
+
|
|
3225
|
+
return PathObjectRef(
|
|
3226
|
+
internal_id=obj_data["internalId"] if "internalId" in obj_data else None,
|
|
3227
|
+
position=position,
|
|
3228
|
+
object_type=object_type,
|
|
3229
|
+
stroke_color=stroke_color,
|
|
3230
|
+
fill_color=fill_color,
|
|
3231
|
+
)
|
|
3232
|
+
|
|
3162
3233
|
@staticmethod
|
|
3163
3234
|
def _parse_position(pos_data: dict) -> Position:
|
|
3164
3235
|
"""Parse JSON position data into Position instance."""
|
|
@@ -3473,6 +3544,9 @@ class PDFDancer:
|
|
|
3473
3544
|
):
|
|
3474
3545
|
# Parse as FormFieldRef to capture name and value
|
|
3475
3546
|
elements.append(self._parse_form_field_ref(elem_data))
|
|
3547
|
+
elif elem_type == ObjectType.PATH:
|
|
3548
|
+
# Parse as PathObjectRef to capture stroke/fill colors
|
|
3549
|
+
elements.append(self._parse_path_object_ref(elem_data))
|
|
3476
3550
|
else:
|
|
3477
3551
|
# Parse as basic ObjectRef
|
|
3478
3552
|
elements.append(self._parse_object_ref(elem_data))
|
|
@@ -3526,9 +3600,7 @@ class PDFDancer:
|
|
|
3526
3600
|
self._client.close()
|
|
3527
3601
|
|
|
3528
3602
|
def _to_path_objects(self, refs: List[ObjectRef]) -> List[PathObject]:
|
|
3529
|
-
return [
|
|
3530
|
-
PathObject(self, ref.internal_id, ref.type, ref.position) for ref in refs
|
|
3531
|
-
]
|
|
3603
|
+
return [PathObject(self, ref) for ref in refs]
|
|
3532
3604
|
|
|
3533
3605
|
def _to_paragraph_objects(self, refs: List[TextObjectRef]) -> List[ParagraphObject]:
|
|
3534
3606
|
return [ParagraphObject(self, ref) for ref in refs]
|
pdfdancer/types.py
CHANGED
|
@@ -4,7 +4,7 @@ import sys
|
|
|
4
4
|
from dataclasses import dataclass
|
|
5
5
|
from typing import TYPE_CHECKING, Optional
|
|
6
6
|
|
|
7
|
-
from . import FormFieldRef, ObjectRef, ObjectType, Point, Position, TextObjectRef
|
|
7
|
+
from . import FormFieldRef, ObjectRef, ObjectType, PathObjectRef, Point, Position, TextObjectRef
|
|
8
8
|
from .exceptions import ValidationException
|
|
9
9
|
|
|
10
10
|
if TYPE_CHECKING:
|
|
@@ -86,11 +86,44 @@ class PDFObjectBase:
|
|
|
86
86
|
class PathObject(PDFObjectBase):
|
|
87
87
|
"""Represents a vector path object inside a PDF page."""
|
|
88
88
|
|
|
89
|
+
def __init__(self, client: "PDFDancer", object_ref):
|
|
90
|
+
"""
|
|
91
|
+
Initialize a PathObject.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
client: PDFDancer client instance
|
|
95
|
+
object_ref: ObjectRef or PathObjectRef with path data
|
|
96
|
+
"""
|
|
97
|
+
super().__init__(
|
|
98
|
+
client, object_ref.internal_id, object_ref.type, object_ref.position
|
|
99
|
+
)
|
|
100
|
+
self._object_ref = object_ref
|
|
101
|
+
|
|
89
102
|
@property
|
|
90
103
|
def bounding_box(self) -> Optional[BoundingRect]:
|
|
91
104
|
"""Optional bounding rectangle (if available)."""
|
|
92
105
|
return self.position.bounding_rect
|
|
93
106
|
|
|
107
|
+
def edit(self) -> PathEditSession:
|
|
108
|
+
"""Start a fluent editing session to modify path colors."""
|
|
109
|
+
return PathEditSession(self._client, self.object_ref())
|
|
110
|
+
|
|
111
|
+
def object_ref(self):
|
|
112
|
+
"""Return an ObjectRef for this path."""
|
|
113
|
+
return self._object_ref
|
|
114
|
+
|
|
115
|
+
def get_stroke_color(self) -> Optional["Color"]:
|
|
116
|
+
"""Get the stroke/outline color of the path, or None if not set."""
|
|
117
|
+
if isinstance(self._object_ref, PathObjectRef):
|
|
118
|
+
return self._object_ref.get_stroke_color()
|
|
119
|
+
return None
|
|
120
|
+
|
|
121
|
+
def get_fill_color(self) -> Optional["Color"]:
|
|
122
|
+
"""Get the fill color of the path, or None if not set."""
|
|
123
|
+
if isinstance(self._object_ref, PathObjectRef):
|
|
124
|
+
return self._object_ref.get_fill_color()
|
|
125
|
+
return None
|
|
126
|
+
|
|
94
127
|
def __eq__(self, other):
|
|
95
128
|
if not isinstance(other, PathObject):
|
|
96
129
|
return False
|
|
@@ -748,3 +781,61 @@ class FormFieldObject(PDFObjectBase):
|
|
|
748
781
|
and self.name == other.name
|
|
749
782
|
and self.value == other.value
|
|
750
783
|
)
|
|
784
|
+
|
|
785
|
+
|
|
786
|
+
class PathEditSession:
|
|
787
|
+
"""
|
|
788
|
+
Fluent editing helper for modifying path stroke and fill colors.
|
|
789
|
+
"""
|
|
790
|
+
|
|
791
|
+
def __init__(self, client: "PDFDancer", object_ref):
|
|
792
|
+
self._client = client
|
|
793
|
+
self._object_ref = object_ref
|
|
794
|
+
self._stroke_color = None
|
|
795
|
+
self._fill_color = None
|
|
796
|
+
|
|
797
|
+
def __enter__(self):
|
|
798
|
+
return self
|
|
799
|
+
|
|
800
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
801
|
+
if exc_type:
|
|
802
|
+
return False
|
|
803
|
+
self.apply()
|
|
804
|
+
return False
|
|
805
|
+
|
|
806
|
+
def stroke_color(self, color) -> "PathEditSession":
|
|
807
|
+
"""
|
|
808
|
+
Set the stroke/outline color.
|
|
809
|
+
|
|
810
|
+
Args:
|
|
811
|
+
color: The stroke color (Color object)
|
|
812
|
+
|
|
813
|
+
Returns:
|
|
814
|
+
Self for method chaining
|
|
815
|
+
"""
|
|
816
|
+
self._stroke_color = color
|
|
817
|
+
return self
|
|
818
|
+
|
|
819
|
+
def fill_color(self, color) -> "PathEditSession":
|
|
820
|
+
"""
|
|
821
|
+
Set the fill color.
|
|
822
|
+
|
|
823
|
+
Args:
|
|
824
|
+
color: The fill color (Color object)
|
|
825
|
+
|
|
826
|
+
Returns:
|
|
827
|
+
Self for method chaining
|
|
828
|
+
"""
|
|
829
|
+
self._fill_color = color
|
|
830
|
+
return self
|
|
831
|
+
|
|
832
|
+
def apply(self):
|
|
833
|
+
"""
|
|
834
|
+
Apply the color modifications to the path.
|
|
835
|
+
|
|
836
|
+
Returns:
|
|
837
|
+
CommandResult indicating success or failure
|
|
838
|
+
"""
|
|
839
|
+
return self._client._modify_path(
|
|
840
|
+
self._object_ref, self._stroke_color, self._fill_color
|
|
841
|
+
)
|
{pdfdancer_client_python-0.3.12.dist-info → pdfdancer_client_python-0.3.13.dist-info}/RECORD
RENAMED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
pdfdancer/__init__.py,sha256=
|
|
1
|
+
pdfdancer/__init__.py,sha256=3gVfEG-Fgz2Zes2zS6QfWhE2_TbtSFvDeyc_EGD1azE,2972
|
|
2
2
|
pdfdancer/exceptions.py,sha256=U6kD3NvcdNt05_OU11Tml5dXGtlodEtYC9zcV4fHXkc,2270
|
|
3
3
|
pdfdancer/fingerprint.py,sha256=eL3PHPgv-knMya7s95RXg3qzzpkAA1aevxqb6tuOb34,3061
|
|
4
4
|
pdfdancer/image_builder.py,sha256=aBxMFAMFzzbGTjlVH0hi94mA81cH8tp37Pk84HRPV00,1892
|
|
5
|
-
pdfdancer/models.py,sha256=
|
|
5
|
+
pdfdancer/models.py,sha256=D8v42xWAqXQ7-q3gjpb5z5Gd3dxvjc0NE779Gd2-fBE,62964
|
|
6
6
|
pdfdancer/page_builder.py,sha256=ARWLRtlrLGbES-0nbiigTOsRVmodRX0DNK8YIAkA9Ig,3850
|
|
7
7
|
pdfdancer/paragraph_builder.py,sha256=OmhzYazMnq0n0rhrjWcKbo0LQfEC7BZoiLB29ycF630,20504
|
|
8
8
|
pdfdancer/path_builder.py,sha256=safKb_IeHRWlQbyBTIXfcoBfXxUZhuzYvBIob5Tbp-8,23938
|
|
9
|
-
pdfdancer/pdfdancer_v1.py,sha256=
|
|
9
|
+
pdfdancer/pdfdancer_v1.py,sha256=u7LmwbVJ9szcS31aFYtSXo595nVZUP9RgTq1iskgzKI,141221
|
|
10
10
|
pdfdancer/text_line_builder.py,sha256=8jYknV4hw0fyzwX0OI_oLvnh5aMmCV3jXaVkmYLu6MQ,10273
|
|
11
|
-
pdfdancer/types.py,sha256=
|
|
12
|
-
pdfdancer_client_python-0.3.
|
|
13
|
-
pdfdancer_client_python-0.3.
|
|
14
|
-
pdfdancer_client_python-0.3.
|
|
15
|
-
pdfdancer_client_python-0.3.
|
|
16
|
-
pdfdancer_client_python-0.3.
|
|
17
|
-
pdfdancer_client_python-0.3.
|
|
11
|
+
pdfdancer/types.py,sha256=GNThFde9dRloHB482nu3txhYc9wysI244cM1D7L8fa4,27501
|
|
12
|
+
pdfdancer_client_python-0.3.13.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
13
|
+
pdfdancer_client_python-0.3.13.dist-info/licenses/NOTICE,sha256=xaC4l-IChAmtViNDie8ZWzUk0O6XRMyzOl0zLmVZ2HE,232
|
|
14
|
+
pdfdancer_client_python-0.3.13.dist-info/METADATA,sha256=xMyuh8uwwfxel2KotjXORNIpB-fxPmFaXMZjsWRXd6k,28756
|
|
15
|
+
pdfdancer_client_python-0.3.13.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
16
|
+
pdfdancer_client_python-0.3.13.dist-info/top_level.txt,sha256=ICwSVRpcCKrdBF9QlaX9Y0e_N3Nk1p7QVxadGOnbxeY,10
|
|
17
|
+
pdfdancer_client_python-0.3.13.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pdfdancer_client_python-0.3.12.dist-info → pdfdancer_client_python-0.3.13.dist-info}/top_level.txt
RENAMED
|
File without changes
|