Stability-AI / api-interfaces

Interface definitions for API interactions between components
140 stars 78 forks source link

Request a Golang usage document #49

Open panaoshuai opened 1 year ago

panaoshuai commented 1 year ago

I use git clone -- recurse submodules according to the document git@github.com :Stability-AI/api-interfaces. The git gets the code, but it can't be completed successfully when using cmake. Is there a compiled go file that can be used directly? Please explain how the interface should be called by the way. Check that there is no api key input in the source code

arsenetar commented 1 year ago

To use the already generated sources for go you can use go get github.com/stability-ai/api-interfaces/gooseai@latest to fetch the latest version.

carryinfo commented 1 year ago

To use the already generated sources for go you can use go get github.com/stability-ai/api-interfaces/gooseai@latest to fetch the latest version.

can you give a sample code to use ? I tried many times, but failed. can you help me?

https://github.com/Stability-AI/api-interfaces/issues/40#issuecomment-1359317193

arsenetar commented 1 year ago

@panaoshuai, @carryinfo Below is some example snippets that may be useful as an example:

Creating a client:

// Create a new client from an addr string host:port
func createClient(addr string) generation.GenerationServiceClient {
    conn, err := connect(addr)
    if err != nil {
        panic(err)
    }
    return generation.NewGenerationServiceClient(conn)
}

// Create a new grpc connection from addr string host:port
func connect(addr string) (*grpc.ClientConn, error) {
    grpcOptions := []grpc.DialOption{
        // For TLS
        grpc.WithTransportCredentials(
            credentials.NewTLS(&tls.Config{}),
        ),
        // Recommended to set keepalive for better handling of network related issues
        grpc.WithKeepaliveParams(
            keepalive.ClientParameters{
                Time:                10 * time.Second,
                Timeout:             20 * time.Second,
                PermitWithoutStream: true,
            },
        ),
    }
    return grpc.Dial(addr, grpcOptions...)
}

Loading the token into the context:

// Create a grpc context with provided token
func createGrpcCtx(ctx context.Context, token string) context.Context {
    md := metadata.New(
        map[string]string{
            "authorization": "Bearer " + token,
        },
    )
    return metadata.NewOutgoingContext(ctx, md)
}

Running a generation:

// Run a generation with a client and request
func generate(
    ctx context.Context,
    client generation.GenerationServiceClient,
    request *generation.Request,
) error {
    start := time.Now()
    stream, err := client.Generate(ctx, request)
    if err != nil {
        log.Printf("Error on conn: %v\n", err)
        return err
    }
    for {
        answer, err := stream.Recv()
        // io.EOF indicates end of stream
        if err == io.EOF {
            break
        }
        if err != nil {
            log.Printf("Error after %0.3f s: %v\n", time.Since(start).Seconds(), err)
            return err
        }
        if answer == nil {
            break
        }
        log.Printf(
            "Answer %s received with %d artifacts in %fs\n",
            answer.AnswerId,
            len(answer.GetArtifacts()),
            time.Since(start).Seconds(),
        )
        for _, artifact := range answer.GetArtifacts() {
            log.Printf(
                "Artifact %s: %d:%d - %s",
                artifact.Type.String(),
                artifact.Id,
                artifact.Index,
                artifact.Uuid,
            )
            if artifact.Type == generation.ArtifactType_ARTIFACT_IMAGE {
                os.WriteFile(
                    fmt.Sprintf("images/%s-%d.png", answer.AnswerId, artifact.Id),
                    artifact.GetBinary(),
                    0664,
                )
            }
        }
    }

    return err
}

Example main function putting this all together:

func main() {
    client := createClient("grpc.stability.ai:443")
    token := "<TOKEN_VALUE>"
    request := generation.Request{
        EngineId:      "stable-diffusion-v1-5",
        RequestedType: generation.ArtifactType_ARTIFACT_IMAGE,
        Params: &generation.Request_Image{
            Image: &generation.ImageParameters{},
        },
        Prompt: []*generation.Prompt{{
            Prompt: &generation.Prompt_Text{Text: "Test prompt"},
        }},
    }
    generate(createGrpcCtx(context.Background(), token), client, &request)
}
Davincible commented 1 year ago

@arsenetar thanks for the example above. It would be nice to have the options better documented. There are a lot of options and its a bit overwhelming when just getting started. Even more detailed comments for all the options in the proto file would already help a lot