mongo-pipebuilder 0.2.3__py3-none-any.whl → 0.3.0__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.
- mongo_pipebuilder/__init__.py +1 -1
- mongo_pipebuilder/builder.py +102 -0
- {mongo_pipebuilder-0.2.3.dist-info → mongo_pipebuilder-0.3.0.dist-info}/METADATA +60 -1
- mongo_pipebuilder-0.3.0.dist-info/RECORD +7 -0
- {mongo_pipebuilder-0.2.3.dist-info → mongo_pipebuilder-0.3.0.dist-info}/licenses/LICENSE +11 -0
- mongo_pipebuilder-0.2.3.dist-info/RECORD +0 -7
- {mongo_pipebuilder-0.2.3.dist-info → mongo_pipebuilder-0.3.0.dist-info}/WHEEL +0 -0
- {mongo_pipebuilder-0.2.3.dist-info → mongo_pipebuilder-0.3.0.dist-info}/top_level.txt +0 -0
mongo_pipebuilder/__init__.py
CHANGED
mongo_pipebuilder/builder.py
CHANGED
|
@@ -6,6 +6,8 @@ Builder Pattern implementation for safe construction of MongoDB aggregation pipe
|
|
|
6
6
|
|
|
7
7
|
Author: seligoroff
|
|
8
8
|
"""
|
|
9
|
+
import json
|
|
10
|
+
from pathlib import Path
|
|
9
11
|
from typing import Any, Dict, List, Optional, Union
|
|
10
12
|
|
|
11
13
|
# For compatibility with Python < 3.11
|
|
@@ -753,6 +755,106 @@ class PipelineBuilder:
|
|
|
753
755
|
self._stages.insert(position, stage)
|
|
754
756
|
return self
|
|
755
757
|
|
|
758
|
+
def get_stage_at(self, index: int) -> Dict[str, Any]:
|
|
759
|
+
"""
|
|
760
|
+
Get a specific stage from the pipeline by index.
|
|
761
|
+
|
|
762
|
+
Args:
|
|
763
|
+
index: Zero-based index of the stage to retrieve
|
|
764
|
+
|
|
765
|
+
Returns:
|
|
766
|
+
Dictionary representing the stage at the given index
|
|
767
|
+
|
|
768
|
+
Raises:
|
|
769
|
+
IndexError: If index is out of range
|
|
770
|
+
|
|
771
|
+
Example:
|
|
772
|
+
>>> builder = PipelineBuilder()
|
|
773
|
+
>>> builder.match({"status": "active"}).limit(10)
|
|
774
|
+
>>> stage = builder.get_stage_at(0)
|
|
775
|
+
>>> stage
|
|
776
|
+
{"$match": {"status": "active"}}
|
|
777
|
+
"""
|
|
778
|
+
if index < 0 or index >= len(self._stages):
|
|
779
|
+
raise IndexError(
|
|
780
|
+
f"Index {index} out of range [0, {len(self._stages)}]"
|
|
781
|
+
)
|
|
782
|
+
return self._stages[index].copy()
|
|
783
|
+
|
|
784
|
+
def pretty_print(self, indent: int = 2, ensure_ascii: bool = False) -> str:
|
|
785
|
+
"""
|
|
786
|
+
Return a formatted JSON string representation of the pipeline.
|
|
787
|
+
|
|
788
|
+
Useful for debugging and understanding pipeline structure.
|
|
789
|
+
|
|
790
|
+
Args:
|
|
791
|
+
indent: Number of spaces for indentation (default: 2)
|
|
792
|
+
ensure_ascii: If False, non-ASCII characters are output as-is (default: False)
|
|
793
|
+
|
|
794
|
+
Returns:
|
|
795
|
+
Formatted JSON string of the pipeline
|
|
796
|
+
|
|
797
|
+
Example:
|
|
798
|
+
>>> builder = PipelineBuilder()
|
|
799
|
+
>>> builder.match({"status": "active"}).limit(10)
|
|
800
|
+
>>> print(builder.pretty_print())
|
|
801
|
+
[
|
|
802
|
+
{
|
|
803
|
+
"$match": {
|
|
804
|
+
"status": "active"
|
|
805
|
+
}
|
|
806
|
+
},
|
|
807
|
+
{
|
|
808
|
+
"$limit": 10
|
|
809
|
+
}
|
|
810
|
+
]
|
|
811
|
+
"""
|
|
812
|
+
return json.dumps(self._stages, indent=indent, ensure_ascii=ensure_ascii)
|
|
813
|
+
|
|
814
|
+
def to_json_file(
|
|
815
|
+
self,
|
|
816
|
+
filepath: Union[str, Path],
|
|
817
|
+
indent: int = 2,
|
|
818
|
+
ensure_ascii: bool = False,
|
|
819
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
820
|
+
) -> None:
|
|
821
|
+
"""
|
|
822
|
+
Save the pipeline to a JSON file.
|
|
823
|
+
|
|
824
|
+
Useful for debugging, comparison with other pipelines, or versioning.
|
|
825
|
+
|
|
826
|
+
Args:
|
|
827
|
+
filepath: Path to the output JSON file (str or Path)
|
|
828
|
+
indent: Number of spaces for indentation (default: 2)
|
|
829
|
+
ensure_ascii: If False, non-ASCII characters are output as-is (default: False)
|
|
830
|
+
metadata: Optional metadata to include in the JSON file
|
|
831
|
+
|
|
832
|
+
Raises:
|
|
833
|
+
IOError: If file cannot be written
|
|
834
|
+
|
|
835
|
+
Example:
|
|
836
|
+
>>> builder = PipelineBuilder()
|
|
837
|
+
>>> builder.match({"status": "active"}).limit(10)
|
|
838
|
+
>>> builder.to_json_file("debug_pipeline.json")
|
|
839
|
+
|
|
840
|
+
>>> # With metadata
|
|
841
|
+
>>> builder.to_json_file(
|
|
842
|
+
... "pipeline.json",
|
|
843
|
+
... metadata={"version": "1.0", "author": "developer"}
|
|
844
|
+
... )
|
|
845
|
+
"""
|
|
846
|
+
filepath = Path(filepath)
|
|
847
|
+
filepath.parent.mkdir(parents=True, exist_ok=True)
|
|
848
|
+
|
|
849
|
+
output: Dict[str, Any] = {
|
|
850
|
+
"pipeline": self._stages,
|
|
851
|
+
}
|
|
852
|
+
if metadata:
|
|
853
|
+
output["metadata"] = metadata
|
|
854
|
+
|
|
855
|
+
with open(filepath, "w", encoding="utf-8") as f:
|
|
856
|
+
json.dump(output, f, indent=indent, ensure_ascii=ensure_ascii)
|
|
857
|
+
|
|
756
858
|
def build(self) -> List[Dict[str, Any]]:
|
|
757
859
|
"""
|
|
758
860
|
Return the completed pipeline.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mongo-pipebuilder
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Type-safe, fluent MongoDB aggregation pipeline builder
|
|
5
5
|
Author-email: seligoroff <seligoroff@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -297,6 +297,54 @@ builder.add_stage({"$out": "output"}).match({"status": "active"})
|
|
|
297
297
|
builder.validate() # Raises ValueError: $out stage must be the last stage
|
|
298
298
|
```
|
|
299
299
|
|
|
300
|
+
##### `get_stage_at(index: int) -> Dict[str, Any]`
|
|
301
|
+
|
|
302
|
+
Gets a specific stage from the pipeline by index. Returns a copy of the stage.
|
|
303
|
+
|
|
304
|
+
```python
|
|
305
|
+
builder = PipelineBuilder()
|
|
306
|
+
builder.match({"status": "active"}).limit(10)
|
|
307
|
+
stage = builder.get_stage_at(0) # Returns {"$match": {"status": "active"}}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
##### `pretty_print(indent: int = 2, ensure_ascii: bool = False) -> str`
|
|
311
|
+
|
|
312
|
+
Returns a formatted JSON string representation of the pipeline. Useful for debugging.
|
|
313
|
+
|
|
314
|
+
```python
|
|
315
|
+
builder = PipelineBuilder()
|
|
316
|
+
builder.match({"status": "active"}).limit(10)
|
|
317
|
+
print(builder.pretty_print())
|
|
318
|
+
# [
|
|
319
|
+
# {
|
|
320
|
+
# "$match": {
|
|
321
|
+
# "status": "active"
|
|
322
|
+
# }
|
|
323
|
+
# },
|
|
324
|
+
# {
|
|
325
|
+
# "$limit": 10
|
|
326
|
+
# }
|
|
327
|
+
# ]
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
##### `to_json_file(filepath: Union[str, Path], indent: int = 2, ensure_ascii: bool = False, metadata: Optional[Dict[str, Any]] = None) -> None`
|
|
331
|
+
|
|
332
|
+
Saves the pipeline to a JSON file. Useful for debugging, comparison, or versioning.
|
|
333
|
+
|
|
334
|
+
```python
|
|
335
|
+
builder = PipelineBuilder()
|
|
336
|
+
builder.match({"status": "active"}).limit(10)
|
|
337
|
+
|
|
338
|
+
# Basic usage
|
|
339
|
+
builder.to_json_file("debug_pipeline.json")
|
|
340
|
+
|
|
341
|
+
# With metadata
|
|
342
|
+
builder.to_json_file(
|
|
343
|
+
"pipeline.json",
|
|
344
|
+
metadata={"version": "1.0", "author": "developer"}
|
|
345
|
+
)
|
|
346
|
+
```
|
|
347
|
+
|
|
300
348
|
##### `build() -> List[Dict[str, Any]]`
|
|
301
349
|
|
|
302
350
|
Returns the complete pipeline as a list of stage dictionaries.
|
|
@@ -544,3 +592,14 @@ MIT License - see [LICENSE](LICENSE) file for details.
|
|
|
544
592
|
|
|
545
593
|
|
|
546
594
|
|
|
595
|
+
|
|
596
|
+
|
|
597
|
+
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
|
|
601
|
+
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
|
|
605
|
+
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
mongo_pipebuilder/__init__.py,sha256=pP27GA8G6dttP-gMq9uNCJoS66-cb3JJiVVdI340er4,336
|
|
2
|
+
mongo_pipebuilder/builder.py,sha256=oQxRYL9ycjYCv2ErP_YHz-Uoo2pPRaRBaaaCLEsL5Mo,30286
|
|
3
|
+
mongo_pipebuilder-0.3.0.dist-info/licenses/LICENSE,sha256=-ZkZpDLHDQAc-YBIojJ6eDsMwxwx5pRuQz3RHnl9Y8w,1104
|
|
4
|
+
mongo_pipebuilder-0.3.0.dist-info/METADATA,sha256=KkgWrj5TD22yDj915Jrri_JftYMEpTz6hXSeHKEM7mk,15850
|
|
5
|
+
mongo_pipebuilder-0.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
6
|
+
mongo_pipebuilder-0.3.0.dist-info/top_level.txt,sha256=wLn7H_v-qaNIws5FeBbKPZBCmYFYgFEhPaLjoCWcisc,18
|
|
7
|
+
mongo_pipebuilder-0.3.0.dist-info/RECORD,,
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
mongo_pipebuilder/__init__.py,sha256=82PaAyv4VoEvfvVhlYnMTPnZEMiOI24Q4Nw9RSrEjdA,336
|
|
2
|
-
mongo_pipebuilder/builder.py,sha256=GivmjNqk2K5v3fX1TWMFFH7jx3WxlWWhlggWoRxCNl4,26875
|
|
3
|
-
mongo_pipebuilder-0.2.3.dist-info/licenses/LICENSE,sha256=ITJa-Zkh2Qc1_xRiHcfkL5zsmTicbSxqsMih4cjtBM4,1093
|
|
4
|
-
mongo_pipebuilder-0.2.3.dist-info/METADATA,sha256=eh6i_U365QAqWhERNAsFOgEVpjokTt4VEEJH8SqDAtA,14661
|
|
5
|
-
mongo_pipebuilder-0.2.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
6
|
-
mongo_pipebuilder-0.2.3.dist-info/top_level.txt,sha256=wLn7H_v-qaNIws5FeBbKPZBCmYFYgFEhPaLjoCWcisc,18
|
|
7
|
-
mongo_pipebuilder-0.2.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|