1
+ package main
2
+
3
+ import (
4
+ "context"
5
+ "github.com/joho/godotenv"
6
+ modzy "github.com/modzy/sdk-go"
7
+ "log"
8
+ "os"
9
+ "time"
10
+ )
11
+
12
+ var (
13
+ ctx = context .TODO ()
14
+ )
15
+
16
+ func main () {
17
+ // The system admin can provide the right base API URL, the API key can be downloaded from your profile page on Modzy.
18
+ // You can configure those params as is described in the README file (as environment variables, or by using the .env file),
19
+ // or you can just update the BASE_URL and API_KEY variables and use this sample code (not recommended for production environments).
20
+ err := godotenv .Load ()
21
+ if err != nil {
22
+ log .Fatal ("Error loading .env file" )
23
+ }
24
+ // The MODZY_BASE_URL should point to the API services route which may be different from the Modzy page URL.
25
+ // (ie: https://modzy.example.com).
26
+ baseURL := os .Getenv ("MODZY_BASE_URL" )
27
+ // The MODZY_API_KEY is your own personal API key. It is composed by a public part, a dot character, and a private part
28
+ // (ie: AzQBJ3h4B1z60xNmhAJF.uQyQh8putLIRDi1nOldh).
29
+ apiKey := os .Getenv ("MODZY_API_KEY" )
30
+ // Client initialization:
31
+ // Initialize the ApiClient instance with the BASE_URL and the API_KEY to store those arguments
32
+ // for the following API calls.
33
+ client := modzy .NewClient (baseURL ).WithAPIKey (apiKey )
34
+ // Create a Job with a text input, wait, and retrieve results:
35
+ // Get the model object:
36
+ // If you already know the model identifier (i.e.: you got it from the URL of the model details page or from the input sample),
37
+ // you can skip this step. If you don't, you can find the model identifier by using its name as follows:
38
+ //model, err := client.Models().GetModelDetailsByName(ctx, &modzy.GetModelDetailsByNameInput{Name: "Sentiment Analysis"})
39
+ // Or if you already know the model id and want to know more about the model, you can use this instead:
40
+ model , err := client .Models ().GetModelDetails (ctx , & modzy.GetModelDetailsInput {ModelID : "cbf9e8d6da" })
41
+ // You can find more information about how to query the models on the model_sample.go file.
42
+ // The model identifier is under the ModelID key. You can take a look at the other properties under ModelDetails struct
43
+ // Or just log the model identifier, and potencially the latest version
44
+ log .Printf ("The model identifier is %s and the latest version is %s\n " , model .Details .ModelID , model .Details .LatestVersion )
45
+ // Get the model version object:
46
+ // If you already know the model version and the input key(s) of the model version you can skip this step. Also, you can
47
+ // use the following code block to know about the inputs keys and skip the call on future job submissions.
48
+ modelVersion , err := client .Models ().GetModelVersionDetails (ctx , & modzy.GetModelVersionDetailsInput {ModelID : model .Details .ModelID , Version : model .Details .LatestVersion })
49
+ if err != nil {
50
+ log .Fatalf ("Unexpected error %s" , err )
51
+ return
52
+ }
53
+ // The info stored in modelVersion provides insights about the amount of time that the model can spend processing, the inputs, and
54
+ // output keys of the model.
55
+ log .Printf ("The model version is %s\n " , modelVersion .Details .Version )
56
+ log .Printf (" timeouts: status %dms, run %dms\n " ,modelVersion .Details .Timeout .Status , modelVersion .Details .Timeout .Run )
57
+ log .Println (" inputs:" )
58
+ for _ , input := range modelVersion .Details .Inputs {
59
+ log .Printf (" key %s, type %s, description: %s\n " , input .Name , input .AcceptedMediaTypes , input .Description )
60
+ }
61
+ log .Println (" outputs:" )
62
+ for _ , output := range modelVersion .Details .Outputs {
63
+ log .Printf (" key %s, type %s, description: %s\n " , output .Name , output .MediaType , output .Description )
64
+ }
65
+ // Send the job:
66
+ // With the info about the model (identifier), the model version (version string, input/output keys), you are ready to
67
+ // submit the job. Just prepare the source map:
68
+ mapSource := make (map [string ]modzy.TextInputItem )
69
+ mapInput := make (modzy.TextInputItem )
70
+ mapInput ["input.txt" ] = "Modzy is great!"
71
+ mapSource ["source-key" ] = mapInput
72
+ // An inference job groups input data that you send to a model. You can send any amount of inputs to
73
+ // process and you can identify and refer to a specific input by the key that you assign, for example we can add:
74
+ mapInput = make (modzy.TextInputItem )
75
+ mapInput ["input.txt" ] = "Sometimes I really hate ribs"
76
+ mapSource ["second-key" ] = mapInput
77
+ mapInput = make (modzy.TextInputItem )
78
+ mapInput ["input.txt" ] = "Born and raised in Pennsylvania, Swift moved to Nashville, Tennessee, at the age of 14 to pursue a career in country music"
79
+ mapSource ["another-key" ] = mapInput
80
+ //If you send a wrong input key, the model fails to process the input.
81
+ mapInput = make (modzy.TextInputItem )
82
+ mapInput ["a.wrong.key" ] = "This input is wrong!"
83
+ mapSource ["wrong-key" ] = mapInput
84
+ // When you have all your inputs ready, you can use our helper method to submit the job as follows:
85
+ job , err := client .Jobs ().SubmitJobText (ctx , & modzy.SubmitJobTextInput {
86
+ ModelIdentifier : model .Details .ModelID ,
87
+ ModelVersion : modelVersion .Details .Version ,
88
+ Inputs : mapSource ,
89
+ })
90
+ if err != nil {
91
+ log .Fatalf ("Unexpected error %s" , err )
92
+ return
93
+ }
94
+ // Modzy creates the job and queue for processing. The job object contains all the info that you need to keep track
95
+ // of the process, the most important being the job identifier and the job status.
96
+ log .Printf ("job: %s \n " , job .Response .JobIdentifier )
97
+ // The job moves to SUBMITTED, meaning that Modzy acknowledged the job and sent it to the queue to be processed.
98
+ // We provide a helper method to listen until the job finishes processing. Its a good practice to set a max timeout
99
+ // if you're doing a test (ie: 2*status+run). Otherwise, if the timeout is set to None, it will listen until the job finishes and moves to
100
+ // COMPLETED, CANCELED, or TIMEOUT.
101
+ job2 , err := client .Jobs ().WaitForJobCompletion (ctx , & modzy.WaitForJobCompletionInput {JobIdentifier : job .Response .JobIdentifier }, 20 * time .Second )
102
+ if err != nil {
103
+ log .Fatalf ("Unexpected error %s" , err )
104
+ return
105
+ }
106
+ // Get the results:
107
+ // Check the status of the job. Jobs may be canceled or may reach a timeout.
108
+ if job2 .Details .Status == "COMPLETED" {
109
+ // A completed job means that all the inputs were processed by the model. Check the results for each
110
+ // input key provided in the source map to see the model output.
111
+ results , err := client .Jobs ().GetJobResults (ctx , & modzy.GetJobResultsInput {JobIdentifier : job .Response .JobIdentifier })
112
+ if err != nil {
113
+ log .Fatalf ("Unexpected error %s" , err )
114
+ return
115
+ }
116
+ // The result object has some useful info:
117
+ log .Printf ("Result: finished: %s, total: %d, completed: %d, failed: %d" ,
118
+ results .Results .Finished ,
119
+ results .Results .Total ,
120
+ results .Results .Completed ,
121
+ results .Results .Failed )
122
+ // Notice that we are iterating through the same input source keys
123
+ for key , _ := range mapSource {
124
+ // The result object has the individual results of each job input. In this case the output key is called
125
+ // results.json, so we can get the results as follows:
126
+ if result , exists := results .Results .Results [key ]; exists {
127
+ // The output for this model comes in a JSON format, so we can directly log the model results:
128
+ log .Printf (" %s: %s\n " , key , result .Data ["results.json" ])
129
+ } else {
130
+ // If the model raises an error, we can get the specific error message:
131
+ log .Fatalf (" %s: %s\n " , key , result .Data )
132
+ }
133
+ }
134
+
135
+ } else {
136
+ log .Fatalf ("The job ends with status %s" , job2 .Details .Status )
137
+ }
138
+ }
0 commit comments