A Migration Guide for the new SDK - v0.5
Learn how to migrate to the latest version of the JFrog ML Python SDK.
About v0.5
This version brings a multitude of improvements, new features, and enhanced performance, all aimed at providing you with an even better JFrog ML experience.
With v0.5, we introduce the qwak-sdk
as a public Python package. We reduced package dependencies and refactored the codebase to make it more lightweight.
While these changes bring many benefits, they also introduce breaking changing that require minor modifications to your existing codebase.
Installing the new SDK
Starting with v0.5, the qwak-sdk
can be found on the public PyPI package repository. All you need is to run:
pip install qwak-sdk
Alternatively, when upgrading an existing qwak-sdk
installation, run the following command:
pip install --upgrade qwak-sdk
Models changes
We recommend starting to migrate models one by one to the new JFrog ML SDK, even if they are not built regularly.
Model base class
In the new SDK, the old QwakModelInterface
becomes QwakModel
to simplify the name of the main JFrog ML model interface. Here's how the imports look like:
New Qwak SDK - v0.5
from qwak.model.base import QwakModel
class NewPredicitionModel(QwakModel):
def __init__(self):
pass
Qwak SDK - v0.9
from qwak.model.base import QwakModelInterface
class OldPredicitionModlel(QwakModelInterface):
def __init__(self):
pass
Building with
--from-file
If you're using configuration files with your
qwak models build
commands, keep in mind that there have been some small changes in the configurations between SDK versions. We recommend running a sample build command with the--out-conf
flag. This will create a basic config file for you. Start with this default config and then transfer any settings from your old file to the new one.
Additional model import changes
#V0.9
qwak.model.loggers import artifact_logger
# V0.5
from qwak.model_loggers import artifact_logger
Local testing
We updated and improved the way local testing and debugging work for JFrog ML models.
Please note that run_local
method is now imported externally from from qwak.model.tools import run_local
and receives the model object as input.
New Qwak SDK - v0.5
from qwak.model.tools import run_local
model = MyQwakModel()
input_vector = DataFrame(
[{
"prompt": "Why does it matter if a Central Bank has a negative rather than 0% interest rate?"
}]
).to_json()
prediction = run_local(m, input_vector)
Qwak SDK - v0.9
from qwak.model.tools import run_local
model = MyQwakModel()
input_vector = DataFrame(
[{
"prompt": "Why does it matter if a Central Bank has a negative rather than 0% interest rate?"
}]
).to_json()
precidtion = model.run_local(input_vector)
ModelSchema
The model schema defines your model's inputs and outputs.
The class constructor fields changed from features
/ predictions
originally, to inputs
/ outputs
.
Moreover, the previous outputs Prediction
class has now been renamed to InferenceOutput
, the import path remaining the same.
New Qwak SDK - v0.5
from qwak.model.base import QwakModel
from qwak.model.schema import ModelSchema, ExplicitFeature, InferenceOutput
class NewModelWithSchema(QwakModel):
def schema(self):
model_schema = ModelSchema(
inputs=[
ExplicitFeature(name="User_Name", type=str),
ExplicitFeature(name="Duration", type=int),
],
outputs=[
InferenceOutput(name="Churn_Probability", type=float)
])
return model_schema
Qwak SDK - v0.9
from qwak.model.base import QwakModelInterface
from qwak.model.schema import ModelSchema, ExplicitFeature, InferenceOutput
class ModelWithSchema(QwakModelInterface):
def schema(self):
model_schema = ModelSchema(
features=[
ExplicitFeature(name="User_Name", type=str),
ExplicitFeature(name="Duration", type=int),
],
predictions=[
Prediction(name="Churn_Probability", type=float)
])
return model_schema
Unifying test mocks
The origianl integration tests mocks from the qwak_mock
package, are now deprecated and the new mock modules have been moved under the qwak.testing
in the main qwak
package.
New Qwak SDK - v0.5
from qwak.testing.fixtures import real_time_client
def test_realtime_api(real_time_client):
feature_vector = [
{
'text': 'To the Moon!'
}]
real_time_client.predict(feature_vector)
Qwak SDK - v0.9
from qwak_mock import real_time_client
def test_realtime_api(real_time_client):
feature_vector = [
{
'text': 'To the Moon!'
}]
real_time_client.predict(feature_vector)
JFrog ML Secret Service
The older client SecretServiceGrpcClient
has now changed to the new SecretServiceClient
together with the package as shown below. Moreover, the secret service client is now under the qwak.clients
package, together with other client libraries.
New Qwak SDK - v0.5
from qwak import QwakModel
from qwak.clients.secret_service import SecretServiceClient
class TestModel(QwakModel)
# ...
def build():
secret_service = SecretServiceClient()
aws_api_key = secret_service.get_secret('aws_api_key')
aws_secret_key = secret_service.get_secret('aws_secret_key')
Qwak SDK - v0.9
from qwak import QwakModelInterface
from qwak.secret_service.client import SecretServiceGrpcClient
class TestModel(QwakModel)
# ...
def build():
secrets_client = SecretServiceGrpcClient()
aws_api_key = secret_service.get_secret('aws_api_key')
aws_secret_key = secret_service.get_secret('aws_secret_key')
Calling the live model
The RealTimeClient
used to request predictions against the live model has been moved to a different dependency, which is installed separately with:
pip install qwak-inference
By doing that, we removed the dependencies from the main qwak-sdk
package, which is now lighter.
New Qwak SDK v0.5
from qwak_inference import RealTimeClient
QWAK_MODEL_ID = 'text-summarizer'
if __name__ == '__main__':
feature_vector = [
{
"text" : "Please summarize this sentence",
}
]
client = RealTimeClient(model_id=QWAK_MODEL_ID)
response = client.predict(feature_vector)
Qwak SDK v0.9
from qwak.inference.clients import RealTimeClient
QWAK_MODEL_ID = 'text-summarizer'
if __name__ == '__main__':
feature_vector = [
{
"text" : "Please summarize this sentence",
}
]
client = RealTimeClient(model_id=QWAK_MODEL_ID)
response = client.predict(feature_vector)
CLI changes
Simplifying model creation
Creating new models and projects required two commands. We merged them into one, and made description optional.
New Qwak SDK v0.5
qwak models create “Credit Risk” --project “Credit Risk Modeling”
Qwak SDK v0.9
qwak projects create --project-name "Credit Risk Modeling" --project-description "An example project"
qwak models create --project-id <your-project-id> --model-name "Credit Risk" --model-description "An example model"
Automatic build and deploy
Deploy models automatically in a single command using qwak models build
and the --deploy
parameter.
New Qwak SDK v0.5
qwak models build ./credit_risk --model-id "credit_risk" --deploy
Qwak SDK v0.9
qwak models build ./credit_risk --model-id "credit_risk"
qwak models deploy realtime --model-id "credit_risk" --build-id <your-build-id>
Feature Store Changes
When it comes to updating Feature Store related objects, it's not mandatory to re-create the existing data sources, feature sets, entities and so on. However, the new SDK should be used for any new registered objects, going forward.
Batch Feature Set
Starting with the new SDK, the packages and classes related to batch feature sets can be found in qwak.feature_store.feature_sets
.
New Qwak SDK v0.5
from qwak.feature_store.feature_sets import batch
from qwak.feature_store.feature_sets.transformations import SparkSqlTransformation
from qwak.feature_store.feature_sets.execution_spec import ClusterTemplate
from qwak.feature_store.feature_sets.read_policies import ReadPolicy
Qwak SDK v0.9
from qwak.feature_store.v1 import batch, SparkSqlTransformation
from qwak.feature_store.features.execution_spec import ClusterTemplate
from qwak.feature_store.features import ReadPolicy
Data source import path
Similarly to feature sets, we also simplified the import path of all data sources to qwak.feature_store.data_sources
.
New Qwak SDK v0.5
from qwak.feature_store.data_sources import CsvSource, SnowflakeSource
Qwak SDK v0.9
from qwak.feature_store.sources.data_sources import CsvSource, SnowflakeSource
Offline & Online Features
The previous feature querying and fetching libraries for the online and offline stores have been migrated to the qwak.feature_store.online
and .offline
packages. The new clients are now called OfflineClient
and OnlineClient
as seen below:
New Qwak SDK v0.5
from qwak.feature_store.offline.client import OfflineClient
offline_feature_store = OfflineClient()
from qwak.feature_store.online.client import OnlineClient
online_feature_store = OnlineClient()
Qwak SDK v0.9
from qwak.feature_store.offline import OfflineFeatureStore
offline_feature_store = OfflineFeatureStore()
New dependency requirements
When fetching features from the OfflineClient, it is now required to add the following libraries to your dependency management file:
pyathena
andpyarrow==12.0.1
When retrieving online features, either through the use of the feature_extraction
decorator flag or by employing the OnlineClient
, the columns in the resulting DataFrame will be named according to the following convention
feature-set-name.feature-name
as outlined in the example below:
def schema(self) -> ModelSchema:
model_schema = ModelSchema(
inputs=[
FeatureStoreInput(name='users-feature-set.count')]
)
return model_schema
@qwak.api(feature_extraction=True)
def predict(self, dfs, extracted_df):
# Here's how to reference with the old SDK
old_extracted_feature = extracted_df['count']
# Here's how to reference with the new SDK (correct way)
new_extracted_feature = extracted_df['users-feature-set.count']
If you think something is missing from this guide, please let our team know and we will update it accordingly.
Updated 18 days ago