phpcurlmultipartform-dataguzzlestability

Mimic curl working script in Guzzle (multipart data with binary uploads together)


I have curl command that works perfectly (using img2img via Stability API):

curl --request POST 'https://api.stability.ai/v1/generation/stable-diffusion-xl-1024-v1-0/image-to-image' \
    --header 'Content-Type: multipart/form-data' \
    --header 'Accept: application/json' \
    --header 'Authorization: Bearer somesecrettoken' \
    --form 'init_image=@"/full/path/to/init_image.png"' \
    --form 'text_prompts[0][text]=Beautiful php code' \
    --output '/full/path/to/response.json'

I've tried this PHP code with Guzzle v.6.5.8 which gives me HTTP 520:

(new Client())
->post(
    'https://api.stability.ai/v1/generation/stable-diffusion-xl-1024-v1-0/image-to-image',
    [
        RequestOptions::HEADERS   => [
            'Accept'        => 'application/json',
            'Authorization' => 'Bearer somesecrettoken',
            'Content-Type'  => 'multipart/form-data',
        ],
        RequestOptions::MULTIPART => [
            [
                'name'     => 'text_prompts[0][text]',
                'contents' => 'Beautiful php code',
            ],
            [
                'name'     => 'init_image',
                'contents' => (new File('/full/path/to/init_image.png'))->getContent(),
//                'contents' => \GuzzleHttp\Psr7\Utils::tryFopen('/full/path/to/init_image.png', 'rb'), // This won't work too
            ],
        ],
        RequestOptions::SINK      => '/full/path/to/response.json',
        RequestOptions::DEBUG     => true,
    ],
)

What i'm doing wrong here?


Solution

  • Assuming that app.stability.key contains only your somesecrettoken, your Authorization header would be missing the Bearer keyword.

    Also, leaving out the Content-Type header might be a good idea. This header eventually needs to include the boundary value the library used to separate the individual parts of this request - and when using RequestOptions::MULTIPART, it should add this header, including the boundary value, on its own. If you explicitly specify it, it might be that this overwrites what the library would create by itself, and then the boundary would be missing.