How do you implement OpenAI GPT-3 Api Client in PHP? - php

I need help understanding the vague instructions on https://packagist.org/packages/orhanerday/open-ai
I downloaded the package from https://github.com/orhanerday/open-ai
I installed the package by running "composer require orhanerday/open-ai" in my Command Prompt
Instructions stop making sense from there.....
What does the "use Orhanerday\OpenAi\OpenAi;" code mean and where is it applied?
Am I to create a php file say index.php with content:
<?php
use Orhanerday\OpenAi\OpenAi;
$complete = $open_ai->complete([
'engine' => 'davinci',
'prompt' => 'Hello',
'temperature' => 0.9,
'max_tokens' => 150,
'frequency_penalty' => 0,
'presence_penalty' => 0.6,
]
?>
how and where do I add my api key? Do I create a file Orhanerday\OpenAi\OpenAi.php and enter my api key there?
i.e. OPENAI_API_KEY=sk-**********************************************

You should define the $open_ai variable as an OpenAI object by passing your private KEY value, like; new OpenAi('Your-OPENAI-KEY');
An Example;
<?php
use Orhanerday\OpenAi\OpenAi;
$open_ai = new OpenAi('OPEN-AI-KEY');// <- define the variable.
$complete = $open_ai->complete([
'engine' => 'davinci',
'prompt' => 'Hello',
'temperature' => 0.9,
'max_tokens' => 150,
'frequency_penalty' => 0,
'presence_penalty' => 0.6,
]);
I also add the Quick Start Part to orhanerday/OpenAI readme.

First you have you include thé 'autoload'file. 'use' doesn't mean that you have to create a file yourself.

Related

"Amazon Personalize" PutItems, PutEvents, PutUsers using aws/aws-sdk-php

I am building an integration between my Laravel application and Amazon Personalize using:
aws/aws-sdk-php
Everything goes ok, but when I look on how to update the datasets with new Users, interactions and items, I couldn't find the right method/approach to do this, or if it is even possible.
I have created the Event Tracker but I can't find how to replicate this Python code into PHP:
# Configure Properties:
event = {
"itemId": str(ITEM_ID),
}
event_json = json.dumps(event)
# Make Call
personalize_events.put_events(
trackingId = TRACKING_ID,
userId= USER_ID,
sessionId = session_ID,
eventList = [{
'sentAt': int(time.time()),
'eventType': 'EVENT_TYPE',
'properties': event_json
}]
The code above is a portion extracted from here https://github.com/aws-samples/amazon-personalize-samples/blob/master/getting_started/notebooks/1.Building_Your_First_Campaign.ipynb
That would be for tracking new events:
https://docs.aws.amazon.com/personalize/latest/dg/API_UBS_PutEvents.html
If there is a chance to avoid executing an extra Python script better, if not I will go for that option.
Thanks in advance!
I found that I need to use the PersonalizeEventsClient instead of PersonalizeClient for this purpose, as stated here:
https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-personalize-events-2018-03-22.html#putevents
The link is part of the AWS Personalize documentation, I missed that previously, there they explain how to PutEvents, Items and Users using the AWS SDK PHP, for example:
$client = AWS::createClient('personalizeevents');
$result = $client->putEvents([
'eventList' => [ // REQUIRED
[
'eventId' => '<string>',
'eventType' => '<string>', // REQUIRED
'eventValue' => <float>,
'impression' => ['<string>', ...],
'itemId' => '<string>',
'properties' => '<string>',
'recommendationId' => '<string>',
'sentAt' => <integer || string || DateTime>, // REQUIRED
],
// ...
],
'sessionId' => '<string>', // REQUIRED
'trackingId' => '<string>', // REQUIRED
'userId' => '<string>',
]);
I am also using this service provider for Laravel:
https://github.com/aws/aws-sdk-php-laravel

The "access_key" option must be provided to use fixer.io

For the currency conversion i am using "florianv/laravel-swap": "^1.1" library. Florianv/Laravel-swap.
As Fixer.io has changed its implementation, it is necessary to pass the access_key with the request, and because of that i am getting this error: "InvalidArgumentException: The "access_key" option must be provided to use fixer.io in /var/www/project/project-files/vendor/florianv/exchanger/src/Service/Fixer.php:51".
I registered and got the access_key.
I updated the library using composer and now i can see three constants in the vendor/florianv/exchanger/src/Service/Fixer.php.
const ACCESS_KEY_OPTION = 'access_key';
const LATEST_URL = 'http://data.fixer.io/api/latest?base=%s&access_key=%s';
const HISTORICAL_URL = 'http://data.fixer.io/api/%s?base=%s&access_key=%s';
To pass the access key i tried this:
I have a swap.php in config folder which looks something like this:
return [
'options' => [
'cache_ttl' => 86400, // 24 hours.
'cache_key_prefix' => 'currency_rate'
],
'services' => [
'fixer' => true,
],
'currency_layer' => [
'access_key' => 'asdfas7832mw3nsdfa776as8dfa', // Your app id
'enterprise' => true, // True if your AppId is an enterprise one
],
'cache' => env('CACHE_DRIVER', 'file'),
'http_client' => null,
'request_factory' => null,
'cache_item_pool' => null,
];
This had one more option which was commented, i enabled and passed the access_key in it but it doesn't work.
I also added it in services block below 'fixer => true'.
'currency_layer' => [
'access_key' => 'asdfas7832mw3nsdfa776as8dfa'
]
Also in options block:
'options' => [
'cache_ttl' => 86400, // 24 hours.
'cache_key_prefix' => 'currency_rate',
'access_key'=>'7ca208e9136c5e140d6a14427bf9ed21'
],
I tried with adding access_key in config/services.php file but it also didn't work.
'fixer' => [
'access_key' => 'asdfas7832mw3nsdfa776as8dfa'
],
Even i tried, adding to env file and calling from there, but no success. How do i pass the access_key, can anyone help me on this, what should be the approach.
vendor/florianv/exchanger/src/Service/Fixer.php -> don't touch the constant (that was my own error).
Pass the options-array by creating the Builder:
$options = ['access_key' => 'YourGeneratedAPIKeyAtCurrencyLayer'];
$this->exchangeSwap = (new Builder($options))
->add('fixer', $options )
->build();
I hope I could help ;-)

PHP Mongo MapReduce - How to Call Server Loaded JavaScript Functions

First, I want to say that this is more of a PHP Mongo Driver issue than MongoDB issue.
I have a problem with calling MapReduce through PHP. I have 3 custom functions inside Mongo for MapReduce: mapItems, reduceItems, finalizeItems.
When I test my functions from inside Mongo Shell, everything works great:
db.loadServerScripts();
db.runCommand({
mapreduce: 'items',
map: mapItems,
reduce: reduceItems,
finalize: finalizeItems,
out: {inline: 1},
scope: {members: {a1: 0, a2: 0}
});
Now when I try to do the same in PHP Mongo Driver, nothing works.
$db->command([
'mapreduce' => 'items',
'map' => 'mapItems',
'reduce' => 'reduceItems',
'finalize' => 'finalizeItems',
'out' => ['inline' => 1],
'scope' => ['members' => ['a1' => 0, 'a2' => 0]]
]);
I thought maybe I need to use MongoCode for the functions, but that still didn't work:
$db->command([
'mapreduce' => 'items',
'map' => new \MongoCode('mapItems'),
'reduce' => new \MongoCode('reduceItems'),
'finalize' => new \MongoCode('finalizeItems'),
'out' => ['inline' => 1],
'scope' => ['members' => ['a1' => 0, 'a2' => 0]]
]);
Then I thought maybe the PHP driver is being stupid, so I copy pasted the functions into PHP and tried them:
$db->command([
'mapreduce' => 'items',
'map' => new \MongoCode($mapFn),
'reduce' => new \MongoCode($reduceFn),
'finalize' => new \MongoCode($finalizeFn),
'out' => ['inline' => 1],
'scope' => ['members' => ['a1' => 0, 'a2' => 0]]
]);
And this worked.
How do I need to pass the internal functions to Mongo through PHP?
What you have done so far
This is a classic case of things not working how you seem to think they work. Let's break this down logically for everyone to understand.
So what you clearly have done to date is create some JavaScript function definitions and stored them in system.js. Now anything that has been stored in such a way can be called by server side JavaScript operations, which is fine. An example:
db.system.js.save({
"_id": squareThis",
"value": function(x) { return x*x; }
})
db.test.insert({ "a": 3 ))
db.test.find(function() { return squareThis(this.a) == 9 })
So that works as expected where the "server" can use the function. Not if you did this ( as you mention earlier ) :
db.loadServerScripts();
Now any functions in system.js are now available for the "shell client" to use as well. So you can now do this in the JavaScript REPL:
> squareThis(3) == 9
true
What you are doing wrong
Now you want to code with PHP. So you go to call your JavaScript methods you created on the "server" from your PHP code and you try this:
'map' => new \MongoCode('mapItems'),
So what is MongoCode? Well it basically defines a BSON type for a code reference ( expected to be JavaScript ) and sends that to the server.
The clear problem here is that "mapItems" is not JavaScript code. You "shell client" recognized that, but only after calling db.loadServerScripts(), which of course it can do, because that client understands JavaScript.
The same is true for the earlier attempt. Your PHP mapReduce command expects to have MongoCode objects that actually contain valid JavaScript. These are going to be sent to the server where it can acutally call functions defined there, but you still need to provide the mapReduce command with "real code" that does something.
Fixing It
Fortunately there is a way around this, in that you can basically "define a function to call a function" essentially "wrapping" the method calls so the "server" loaded code can be called.
The sytax varies depending on if the function is supposed to return anything so:
$db->command([
'mapreduce' => 'items',
'map' => new \MongoCode('function() { mapItems(this) }'),
'reduce' => new \MongoCode('function(key,values) { return reduceItems(key,values) }'),
'finalize' => new \MongoCode('function(key,value) { return finalizeItems(key,value)}'),
'out' => ['inline' => 1],
'scope' => ['members' => ['a1' => 0, 'a2' => 0]]
]);
So now your PHP mapReduce command sends up it's "packaged command" with valid JavaScript functions attached to the appropriate method stages. These "code wrappers" execute on the "server" and can then call the respective "server" methods that are stored in system.js.
The reason for the explicit argument passing i.e
function(key,values){ serverFunction(key,values) }
Is because your "wrappers" need to create the same sort of "signatures" as expected by the functions of "mapReduce" in general. And since they are "calling" the other methods "server side", then you need to "pass-through" the expected parameters.
This also has another implication for the "mapper" function. You are likely referring to all document content through the this context of JavaScript objects. Once you do this then you cannot do that anymore and will need to "explicitly" define a document argument to your "mapper"
db.system.js({
"_id": "mapper",
"value": function(doc) {
// use doc instead of this
}
And then even from the Mongo Shell you will also need to call like this:
db.runCommand({
"mapReduce": "items",
"mapper": function() { mapper(this) }
In order for the logic to work.
So server side functions are not really what you thought they are. You can use them, but you need to follow the rules of how they can be used.
In general it is probably better that you simply just code all of these up in your client rather than jump through all the hoops. It is afterall "JavaScript" execution for which the only language is "JavaScript", so that is why alternate methods of processing are generally preferred as long as they can be applied.
And if your document structure needs JavaScript processing, then you probably have your document structure wrong in the first place. So the better case here is "re-evaluate" your structure and processing needs to get you "cleaner" and "faster" code.

Is it possible to add a subdomain to Route53 using the AWS PHP SDK?

I am working on a project where we will be creating both subdomains as well as domains in Route53. We are hoping that there is a way to do this programmatically. The SDK for PHP documentation seems a little light, but it appears that createHostedZone can be used to create a domain or subdomain record and that changeResourceRecordSets can be used to create the DNS records necessary. Does anyone have examples of how to actually accomplish this?
Yes, this is possible using the changeResourceRecordSets call, as you already indicated. But it is a bit clumsy since you have to structure it like a batch even if you're changing/creating only one record, and even creations are changes. Here is a full example, without a credentials method:
<?php
// Include the SDK using the Composer autoloader
require 'vendor/autoload.php';
use Aws\Route53\Route53Client;
use Aws\Common\Credentials\Credentials;
$client = Route53Client::factory(array(
'credentials' => $credentials
));
$result = $client->changeResourceRecordSets(array(
// HostedZoneId is required
'HostedZoneId' => 'Z2ABCD1234EFGH',
// ChangeBatch is required
'ChangeBatch' => array(
'Comment' => 'string',
// Changes is required
'Changes' => array(
array(
// Action is required
'Action' => 'CREATE',
// ResourceRecordSet is required
'ResourceRecordSet' => array(
// Name is required
'Name' => 'myserver.mydomain.com.',
// Type is required
'Type' => 'A',
'TTL' => 600,
'ResourceRecords' => array(
array(
// Value is required
'Value' => '12.34.56.78',
),
),
),
),
),
),
));
The documentation of this method can be found here. You'll want to take very careful note of the required fields as well as the possible values for others. For instance, the name field must be a FQDN ending with a dot (.).
Also worth noting: You get no response back from the API after this call by default, i.e. there is no confirmation or transaction id. (Though it definitely gives errors back if something is wrong.) So that means that if you want your code to be bulletproof, you should write a Guzzle response handler AND you may want to wait a few seconds and then run a check that the new/changed record indeed exists.
Hope this helps!
Yes, I done using changeResourceRecordSets method.
<?php
require 'vendor/autoload.php';
use Aws\Route53\Route53Client;
use Aws\Exception\CredentialsException;
use Aws\Route53\Exception\Route53Exception;
//To build connection
try {
$client = Route53Client::factory(array(
'region' => 'string', //eg . us-east-1
'version' => 'date', // eg. latest or 2013-04-01
'credentials' => [
'key' => 'XXXXXXXXXXXXXXXXXXX', // eg. VSDFAJH6KXE7TXXXXXXXXXX
'secret' => 'XXXXXXXXXXXXXXXXXXXXXXX', //eg. XYZrnl/ejPEKyiME4dff45Pds54dfgr5XXXXXX
]
));
} catch (Exception $e) {
echo $e->getMessage();
}
/* Create sub domain */
try {
$dns = 'yourdomainname.com';
$HostedZoneId = 'XXXXXXXXXXXX'; // eg. A4Z9SD7DRE84I ( like 13 digit )
$name = 'test.yourdomainname.com.'; //eg. subdomain name you want to create
$ip = 'XX.XXXX.XX.XXX'; // aws domain Server ip address
$ttl = 300;
$recordType = 'CNAME';
$ResourceRecordsValue = array('Value' => $ip);
$client->changeResourceRecordSets([
'ChangeBatch' => [
'Changes' => [
[
'Action' => 'CREATE',
"ResourceRecordSet" => [
'Name' => $name,
'Type' => $recordType,
'TTL' => $ttl,
'ResourceRecords' => [
$ResourceRecordsValue
]
]
]
]
],
'HostedZoneId' => $HostedZoneId
]);
}
If you get any error please check into server error.log file. If you get error from SDK library then there is might PHP version not supported.
if you run this code from your local machine then you might get "SignatureDoesNotMatch" error then Make sure run this code into same (AWS)server environment.

Laravel return array value from app/config/package folder

Hi I am using a laravel package https://github.com/greggilbert/recaptcha and I have published the config files where I need to store my public and private keys for my recaptcha. I want to call this elsewhere in my app in an attempt to process this via AJAX . I've tried to call this as
dd(Config::get('packages.greggilbert.recaptcha')['public_key']);
however this returns as null. The array is kept in the following folder:
app/config/packages/greggilbert/recaptcha/config.php
the array is built as so:
<?php
return array(
'public_key' => 'publickey',
'private_key' => 'privatekey',
'template' => '',
'driver' => 'curl',
'options' => array(
'curl_timeout' => 1,
),
'version' => 2,
);
Any ideas how I can retrieve the public_key value??
Retrieving configs from a package works a bit different. You use a so-called namespace:
Config::get('recaptcha::public_key');

Categories