polygon-io/client-php

Getting Started Issue with stocks invocation

brakop opened this issue · 3 comments

Working within a docker container, I've used composer to pull polygon-io onto a PHP7.4 running apache with Debian 11 environment:

`php -v
PHP 7.4.29 (cli) (built: May 11 2022 14:19:20) ( NTS )

cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
NAME="Debian GNU/Linux"
VERSION_ID="11"
`

Composer JSON:
{ "require": { "monolog/monolog": "2.5.*", "polygon-io/api" : "*" } }

When I try the default example for Rest:
require __DIR__ . '/vendor/autoload.php'; use PolygonIO\Rest\Rest; $rest = new Rest('<MyWorkingAPIKey>'); print_r($rest->forex->realTimeCurrencyConversion->get('USD', 'EUR', 10));

I get:
Warning: array_merge(): Expected parameter 2 to be an array, null given in /var/www/html/vendor/polygon-io/api/src/Rest/RestResource.php on line 63

Fatal error: Uncaught GuzzleHttp\Exception\ClientException: Client error: GET https://api.polygon.io/v1/conversion/USD/EUR resulted in a 401 Unauthorized response: {"status":"ERROR","request_id":"8ff237f073510360d8f36cab29e25062","error":"API Key was not provided"} in /var/www/html/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:113 Stack trace: #0 /var/www/html/vendor/guzzlehttp/guzzle/src/Middleware.php(69): GuzzleHttp\Exception\RequestException::create(Object(GuzzleHttp\Psr7\Request), Object(GuzzleHttp\Psr7\Response), NULL, Array, NULL) #1 /var/www/html/vendor/guzzlehttp/promises/src/Promise.php(204): GuzzleHttp\Middleware::GuzzleHttp{closure}(Object(GuzzleHttp\Psr7\Response)) #2 /var/www/html/vendor/guzzlehttp/promises/src/Promise.php(153): GuzzleHttp\Promise\Promise::callHandler(1, Object(GuzzleHttp\Psr7\Response), NULL) #3 /var/www/html/vendor/guzzlehttp/promises/src/TaskQueue.php(48): GuzzleHttp\Promise\Promise::GuzzleHttp\Promise{closure}() #4 /var/www/html/vendor/guzzlehttp/promises/src/Promise in /var/www/html/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php on line 113

If I send an array as my third parameter:
print_r($rest->forex->realTimeCurrencyConversion->get('USD', 'EUR', [10]));

I get to this point:
Fatal error: Uncaught GuzzleHttp\Exception\ClientException: Client error: GET https://api.polygon.io/v1/conversion/USD/EUR?apiKey=qr5awPnGKxOCH1B6FZgFbj43RTzodzIF&amount=100&precision=2&0=10 resulted in a 403 Forbidden response: {"status":"NOT_AUTHORIZED","request_id":"60695e7c911dd93ffba6bda276415743","message":"You are not entitled to this data. (truncated...)

Which is probably fine, my focus is on stock info, so I tried to switch from forex to just a staple (easy) Rest API. I looked at the structure of the $rest variable and saw you have ->stocks->snapshotAllTickers, so I thought this would invoke that for me:
var_dump(json_encode($rest->stocks->snapshotAllTickers->get()));
And while it seems to be trying to process something, all I get back is:
Fatal error: Uncaught TypeError: Argument 1 passed to PolygonIO\Rest\Common\Mappers::snapshotQuote() must be of the type array, null given, called in /var/www/html/vendor/polygon-io/api/src/Rest/Common/Mappers.php on line 88 and defined in /var/www/html/vendor/polygon-io/api/src/Rest/Common/Mappers.php:150 Stack trace: #0 /var/www/html/vendor/polygon-io/api/src/Rest/Common/Mappers.php(88): PolygonIO\Rest\Common\Mappers::snapshotQuote(NULL) #1 /var/www/html/vendor/polygon-io/api/src/Rest/Stocks/SnapshotAllTickers.php(34): PolygonIO\Rest\Common\Mappers::snapshotTicker(Array) #2 [internal function]: PolygonIO\Rest\Stocks\SnapshotAllTickers->PolygonIO\Rest\Stocks{closure}(Array) #3 /var/www/html/vendor/polygon-io/api/src/Rest/Stocks/SnapshotAllTickers.php(36): array_map(Object(Closure), Array) #4 /var/www/html/vendor/polygon-io/api/src/Rest/RestResource.php(79): PolygonIO\Rest\Stocks\SnapshotAllTickers->mapper(Array) #5 /var/www/html/vendor/polygon-io/api/src/Rest/Stocks/SnapshotAllTickers.php(22): PolygonIO\Rest\RestResourc in /var/www/html/vendor/polygon-io/api/src/Rest/Common/Mappers.php on line 150

Now I haven't paid for quotes, so I'm wondering if this is a glitch where the lack of a quote response is messing up the PHP?

Anyway, this is my first rodeo with particular library, so if you have some clean usage examples on the stocks front, I'd appreciate it. I tried the websocket example too and it failed, but I'll wait to action anything on that until I can at least 'hello world'.

Cheers!

Making some progress, seems I was correct on the Quote issue for the Rest request, the quote isn't returned unless the API key is authorized (paid enough) for it, so you need to avoid NULL response in your mapping:
Line 88 of Mappers.php:
$snap['lastQuote'] = Mappers::snapshotQuote((is_array($snap['lastquote']) ? $snap['lastquote'] : array()));

Also, not sure why, but parameters are not being passed into your RestResource.php as an array so on line 64 I needed:
(is_array($params) ? $params: array($params) )
Which for your example REST request gets me past the PHP error and into the "Forbidden" error, which I think could be handled without a FATAL error, but maybe that's a limitation of guzzlehttp.

I'm looking at the websocket layer now.

Well, I got connected only to be immediately disconnected:
`use PolygonIO\Websockets\Websockets;

$client = new Websockets('stocks','MyWorkingAPIKey');

$connection= $client->stocks->connect('AM.AAPL',
function($data) {
echo "
Received data:";
var_dump(json_encode($data));
}
);`

At least this gets me this:
Received data:string(73) "[{"ev":"status","status":"connected","message":"Connected Successfully"}]"
Received data:string(74) "[{"ev":"status","status":"auth_failed","message":"authentication failed"}]"

But not sure why I'm getting rejected at step 2. My Stock Developer plan says it includes websockets, so I think that's about as far as I can take this without some assistance. Anyone monitoring this?

Cheers!

Finally got connected! When I directly instantiate the Websockets class I don't pass $topic into the constructor, and then it will connect. Also, because I'm not on "realtime" I had to change line 9 of WebsocketResource.php from:
public const SOCKET_URI = 'wss://socket.polygon.io:443';
To:
public const SOCKET_URI = 'wss://delayed.polygon.io:443';

So this is the working code:
use PolygonIO\Websockets\Websockets;

$client = new Websockets('MyWorkingAPIKey');

$connection= $client->stocks->connect('AM.AAPL',
function($data) {
echo "
Received data:";
var_dump(json_encode($data));
//And then do cooler stuff
}
);

I've seen other posts on here about multi-threading and MQ, but we'll cross that road when we come to it:
Received data: string(73) "[{"ev":"status","status":"connected","message":"Connected Successfully"}]"
Received data: string(67) "[{"ev":"status","status":"auth_success","message":"authenticated"}]"
Received data: string(71) "[{"ev":"status","status":"success","message":"subscribed to: AM.AAPL"}]"

I'm hoping to see some actual data come across once it gets to USA trading hours, but I guess we'll just wait and see!