Integrate Chalk into your production decisioning systems.
If you want to skip ahead, you can find the full source code for this tutorial on GitHub.
Now that we’ve written some features and resolvers and deployed them to Chalk, we’re ready to integrate Chalk into our production decisioning systems.
As a sanity check, it can be helpful to use the Chalk CLI to query a well-known input and ensure that we get the expected output.
We can use the chalk query
command,
passing in the id of a user, and the names of the features
we want to resolve:
$ chalk query --in user.id=1 \
--out user.name \
--out user.email \
--out user.account.balance
Results
user.name "John Doe"
email "john@doe.com"
user.account.balance 2032.91
Once we’re satisfied that our features and resolvers are working as expected, we can use a client library to query Chalk from our application.
In this first example, we’ll use the
ChalkClient
in the
chalkpy
package
to query Chalk from our application:
from src.models import User
from chalk.client import ChalkClient
# Create a new Chalk client. By default, this will
# pick up the login credentials generated after running
# `chalk login`.
client = ChalkClient()
client.query(
input=User(id=1234),
output=[
User.id,
User.name,
User.fico_score,
User.account.balance,
],
)
We use the same feature definitions for querying our data as we used for defining our features and resolvers.
Chalk has API client libraries in several languages, including Python, Go, Typescript, and Elixir.
All API clients can operate on the string names of features. However, in a production system, you may have many hundreds or thousands of features, and want to avoid hard-coding the names of each feature in your code.
To help with this, Chalk can codegen a library of strongly-typed feature names for you.
For example, say the service that calls into Chalk is written in Go. We can generate a Go library of feature names with the following command:
$ chalk codegen go --out ./clients/go/client.go --package=client
✓ Found resolvers
✓ Wrote features to file './clients/go/client.go'
✓ Please do not change the generated code.
This generates a file
clients/go/client.go
that looks like this:
package client
/**************************************
Code generated by Chalk. DO NOT EDIT.
> chalk codegen go --out ./clients/go/client.go --package client
**************************************/
import (
"github.com/chalk-ai/chalk-go"
"time"
)
var InitFeaturesErr error
type Account struct {
Id *int64
Title *string
UserId *int64
Balance *float64
User *User
UpdatedAt *time.Time
}
type User struct {
Id *int64
Name *string
Email *string
Account *Account
AccountNameMatch *float64
FicoScore *int64
CreditScoreTags *[]any
}
var Features struct {
Account *Account
User *User
}
func init() {
InitFeaturesErr = chalk.InitFeatures(&Features)
}
We can then use this library to query Chalk:
import (
"github.com/chalk-ai/chalk-go"
)
// Create a new Chalk client.
client := chalk.NewClient()
// Create an empty struct to hold the results.
user := User{}
// Query Chalk, and add the results to the struct.
_, err = client.OnlineQuery(
chalk.OnlineQueryParams{}.
WithInput(Features.User.Id, 1234).
WithOutputs(
Features.User.Id,
Features.User.LastName,
Features.User.FicoScore,
Features.User.Account.Balance,
),
&user,
)
// Now, you can access the properties of the
// user for which there was a matching `output`.
fmt.Println(user.Account.Balance)
If your calling service is written in Python, but you don’t want to take a dependency on the repository that contains your Chalk features, you can generate your Python features into a separate repository:
$ chalk codegen python --out ./clients/python/client.py
You can see the generated code in
clients/python/client.py
.
If you are generating Python into a subdirectory of your
Chalk project, be sure to add an entry to your
.chalkignore
containing the directory of your generated code
(in the above example, clients/
).
Otherwise, Chalk will find duplicate definitions
of your features.