Amazon transcribe "Operation not found: StartTranscriptionJob" - php

Windows 7 Pro
PHP 7.0.2
AWS transcribe API 2017-10-26
Hi,
I'm trying to use Amazon Web Services to transcribe recordings from an IVR (Please leave your name after the tone. etc) using PHP. I can upload the recordings to my AWS bucket (so something is right) but when I try to start the transcription job I get the following error:
"Operation not found: StartTranscriptionJob"
I can get transcription to work using the AWS CLI so my system seems to be set up OK. There is not a lot online about this issue, I've done all the usual Googling and the info isn't very helpful - such as:
https://docs.aws.amazon.com/transcribe/latest/dg/API_StartTranscriptionJob.html
https://docs.aws.amazon.com/sdk-for-go/api/service/transcribeservice/#TranscribeService.StartTranscriptionJob
Here's my code, the StartTranscriptionJob is at the end:
<?php
require 'aws\aws-autoloader.php';
chdir('asr');
$logFile = 'asr.log';
$log = "\n\n".date("d/m/Y H:i:s");
###################
# get the recording
###################
$service = htmlspecialchars($_GET["service"]);
$recording = htmlspecialchars($_GET["recording"]);
$ftp_server = "ftp.****";
$ftp_username = "****";
$ftp_userpass = "****";
$ftp_conn = ftp_connect($ftp_server,7721) or die("Could not connect to $ftp_server");
ftp_login($ftp_conn, $ftp_username, $ftp_userpass);
ftp_chdir($ftp_conn,'Recordings');
ftp_pasv($ftp_conn, true);
ftp_chdir($ftp_conn,$service);
ftp_get ($ftp_conn , $recording , $recording, FTP_BINARY);
ftp_close($ftp_conn);
######################
# Upload to AWS bucket
######################
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
$credentials = new Aws\Credentials\Credentials('****', '****');
$bucket = 'asr-bucket-test';
$keyname = $recording;
$s3 = new S3Client([
'profile' => 'default',
'version' => 'latest',
'region' => 'us-west-2',
'credentials' => $credentials
]);
try {
// Upload data.
$result = $s3->putObject([
'Bucket' => $bucket,
'Key' => $keyname,
'SourceFile' => '\xampp\htdocs\****.co.uk\asr\\'.$recording,
'ACL' => 'public-read'
]);
// Print the URL to the object.
$log.= "\n".$result['ObjectURL'] . PHP_EOL;
} catch (S3Exception $e) {
$log.= "\n".$e->getMessage() . PHP_EOL;
}
############
# Transcribe
############
try {
$result = $s3->StartTranscriptionJob([
'LanguageCode' => 'en-US', // REQUIRED
'Media' => [
'MediaFileUri' => 'https://s3-us-west-2.amazonaws.com/asr-bucket-test/'.$recording,
],
'MediaFormat' => 'wav', // REQUIRED
'OutputBucketName' => $bucket,
'Settings' => [
# 'ChannelIdentification' => true || false,
'MaxSpeakerLabels' => 5,
# 'ShowSpeakerLabels' => true || false,
# 'VocabularyName' => $recording
],
'TranscriptionJobName' => 'test_job', // REQUIRED
]);
$log.="\n".$result;
} catch (Exception $e) {
$log.="\nError: Cannot start transcripion job " . $e->getMessage();
}
file_put_contents($logFile, $log,FILE_APPEND);
exit();
?>

You are trying to use S3Client to start the transcription:
$result = $s3->StartTranscriptionJob
Per the error message, S3 doesn't support the StartTranscriptionJob operation. You need to setup and use the TranscribeServiceClient.
You linked to the AWS SDK docs for Go, but your code is PHP. Relevant docs for PHP:
https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.TranscribeService.TranscribeServiceClient.html

You have to create a new TranscribeServiceClient and then connect through that. Here's a snippet from my working code:
$transcribe = new Aws\TranscribeService\TranscribeServiceClient([
'region' => $region,
'version' => 'latest',
'credentials' => [
'key' => $accessKey,
'secret' => $secretKey,
],
]);
//print_r($transcribe);
$result = $transcribe->startTranscriptionJob([
'LanguageCode' => $languageCode, // REQUIRED
'Media' => [ // REQUIRED
'MediaFileUri' => $mediaURI,
],
'MediaFormat' => $fileExt, // REQUIRED
'OutputBucketName' => $bucketName,
'Settings' => [
'ChannelIdentification' => false,
'MaxSpeakerLabels' => 5,
'ShowSpeakerLabels' => true,
'VocabularyName' => '',
],
'TranscriptionJobName' => $fileName . "-" . date('Ymd-his') // REQUIRED
]);

Related

I Unable to move images in S3 bucket from our main server

I want to upload my images in the amazon s3 bucket. My images database uploaded to another web server. I am unable to move it to the S3 bucket. I referred to some solutions from StackOverflow.
Here is my code I have tried:
use \usr\share\php\AWSSDKforPHP\S3;
use \usr\share\php\AWSSDKforPHP\S3\S3Client;
use \usr\share\php\AWSSDKforPHP\S3\Exception\S3Exception;
$bucket = 'cdn.example.com';
$keyname = $newfilename;
$s3 = new S3Client([
'version' => 'latest',
'region' => 'us-east-1',
'credentials' => [
'key' => "**********************",
'secret' => "**********************************"
]
]);
try {
// Upload data.
$result = $s3->putObject([
'Bucket' => $bucket,
'Key' => $keyname,
'SourceFile' => $oldfilepath,
'ACL' => 'public-read'
]);
// Print the URL to the object.
echo $result['ObjectURL'] . PHP_EOL;
} catch (S3Exception $e) {
echo $e->getMessage() . PHP_EOL;
}
Showing error in output:
Fatal error: Class 'usr\share\php\AWSSDKforPHP\S3\S3Client' not found in /var/www/html/cron-jobs/shift-img.php on line 35

How to customize s3 uploaded files url in yii2?

I have used vlaim\fileupload\FileUpload; and yii\web\UploadedFile;
$image = UploadedFile::getInstance($model, 'flag');
$model->flag = new FileUpload(FileUpload::S_S3, [
'version' => 'latest',
'region' => 'us-west-2',
'credentials' => [
'key' => 'KEY',
'secret' => 'SECRET'
],
'bucket' => 'mybucket/uploads/flags/'.$model->code
]);
$uploader = $model->flag;
$model->flag = $uploader->uploadFromFile($image)->path;
In db i'm saving the path. How to customize the url?
Now my url looks like https://s3-us-west-2.amazonaws.com/mybucket%2Fuploads%2Fflags%2Fus/uploads%5C9f%5C7e%5Cc093ad5a.png
I need the url like https://mybucket.s3.amazonaws.com/uploads/flags/us.png
S3 does not have the concept of folders, It is an object store, with key/value pairs. They key for your file would be uploads/flags/us.png
with the PHP SDK it's easy to set the key of the object.
$USAGE = "\n" .
"To run this example, supply the name of an S3 bucket and a file to\n" .
"upload to it.\n" .
"\n" .
"Ex: php PutObject.php <bucketname> <filename>\n";
if (count($argv) <= 2){
echo $USAGE;
exit();
}
$bucket = $argv[1];
$file_Path = $argv[2];
$key = basename($argv[2]);
try{
//Create a S3Client
$s3Client = new S3Client([
'region' => 'us-west-2',
'version' => '2006-03-01'
]);
$result = $s3Client->putObject([
'Bucket' => $bucket,
'Key' => $key,
'SourceFile' => $file_Path,
]);
} catch (S3Exception $e) {
echo $e->getMessage() . "\n";
}
yii2 i think you need to set setFsUrl()
http://www.yiiframework.com/extension/yii2-file-upload/#hh8
setFsUrl(string $url)
(Only for Local mode)
Sets url. For example, if you set path to 'http://static.example.com' file after uploading will have URL http://static.example.com/path/to/your/file
Default to /
php $uploader->setFsPath('http://pathtoyoursite.com');

unable to upload file to sub-folder of main bucket

I am trying to upload error file in AWSS3 but it shows error like "The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint: "test9011960909.s3.amazonaws.com"."
i also specified 'region' => 'us-east-1' but still same error occurs.
it is working when i specify
'Bucket' => $this->bucket,
but i wanted to upload file in sub-folder of main bucket
'Bucket' => $this->bucket . "/" . $PrefixFolderPath,
i already applied approved answer from AWS S3: The bucket you are attempting to access must be addressed using the specified endpoint
but still getting same error, i am using php
Code :
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
class AWSS3Factory {
private $bucket;
private $keyname;
public function __construct() {
$this->bucket = AWSS3_BucketName;
$this->keyname = AWSS3_AccessKey;
// Instantiate the client.
}
public function UploadFile($FullFilePath,$PrefixFolderPath="") {
try {
$s3 = S3Client::factory(array(
'credentials' => array(
'key' => MYKEY,
'secret' => MYSECKEY,
'region' => 'eu-west-1',
)
));
// Upload data.
$result = $s3->putObject(array(
'Bucket' => $this->bucket . "/" . $PrefixFolderPath,
'Key' => $this->keyname,
'SourceFile' => $FullFilePath,
'StorageClass' => 'REDUCED_REDUNDANCY'
));
return true;
// Print the URL to the object.
//echo $result['ObjectURL'] . "\n";
} catch (S3Exception $e) {
echo $e->getMessage() . "\n";
}
}
}
You must create s3 instance in another way, like this:
$s3 = S3Client::factory([
'region' => '',
'credentials' => ['key' => '***', 'secret' => '***'],
'version' => 'latest',
]);
You must add $PrefixFolderPath not to 'Bucket' but to 'Key':
$result = $s3->putObject(array(
'Bucket' => $this->bucket,
'Key' => $PrefixFolderPath . "/" . $this->keyname,
'SourceFile' => $FullFilePath,
'StorageClass' => 'REDUCED_REDUNDANCY'
));

Amazon s3 SDK for php can not get Bucket object list

I was getting list of object from a bucket but it getting error of endpoint.
define('AWS_KEY', 'xxxxxx');
define('AWS_SECRET_KEY', 'x+x/xxxxxxxx/');
define('AWS_CANONICAL_ID','xx');
define('AWS_CANONICAL_NAME', 'xxxxx');
$HOST = 's3.amazonaws.com';
require_once 'php_plugins/aws/v1/sdk.class.php';
$Connection = new AmazonS3(array(
'key' => AWS_KEY,
'secret' => AWS_SECRET_KEY,
'canonical_id' => AWS_CANONICAL_ID,
'canonical_name' => AWS_CANONICAL_NAME,
));
$ListResponse = $Connection->list_buckets();
$Buckets = $ListResponse->body->Buckets->Bucket;
foreach ($Buckets as $Bucket) {
echo $Bucket->Name . "\t" . $Bucket->CreationDate . "\n";
$response = $Connection->list_objects($Bucket->Name);
}
I am getting response.
[body] => CFSimpleXML Object
(
[Code] => PermanentRedirect
[Message] => The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint.
[Bucket] => pics.online.com
[Endpoint] => pics.online.com.s3.amazonaws.com
[RequestId] => 5F102571A54DA3BA
[HostId] => tBBxwxfUbdlV+m1R/Z9BnjLViyjROdzXrhPfc28WHaZYo/1zAwof2C0G5CVpZvkP8oZERTL0CD8=
)
[status] => 301
I think error is in URL
code call "host name/bucket name"
here I have change my bucketname
https://s3.amazonaws.com/pics.online.com/
it should call
https://pics.online.com.s3.amazonaws.com/
can you anyone tell me how to change this path for amazon s3 PHP?
try this
<?php
require 'aws-autoloader.php';
$credentials = new Aws\Credentials\Credentials('XXXXXXXXXXXXX', 'XXXXXXXXXXXXXX');
$bucket = "";
$s3 = \Aws\S3\S3Client::factory([
'signature' => 'v4',
'version' => 'latest',
'region' => 'ap-southeast-1',
'credentials' => $credentials,
'http' => [
'verify' => '/home/ubuntu/cacert.pem'
],
'Statement' => [
'Action ' => "*",
],
// 'debug' => [
// 'logfn' => function ($msg) {
// echo $msg . "\n";
// },
// 'stream_size' => 0,
// 'scrub_auth' => true,
// 'http' => true,
// ]
]);
try {
$objects = $s3->getIterator('ListObjects', array(
'Bucket' => $bucket //bucket name
));
echo "Keys retrieved!\n";
foreach ($objects as $object) {
echo $object['Key'] . "\n";
}
} catch (S3Exception $e) {
echo $e->getMessage() . "\n";
}
?>
download the sdk from AWS PHP SDK
UPDATE
First check you system for AWS Compatibility by using the following files.
https://github.com/amazonwebservices/aws-sdk-for-php/tree/master/_compatibility_test
you can use cacert.pem for fetching whole data from AWS S3.
you can download cacert.pem from here. and modify your php.ini by adding below code.
curl.cainfo = D:\xampp\php\cacert.pem
Here is the code I use on my local machine for fetching data without https. I have PHP V5.6 .
require 'aws-autoloader.php';
$s3 = \Aws\S3\S3Client::factory(array(
'credentials' => array(
'key' => '************',
'secret' => '*************',
),
'signature' => 'v4',
'version' => 'latest',
'region' => 'ap-southeast-1',
));
print_r($result = $s3->listBuckets());
if you face errors in following format. you can use array format for initializing S3 object.
You can specify the bucket name using the set_hostname method...
$Connection->set_hostname($HOST); // Set the hostname
$Connection->allow_hostname_override(false); // Stop the hostname being changed later.
Your code should then read as follows...
define('AWS_KEY', 'xxxxxx');
define('AWS_SECRET_KEY', 'x+x/xxxxxxxx/');
define('AWS_CANONICAL_ID','xx');
define('AWS_CANONICAL_NAME', 'xxxxx');
$HOST = 's3.amazonaws.com';
require_once 'php_plugins/aws/v1/sdk.class.php';
$Connection = new AmazonS3(array(
'key' => AWS_KEY,
'secret' => AWS_SECRET_KEY,
'canonical_id' => AWS_CANONICAL_ID,
'canonical_name' => AWS_CANONICAL_NAME,
));
$Connection->set_hostname('pics.online.com.s3.amazonaws.com');
$Connection->allow_hostname_override(false);
$ListResponse = $Connection->list_buckets();
$Buckets = $ListResponse->body->Buckets->Bucket;
foreach ($Buckets as $Bucket) {
echo $Bucket->Name . "\t" . $Bucket->CreationDate . "\n";
$response = $Connection->list_objects($Bucket->Name);
}
I'm not sure which region is your buckets in. I thought you have multiple buckets in multiple regions. You can not call object related operation using S3Client for different region. It's only working for a specific region.
<?php
define('AWS_KEY', 'AKIAXXXXXXXXXXXXXXXX');
define('AWS_SECRET_KEY', 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');
define('REGION', 'ap-southeast-1');
require_once 'aws-sdk-php-3.4.0/aws-autoloader.php';
$client = new Aws\S3\S3Client(array(
'credentials' => array(
'key' => AWS_KEY,
'secret' => AWS_SECRET_KEY,
),
'region' => REGION,
'version' => 'latest',
));
$listBuckets = $client->listBuckets();
foreach ($listBuckets['Buckets'] as $bucket) {
// Get bucket location
$location = $client->getBucketLocation(array(
'Bucket' => $bucket['Name']
));
// Print bucket information
echo $bucket['Name'] . "\t" . $bucket['CreationDate'] . "\t" . $location['LocationConstraint'] . "\n";
// Check if the bucket location is in client region
if ($location['LocationConstraint'] == $client->getRegion()) {
$listObjects = $client->listObjects(array(
'Bucket' => $bucket['Name']
));
foreach ($listObjects['Contents'] as $object) {
echo $object['Key'] . "\t" . $object['Size'] . "\n";
}
} else {
echo "--> The bucket is not in " . $client->getRegion() . ". Skipped.\n";
}
}
If you are working on multiple regions, you can create separated S3Client for each region.

AWS S3 access denied when getting image by url

I am working on AWS EC2 Ubuntu Machine and trying to fetch image from AWS S3 but following error has been shown to me every time.
<Error>
<Code>InvalidArgument</Code>
<Message>
Requests specifying Server Side Encryption with AWS KMS managed keys require AWS Signature Version 4.
</Message>
<ArgumentName>Authorization</ArgumentName>
<ArgumentValue>null</ArgumentValue>
<RequestId>7C8B4BF1CE2FDC9E</RequestId>
<HostId>
/L5kjuOET4XFgGter2eFHX+aRSvVm/7VVmIBqQE/oMLeQZ1ditSMZuHPOlsMaKi8hYRnGilTqZY=
</HostId>
</Error>
Here is my bucket policy
{
"Version": "2012-10-17",
"Id": "Policy1441213815928",
"Statement": [
{
"Sid": "Stmt1441213813464",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mytest.sample/*"
}
]
}
Here is the code
require 'aws-autoloader.php';
$credentials = new Aws\Credentials\Credentials('key', 'key');
$bucketName = "mytest.sample";
$s3 = new Aws\S3\S3Client([
'signature' => 'v4',
'version' => 'latest',
'region' => 'ap-southeast-1',
'credentials' => $credentials,
'http' => [
'verify' => '/home/ubuntu/cacert.pem'
],
'Statement' => [
'Action ' => "*",
],
]);
$result = $s3->getObject(array(
'Bucket' => $bucketName,
'Key' => 'about_us.jpg',
));
Html
<img src="<?php echo $result['#metadata']['effectiveUri']; ?>" />
Edit for Michael - sqlbot : here I am using default KMS.
try {
$result = $this->Amazon->S3->putObject(array(
'Bucket' => 'mytest.sample',
'ACL' => 'authenticated-read',
'Key' => $newfilename,
'ServerSideEncryption' => 'aws:kms',
'SourceFile' => $filepath,
'ContentType' => mime_content_type($filepath),
'debug' => [
'logfn' => function ($msg) {
echo $msg . "\n";
},
'stream_size' => 0,
'scrub_auth' => true,
'http' => true,
],
));
} catch (S3Exception $e) {
echo $e->getMessage() . "\n";
}
let me know if you need more.
PHP sdk v2
the Credentials package is Aws\Common\Credentials
to create an S3Client you need a factory
Try something like this
use Aws\S3\S3Client;
use Aws\Common\Credentials\Credentials;
$credentials = new Credentials('YOUR_ACCESS_KEY', 'YOUR_SECRET_KEY');
// Instantiate the S3 client with your AWS credentials
$s3Client = S3Client::factory(array(
'signature' => 'v4',
'region' => 'ap-southeast-1',
'credentials' => $credentials,
.....
]);
)
If that does not work you might try to declare explicitly a SignatureV4 object
use Aws\S3\S3Client;
use Aws\Common\Credentials\Credentials;
use Aws\Common\Signature\SignatureV4;
$credentials = new Credentials('YOUR_ACCESS_KEY', 'YOUR_SECRET_KEY');
// Instantiate the S3 client with your AWS credentials
$s3Client = S3Client::factory(array(
'signature' => new SignatureV4(),
'region' => 'ap-southeast-1',
'credentials' => $credentials,
.....
]);
)
In case you upgrade to sdk v3
You need to have signature_version (instead of signature) as parameter when you declare your s3 client
Statement does not appear to be a valid parameter (http://docs.aws.amazon.com/aws-sdk-php/v3/guide/guide/configuration.html#signature-version)
if issue you can turn on debug param to get more output
This would look like this
$s3 = new Aws\S3\S3Client([
'signature_version' => 'v4',
'version' => 'latest',
'region' => 'ap-southeast-1',
'credentials' => $credentials,
'http' => [
'verify' => '/home/ubuntu/cacert.pem'
],
'debug' => true
]);
see here for the full list of available parameter
I have also face this issue with aws:kms encyrption key, I suggest that if you wanted to use kms key then you have to create your kms key in IAM section of AWS Console. I love to recommended AES256 server side encryption, here S3 automatically Encrypted your data while putting and decryption while getting object. Please go through below link:
S3 Server Side encryption with AES256
My Solution is change this line 'ServerSideEncryption' => 'aws:kms' with 'ServerSideEncryption' => 'AES256'
try {
$result = $this->Amazon->S3->putObject(array(
'Bucket' => 'mytest.sample',
'ACL' => 'authenticated-read',
'Key' => $newfilename,
'ServerSideEncryption' => 'AES256',
'SourceFile' => $filepath,
'ContentType' => mime_content_type($filepath),
'debug' => [
'logfn' => function ($msg) {
echo $msg . "\n";
},
'stream_size' => 0,
'scrub_auth' => true,
'http' => true,
],
));
} catch (S3Exception $e) {
echo $e->getMessage() . "\n";
}
Please also update your bucket policy with below json, it will prevent you to upload object with out AES256 encryption
{
"Sid": "DenyUnEncryptedObjectUploads",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::yourbucketname/*",
"Condition": {
"StringNotEquals": {
"s3:x-amz-server-side-encryption": "AES256"
}
}
}

Categories