Http POST request returns status code 500

265 views Asked by At

I've been following this tutorial to build a flutter app that uses Cloud AutoML : https://medium.com/@epynic/using-automl-vision-in-your-next-flutter-app-3cc436312443 . I created a VM instance using Google Cloud, and the application is supposed to send a http POST request to a php file on the instance, and the PHP file will act like a proxy to interact with AutoML Vision. However, when I make a http request from the flutter application, I got the status code 500.

This is the code of the automl.php file (Some part of the URL was hidden for security reason):

<?php
$image = $_POST['image'];
$key = trim(shell_exec('sudo -u FlutterServiceAccount gcloud auth application-default print-access-token 2<&1')); // replace service_name with your service account name
$post = '{"payload":{"image":{"imageBytes": "' . $image . '"}}}';
$curl = curl_init();
// The REST API URL can be found from the predict tab example replace with your account URL https://automl.googleapis.com/v1beta1/projects/quizappflutter/locations/us-central1/models/ICNXXXXXXXXXX41:predict
curl_setopt_array($curl, array(
    CURLOPT_URL => "https://automl.googleapis.com/v1beta1/projects/103XXXXXXXXXX/locations/us-central1/models/ICN49XXXXXXXXXXXX:predict",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => $post,
    CURLOPT_HTTPHEADER => array(
        "Authorization: Bearer $key",
        "Content-Type: application/json",
    ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
    echo "cURL Error #:" . $err;
} else {
    echo $response;
}

And here is the code of main.dart of the flutter app

import 'dart:convert';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

import 'package:image_picker/image_picker.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'QuizApp Solver'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  File _image;
  bool predictionStarted = false;
  bool predictionComplete = false;
  var predictionResult = 'Please wait....';

  Future getImage() async {
    setState(() {
      predictionStarted = false;
      predictionComplete = false;
    });

    // var image = await ImagePicker.pickImage(source: ImageSource.camera);
    var image = await ImagePicker.pickImage(source: ImageSource.gallery);
    setState(() {
      _image = image;
      predictionStarted = true;
    });

    //post image
    List<int> imageBytes = image.readAsBytesSync();
    String base64Image = base64.encode(imageBytes);

    print(base64Image);

    Map<String, String> headers = {"Accept": "application/json"};
    Map body = {"image": base64Image};

    //
    var response = await http.post('http://35.XXX.XXX.XXX/automl.php',
        body: body, headers: headers);
    print('Status code');
    print(response.statusCode);
    setState(() {
      predictionResult = response.body;
      predictionComplete = true;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: SingleChildScrollView(
        child: Column(
          children: <Widget>[
            SizedBox(
              height: 20,
            ),
            Text(
              'Push the camera button',
              textAlign: TextAlign.center,
            ),
            RaisedButton(
              onPressed: getImage,
              child: Text('Camera'),
            ),
            (_image != null)
                ? Image.file(
                    _image,
                    scale: 20,
                  )
                : Text('No Image Picked'),
            predictionBody()
          ],
        ),
      ),
    );
  }

  Widget predictionBody() {
    var predictionText = (predictionComplete) ? 'Result' : 'Prediction started';
    if (predictionStarted) {
      return Column(
        children: <Widget>[
          Divider(),
          Text(predictionText),
          Text(predictionResult)
        ],
      );
    } else {
      return Container();
    }
  }
}

pubspec.yaml

name: awsquizsolver
description: A new Flutter project.

# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1

environment:
  sdk: ">=2.1.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2
  image_picker: ^0.6.0+2
  http: ^0.12.0+2

dev_dependencies:
  flutter_test:
    sdk: flutter


# For information on the generic Dart part of this file, see the
# following page: https://www.dartlang.org/tools/pub/pubspec

# The following section is specific to Flutter.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

  # To add assets to your application, add an assets section, like this:
  # assets:
  #  - images/a_dot_burr.jpeg
  #  - images/a_dot_ham.jpeg

  # An image asset can refer to one or more resolution-specific "variants", see
  # https://flutter.io/assets-and-images/#resolution-aware.

  # For details regarding adding assets from package dependencies, see
  # https://flutter.io/assets-and-images/#from-packages

  # To add custom fonts to your application, add a fonts section here,
  # in this "flutter" section. Each entry in this list should have a
  # "family" key with the font family name, and a "fonts" key with a
  # list giving the asset and other descriptors for the font. For
  # example:
  # fonts:
  #   - family: Schyler
  #     fonts:
  #       - asset: fonts/Schyler-Regular.ttf
  #       - asset: fonts/Schyler-Italic.ttf
  #         style: italic
  #   - family: Trajan Pro
  #     fonts:
  #       - asset: fonts/TrajanPro.ttf
  #       - asset: fonts/TrajanPro_Bold.ttf
  #         weight: 700
  #
  # For details regarding fonts from package dependencies,
  # see https://flutter.io/custom-fonts/#from-packages

Thank you.

0

There are 0 answers