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.
- {datatoolpack-0.6.0 → datatoolpack-0.7.0}/PKG-INFO +1 -1
- {datatoolpack-0.6.0 → datatoolpack-0.7.0}/datatoolpack/__init__.py +1 -1
- {datatoolpack-0.6.0 → datatoolpack-0.7.0}/datatoolpack/client.py +130 -0
- {datatoolpack-0.6.0 → datatoolpack-0.7.0}/datatoolpack.egg-info/PKG-INFO +1 -1
- {datatoolpack-0.6.0 → datatoolpack-0.7.0}/setup.py +1 -1
- {datatoolpack-0.6.0 → datatoolpack-0.7.0}/README.md +0 -0
- {datatoolpack-0.6.0 → datatoolpack-0.7.0}/datatoolpack.egg-info/SOURCES.txt +0 -0
- {datatoolpack-0.6.0 → datatoolpack-0.7.0}/datatoolpack.egg-info/dependency_links.txt +0 -0
- {datatoolpack-0.6.0 → datatoolpack-0.7.0}/datatoolpack.egg-info/requires.txt +0 -0
- {datatoolpack-0.6.0 → datatoolpack-0.7.0}/datatoolpack.egg-info/top_level.txt +0 -0
- {datatoolpack-0.6.0 → datatoolpack-0.7.0}/pyproject.toml +0 -0
- {datatoolpack-0.6.0 → datatoolpack-0.7.0}/setup.cfg +0 -0
|
@@ -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(
|
|
@@ -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.
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|