Skip to content

Commit 9f73db4

Browse files
committed
add lite model information to brickDetails endpoint
1 parent 84d7584 commit 9f73db4

File tree

7 files changed

+76
-12
lines changed

7 files changed

+76
-12
lines changed

internal/api/docs/openapi.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,6 +1171,8 @@ components:
11711171
runner:
11721172
type: string
11731173
type: object
1174+
AIModelLite:
1175+
type: object
11741176
AIModelsListResult:
11751177
properties:
11761178
models:
@@ -1314,6 +1316,11 @@ components:
13141316
type: string
13151317
id:
13161318
type: string
1319+
models:
1320+
items:
1321+
$ref: '#/components/schemas/AIModelLite'
1322+
nullable: true
1323+
type: array
13171324
name:
13181325
type: string
13191326
readme:

internal/e2e/client/client.gen.go

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/e2e/daemon/brick_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
"github.com/arduino/arduino-app-cli/internal/e2e/client"
3131
"github.com/arduino/arduino-app-cli/internal/orchestrator/bricksindex"
3232
"github.com/arduino/arduino-app-cli/internal/orchestrator/config"
33+
"github.com/arduino/arduino-app-cli/internal/orchestrator/modelsindex"
3334
"github.com/arduino/arduino-app-cli/internal/store"
3435
)
3536

@@ -115,6 +116,17 @@ func TestBricksDetails(t *testing.T) {
115116
},
116117
}
117118

119+
expectedModelLiteInfo := []modelsindex.AIModelLite{
120+
{
121+
ID: "mobilenet-image-classification",
122+
Name: "General purpose image classification",
123+
ModuleDescription: "General purpose image classification model based on MobileNetV2. This model is trained on the ImageNet dataset and can classify images into 1000 categories.",
124+
},
125+
{
126+
ID: "person-classification",
127+
Name: "Person classification",
128+
ModuleDescription: "Person classification model based on WakeVision dataset. This model is trained to classify images into two categories: person and not-person.",
129+
}}
118130
response, err := httpClient.GetBrickDetailsWithResponse(t.Context(), validBrickID, func(ctx context.Context, req *http.Request) error { return nil })
119131
require.NoError(t, err)
120132
require.Equal(t, http.StatusOK, response.StatusCode(), "status code should be 200 ok")
@@ -133,5 +145,7 @@ func TestBricksDetails(t *testing.T) {
133145
require.NotEmpty(t, *response.JSON200.Readme)
134146
require.NotNil(t, response.JSON200.UsedByApps, "UsedByApps should not be nil")
135147
require.Equal(t, expectedUsedByApps, *(response.JSON200.UsedByApps))
148+
require.NotNil(t, response.JSON200.Models, "Models should not be nil")
149+
require.Equal(t, expectedModelLiteInfo, *(response.JSON200.Models))
136150
})
137151
}

internal/orchestrator/bricks/bricks.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,6 @@ func (s *Service) BricksDetails(id string, idProvider *app.IDProvider,
190190
if err != nil {
191191
return BrickDetailsResult{}, fmt.Errorf("unable to get used by apps: %w", err)
192192
}
193-
194193
return BrickDetailsResult{
195194
ID: id,
196195
Name: brick.Name,
@@ -203,6 +202,7 @@ func (s *Service) BricksDetails(id string, idProvider *app.IDProvider,
203202
ApiDocsPath: apiDocsPath,
204203
CodeExamples: codeExamples,
205204
UsedByApps: usedByApps,
205+
Models: s.modelsIndex.GetModelsLiteInfoByBrick(brick.ID),
206206
}, nil
207207
}
208208

internal/orchestrator/bricks/types.go

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
package bricks
1717

18+
import "github.com/arduino/arduino-app-cli/internal/orchestrator/modelsindex"
19+
1820
type BrickListResult struct {
1921
Bricks []BrickListItem `json:"bricks"`
2022
}
@@ -66,15 +68,16 @@ type AppReference struct {
6668
}
6769

6870
type BrickDetailsResult struct {
69-
ID string `json:"id"`
70-
Name string `json:"name"`
71-
Author string `json:"author"`
72-
Description string `json:"description"`
73-
Category string `json:"category"`
74-
Status string `json:"status"`
75-
Variables map[string]BrickVariable `json:"variables,omitempty"`
76-
Readme string `json:"readme"`
77-
ApiDocsPath string `json:"api_docs_path"`
78-
CodeExamples []CodeExample `json:"code_examples"`
79-
UsedByApps []AppReference `json:"used_by_apps"`
71+
ID string `json:"id"`
72+
Name string `json:"name"`
73+
Author string `json:"author"`
74+
Description string `json:"description"`
75+
Category string `json:"category"`
76+
Status string `json:"status"`
77+
Variables map[string]BrickVariable `json:"variables,omitempty"`
78+
Readme string `json:"readme"`
79+
ApiDocsPath string `json:"api_docs_path"`
80+
CodeExamples []CodeExample `json:"code_examples"`
81+
UsedByApps []AppReference `json:"used_by_apps"`
82+
Models []modelsindex.AIModelLite `json:"models"`
8083
}

internal/orchestrator/modelsindex/models_index.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ type AIModel struct {
5353
ModelConfiguration map[string]string `yaml:"model_configuration,omitempty"`
5454
}
5555

56+
type AIModelLite struct {
57+
ID string `yaml:"-"`
58+
Name string `yaml:"name"`
59+
ModuleDescription string `yaml:"description"`
60+
}
61+
5662
type ModelsIndex struct {
5763
models []AIModel
5864
}
@@ -82,6 +88,25 @@ func (m *ModelsIndex) GetModelsByBrick(brick string) []AIModel {
8288
return matches
8389
}
8490

91+
func (m *ModelsIndex) GetModelsLiteInfoByBrick(brick string) []AIModelLite {
92+
var matches []AIModelLite
93+
for i := range m.models {
94+
if len(m.models[i].Bricks) > 0 && slices.Contains(m.models[i].Bricks, brick) {
95+
matches = append(matches,
96+
AIModelLite{
97+
ID: m.models[i].ID,
98+
Name: m.models[i].Name,
99+
ModuleDescription: m.models[i].ModuleDescription,
100+
},
101+
)
102+
}
103+
}
104+
if len(matches) == 0 {
105+
return []AIModelLite{}
106+
}
107+
return matches
108+
}
109+
85110
func (m *ModelsIndex) GetModelsByBricks(bricks []string) []AIModel {
86111
var matchingModels []AIModel
87112
for _, model := range m.models {

internal/orchestrator/modelsindex/modelsindex_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,15 @@ func TestModelsIndex(t *testing.T) {
6969
assert.Equal(t, "face-detection", models[0].ID)
7070
assert.Equal(t, "yolox-object-detection", models[1].ID)
7171
})
72+
73+
t.Run("it gets models lite by a brick", func(t *testing.T) {
74+
model := modelsIndex.GetModelsLiteInfoByBrick("not-existing-brick")
75+
assert.Nil(t, model)
76+
77+
model = modelsIndex.GetModelsLiteInfoByBrick("arduino:object_detection")
78+
assert.Len(t, model, 1)
79+
assert.Equal(t, "face-detection", model[0].ID)
80+
assert.Equal(t, "Face bounding box detection. This model is trained on the WIDER FACE dataset and can detect faces in images.", model[0].ModuleDescription)
81+
assert.Equal(t, "Lightweight-Face-Detection", model[0].Name)
82+
})
7283
}

0 commit comments

Comments
 (0)