syntax = "proto3";
package flyteidl.service;

option go_package = "github.com/flyteorg/flyte/flyteidl/gen/pb-go/flyteidl/service";

import "google/api/annotations.proto";
import "protoc-gen-openapiv2/options/annotations.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "flyteidl/core/identifier.proto";
import "flyteidl/core/literals.proto";


message CreateUploadLocationResponse {
  // SignedUrl specifies the url to use to upload content to (e.g. https://my-bucket.s3.amazonaws.com/randomstring/suffix.tar?X-...)
  string signed_url = 1;

  // NativeUrl specifies the url in the format of the configured storage provider (e.g. s3://my-bucket/randomstring/suffix.tar)
  string native_url = 2;

  // ExpiresAt defines when will the signed URL expires.
  google.protobuf.Timestamp expires_at = 3;

  // Data proxy generates these headers for client, and they have to add these headers to the request when uploading the file.
  map<string, string> headers = 4;
}

// CreateUploadLocationRequest specified request for the CreateUploadLocation API.
// The implementation in data proxy service will create the s3 location with some server side configured prefixes,
// and then:
//   - project/domain/(a deterministic str representation of the content_md5)/filename (if present); OR
//   - project/domain/filename_root (if present)/filename (if present).
message CreateUploadLocationRequest {
  // Project to create the upload location for
  // +required
  string project = 1;

  // Domain to create the upload location for.
  // +required
  string domain = 2;

  // Filename specifies a desired suffix for the generated location. E.g. `file.py` or `pre/fix/file.zip`.
  // +optional. By default, the service will generate a consistent name based on the provided parameters.
  string filename = 3;

  // ExpiresIn defines a requested expiration duration for the generated url. The request will be rejected if this
  // exceeds the platform allowed max.
  // +optional. The default value comes from a global config.
  google.protobuf.Duration expires_in = 4;

  // ContentMD5 restricts the upload location to the specific MD5 provided. The ContentMD5 will also appear in the
  // generated path.
  // +required
  bytes content_md5 = 5;

  // If present, data proxy will use this string in lieu of the md5 hash in the path. When the filename is also included
  // this makes the upload location deterministic. The native url will still be prefixed by the upload location prefix
  // in data proxy config. This option is useful when uploading multiple files.
  // +optional
  string filename_root = 6;

  // If true, the data proxy will add content_md5 to the metadata to the signed URL and
  // it will force clients to add this metadata to the object.
  // This make sure dataproxy is backward compatible with the old flytekit.
  bool add_content_md5_metadata = 7;


  // Optional, org key applied to the resource.
  string org = 8;
}

// CreateDownloadLocationRequest specified request for the CreateDownloadLocation API.
message CreateDownloadLocationRequest {
  option deprecated = true;
  // NativeUrl specifies the url in the format of the configured storage provider (e.g. s3://my-bucket/randomstring/suffix.tar)
  string native_url = 1;

  // ExpiresIn defines a requested expiration duration for the generated url. The request will be rejected if this
  // exceeds the platform allowed max.
  // +optional. The default value comes from a global config.
  google.protobuf.Duration expires_in = 2;
}

message CreateDownloadLocationResponse {
  option deprecated = true;
  // SignedUrl specifies the url to use to download content from (e.g. https://my-bucket.s3.amazonaws.com/randomstring/suffix.tar?X-...)
  string signed_url = 1;
  // ExpiresAt defines when will the signed URL expires.
  google.protobuf.Timestamp expires_at = 2;
}

// ArtifactType
enum ArtifactType {
  // ARTIFACT_TYPE_UNDEFINED is the default, often invalid, value for the enum.
  ARTIFACT_TYPE_UNDEFINED = 0;

  // ARTIFACT_TYPE_DECK refers to the deck html file optionally generated after a task, a workflow or a launch plan
  // finishes executing.
  ARTIFACT_TYPE_DECK = 1;
}

// CreateDownloadLinkRequest defines the request parameters to create a download link (signed url)
message CreateDownloadLinkRequest {
  // ArtifactType of the artifact requested.
  ArtifactType artifact_type = 1;

  // ExpiresIn defines a requested expiration duration for the generated url. The request will be rejected if this
  // exceeds the platform allowed max.
  // +optional. The default value comes from a global config.
  google.protobuf.Duration expires_in = 2;

  oneof source {
    // NodeId is the unique identifier for the node execution. For a task node, this will retrieve the output of the
    // most recent attempt of the task.
    core.NodeExecutionIdentifier node_execution_id = 3;
  }
}

// CreateDownloadLinkResponse defines the response for the generated links
message CreateDownloadLinkResponse {
  // SignedUrl specifies the url to use to download content from (e.g. https://my-bucket.s3.amazonaws.com/randomstring/suffix.tar?X-...)
  repeated string signed_url = 1 [deprecated = true];

  // ExpiresAt defines when will the signed URL expire.
  google.protobuf.Timestamp expires_at = 2 [deprecated = true];

  // New wrapper object containing the signed urls and expiration time
  PreSignedURLs pre_signed_urls = 3;
}

// Wrapper object since the message is shared across this and the GetDataResponse
message PreSignedURLs {
  // SignedUrl specifies the url to use to download content from (e.g. https://my-bucket.s3.amazonaws.com/randomstring/suffix.tar?X-...)
  repeated string signed_url = 1;

  // ExpiresAt defines when will the signed URL expire.
  google.protobuf.Timestamp expires_at = 2;
}

// General request artifact to retrieve data from a Flyte artifact url.
message GetDataRequest {
  // A unique identifier in the form of flyte://<something> that uniquely, for a given Flyte
  // backend, identifies a Flyte artifact ([i]nput, [o]output, flyte [d]eck, etc.).
  // e.g. flyte://v1/proj/development/execid/n2/0/i (for 0th task execution attempt input)
  //      flyte://v1/proj/development/execid/n2/i (for node execution input)
  //      flyte://v1/proj/development/execid/n2/o/o3 (the o3 output of the second node)
  string flyte_url = 1;
}

message GetDataResponse {
  oneof data {
    // literal map data will be returned
    core.LiteralMap literal_map = 1;

    // Flyte deck html will be returned as a signed url users can download
    PreSignedURLs pre_signed_urls = 2;

    // Single literal will be returned. This is returned when the user/url requests a specific output or input
    // by name. See the o3 example above.
    core.Literal literal = 3;
  }
}

// DataProxyService defines an RPC Service that allows access to user-data in a controlled manner.
service DataProxyService {
  // CreateUploadLocation creates a signed url to upload artifacts to for a given project/domain.
  rpc CreateUploadLocation (CreateUploadLocationRequest) returns (CreateUploadLocationResponse) {
    option (google.api.http) = {
      post: "/api/v1/dataproxy/artifact_urn"
      body: "*"
    };
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
      description: "Creates a write-only http location that is accessible for tasks at runtime."
    };
  }

  // CreateDownloadLocation creates a signed url to download artifacts.
  rpc CreateDownloadLocation (CreateDownloadLocationRequest) returns (CreateDownloadLocationResponse) {
    option deprecated = true;
    option (google.api.http) = {
      get: "/api/v1/dataproxy/artifact_urn"
    };
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
      description: "Deprecated: Please use CreateDownloadLink instead. Creates a read-only http location that is accessible for tasks at runtime."
    };
  }

  // CreateDownloadLocation creates a signed url to download artifacts.
  rpc CreateDownloadLink (CreateDownloadLinkRequest) returns (CreateDownloadLinkResponse) {
    option (google.api.http) = {
      post: "/api/v1/dataproxy/artifact_link"
      body: "*"
    };
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
      description: "Creates a read-only http location that is accessible for tasks at runtime."
    };
  }

  rpc GetData (GetDataRequest) returns (GetDataResponse) {
    // Takes an address like flyte://v1/proj/development/execid/n2/0/i and return the actual data
    option (google.api.http) = {
      get: "/api/v1/data"
    };
  }
}
