Simple PHP wrapper library for Keboola Storage API.
Library is available as composer package. To start using composer in your project follow these steps:
Install composer
curl -s http://getcomposer.org/installer | php
mv ./composer.phar ~/bin/composer # or /usr/local/bin/composerCreate composer.json file in your project root folder:
{
"require": {
"php" : ">=8.1",
"keboola/storage-api-client": "^14.0"
}
}Install package:
composer installAdd autoloader in your bootstrap script:
require 'vendor/autoload.php';Read more in Composer documentation.
Table write:
require 'vendor/autoload.php';
use Keboola\StorageApi\Client;
use Keboola\Csv\CsvFile;
$client = new Client([
'token' => 'YOUR_TOKEN',
'url' => 'https://connection.keboola.com'
]);
$csvFile = new CsvFile(__DIR__ . '/my.csv', ',', '"');
$client->writeTableAsync('in.c-main.my-table', $csvFile);Table export to file:
require 'vendor/autoload.php';
use Keboola\StorageApi\Client;
use Keboola\StorageApi\TableExporter;
$client = new Client([
'token' => 'YOUR_TOKEN',
'url' => 'https://connection.keboola.com'
]);
$exporter = new TableExporter($client);
$exporter->exportTable('in.c-main.my-table', './in.c-main.my-table.csv', []);File downloads (Client::downloadFile(), Client::downloadSlicedFile() and TableExporter) are
not bounded by object size on AWS and GCP — a download of any realistic size can finish, as long
as it keeps making progress. Behaviour differs per file storage provider:
The three providers do not behave the same. AWS (S3ClientFactory) and GCP
(GcsClientFactory) share one deliberate transfer policy; Azure still runs on its SDK defaults
and has a far lower effective ceiling on how large a file it can download:
AWS (S3ClientFactory) |
Azure (BlobClientFactory) |
GCP (GcsClientFactory) |
|
|---|---|---|---|
| Total request deadline | 12 h liveness backstop | 120 s per blob request | 12 h liveness backstop |
| Stall detection | below 1 KB/s for 60 s | none | below 1 KB/s for 60 s |
| Connect timeout | 10 s | 10 s | 10 s |
| Retries | awsRetries, default Client::DEFAULT_RETRIES_COUNT (15) |
5, exponential (BlobStorageRetryMiddleware) |
3 (Google client default) |
| Writes to disk by streaming | yes (SaveAs) |
yes | yes (downloadToFile()) |
| Effective size ceiling | ~3.3 TB at 80 MB/s | ~10 GB at 80 MB/s | ~3.3 TB at 80 MB/s |
Notes:
- The AWS and GCP deadlines are liveness backstops, not size caps. Stall detection alone cannot guarantee termination: it only fires below 1 KB/s and needs the whole 60 s window under the limit, so a link crawling just above that would otherwise run for months (40 GB at 1 KB/s is over a year). They are sized so no healthy transfer of any plausible export can reach them.
- Retries restart the whole object transfer from the first byte on AWS and Azure, so each retry pays
full egress. Keep
awsRetrieslow if you download very large files. On GCP an interruption that still carried a 2xx response resumes from the last fetched byte with aRangeheader (Rest::downloadObject()); any other failure restarts from the first byte. - Guzzle's
read_timeoutoption is honoured only by itsStreamHandler. The AWS SDK and the google-cloud client both use the cURL handler, where the equivalent isCURLOPT_LOW_SPEED_LIMIT/CURLOPT_LOW_SPEED_TIME. - The Azure 120 s deadline caps a single blob download and is currently the strictest limit of the three. Known limitation, tracked separately.
- The GCP policy is passed per download call (
GcsClientFactory::downloadOptions()) rather than configured on theStorageClient, because client-level options never reach a download:Rest::downloadObject()always sets its ownrestOptions, andRequestWrapper::getRequestOptions()picks the per-requestrestOptionsover the client-level ones with??instead of merging them.
See LICENSE file.