From 9b233aa255cdf84366ef0696698511474bea074c Mon Sep 17 00:00:00 2001 From: Alex Pliutau Date: Wed, 3 Jul 2024 10:43:35 +0200 Subject: [PATCH] New API version: 20240304 --- .github/workflows/test.yaml | 6 +- CHANGELOG.md | 6 ++ README.md | 9 +-- apps.go | 32 ++++----- entity.go | 69 +++++++++++------- entity_test.go | 16 ++--- go.mod | 2 +- integration_test.go | 136 ++++++------------------------------ intent.go | 10 +-- language_detection.go | 6 +- message.go | 10 +-- trait.go | 16 ++--- utterance.go | 22 +++--- witai.go | 18 +++-- 14 files changed, 144 insertions(+), 214 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index c9b4373..03a088a 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -6,12 +6,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Install Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v5 with: - go-version: 1.14 + go-version: 1.22 - name: Check out code into the Go module directory - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Run Tests run: go test -race -v . diff --git a/CHANGELOG.md b/CHANGELOG.md index 071f2f0..dc627f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +July 3, 2024 + +- New default API version: 20240304. Adjusted types to new version +- Switch to latest Go version 1.22 +- Fix integration tests + Nov 16, 2020 - Switch to Github Actions for CI/CD diff --git a/README.md b/README.md index 42778f9..01dbc5b 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,13 @@ ![wit.ai](https://s3.amazonaws.com/pliutau.com/wit.png) -[![GoDoc](https://godoc.org/github.com/wit-ai/wit-go?status.svg)](https://godoc.org/github.com/wit-ai/wit-go) [![Go Report Card](https://goreportcard.com/badge/github.com/wit-ai/wit-go)](https://goreportcard.com/report/github.com/wit-ai/wit-go) +[![Go Reference](https://pkg.go.dev/badge/github.com/wit-ai/wit-go)](https://pkg.go.dev/github.com/wit-ai/wit-go) *This repository is community-maintained. We gladly accept pull requests. Please see the [Wit HTTP Reference](https://wit.ai/docs/http/latest) for all supported endpoints.* Go client for [wit.ai](https://wit.ai/) HTTP API. +API version: 20240304 + ## Install ``` @@ -37,7 +39,7 @@ func main() { ## Testing -Both Unit / Integration tests are executed by Github Actions. +Unit tests are executed by Github Actions, but Integration tests have to be executed manually by providing a valid token via `WITAI_INTEGRATION_TOKEN` env var. ### Unit tests @@ -50,8 +52,7 @@ go test -race -v Integration tests are connecting to real Wit.ai API, so you need to provide a valid token: ``` -export WITAI_INTEGRATION_TOKEN=your_secret_token_here -go test -v -tags=integration +WITAI_INTEGRATION_TOKEN={SERVER_ACCESS_TOKEN} go test -v -tags=integration ``` ## License diff --git a/apps.go b/apps.go index e2b8ea7..a592590 100644 --- a/apps.go +++ b/apps.go @@ -24,7 +24,7 @@ const ( Ongoing AppTrainingStatus = "ongoing" ) -// App - https://wit.ai/docs/http/20200513/#get__apps_link +// App - https://wit.ai/docs/http/#get__apps_link type App struct { ID string `json:"id,omitempty"` Name string `json:"name"` @@ -60,7 +60,7 @@ func (witTime *Time) UnmarshalJSON(input []byte) error { return nil } -// CreatedApp - https://wit.ai/docs/http/20200513/#post__apps_link +// CreatedApp - https://wit.ai/docs/http/#post__apps_link type CreatedApp struct { AccessToken string `json:"access_token"` AppID string `json:"app_id"` @@ -68,7 +68,7 @@ type CreatedApp struct { // GetApps - Returns an array of all apps that you own. // -// https://wit.ai/docs/http/20200513/#get__apps_link +// https://wit.ai/docs/http/#get__apps_link func (c *Client) GetApps(limit int, offset int) ([]App, error) { if limit <= 0 { limit = 0 @@ -92,7 +92,7 @@ func (c *Client) GetApps(limit int, offset int) ([]App, error) { // GetApp - Returns an object representation of the specified app. // -// https://wit.ai/docs/http/20200513/#get__apps__app_link +// https://wit.ai/docs/http/#get__apps__app_link func (c *Client) GetApp(id string) (*App, error) { resp, err := c.request(http.MethodGet, fmt.Sprintf("/apps/%s", url.PathEscape(id)), "application/json", nil) if err != nil { @@ -112,7 +112,7 @@ func (c *Client) GetApp(id string) (*App, error) { // CreateApp - creates new app. // -// https://wit.ai/docs/http/20200513/#post__apps_link +// https://wit.ai/docs/http/#post__apps_link func (c *Client) CreateApp(app App) (*CreatedApp, error) { appJSON, err := json.Marshal(app) if err != nil { @@ -135,7 +135,7 @@ func (c *Client) CreateApp(app App) (*CreatedApp, error) { // UpdateApp - Updates an app. // -// https://wit.ai/docs/http/20200513/#put__apps__app_link +// https://wit.ai/docs/http/#put__apps__app_link func (c *Client) UpdateApp(id string, app App) error { appJSON, err := json.Marshal(app) if err != nil { @@ -152,7 +152,7 @@ func (c *Client) UpdateApp(id string, app App) error { // DeleteApp - deletes app by ID. // -// https://wit.ai/docs/http/20200513/#delete__apps__app_link +// https://wit.ai/docs/http/#delete__apps__app_link func (c *Client) DeleteApp(id string) error { resp, err := c.request(http.MethodDelete, fmt.Sprintf("/apps/%s", url.PathEscape(id)), "application/json", nil) if err == nil { @@ -162,7 +162,7 @@ func (c *Client) DeleteApp(id string) error { return err } -// AppTag - https://wit.ai/docs/http/20200513/#get__apps__app_tags__tag_link +// AppTag - https://wit.ai/docs/http/#get__apps__app_tags__tag_link type AppTag struct { Name string `json:"name,omitempty"` Desc string `json:"desc,omitempty"` @@ -174,7 +174,7 @@ type AppTag struct { // GetAppTags - Returns an array of all tag groups for an app. // Within a group, all tags point to the same app state (as a result of moving tags). // -// https://wit.ai/docs/http/20200513/#get__apps__app_tags_link +// https://wit.ai/docs/http/#get__apps__app_tags_link func (c *Client) GetAppTags(appID string) ([][]AppTag, error) { resp, err := c.request(http.MethodGet, fmt.Sprintf("/apps/%s/tags", url.PathEscape(appID)), "application/json", nil) if err != nil { @@ -191,7 +191,7 @@ func (c *Client) GetAppTags(appID string) ([][]AppTag, error) { // GetAppTag - returns the detail of the specified tag. // -// https://wit.ai/docs/http/20200513/#get__apps__app_tags__tag_link +// https://wit.ai/docs/http/#get__apps__app_tags__tag_link func (c *Client) GetAppTag(appID, tagID string) (*AppTag, error) { resp, err := c.request(http.MethodGet, fmt.Sprintf("/apps/%s/tags/%s", url.PathEscape(appID), url.PathEscape(tagID)), "application/json", nil) if err != nil { @@ -209,7 +209,7 @@ func (c *Client) GetAppTag(appID, tagID string) (*AppTag, error) { // CreateAppTag - Take a snapshot of the current app state, save it as a tag (version) // of the app. The name of the tag created will be returned in the response. // -// https://wit.ai/docs/http/20200513/#post__apps__app_tags_link +// https://wit.ai/docs/http/#post__apps__app_tags_link func (c *Client) CreateAppTag(appID string, tag string) (*AppTag, error) { type appTag struct { Tag string `json:"tag"` @@ -237,14 +237,14 @@ func (c *Client) CreateAppTag(appID string, tag string) (*AppTag, error) { return &AppTag{Name: tmp.Tag}, nil } -// UpdateAppTagRequest - https://wit.ai/docs/http/20200513/#put__apps__app_tags__tag_link +// UpdateAppTagRequest - https://wit.ai/docs/http/#put__apps__app_tags__tag_link type UpdateAppTagRequest struct { Tag string `json:"tag,omitempty"` Desc string `json:"desc,omitempty"` MoveTo string `json:"move_to,omitempty"` } -// UpdateAppTagResponse - https://wit.ai/docs/http/20200513/#put__apps__app_tags__tag_link +// UpdateAppTagResponse - https://wit.ai/docs/http/#put__apps__app_tags__tag_link type UpdateAppTagResponse struct { Tag string `json:"tag,omitempty"` Desc string `json:"desc,omitempty"` @@ -253,7 +253,7 @@ type UpdateAppTagResponse struct { // UpdateAppTag - Update the tag's name or description // -// https://wit.ai/docs/http/20200513/#put__apps__app_tags__tag_link +// https://wit.ai/docs/http/#put__apps__app_tags__tag_link func (c *Client) UpdateAppTag(appID, tagID string, updated AppTag) (*AppTag, error) { type tag struct { Tag string `json:"tag,omitempty"` @@ -286,7 +286,7 @@ type MovedAppTag struct { // MoveAppTag - move the tag to point to another tag. // -// https://wit.ai/docs/http/20200513/#put__apps__app_tags__tag_link +// https://wit.ai/docs/http/#put__apps__app_tags__tag_link func (c *Client) MoveAppTag(appID, tagID string, to string, updated *AppTag) (*MovedAppTag, error) { type tag struct { Tag string `json:"tag,omitempty"` @@ -320,7 +320,7 @@ func (c *Client) MoveAppTag(appID, tagID string, to string, updated *AppTag) (*M // DeleteAppTag - Permanently delete the tag. // -// https://wit.ai/docs/http/20200513/#delete__apps__app_tags__tag_link +// https://wit.ai/docs/http/#delete__apps__app_tags__tag_link func (c *Client) DeleteAppTag(appID, tagID string) error { resp, err := c.request(http.MethodDelete, fmt.Sprintf("/apps/%s/tags/%s", url.PathEscape(appID), url.PathEscape(tagID)), "application/json", nil) if err == nil { diff --git a/entity.go b/entity.go index cb4cfcc..daebc01 100644 --- a/entity.go +++ b/entity.go @@ -12,7 +12,7 @@ import ( // Entity represents a wit-ai Entity. // -// https://wit.ai/docs/http/20200513/#post__entities_link +// https://wit.ai/docs/http/#post__entities_link type Entity struct { ID string `json:"id"` Name string `json:"name"` @@ -21,9 +21,22 @@ type Entity struct { Keywords []EntityKeyword `json:"keywords,omitempty"` } +type CreateEntityResponse struct { + ID string `json:"id"` + Name string `json:"name"` + Lookups []string `json:"lookups,omitempty"` + Roles []EntityRole `json:"roles,omitempty"` + Keywords []EntityKeyword `json:"keywords,omitempty"` +} + +type EntityRole struct { + ID string `json:"id"` + Name string `json:"name"` +} + // EntityKeyword is a keyword lookup for an Entity. // -// https://wit.ai/docs/http/20200513/#post__entities__entity_keywords_link +// https://wit.ai/docs/http/#post__entities__entity_keywords_link type EntityKeyword struct { Keyword string `json:"keyword"` Synonyms []string `json:"synonyms"` @@ -31,7 +44,7 @@ type EntityKeyword struct { // GetEntities - returns list of entities. // -// https://wit.ai/docs/http/20200513/#get__entities_link +// https://wit.ai/docs/http/#get__entities_link func (c *Client) GetEntities() ([]Entity, error) { resp, err := c.request(http.MethodGet, "/entities", "application/json", nil) if err != nil { @@ -48,8 +61,8 @@ func (c *Client) GetEntities() ([]Entity, error) { // CreateEntity - Creates a new entity with the given attributes // -// https://wit.ai/docs/http/20200513/#post__entities_link -func (c *Client) CreateEntity(entity Entity) (*Entity, error) { +// https://wit.ai/docs/http/#post__entities_link +func (c *Client) CreateEntity(entity Entity) (*CreateEntityResponse, error) { entityJSON, err := json.Marshal(entity) if err != nil { return nil, err @@ -62,7 +75,7 @@ func (c *Client) CreateEntity(entity Entity) (*Entity, error) { defer resp.Close() - var entityResp *Entity + var entityResp *CreateEntityResponse decoder := json.NewDecoder(resp) err = decoder.Decode(&entityResp) return entityResp, err @@ -70,8 +83,8 @@ func (c *Client) CreateEntity(entity Entity) (*Entity, error) { // GetEntity - returns entity by ID or name. // -// https://wit.ai/docs/http/20200513/#get__entities__entity_link -func (c *Client) GetEntity(entityID string) (*Entity, error) { +// https://wit.ai/docs/http/#get__entities__entity_link +func (c *Client) GetEntity(entityID string) (*CreateEntityResponse, error) { resp, err := c.request(http.MethodGet, fmt.Sprintf("/entities/%s", url.PathEscape(entityID)), "application/json", nil) if err != nil { return nil, err @@ -79,37 +92,39 @@ func (c *Client) GetEntity(entityID string) (*Entity, error) { defer resp.Close() - var entity *Entity + var entity *CreateEntityResponse decoder := json.NewDecoder(resp) err = decoder.Decode(&entity) return entity, err } -// UpdateEntity - Updates an entity by ID or name. +// UpdateEntity - Updates an entity by name. // -// https://wit.ai/docs/http/20200513/#put__entities__entity_link -func (c *Client) UpdateEntity(entityID string, entity Entity) error { +// https://wit.ai/docs/http/#put__entities__entity_link +func (c *Client) UpdateEntity(name string, entity Entity) (*CreateEntityResponse, error) { entityJSON, err := json.Marshal(entity) if err != nil { - return err + return nil, err } - resp, err := c.request(http.MethodPut, fmt.Sprintf("/entities/%s", url.PathEscape(entityID)), "application/json", bytes.NewBuffer(entityJSON)) + resp, err := c.request(http.MethodPut, fmt.Sprintf("/entities/%s", url.PathEscape(name)), "application/json", bytes.NewBuffer(entityJSON)) if err != nil { - return err + return nil, err } defer resp.Close() + var entityResp *CreateEntityResponse decoder := json.NewDecoder(resp) - return decoder.Decode(&entity) + err = decoder.Decode(&entityResp) + return entityResp, err } -// DeleteEntity - deletes entity by ID or name. +// DeleteEntity - deletes entity by name // -// https://wit.ai/docs/http/20200513/#delete__entities__entity_link -func (c *Client) DeleteEntity(entityID string) error { - resp, err := c.request(http.MethodDelete, fmt.Sprintf("/entities/%s", url.PathEscape(entityID)), "application/json", nil) +// https://wit.ai/docs/http/#delete__entities__entity_link +func (c *Client) DeleteEntity(name string) error { + resp, err := c.request(http.MethodDelete, fmt.Sprintf("/entities/%s", url.PathEscape(name)), "application/json", nil) if err == nil { resp.Close() } @@ -119,9 +134,9 @@ func (c *Client) DeleteEntity(entityID string) error { // DeleteEntityRole - deletes entity role. // -// https://wit.ai/docs/http/20200513/#delete__entities__entity_role_link -func (c *Client) DeleteEntityRole(entityID string, role string) error { - resp, err := c.request(http.MethodDelete, fmt.Sprintf("/entities/%s:%s", url.PathEscape(entityID), url.PathEscape(role)), "application/json", nil) +// https://wit.ai/docs/http/#delete__entities__entity_role_link +func (c *Client) DeleteEntityRole(name string, role string) error { + resp, err := c.request(http.MethodDelete, fmt.Sprintf("/entities/%s:%s", url.PathEscape(name), url.PathEscape(role)), "application/json", nil) if err == nil { resp.Close() } @@ -131,7 +146,7 @@ func (c *Client) DeleteEntityRole(entityID string, role string) error { // AddEntityKeyword - Add a possible value into the list of values for the keyword entity. // -// https://wit.ai/docs/http/20200513/#post__entities__entity_keywords_link +// https://wit.ai/docs/http/#post__entities__entity_keywords_link func (c *Client) AddEntityKeyword(entityID string, keyword EntityKeyword) (*Entity, error) { valueJSON, err := json.Marshal(keyword) if err != nil { @@ -156,7 +171,7 @@ func (c *Client) AddEntityKeyword(entityID string, keyword EntityKeyword) (*Enti // DeleteEntityKeyword - Delete a keyword from the keywords entity. // -// https://wit.ai/docs/http/20200513/#delete__entities__entity_keywords__keyword_link +// https://wit.ai/docs/http/#delete__entities__entity_keywords__keyword_link func (c *Client) DeleteEntityKeyword(entityID string, keyword string) error { resp, err := c.request(http.MethodDelete, fmt.Sprintf("/entities/%s/keywords/%s", url.PathEscape(entityID), url.PathEscape(keyword)), "application/json", nil) if err == nil { @@ -168,7 +183,7 @@ func (c *Client) DeleteEntityKeyword(entityID string, keyword string) error { // AddEntityKeywordSynonym - Create a new synonym of the canonical value of the keywords entity. // -// https://wit.ai/docs/http/20200513/#post__entities__entity_keywords__keyword_synonyms_link +// https://wit.ai/docs/http/#post__entities__entity_keywords__keyword_synonyms_link func (c *Client) AddEntityKeywordSynonym(entityID string, keyword string, synonym string) (*Entity, error) { type syn struct { Synonym string `json:"synonym"` @@ -199,7 +214,7 @@ func (c *Client) AddEntityKeywordSynonym(entityID string, keyword string, synony // DeleteEntityKeywordSynonym - Delete a synonym of the keyword of the entity. // -// https://wit.ai/docs/http/20200513/#delete__entities__entity_keywords__keyword_synonyms__synonym_link +// https://wit.ai/docs/http/#delete__entities__entity_keywords__keyword_synonyms__synonym_link func (c *Client) DeleteEntityKeywordSynonym(entityID string, keyword string, expression string) error { resp, err := c.request(http.MethodDelete, fmt.Sprintf("/entities/%s/keywords/%s/synonyms/%s", url.PathEscape(entityID), url.PathEscape(keyword), url.PathEscape(expression)), "application/json", nil) if err == nil { diff --git a/entity_test.go b/entity_test.go index e09d9f7..65d3f92 100644 --- a/entity_test.go +++ b/entity_test.go @@ -44,7 +44,7 @@ func TestCreateEntity(t *testing.T) { w.Write([]byte(`{ "id": "5418abc7-cc68-4073-ae9e-3a5c3c81d965", "name": "favorite_city", - "roles": ["favorite_city"], + "roles": [{"id": "1", "name": "favorite_city"}], "lookups": ["free-text", "keywords"], "keywords": [] }`)) @@ -58,10 +58,10 @@ func TestCreateEntity(t *testing.T) { Roles: []string{}, }) - wantEntity := &Entity{ + wantEntity := &CreateEntityResponse{ ID: "5418abc7-cc68-4073-ae9e-3a5c3c81d965", Name: "favorite_city", - Roles: []string{"favorite_city"}, + Roles: []EntityRole{{ID: "1", Name: "favorite_city"}}, Lookups: []string{"free-text", "keywords"}, Keywords: []EntityKeyword{}, } @@ -80,7 +80,7 @@ func TestGetEntity(t *testing.T) { "id": "571979db-f6ac-4820-bc28-a1e0787b98fc", "name": "first_name", "lookups": ["free-text", "keywords"], - "roles": ["first_name"], + "roles": [{"id": "1", "name": "first_name"}], "keywords": [ { "keyword": "Willy", "synonyms": ["Willy"] @@ -99,10 +99,10 @@ func TestGetEntity(t *testing.T) { c.APIBase = testServer.URL entity, err := c.GetEntity("first_name") - wantEntity := &Entity{ + wantEntity := &CreateEntityResponse{ ID: "571979db-f6ac-4820-bc28-a1e0787b98fc", Name: "first_name", - Roles: []string{"first_name"}, + Roles: []EntityRole{{ID: "1", Name: "first_name"}}, Lookups: []string{"free-text", "keywords"}, Keywords: []EntityKeyword{ {Keyword: "Willy", Synonyms: []string{"Willy"}}, @@ -124,7 +124,7 @@ func TestUpdateEntity(t *testing.T) { res.Write([]byte(`{ "id": "5418abc7-cc68-4073-ae9e-3a5c3c81d965", "name": "favorite_city", - "roles": ["favorite_city"], + "roles": [{"id": "1", "name": "favorite_city"}], "lookups": ["free-text", "keywords"], "keywords": [ { @@ -143,7 +143,7 @@ func TestUpdateEntity(t *testing.T) { c := NewClient(unitTestToken) c.APIBase = testServer.URL - if err := c.UpdateEntity("favorite_city", Entity{ + if _, err := c.UpdateEntity("favorite_city", Entity{ Name: "favorite_city", Roles: []string{"favorite_city"}, Lookups: []string{"free-text", "keywords"}, diff --git a/go.mod b/go.mod index b7e9401..c896801 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ module github.com/wit-ai/wit-go/v2 -go 1.16 +go 1.22 diff --git a/integration_test.go b/integration_test.go index 2397a5b..48f3111 100644 --- a/integration_test.go +++ b/integration_test.go @@ -15,25 +15,23 @@ import ( var ( integrationEntity = Entity{ - ID: "integration_entity_id", - Doc: "integration_entity_doc", + Name: "integration_entity_name", + Roles: []string{"favorite_city"}, } integrationApp = App{ - Name: "integration_app_id", - Private: false, - Description: "integration_app_desc", - Lang: "en", + Name: "integration_app_id", + Private: false, } integrationEntityUpdateFields = Entity{ - ID: "integration_entity_id", + Name: "integration_entity_name", + Roles: []string{"favorite_city"}, Lookups: []string{"keywords"}, - Doc: "integration_entity_doc_updated", } ) func TestIntegrationInvalidToken(t *testing.T) { c := NewClient("invalid_token") - _, err := c.GetEntity(integrationEntity.ID) + _, err := c.GetEntity(integrationEntity.Name) if err == nil { t.Fatalf("expected error, got: nil") } @@ -67,7 +65,10 @@ func TestIntegrationCreateEntity(t *testing.T) { c := getIntegrationClient() // just to make sure we don't create duplicates - c.DeleteEntity(integrationEntity.ID) + c.DeleteEntity(integrationEntity.Name) + + // delete may take some time + time.Sleep(2 * time.Second) // create entity entity, err := c.CreateEntity(integrationEntity) @@ -77,8 +78,8 @@ func TestIntegrationCreateEntity(t *testing.T) { if entity == nil { t.Fatalf("expected non nil entity") } - if entity.Lang != "en" { - t.Fatalf("expected lang=en, got: %s", entity.Lang) + if entity.Name != integrationEntity.Name { + t.Fatalf("expected entity name %s, got %s", integrationEntity.Name, entity.Name) } // create may take some time @@ -89,65 +90,29 @@ func TestIntegrationUpdateEntity(t *testing.T) { c := getIntegrationClient() // update entity - err := c.UpdateEntity(integrationEntity.ID, integrationEntityUpdateFields) + entity, err := c.UpdateEntity(integrationEntity.Name, integrationEntityUpdateFields) if err != nil { t.Fatalf("expected nil error, got %v", err) } - - time.Sleep(time.Second) -} - -func TestIntegrationAddEntityValue(t *testing.T) { - c := getIntegrationClient() - - var err error - - // add entity value 1 - if _, err = c.AddEntityValue(integrationEntity.ID, EntityValue{ - Value: "London", - Expressions: []string{"London"}, - }); err != nil { - t.Fatalf("expected nil error, got %v", err) - } - // add entity value 2 - if _, err = c.AddEntityValue(integrationEntity.ID, EntityValue{ - Value: "Ho Chi Minh City", - Expressions: []string{"Ho Chi Minh City"}, - }); err != nil { - t.Fatalf("expected nil error, got %v", err) - } - // add entity value expression - if _, err = c.AddEntityValueExpression(integrationEntity.ID, "Ho Chi Minh City", "HoChiMinh"); err != nil { - t.Fatalf("expected nil error, got %v", err) - } - if _, err = c.AddEntityValueExpression(integrationEntity.ID, "Ho Chi Minh City", "hochiminhcity"); err != nil { - t.Fatalf("expected nil error, got %v", err) + if entity == nil { + t.Fatalf("expected non nil entity") } - if err = c.DeleteEntityValueExpression(integrationEntity.ID, "Ho Chi Minh City", "HoChiMinh"); err != nil { - t.Fatalf("expected nil error, got %v", err) + if entity.Name != integrationEntity.Name { + t.Fatalf("expected entity name %s, got %s", integrationEntity.Name, entity.Name) } - // delete entity value 1 - if err = c.DeleteEntityValue(integrationEntity.ID, "Ho Chi Minh City"); err != nil { - t.Fatalf("expected nil error, got %v", err) - } + time.Sleep(time.Second) } func TestIntegrationGetEntity(t *testing.T) { c := getIntegrationClient() - // check entity - e, err := c.GetEntity(integrationEntity.ID) + e, err := c.GetEntity(integrationEntity.Name) if err != nil { t.Fatalf("expected nil error, got %v", err) } - - if len(e.Values) != 1 { - t.Fatalf("expected 1 value, got %v", e.Values) - } - - if e.Doc != integrationEntityUpdateFields.Doc { - t.Fatalf("expected doc=%s, got %s", integrationEntityUpdateFields.Doc, e.Doc) + if e.Name != integrationEntity.Name { + t.Fatalf("expected entity name %s, got %s", integrationEntity.Name, e.Name) } entities, err := c.GetEntities() @@ -158,67 +123,12 @@ func TestIntegrationGetEntity(t *testing.T) { t.Fatalf("expected >0 entities, got %v", entities) } - err = c.DeleteEntity(integrationEntity.ID) + err = c.DeleteEntity(integrationEntity.Name) if err != nil { t.Fatalf("expected nil error got err=%v", err) } } -func TestIntegrationSamples(t *testing.T) { - c := getIntegrationClient() - - // cleanup - c.DeleteSamples([]Sample{ - { - Text: "I want to fly to SFO", - }, - }) - - // Deletion takes time - time.Sleep(time.Second * 5) - - // samples test - _, validateErr := c.ValidateSamples([]Sample{ - { - Text: "I want to fly to SFO", - Entities: []SampleEntity{ - { - Entity: "wit$location", - Value: "SFO", - Start: 17, - End: 20, - }, - }, - }, - }) - - if validateErr != nil { - t.Fatalf("expected nil error, got %v", validateErr) - } - - // Training takes time - time.Sleep(time.Second * 20) - - // get samples - samples, samplesErr := c.GetSamples(1, 0) - if samplesErr != nil { - t.Fatalf("expected nil error, got %v", samplesErr) - } - if len(samples) != 1 { - t.Fatalf("expected 1 sample, got %v", samples) - } - - // delete samples - _, delSamplesErr := c.DeleteSamples([]Sample{ - { - Text: "I want to fly to SFO", - }, - }) - if delSamplesErr != nil { - t.Fatalf("expected nil error, got %v", delSamplesErr) - } -} - func TestIntegrationExport(t *testing.T) { c := getIntegrationClient() diff --git a/intent.go b/intent.go index f90a4bb..0b5bb3c 100644 --- a/intent.go +++ b/intent.go @@ -12,7 +12,7 @@ import ( // Intent - represents a wit-ai intent. // -// https://wit.ai/docs/http/20200513/#get__intents_link +// https://wit.ai/docs/http/#get__intents_link type Intent struct { ID string `json:"id"` Name string `json:"name"` @@ -21,7 +21,7 @@ type Intent struct { // GetIntents - returns the list of intents. // -// https://wit.ai/docs/http/20200513/#get__intents_link +// https://wit.ai/docs/http/#get__intents_link func (c *Client) GetIntents() ([]Intent, error) { resp, err := c.request(http.MethodGet, "/intents", "application/json", nil) if err != nil { @@ -37,7 +37,7 @@ func (c *Client) GetIntents() ([]Intent, error) { // CreateIntent - creates a new intent with the given name. // -// https://wit.ai/docs/http/20200513/#post__intents_link +// https://wit.ai/docs/http/#post__intents_link func (c *Client) CreateIntent(name string) (*Intent, error) { intentJSON, err := json.Marshal(Intent{Name: name}) if err != nil { @@ -58,7 +58,7 @@ func (c *Client) CreateIntent(name string) (*Intent, error) { // GetIntent - returns intent by name. // -// https://wit.ai/docs/http/20200513/#get__intents__intent_link +// https://wit.ai/docs/http/#get__intents__intent_link func (c *Client) GetIntent(name string) (*Intent, error) { resp, err := c.request(http.MethodGet, fmt.Sprintf("/intents/%s", url.PathEscape(name)), "application/json", nil) if err != nil { @@ -74,7 +74,7 @@ func (c *Client) GetIntent(name string) (*Intent, error) { // DeleteIntent - permanently deletes an intent by name. // -// https://wit.ai/docs/http/20200513/#delete__intents__intent_link +// https://wit.ai/docs/http/#delete__intents__intent_link func (c *Client) DeleteIntent(name string) error { resp, err := c.request(http.MethodDelete, fmt.Sprintf("/intents/%s", url.PathEscape(name)), "application/json", nil) if err == nil { diff --git a/language_detection.go b/language_detection.go index 33daef3..84d128f 100644 --- a/language_detection.go +++ b/language_detection.go @@ -9,18 +9,18 @@ import ( "net/url" ) -// Locales - https://wit.ai/docs/http/20200513#get__language_link +// Locales - https://wit.ai/docs/http#get__language_link type Locales struct { DetectedLocales []Locale `json:"detected_locales"` } -// Locale - https://wit.ai/docs/http/20200513#get__language_link +// Locale - https://wit.ai/docs/http#get__language_link type Locale struct { Locale string `json:"locale"` Confidence float64 `json:"confidence"` } -// Detect - returns the detected languages from query - https://wit.ai/docs/http/20200513#get__language_link +// Detect - returns the detected languages from query - https://wit.ai/docs/http#get__language_link func (c *Client) Detect(text string) (*Locales, error) { resp, err := c.request(http.MethodGet, fmt.Sprintf("/language?q=%s", url.PathEscape(text)), "application/json", nil) if err != nil { diff --git a/message.go b/message.go index 0bdbe49..4f71627 100644 --- a/message.go +++ b/message.go @@ -11,7 +11,7 @@ import ( "net/url" ) -// MessageResponse - https://wit.ai/docs/http/20200513/#get__message_link +// MessageResponse - https://wit.ai/docs/http/#get__message_link type MessageResponse struct { ID string `json:"msg_id"` Text string `json:"text"` @@ -20,7 +20,7 @@ type MessageResponse struct { Traits map[string][]MessageTrait `json:"traits"` } -// MessageEntity - https://wit.ai/docs/http/20200513/#get__message_link +// MessageEntity - https://wit.ai/docs/http/#get__message_link type MessageEntity struct { ID string `json:"id"` Name string `json:"name"` @@ -34,7 +34,7 @@ type MessageEntity struct { Extra map[string]interface{} `json:"-"` } -// MessageTrait - https://wit.ai/docs/http/20200513/#get__message_link +// MessageTrait - https://wit.ai/docs/http/#get__message_link type MessageTrait struct { ID string `json:"id"` Value string `json:"value"` @@ -42,14 +42,14 @@ type MessageTrait struct { Extra map[string]interface{} `json:"-"` } -// MessageIntent - https://wit.ai/docs/http/20200513/#get__message_link +// MessageIntent - https://wit.ai/docs/http/#get__message_link type MessageIntent struct { ID string `json:"id"` Name string `json:"name"` Confidence float64 `json:"confidence"` } -// MessageRequest - https://wit.ai/docs/http/20200513/#get__message_link +// MessageRequest - https://wit.ai/docs/http/#get__message_link type MessageRequest struct { Query string `json:"q"` Tag string `json:"tag"` diff --git a/trait.go b/trait.go index d8862fa..37f93b3 100644 --- a/trait.go +++ b/trait.go @@ -12,7 +12,7 @@ import ( // Trait - represents a wit-ai trait. // -// https://wit.ai/docs/http/20200513/#post__traits_link +// https://wit.ai/docs/http/#post__traits_link type Trait struct { ID string `json:"id"` Name string `json:"name"` @@ -21,7 +21,7 @@ type Trait struct { // TraitValue - represents the value of a Trait. // -// https://wit.ai/docs/http/20200513/#get__traits__trait_link +// https://wit.ai/docs/http/#get__traits__trait_link type TraitValue struct { ID string `json:"id"` Value string `json:"value"` @@ -29,7 +29,7 @@ type TraitValue struct { // GetTraits - returns a list of traits. // -// https://wit.ai/docs/http/20200513/#get__traits_link +// https://wit.ai/docs/http/#get__traits_link func (c *Client) GetTraits() ([]Trait, error) { resp, err := c.request(http.MethodGet, "/traits", "application/json", nil) if err != nil { @@ -46,7 +46,7 @@ func (c *Client) GetTraits() ([]Trait, error) { // CreateTrait - creates a new trait with the given values. // -// https://wit.ai/docs/http/20200513/#post__traits_link +// https://wit.ai/docs/http/#post__traits_link func (c *Client) CreateTrait(name string, values []string) (*Trait, error) { type trait struct { Name string `json:"name"` @@ -73,7 +73,7 @@ func (c *Client) CreateTrait(name string, values []string) (*Trait, error) { // GetTrait - returns all available information about a trait. // -// https://wit.ai/docs/http/20200513/#get__traits__trait_link +// https://wit.ai/docs/http/#get__traits__trait_link func (c *Client) GetTrait(name string) (*Trait, error) { resp, err := c.request(http.MethodGet, fmt.Sprintf("/traits/%s", url.PathEscape(name)), "application/json", nil) if err != nil { @@ -89,7 +89,7 @@ func (c *Client) GetTrait(name string) (*Trait, error) { // DeleteTrait - permanently deletes a trait. // -// https://wit.ai/docs/http/20200513/#delete__traits__trait_link +// https://wit.ai/docs/http/#delete__traits__trait_link func (c *Client) DeleteTrait(name string) error { resp, err := c.request(http.MethodDelete, fmt.Sprintf("/traits/%s", url.PathEscape(name)), "application/json", nil) if err == nil { @@ -101,7 +101,7 @@ func (c *Client) DeleteTrait(name string) error { // AddTraitValue - create a new value for a trait. // -// https://wit.ai/docs/http/20200513/#post__traits__trait_values_link +// https://wit.ai/docs/http/#post__traits__trait_values_link func (c *Client) AddTraitValue(traitName string, value string) (*Trait, error) { type traitValue struct { Value string `json:"value"` @@ -130,7 +130,7 @@ func (c *Client) AddTraitValue(traitName string, value string) (*Trait, error) { // DeleteTraitValue - permanently deletes the trait value. // -// https://wit.ai/docs/http/20200513/#delete__traits__trait_values__value_link +// https://wit.ai/docs/http/#delete__traits__trait_values__value_link func (c *Client) DeleteTraitValue(traitName string, value string) error { resp, err := c.request(http.MethodDelete, fmt.Sprintf("/traits/%s/values/%s", url.PathEscape(traitName), url.PathEscape(value)), "application/json", nil) if err == nil { diff --git a/utterance.go b/utterance.go index 15f32a5..e0bbcb2 100644 --- a/utterance.go +++ b/utterance.go @@ -9,7 +9,7 @@ import ( "net/http" ) -// Utterance - https://wit.ai/docs/http/20200513/#get__utterances_link +// Utterance - https://wit.ai/docs/http/#get__utterances_link type Utterance struct { Text string `json:"text"` Intent UtteranceIntent `json:"intent"` @@ -17,13 +17,13 @@ type Utterance struct { Traits []UtteranceTrait `json:"traits"` } -// UtteranceIntent - https://wit.ai/docs/http/20200513/#get__utterances_link +// UtteranceIntent - https://wit.ai/docs/http/#get__utterances_link type UtteranceIntent struct { ID string `json:"id"` Name string `json:"name"` } -// UtteranceEntity - https://wit.ai/docs/http/20200513/#get__utterances_link +// UtteranceEntity - https://wit.ai/docs/http/#get__utterances_link type UtteranceEntity struct { ID string `json:"id"` Name string `json:"name"` @@ -34,7 +34,7 @@ type UtteranceEntity struct { Entities []UtteranceEntity `json:"entities"` } -// UtteranceTrait - https://wit.ai/docs/http/20200513/#get__utterances_link +// UtteranceTrait - https://wit.ai/docs/http/#get__utterances_link type UtteranceTrait struct { ID string `json:"id"` Name string `json:"name"` @@ -43,7 +43,7 @@ type UtteranceTrait struct { // GetUtterances - Returns an array of utterances. // -// https://wit.ai/docs/http/20200513/#get__utterances_link +// https://wit.ai/docs/http/#get__utterances_link func (c *Client) GetUtterances(limit int, offset int) ([]Utterance, error) { if limit <= 0 { limit = 0 @@ -67,7 +67,7 @@ func (c *Client) GetUtterances(limit int, offset int) ([]Utterance, error) { // DeleteUtterances - Delete validated utterances from your app. // -// https://wit.ai/docs/http/20200513/#delete__utterances_link +// https://wit.ai/docs/http/#delete__utterances_link func (c *Client) DeleteUtterances(texts []string) (*TrainingResponse, error) { type text struct { Text string `json:"text"` @@ -95,7 +95,7 @@ func (c *Client) DeleteUtterances(texts []string) (*TrainingResponse, error) { return r, err } -// TrainingResponse - https://wit.ai/docs/http/20200513/#post__utterances_link +// TrainingResponse - https://wit.ai/docs/http/#post__utterances_link type Training struct { Text string `json:"text"` Intent string `json:"intent,omitempty"` @@ -103,7 +103,7 @@ type Training struct { Traits []TrainingTrait `json:"traits"` } -// TrainingResponse - https://wit.ai/docs/http/20200513/#post__utterances_link +// TrainingResponse - https://wit.ai/docs/http/#post__utterances_link type TrainingEntity struct { Entity string `json:"entity"` Start int `json:"start"` @@ -112,13 +112,13 @@ type TrainingEntity struct { Entities []TrainingEntity `json:"entities"` } -// TrainingResponse - https://wit.ai/docs/http/20200513/#post__utterances_link +// TrainingResponse - https://wit.ai/docs/http/#post__utterances_link type TrainingTrait struct { Trait string `json:"trait"` Value string `json:"value"` } -// TrainingResponse - https://wit.ai/docs/http/20200513/#post__utterances_link +// TrainingResponse - https://wit.ai/docs/http/#post__utterances_link type TrainingResponse struct { Sent bool `json:"sent"` N int `json:"n"` @@ -126,7 +126,7 @@ type TrainingResponse struct { // TrainUtterances - Add utterances (sentence + entities annotations) to train your app programmatically. // -// https://wit.ai/docs/http/20200513/#post__utterances_link +// https://wit.ai/docs/http/#post__utterances_link func (c *Client) TrainUtterances(trainings []Training) (*TrainingResponse, error) { utterancesJSON, err := json.Marshal(trainings) if err != nil { diff --git a/witai.go b/witai.go index 4ad97f1..b726d1a 100644 --- a/witai.go +++ b/witai.go @@ -11,10 +11,8 @@ import ( ) const ( - // DefaultVersion - https://wit.ai/docs/http/20200513/ - DefaultVersion = "20200513" - // WitTimeFormat - the custom format of the timestamp sent by the api - WitTimeFormat = "2006-01-02T15:04:05Z0700" + DefaultVersion = "20240304" + WitTimeFormat = "2006-01-02T15:04:05Z0700" ) // Client - Wit.ai client type @@ -32,11 +30,16 @@ type errorResp struct { Error string `json:"error"` } -// NewClient - returns Wit.ai client for default API version +// NewClient returns client for default API version func NewClient(token string) *Client { return newClientWithVersion(token, DefaultVersion) } +// SetHTTPClient allows to use your custom http.Client +func (c *Client) SetHTTPClient(httpClient *http.Client) { + c.httpClient = httpClient +} + func newClientWithVersion(token, version string) *Client { headerAuth := fmt.Sprintf("Bearer %s", token) headerAccept := fmt.Sprintf("application/vnd.wit.%s+json", version) @@ -55,11 +58,6 @@ func newClientWithVersion(token, version string) *Client { } } -// SetHTTPClient allows to use your custom http.Client -func (c *Client) SetHTTPClient(httpClient *http.Client) { - c.httpClient = httpClient -} - func (c *Client) request(method, url string, ct string, body io.Reader) (io.ReadCloser, error) { req, err := http.NewRequest(method, c.APIBase+url, body) if err != nil {