Skip to content

Task/dss12.6.2 publish package #292

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions HISTORY.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ Changelog



12.6.2 (2024-05-16)
---------------------

* Initial release for DSS 12.6.2

12.6.0 (2024-04-09)
---------------------

Expand Down
4 changes: 2 additions & 2 deletions dataikuapi/dss/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -622,10 +622,10 @@ def get_client_as(self):
from dataikuapi.dssclient import DSSClient

if self.client.api_key is not None:
return DSSClient(self.client.host, self.client.api_key, extra_headers={"X-DKU-ProxyUser": self.login})
return DSSClient(self.client.host, self.client.api_key, extra_headers={"X-DKU-ProxyUser": self.login}, insecure_tls=not self.client._session.verify)
elif self.client.internal_ticket is not None:
return DSSClient(self.client.host, internal_ticket = self.client.internal_ticket,
extra_headers={"X-DKU-ProxyUser": self.login})
extra_headers={"X-DKU-ProxyUser": self.login}, insecure_tls=not self.client._session.verify)
else:
raise ValueError("Don't know how to proxy this client")

Expand Down
2 changes: 1 addition & 1 deletion dataikuapi/dss/codestudio.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ def pull_from_code_studio(self, zone):

:param str zone: name of the zone to pull (see :meth:`dataikuapi.dss.codestudio.DSSCodeStudioObjectStatus.get_zones`)
"""
return self.client._perform_json("GET", "/projects/%s/code-studios/%s/pull/%s" % (self.project_key, self.code_studio_id, zone))
self.client._perform_empty("GET", "/projects/%s/code-studios/%s/pull/%s" % (self.project_key, self.code_studio_id, zone))

def push_to_code_studio(self, zone):
"""
Expand Down
23 changes: 12 additions & 11 deletions dataikuapi/dss/data_quality.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ class DSSDataQualityRuleSet(object):
"""
Base settings class for dataset data quality rules.

.. caution:: Do not instantiate this class directly, use :meth:`DSSDataset.get_data_quality_rules`
.. caution::
Do not instantiate this class directly, use :meth:`dataikuapi.dss.dataset.DSSDataset.get_data_quality_rules`
"""
def __init__(self, project_key, dataset_name, client):
self.ruleset = { "checks": [] }
Expand All @@ -20,7 +21,7 @@ def list_rules(self, as_type="objects"):
:param str as_type: How to return the rules. Possible values are "dict" and "objects" (defaults to **objects**)

:returns: The rules defined on the dataset.
:rtype: a list of :class:`dataikuapi.dss.data_quality.DSSDataQualityRule` if as_type is "objects",
:rtype: a list of :class:`DSSDataQualityRule` if as_type is "objects",
a list of dict if as_type is "dict"
"""
self.ruleset = self.client._perform_json("GET", "/projects/%s/datasets/%s/data-quality/rules" % (self.project_key, self.dataset_name))
Expand All @@ -38,7 +39,7 @@ def create_rule(self, config=None):
:param object config: The config of the rule

:returns: The created data quality rule
:rtype: :class: `DSSDataQualityRule`
:rtype: :class:`DSSDataQualityRule`
"""
if not config:
raise ValueError("Config is required")
Expand Down Expand Up @@ -69,7 +70,7 @@ def compute_rules(self, partition="NP"):
:param str partition: If the dataset is partitioned, the name of the partition to compute (or "ALL" to compute on the whole dataset). If the dataset is not partitioned use "NP" or None.

:returns: Job of the currently computed data quality rules.
:rtype: :class: `DSSFuture`
:rtype: :class:`dataikuapi.dss.future.DSSFuture`
"""
if not partition:
partition = "NP"
Expand Down Expand Up @@ -103,7 +104,7 @@ def get_last_rules_results(self, partition="NP"):
:param str partition: If the dataset is partitioned, the name of the partition to get the detailed rules results (or "ALL" to compute on the whole dataset). If the dataset is not partitioned use "NP" or None.

:returns: The last result of each rule on the specified partition
:rtype: a list of :class: `dataikuapi.dss.data_quality.DSSDataQualityRuleResult`
:rtype: a list of :class:`DSSDataQualityRuleResult`
"""
if not partition:
partition = "NP"
Expand All @@ -121,7 +122,7 @@ def get_rules_history(self, min_timestamp=None, max_timestamp=None, results_per_
:param list rule_ids: A list of rule ids to get the history from. Default is all the rules on the dataset.

:returns: The detailed execution of data quality rules matching the filters set
:rtype: a list of :class:`dataikuapi.dss.data_quality.DSSDataQualityRuleResult`
:rtype: a list of :class:`DSSDataQualityRuleResult`
"""
rule_results = self.client._perform_json("GET", "/projects/%s/datasets/%s/data-quality/rules-history" % (self.project_key, self.dataset_name), params={ "minTimestamp": min_timestamp, "maxTimestamp": max_timestamp, "resultsPerPage": results_per_page, "page": page, "ruleIds": rule_ids })
return [DSSDataQualityRuleResult(result) for result in rule_results]
Expand All @@ -131,7 +132,7 @@ class DSSDataQualityRule(object):
"""
A rule defined on a dataset.

Do not instantiate this class, use :meth:`dataikuapi.dss.data_quality.DSSDataQualityRuleSet.get_rule`
.. caution:: Do not instantiate this class, use :meth:`DSSDataQualityRuleSet.list_rules`
"""
def __init__(self, rule, dataset_name, project_key, client):
self.rule = rule
Expand Down Expand Up @@ -162,7 +163,7 @@ def compute(self, partition="NP"):
:param str partition: If the dataset is partitioned, the name of the partition to compute (or "ALL" to compute on the whole dataset). If the dataset is not partitioned use "NP" or None.

:returns: A job of the computation of the rule.
:rtype: DSSFuture
:rtype: :class:`dataikuapi.dss.future.DSSFuture`
"""
if not partition:
partition = "NP"
Expand Down Expand Up @@ -192,7 +193,7 @@ def get_last_result(self, partition="NP"):
:param str partition: If the dataset is partitioned, the name of the partition to get the detailed rules results (or "ALL" to refer to the whole dataset). If the dataset is not partitioned use "NP" or None.

:returns: The last result of the rule on the specified partition
:rtype: :class:`dataikuapi.dss.data_quality.DSSDataQualityRuleResult`
:rtype: :class:`DSSDataQualityRuleResult`
"""
if not partition:
partition = "NP"
Expand All @@ -212,7 +213,7 @@ def get_rule_history(self, min_timestamp=None, max_timestamp=None, results_per_p
:param int page: The page to be returned, default will be first page.

:returns: The detailed execution of data quality rule matching the timeframe set
:rtype: a list of :class:`dataikuapi.dss.data_quality.DSSDataQualityRuleResult`
:rtype: a list of :class:`DSSDataQualityRuleResult`
"""
rule_results = self.client._perform_json("GET", "/projects/%s/datasets/%s/data-quality/rules-history" % (self.project_key, self.dataset_name), params={ "minTimestamp": min_timestamp, "maxTimestamp": max_timestamp, "resultsPerPage": results_per_page, "page": page, "ruleId": self.rule["id"] })
return [DSSDataQualityRuleResult(result) for result in rule_results]
Expand All @@ -221,7 +222,7 @@ class DSSDataQualityRuleResult(object):
"""
The result of a rule defined on a dataset

Do not instantiate this class, use :meth:`dataikuapi.dss.data_quality.DSSDataQualityRuleSet.get_last_rules_results`or :meth: `dataikuapi.dss.data_quality.DSSDataQualityRuleSet.get_rules_history` or :meth: `dataikuapi.dss.data_quality.DSSDataQualityRule.get_last_result` or :meth: `dataikuapi.dss.data_quality.DSSDataQualityRule.get_rule_history`
.. caution:: Do not instantiate this class, use: :meth:`DSSDataQualityRuleSet.get_last_rules_results` or :meth:`DSSDataQualityRuleSet.get_rules_history` or :meth:`DSSDataQualityRule.get_last_result` or :meth:`DSSDataQualityRule.get_rule_history`
"""
def __init__(self, data):
self.data = data
Expand Down
6 changes: 3 additions & 3 deletions dataikuapi/dss/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ def run_checks(self, partition='', checks=None):

.. caution::

Deprecated. Use :meth:`DSSDataQualityRuleSet.compute_rules` instead
Deprecated. Use :meth:`dataikuapi.dss.data_quality.DSSDataQualityRuleSet.compute_rules` instead

:param str partition: (optional) partition identifier, use ALL to run checks on all data.
:param list[string] checks: (optional) ids of the checks to run.
Expand Down Expand Up @@ -927,9 +927,9 @@ def new_recipe(self, type, recipe_name=None):

def get_data_quality_rules(self):
"""
Get a DSSDataQualityRuleSet dataiku object to interact with the data quality rules of the dataset.
Get a handle to interact with the data quality rules of the dataset.

:returns:
:returns: A handle to the data quality rules of the dataset.
:rtype: :class:`dataikuapi.dss.data_quality.DSSDataQualityRuleSet`
"""
return DSSDataQualityRuleSet(self.project_key, self.dataset_name, self.client)
Expand Down
7 changes: 7 additions & 0 deletions dataikuapi/dss/flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from .savedmodel import DSSSavedModel
from .modelevaluationstore import DSSModelEvaluationStore
from .recipe import DSSRecipe, DSSRecipeDefinitionAndPayload
from .knowledgebank import DSSKnowledgeBank
from .future import DSSFuture
from .streaming_endpoint import DSSStreamingEndpoint
import logging, json
Expand Down Expand Up @@ -238,6 +239,8 @@ def _to_smart_ref(self, obj):
ot = "STREAMING_ENDPOINT"
elif isinstance(obj, DSSLabelingTask):
ot = "LABELING_TASK"
elif isinstance(obj, DSSKnowledgeBank):
ot = "RETRIEVABLE_KNOWLEDGE"
else:
raise ValueError("Cannot transform to DSS object ref: %s" % obj)

Expand Down Expand Up @@ -447,6 +450,8 @@ def _to_native_obj(self, zone_item):
return p.get_labeling_task(zone_item["objectId"])
elif zone_item["objectType"] == "MODEL_EVALUATION_STORE":
return p.get_model_evaluation_store(zone_item["objectId"])
elif zone_item["objectType"] == "RETRIEVABLE_KNOWLEDGE":
return p.get_knowledge_bank(zone_item["objectId"])
else:
raise ValueError("Cannot transform to DSS object: %s" % zone_item)

Expand Down Expand Up @@ -733,6 +738,8 @@ def _get_object_from_graph_node(self, node):
return DSSStreamingEndpoint(self.flow.client, self.flow.project.project_key, node["ref"])
elif node["type"] == "RUNNABLE_LABELING_TASK":
return DSSLabelingTask(self.flow.client, self.flow.project.project_key, node["ref"])
elif node["type"] == "COMPUTABLE_RETRIEVABLE_KNOWLEDGE":
return DSSKnowledgeBank(self.flow.client, self.flow.project.project_key, node["ref"])
else:
# TODO add streaming elements
raise Exception("unsupported node type: %s" % node["type"])
Expand Down
2 changes: 1 addition & 1 deletion dataikuapi/dss/insight.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class DSSInsight(object):

.. important::

Do not instantiate directly, use :meth:`dataikuapi.dss.DSSProject.get_insight` instead
Do not instantiate directly, use :meth:`dataikuapi.dss.project.DSSProject.get_insight` instead
"""
def __init__(self, client, project_key, insight_id):
self.client = client
Expand Down
171 changes: 169 additions & 2 deletions dataikuapi/dss/llm.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ def new_embeddings(self):
"""
return DSSLLMEmbeddingsQuery(self)

def new_images_generation(self):
return DSSLLMImageGenerationQuery(self)



class DSSLLMEmbeddingsQuery(object):
"""
Expand All @@ -99,7 +103,13 @@ class DSSLLMEmbeddingsQuery(object):
"""
def __init__(self, llm):
self.llm = llm
self.eq = {"queries": [], "llmId": llm.llm_id}
self.eq = {
"queries": [],
"llmId": llm.llm_id,
"settings": {
# TODO: include textOverflowMode when merging into master
}
}

def add_text(self, text):
"""
Expand Down Expand Up @@ -378,4 +388,161 @@ def __init__(self, raw_resp):
def responses(self):
"""The array of responses"""
return [DSSLLMCompletionResponse(x) for x in self._raw]






class DSSLLMImageGenerationQuery(object):
"""
A handle to interact with an image generation query.

.. important::
Do not create this class directly, use :meth:`dataikuapi.dss.llm.DSSLLM.new_images_generation` instead.
"""
def __init__(self, llm):
self.llm = llm
self.gq = {
"prompts": [],
"negativePrompts": [],
"llmId": self.llm.llm_id
}

def with_prompt(self, prompt, weight=None):
"""
"""
self.gq["prompts"].append({"prompt": prompt, "weight": weight})
return self

def with_negative_prompt(self, prompt, weight=None):
"""
"""
self.gq["negativePrompts"].append({"prompt": prompt, "weight": weight})
return self

def with_original_image(self, image, mode=None, weight=None):
if isinstance(image, str):
self.gq["originalImage"] = image
elif isinstance(image, bytes):
import base64
self.gq["originalImage"] = base64.b64encode(image).decode("utf8")

if mode is not None:
self.gq["originalImageEditionMode"] = mode

if weight is not None:
self.gq["originalImageWeight"] = weight
return self

def with_mask(self, mode, image=None, text=None):
self.gq["maskMode"] = mode

if image is not None:
if isinstance(image, str):
self.gq["maskImage"] = image
elif isinstance(image, bytes):
import base64
self.gq["maskImage"] = base64.b64encode(image).decode("utf8")
return self

@property
def height(self):
return self.gq.get("height", None)
@height.setter
def height(self, new_value):
self.gq["height"] = new_value

@property
def width(self):
return self.gq.get("width", None)
@width.setter
def width(self, new_value):
self.gq["width"] = new_value

@property
def fidelity(self):
return self.gq.get("fidelity", None)
@fidelity.setter
def fidelity(self, new_value):
self.gq["fidelity"] = new_value

@property
def quality(self):
return self.gq.get("quality", None)
@quality.setter
def quality(self, new_value):
self.gq["quality"] = new_value

@property
def seed(self):
return self.gq.get("seed", None)
@seed.setter
def seed(self, new_value):
self.gq["seed"] = new_value

@property
def style(self):
"""Style of the image to generate. Valid values depend on the targeted model"""
return self.gq.get("style", None)
@style.setter
def style(self, new_value):
self.gq["style"] = new_value

@property
def images_to_generate(self):
return self.gq.get("nbImagesToGenerate", None)
@images_to_generate.setter
def images_to_generate(self, new_value):
self.gq["nbImagesToGenerate"] = new_value

def with_aspect_ratio(self, ar):
self.gq["height"] = 1024
self.gq["width"] = int(1024 * ar)
return self

def execute(self):
"""
Executes the image generation

:rtype: :class:DSSLLMImageGenerationResponse
"""

ret = self.llm.client._perform_json("POST", "/projects/%s/llms/images" % (self.llm.project_key), body=self.gq)
return DSSLLMImageGenerationResponse(ret)

class DSSLLMImageGenerationResponse(object):
"""
A handle to interact with an image generation response.

.. important::
Do not create this class directly, use :meth:`dataikuapi.dss.llm.DSSLLMImageGenerationQuery.execute` instead.
"""
def __init__(self, raw_resp):
self._raw = raw_resp

@property
def success(self):
"""
:return: The outcome of the image generation query.
:rtype: bool
"""
return self._raw["ok"]

def first_image(self, as_type="bytes"):
"""
:return: The first generated image.
:rtype: str
"""

if not self.success:
raise Exception("Image generation did not succeed: %s" % self._raw["errorMessage"])

if len(self._raw["images"]) == 0:
raise Exception("Image generation succeeded but did not return any image")

if as_type == "bytes":
import base64
return base64.b64decode(self._raw["images"][0]["data"])

else:
return self._raw["images"][0]["data"]
Loading