Skip to content

Commit

Permalink
Merge pull request #88 from UiPath/feature/update-digitize-command
Browse files Browse the repository at this point in the history
Update digitize command to use DocumentUnderstanding Framework API
  • Loading branch information
thschmitt authored Sep 16, 2023
2 parents 5f0acde + 6bc8a3d commit eb109a4
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 30 deletions.
32 changes: 21 additions & 11 deletions plugin/digitizer/digitize_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,19 @@ func (c DigitizeCommand) Command() plugin.Command {
return *plugin.NewCommand("du").
WithCategory("digitization", "Document Digitization").
WithOperation("digitize", "Digitize the given file").
WithParameter("project-id", plugin.ParameterTypeString, "The project id", true).
WithParameter("file", plugin.ParameterTypeBinary, "The file to digitize", true).
WithParameter("content-type", plugin.ParameterTypeString, "The content type", false)
}

func (c DigitizeCommand) Execute(context plugin.ExecutionContext, writer output.OutputWriter, logger log.Logger) error {
operationId, err := c.startDigitization(context, logger)
documentId, err := c.startDigitization(context, logger)
if err != nil {
return err
}

for i := 1; i <= 60; i++ {
finished, err := c.waitForDigitization(operationId, context, writer, logger)
finished, err := c.waitForDigitization(documentId, context, writer, logger)
if err != nil {
return err
}
Expand All @@ -48,7 +49,7 @@ func (c DigitizeCommand) Execute(context plugin.ExecutionContext, writer output.
}
time.Sleep(1 * time.Second)
}
return fmt.Errorf("Digitization with operationId '%s' did not finish in time", operationId)
return fmt.Errorf("Digitization with documentId '%s' did not finish in time", documentId)
}

func (c DigitizeCommand) startDigitization(context plugin.ExecutionContext, logger log.Logger) (string, error) {
Expand Down Expand Up @@ -80,11 +81,11 @@ func (c DigitizeCommand) startDigitization(context plugin.ExecutionContext, logg
if err != nil {
return "", fmt.Errorf("Error parsing json response: %w", err)
}
return result.OperationId, nil
return result.DocumentId, nil
}

func (c DigitizeCommand) waitForDigitization(operationId string, context plugin.ExecutionContext, writer output.OutputWriter, logger log.Logger) (bool, error) {
request, err := c.createDigitizeStatusRequest(operationId, context)
func (c DigitizeCommand) waitForDigitization(documentId string, context plugin.ExecutionContext, writer output.OutputWriter, logger log.Logger) (bool, error) {
request, err := c.createDigitizeStatusRequest(documentId, context)
if err != nil {
return true, err
}
Expand Down Expand Up @@ -123,6 +124,10 @@ func (c DigitizeCommand) createDigitizeRequest(context plugin.ExecutionContext,
if context.Tenant == "" {
return nil, errors.New("Tenant is not set")
}
projectId, _ := c.getParameter("project-id", context.Parameters)
if projectId == "" {
return nil, errors.New("ProjectId is not set")
}
var err error
file := context.Input
if file == nil {
Expand All @@ -140,7 +145,7 @@ func (c DigitizeCommand) createDigitizeRequest(context plugin.ExecutionContext,
contentType, contentLength := c.writeMultipartBody(bodyWriter, file, contentType, requestError)
uploadReader := c.progressReader("uploading...", "completing ", bodyReader, contentLength, uploadBar)

uri := c.formatUri(context.BaseUri, context.Organization, context.Tenant) + "/digitize/start?api-version=1"
uri := c.formatUri(context.BaseUri, context.Organization, context.Tenant, projectId) + "/digitization/start?api-version=1"
request, err := http.NewRequest("POST", uri, uploadReader)
if err != nil {
return nil, err
Expand All @@ -166,26 +171,31 @@ func (c DigitizeCommand) progressReader(text string, completedText string, reade
return progressReader
}

func (c DigitizeCommand) formatUri(baseUri url.URL, org string, tenant string) string {
func (c DigitizeCommand) formatUri(baseUri url.URL, org string, tenant string, projectId string) string {
path := baseUri.Path
if baseUri.Path == "" {
path = "/{organization}/{tenant}/du_/api/digitizer"
path = "/{organization}/{tenant}/du_/api/framework/projects/{projectId}"
}
path = strings.ReplaceAll(path, "{organization}", org)
path = strings.ReplaceAll(path, "{tenant}", tenant)
path = strings.ReplaceAll(path, "{projectId}", projectId)
path = strings.TrimSuffix(path, "/")
return fmt.Sprintf("%s://%s%s", baseUri.Scheme, baseUri.Host, path)
}

func (c DigitizeCommand) createDigitizeStatusRequest(operationId string, context plugin.ExecutionContext) (*http.Request, error) {
func (c DigitizeCommand) createDigitizeStatusRequest(documentId string, context plugin.ExecutionContext) (*http.Request, error) {
if context.Organization == "" {
return nil, errors.New("Organization is not set")
}
if context.Tenant == "" {
return nil, errors.New("Tenant is not set")
}
projectId, _ := c.getParameter("project-id", context.Parameters)
if projectId == "" {
return nil, errors.New("ProjectId is not set")
}

uri := c.formatUri(context.BaseUri, context.Organization, context.Tenant) + fmt.Sprintf("/digitize/result/%s?api-version=1", operationId)
uri := c.formatUri(context.BaseUri, context.Organization, context.Tenant, projectId) + fmt.Sprintf("/digitization/result/%s?api-version=1", documentId)
request, err := http.NewRequest("GET", uri, &bytes.Buffer{})
if err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion plugin/digitizer/digitize_response.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package digitzer

type digitizeResponse struct {
OperationId string `json:"operationId"`
DocumentId string `json:"documentId"`
}
56 changes: 38 additions & 18 deletions plugin/digitizer/digitizer_plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,26 @@ import (
"github.com/UiPath/uipathcli/test"
)

func TestDigitizeWithoutProjectIdParameterShowsValidationError(t *testing.T) {
definition := `
paths:
/digitize:
get:
operationId: digitize
`

context := test.NewContextBuilder().
WithDefinition("du", definition).
WithCommandPlugin(DigitizeCommand{}).
Build()

result := test.RunCli([]string{"du", "digitization", "digitize", "--file", "myfile"}, context)

if !strings.Contains(result.StdErr, "Argument --project-id is missing") {
t.Errorf("Expected stderr to show that project-id parameter is missing, but got: %v", result.StdErr)
}
}

func TestDigitizeWithoutFileParameterShowsValidationError(t *testing.T) {
definition := `
paths:
Expand All @@ -23,7 +43,7 @@ paths:
WithCommandPlugin(DigitizeCommand{}).
Build()

result := test.RunCli([]string{"du", "digitization", "digitize"}, context)
result := test.RunCli([]string{"du", "digitization", "digitize", "--project-id", "1234"}, context)

if !strings.Contains(result.StdErr, "Argument --file is missing") {
t.Errorf("Expected stderr to show that file parameter is missing, but got: %v", result.StdErr)
Expand All @@ -50,7 +70,7 @@ paths:
WithCommandPlugin(DigitizeCommand{}).
Build()

result := test.RunCli([]string{"du", "digitization", "digitize", "--file", "does-not-exist"}, context)
result := test.RunCli([]string{"du", "digitization", "digitize", "--project-id", "1234", "--file", "does-not-exist"}, context)

if !strings.Contains(result.StdErr, "Error sending request: File 'does-not-exist' not found") {
t.Errorf("Expected stderr to show that file was not found, but got: %v", result.StdErr)
Expand All @@ -70,7 +90,7 @@ paths:
WithCommandPlugin(DigitizeCommand{}).
Build()

result := test.RunCli([]string{"du", "digitization", "digitize", "--file", "hello-world"}, context)
result := test.RunCli([]string{"du", "digitization", "digitize", "--project-id", "1234", "--file", "hello-world"}, context)

if !strings.Contains(result.StdErr, "Organization is not set") {
t.Errorf("Expected stderr to show that organization parameter is missing, but got: %v", result.StdErr)
Expand Down Expand Up @@ -101,7 +121,7 @@ paths:
WithResponse(400, "validation error").
Build()

result := test.RunCli([]string{"du", "digitization", "digitize", "--file", path}, context)
result := test.RunCli([]string{"du", "digitization", "digitize", "--project-id", "1234", "--file", path}, context)

if !strings.Contains(result.StdErr, "Digitizer returned status code '400' and body 'validation error'") {
t.Errorf("Expected stderr to show that digitizer call failed, but got: %v", result.StdErr)
Expand All @@ -120,7 +140,7 @@ func TestDigitizeSuccessfully(t *testing.T) {

definition := `
servers:
- url: https://cloud.uipath.com/{organization}/{tenant}/du_/api/digitizer
- url: https://cloud.uipath.com/{organization}/{tenant}/du_/api/framework
description: The production url
variables:
organization:
Expand All @@ -139,11 +159,11 @@ paths:
WithDefinition("du", definition).
WithConfig(config).
WithCommandPlugin(DigitizeCommand{}).
WithResponse(202, `{"operationId":"eb80e441-05de-4a13-9aaa-f65b1babba05"}`).
WithUrlResponse("/my-org/my-tenant/du_/api/digitizer/digitize/result/eb80e441-05de-4a13-9aaa-f65b1babba05?api-version=1", 200, `{"status":"Done"}`).
WithResponse(202, `{"documentId":"eb80e441-05de-4a13-9aaa-f65b1babba05"}`).
WithUrlResponse("/my-org/my-tenant/du_/api/framework/projects/1234/digitization/result/eb80e441-05de-4a13-9aaa-f65b1babba05?api-version=1", 200, `{"status":"Done"}`).
Build()

result := test.RunCli([]string{"du", "digitization", "digitize", "--file", path}, context)
result := test.RunCli([]string{"du", "digitization", "digitize", "--project-id", "1234", "--file", path}, context)

expectedResult := `{
"status": "Done"
Expand Down Expand Up @@ -175,11 +195,11 @@ paths:
WithDefinition("du", definition).
WithConfig(config).
WithCommandPlugin(DigitizeCommand{}).
WithResponse(202, `{"operationId":"eb80e441-05de-4a13-9aaa-f65b1babba05"}`).
WithUrlResponse("/my-org/my-tenant/du_/api/digitizer/digitize/result/eb80e441-05de-4a13-9aaa-f65b1babba05?api-version=1", 200, `{"pages":[],"status":"Done"}`).
WithResponse(202, `{"documentId":"eb80e441-05de-4a13-9aaa-f65b1babba05"}`).
WithUrlResponse("/my-org/my-tenant/du_/api/framework/projects/1234/digitization/result/eb80e441-05de-4a13-9aaa-f65b1babba05?api-version=1", 200, `{"pages":[],"status":"Done"}`).
Build()

result := test.RunCli([]string{"du", "digitization", "digitize", "--file", path, "--debug"}, context)
result := test.RunCli([]string{"du", "digitization", "digitize", "--project-id", "1234", "--file", path, "--debug"}, context)

expected := `{
"pages": [],
Expand All @@ -189,11 +209,11 @@ paths:
if result.StdOut != expected {
t.Errorf("Expected stdout to show the digitize result, but got: %v", result.StdOut)
}
if !strings.Contains(result.StdErr, "/digitize/start") {
t.Errorf("Expected stderr to show the start digitize operation, but got: %v", result.StdErr)
if !strings.Contains(result.StdErr, "/digitization/start") {
t.Errorf("Expected stderr to show the start digitization operation, but got: %v", result.StdErr)
}
if !strings.Contains(result.StdErr, "/digitize/result/eb80e441-05de-4a13-9aaa-f65b1babba05") {
t.Errorf("Expected stderr to show the get digitize result operation, but got: %v", result.StdErr)
if !strings.Contains(result.StdErr, "/digitization/result/eb80e441-05de-4a13-9aaa-f65b1babba05") {
t.Errorf("Expected stderr to show the get digitization result operation, but got: %v", result.StdErr)
}
}

Expand All @@ -217,11 +237,11 @@ paths:
WithConfig(config).
WithCommandPlugin(DigitizeCommand{}).
WithStdIn(stdIn).
WithResponse(202, `{"operationId":"eb80e441-05de-4a13-9aaa-f65b1babba05"}`).
WithUrlResponse("/my-org/my-tenant/du_/api/digitizer/digitize/result/eb80e441-05de-4a13-9aaa-f65b1babba05?api-version=1", 200, `{"status":"Done"}`).
WithResponse(202, `{"documentId":"eb80e441-05de-4a13-9aaa-f65b1babba05"}`).
WithUrlResponse("/my-org/my-tenant/du_/api/framework/projects/1234/digitization/result/eb80e441-05de-4a13-9aaa-f65b1babba05?api-version=1", 200, `{"status":"Done"}`).
Build()

result := test.RunCli([]string{"du", "digitization", "digitize", "--content-type", "application/pdf", "--file", "-"}, context)
result := test.RunCli([]string{"du", "digitization", "digitize", "--project-id", "1234", "--content-type", "application/pdf", "--file", "-"}, context)

expectedResult := `{
"status": "Done"
Expand Down

0 comments on commit eb109a4

Please sign in to comment.