datatoolpack 0.6.0__tar.gz → 0.7.0__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datatoolpack
3
- Version: 0.6.0
3
+ Version: 0.7.0
4
4
  Summary: Official Python SDK for the AutoData ML data preparation pipeline API
5
5
  Home-page: https://autodata.datatoolpack.com
6
6
  Author: AutoData Team
@@ -1,4 +1,4 @@
1
1
  from .client import AutoDataClient, AutoDataError
2
2
 
3
- __version__ = "0.6.0"
3
+ __version__ = "0.7.0"
4
4
  __all__ = ["AutoDataClient", "AutoDataError", "__version__"]
@@ -214,6 +214,7 @@ class AutoDataClient:
214
214
  auto_download: bool = True,
215
215
  output_preferences: Optional[List[str]] = None,
216
216
  compressed: bool = True,
217
+ return_dataframes: bool = False,
217
218
  ) -> Dict:
218
219
  """Upload a data file and start the AutoData pipeline.
219
220
 
@@ -307,6 +308,12 @@ class AutoDataClient:
307
308
  output_preferences=output_preferences,
308
309
  compressed=compressed,
309
310
  )
311
+ # New in 0.7.0: return the output files as DataFrames so callers can
312
+ # skip the "download to disk, then pd.read_csv()" two-step. Gated on
313
+ # an opt-in flag to keep the default light (no pandas import).
314
+ if return_dataframes:
315
+ final = dict(final) # don't mutate the cached result object
316
+ final["dataframes"] = self.get_dataframes(session_id, names=output_preferences)
310
317
  return final
311
318
 
312
319
  def get_status(self, session_id: str) -> Dict:
@@ -564,6 +571,125 @@ class AutoDataClient:
564
571
  if last_err:
565
572
  raise last_err
566
573
 
574
+ # ------------------------------------------------------------------
575
+ # DataFrame-native helpers
576
+ # ------------------------------------------------------------------
577
+ # These let callers skip the "download to disk, then pd.read_csv()" two-step.
578
+ # pandas is imported lazily so the SDK stays light when a caller doesn't
579
+ # need it (the package install_requires only `requests`).
580
+
581
+ @staticmethod
582
+ def _require_pandas():
583
+ try:
584
+ import pandas as pd # noqa: F401
585
+ return pd
586
+ except ImportError as e:
587
+ raise AutoDataError(
588
+ "pandas is required for DataFrame helpers — install it with `pip install pandas` "
589
+ "or use download_file()/download_results() to get raw files instead."
590
+ ) from e
591
+
592
+ def get_dataframe(
593
+ self,
594
+ session_id: str,
595
+ output_name: str,
596
+ *,
597
+ timeout: Optional[float] = None,
598
+ **read_csv_kwargs,
599
+ ):
600
+ """Fetch one output file and return it as a pandas DataFrame.
601
+
602
+ Args:
603
+ session_id: Completed processing session.
604
+ output_name: File base name (e.g. ``"dsg_output"``, ``"mdh_output"``)
605
+ or the full filename (``"dsg_output.csv"``). ``.csv``
606
+ is appended if missing.
607
+ timeout: Per-request timeout; defaults to the SDK's normal
608
+ download timeout (15 min).
609
+ read_csv_kwargs: Forwarded to ``pandas.read_csv`` (e.g. ``dtype``,
610
+ ``parse_dates``, ``usecols``).
611
+
612
+ Returns:
613
+ A pandas.DataFrame.
614
+
615
+ Raises:
616
+ AutoDataError: if pandas isn't installed, the file is missing or
617
+ empty (server failed to generate it), or the
618
+ download was truncated.
619
+ """
620
+ pd = self._require_pandas()
621
+ fname = output_name if output_name.lower().endswith(
622
+ (".csv", ".json", ".parquet", ".feather", ".orc")
623
+ ) else f"{output_name}.csv"
624
+ url = self._url(f"/download/{session_id}/{fname}")
625
+ if not url.startswith("http"):
626
+ url = f"{self.base_url}{url}"
627
+ r = self._request(
628
+ "GET", url, stream=True,
629
+ timeout=timeout if timeout is not None else max(self.timeout, 900),
630
+ )
631
+ self._raise_for_error(r)
632
+ cl = r.headers.get("Content-Length")
633
+ if cl == "0":
634
+ raise AutoDataError(
635
+ f"Server returned an empty file for {fname} — the output likely "
636
+ "failed to generate. Retry the run or check /result/<session_id>."
637
+ )
638
+ # Buffer into memory — pandas.read_csv needs a seekable stream and
639
+ # output files are bounded by the server-side row ceiling anyway.
640
+ body = r.content
641
+ if not body:
642
+ raise AutoDataError(f"Server returned 0 bytes for {fname}")
643
+ import io as _io
644
+ buf = _io.BytesIO(body)
645
+ low = fname.lower()
646
+ if low.endswith(".parquet"):
647
+ return pd.read_parquet(buf)
648
+ if low.endswith(".feather"):
649
+ return pd.read_feather(buf)
650
+ if low.endswith(".orc"):
651
+ return pd.read_orc(buf)
652
+ if low.endswith(".json"):
653
+ return pd.read_json(buf, **read_csv_kwargs)
654
+ return pd.read_csv(buf, **read_csv_kwargs)
655
+
656
+ def get_dataframes(
657
+ self,
658
+ session_id: str,
659
+ names: Optional[List[str]] = None,
660
+ *,
661
+ timeout: Optional[float] = None,
662
+ ) -> Dict:
663
+ """Fetch multiple output files and return a ``{name: DataFrame}`` dict.
664
+
665
+ Args:
666
+ session_id: Completed processing session.
667
+ names: Output base names to fetch. ``None`` means every file
668
+ the server lists for the session (skipping PDF
669
+ reports and .json metadata files, which aren't
670
+ naturally a DataFrame).
671
+ timeout: Per-file timeout; see ``get_dataframe``.
672
+
673
+ Returns:
674
+ Dict of ``{file_stem: pandas.DataFrame}``.
675
+ """
676
+ self._require_pandas()
677
+ if names is None:
678
+ result = self.get_result(session_id)
679
+ names = []
680
+ for f in result.get("files", []):
681
+ fn = f.get("name", "")
682
+ low = fn.lower()
683
+ if not low or low.endswith((".pdf", ".json", ".md")):
684
+ continue
685
+ names.append(fn)
686
+ out: Dict = {}
687
+ for n in names:
688
+ # Strip the extension so callers can access via the logical name.
689
+ key = n.rsplit(".", 1)[0] if "." in n else n
690
+ out[key] = self.get_dataframe(session_id, n, timeout=timeout)
691
+ return out
692
+
567
693
  # ------------------------------------------------------------------
568
694
  # Account / API key management
569
695
  # ------------------------------------------------------------------
@@ -699,6 +825,7 @@ class AutoDataClient:
699
825
  compressed: bool = True,
700
826
  incremental: bool = False,
701
827
  type_casts: Optional[Dict[str, str]] = None,
828
+ return_dataframes: bool = False,
702
829
  ) -> Dict:
703
830
  """Run the AutoData pipeline on data from a connector source.
704
831
 
@@ -799,6 +926,9 @@ class AutoDataClient:
799
926
  output_preferences=output_preferences,
800
927
  compressed=compressed,
801
928
  )
929
+ if return_dataframes:
930
+ final = dict(final)
931
+ final["dataframes"] = self.get_dataframes(session_id, names=output_preferences)
802
932
  return final
803
933
 
804
934
  def write_output(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datatoolpack
3
- Version: 0.6.0
3
+ Version: 0.7.0
4
4
  Summary: Official Python SDK for the AutoData ML data preparation pipeline API
5
5
  Home-page: https://autodata.datatoolpack.com
6
6
  Author: AutoData Team
@@ -7,7 +7,7 @@ with open(os.path.join(here, "README.md"), encoding="utf-8") as f:
7
7
 
8
8
  setup(
9
9
  name="datatoolpack",
10
- version="0.6.0",
10
+ version="0.7.0",
11
11
  description="Official Python SDK for the AutoData ML data preparation pipeline API",
12
12
  long_description=long_description,
13
13
  long_description_content_type="text/markdown",
File without changes
File without changes