Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Binary data implementation #296

Merged
merged 37 commits into from
Dec 8, 2022
Merged

Binary data implementation #296

merged 37 commits into from
Dec 8, 2022

Conversation

lukas-valenta
Copy link
Contributor

@lukas-valenta lukas-valenta commented Oct 28, 2022

Description

In this pull request is introduced new "primitive" type BinaryData.

export interface IBinaryData {
  peek(size?: number): Promise<Buffer | undefined>;
  getAllData(): Promise<Buffer>;
  chunkBy(chunkSize: number): AsyncIterable<Buffer>;
  toStream(): Readable;
}

If BinaryData instance gets to be used as body or value in FormData, it is streamed.
If BinaryData should be returned as outcome, an UnexpectedError is returned. To solve it, call getAllData() to read stream into Buffer. Later streamed results will be added.

Limitations

1. Asynchronous operations on BinaryData
Current limitation for use in Comlink Map is that peek, read and getAllData methods are asynchronous. So, they can't be directly chained with function on Buffer. Most likely toString().

To overcome this limitation, It must be first set into variable, so the interpreter resolves the Promise:

map Example {
  firstBytes = input.binary.peek(10)
  data = input.binary.read(10)
  remainingData = input.binary.getAllData()

  map result {
    firstBytes = firstBytes
    data = data
   remainingData = remainingData
  }
}

Opaque data type
In profile, the type must be omitted for now. Later we may add it to Comlink Profile as new Primitive.

name = "example"
version = "1.0.0"

usecase Example {
  input {
    binary
  }
}

Comlink Map examples

Send file in body:

map SendFile {
  http POST "/resource" {
    request "application/octet-stream" {
      body = input.file
    }

    response 200 "text/plain" {
      map result body
    }
  }
}

Send file as FormData field:

map SendFile {
  http POST "/resource" {
    request "multipart/form-data" {
      body {
        field = input.field
        file1 = input.file1
        file2 = input.file2
      }
    }

    response 200 "text/plain" {
      map result body
    }
  }
}

Send file by chunks:

profile = "[email protected]"
provider = "localhost"

map ChunkedUpload {
  uploadResults = call foreach(chunk of input.file.chunkBy(10)) Upload(chunk = chunk)

  return map result uploaded
}

operation Upload {
  http POST "/upload/{args.uploadId}" {
    request "application/octet-stream" {
      body = args.chunk
    }

    response 200 "text/plain" {
      return true
    }

    response 500 "text/plain" {
      return false
    }
  }
}

Read first bytes of file and then send it in body:

map SendFile {
  firstTen = input.file.peek(10)

  contentType = firstTen.toString('ascii').toLowerCase().includes('pdf') ? 'application/pdf' : 'application/octet-stream'

  http POST "/resource" {
    request {
	  headers {
        'content-type' = contentType
      }
    
      body = input.file
    }

    response 200 "text/plain" {
      map result body
    }
  }
}

OneSDK use example

From user perspective it is used as followed:

import { SuperfaceClient, BinaryData } from '@superfaceai/one-sdk';

const client = new SuperfaceClient();
const profile = await client.getProfile('example');

// for files
const result = await profile.getUseCase('Example').perform({
  binary: BinaryData.fromPath(pathToFile, { mimetype: 'text/plain', filename: 'example.txt' });
});

// or for Readable streams
const stream = getReadableStream();
const result = await profile.getUseCase('Example').perform({
  binary: BinaryData.fromStream(stream);
});

Motivation and Context

To allow the passing of binary data with capabilities like async loading, streaming and chunking.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • I have updated the documentation accordingly. If you are changing code related to user secrets you need to really make sure that security documentation is correct.
  • I have read the CONTRIBUTING document.
  • I haven't repeated the code. (DRY)
  • I have added tests to cover my changes.
  • All new and existing tests passed.

src/core/interpreter/map-interpreter.test.ts Outdated Show resolved Hide resolved
src/interfaces/usecase.ts Outdated Show resolved Hide resolved
src/interfaces/usecase.ts Outdated Show resolved Hide resolved
src/core/interpreter/map-interpreter.ts Outdated Show resolved Hide resolved
src/node/filesystem/binary.node.ts Outdated Show resolved Hide resolved
@freaz freaz force-pushed the feature/binary-data branch 5 times, most recently from 778dcbb to 691614a Compare November 29, 2022 14:46
@freaz freaz force-pushed the feature/binary-data branch 2 times, most recently from 8eaa298 to a8e66e7 Compare November 30, 2022 19:51
@freaz freaz marked this pull request as ready for review December 2, 2022 13:43
src/core/interpreter/map-interpreter.test.ts Outdated Show resolved Hide resolved
src/core/interpreter/map-interpreter.test.ts Outdated Show resolved Hide resolved
src/core/interpreter/map-interpreter.ts Outdated Show resolved Hide resolved
src/core/interpreter/map-interpreter.ts Outdated Show resolved Hide resolved
src/core/interpreter/sandbox/sandbox.ts Outdated Show resolved Hide resolved
src/node/filesystem/binary.node.ts Outdated Show resolved Hide resolved
src/node/filesystem/binary.node.ts Outdated Show resolved Hide resolved
src/node/filesystem/binary.node.test.ts Show resolved Hide resolved
src/node/filesystem/binary.node.ts Outdated Show resolved Hide resolved
src/node/filesystem/binary.node.ts Outdated Show resolved Hide resolved
src/lib/object/object.ts Outdated Show resolved Hide resolved
@freaz freaz merged commit 37cc634 into dev Dec 8, 2022
@freaz freaz deleted the feature/binary-data branch December 8, 2022 14:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants