Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Storage Api Client Laravel Package

keboola/storage-api-client

Keboola Storage API PHP client for managing buckets, tables, files, and workspaces in the Keboola data platform. Handles authentication, data imports and exports, and file transfers via a simple object-oriented interface.

View on GitHub
Deep Wiki
Context7

Getting Started

Install with Composer and confirm you are pulling the real distribution, not just the read-only mirror:

composer require keboola/storage-api-client

This repository is marked [READ-ONLY], has almost no public dependents, and is effectively a mirror of code maintained inside Keboola's monorepo. Check Packagist and the package's changelog before pinning a version, and treat GitHub issues/PRs here as informational rather than the primary support channel.

First steps:

  1. Bootstrap a Client with a Storage API token and the correct stack host:
use Keboola\StorageApi\Client;

$client = new Client([
    'token' => getenv('KBC_STORAGE_TOKEN'),
    'url' => 'https://connection.keboola.com', // or the regional/stack host
]);
  1. Validate the token immediately:
$tokenInfo = $client->verifyToken();

This gives you owner, project, permissions, and expiry before you do any real work. Fail fast here rather than on a random 401 later.

  1. Look first at these classes:

    • Keboola\StorageApi\Client — core HTTP, jobs, raw API helpers, verifyToken, waitForJob
    • Keboola\StorageApi\Buckets, Tables, Workspaces, Components, Tokens, Metadata
    • Keboola\StorageApi\Options\... — typed option objects for many operations
    • Keboola\StorageApi\TableExporter / TableImporter — bulk data paths
    • Keboola\Csv\CsvFile — CSV construction for loads
  2. First real use case: list buckets/tables, then load a CSV into a table asynchronously and wait for the job:

$tables = new \Keboola\StorageApi\Tables($client);
$tableId = 'in.c-main.customers';

$csv = new \Keboola\Csv\CsvFile('/tmp/customers.csv');

$jobId = $client->writeTableAsync($tableId, $csv, [
    'incremental' => false,
]);

$result = $client->waitForJob($jobId);

That async-job handshake is the central pattern of the whole package. If you understand writeTableAsync() + waitForJob(), you understand most of the client.

Implementation Patterns

Wrap the client once and inject it. The Client is cheap but stateful (run ID, backoff settings, token). Build it in your service container, validate the token at boot, and share the same instance. Do not construct a new client per call unless you deliberately want different tokens/hosts.

Treat every data operation as a job. Writes, exports, workspace creation, and many component operations return a job ID. The consistent pattern is:

$jobId = $tables->/* or $client-> */someAsyncOperation(...);
$result = $client->waitForJob($jobId);

Inspect job results for warnings, imported rows, and output file IDs. Do not assume waitForJob() returning means the data is semantically what you expected — check $result['results'] and $result['warnings'].

Choose the right upload path by size.

  • Small/medium CSV files: CsvFile + writeTableAsync().
  • Large files: use sliced/direct upload paths (TableImporter, direct-to-storage uploads, or uploadFile() + async table write) so you do not stream gigabytes through PHP memory.
  • Never use getTableData() for anything large; it returns rows in memory. Use TableExporter::exportTable() to stream to a file.

Export with intent. TableExporter supports column selection, filters, limits, and changed-since/changed-until style options. Use these server-side rather than exporting everything and filtering in PHP. Export to a temp file or stream, then hand off to your own storage/SFTP/warehouse step.

Make loads idempotent. Prefer deterministic table IDs, explicit primary keys, and incremental only when you truly mean append. For full refreshes, write to a staging table and swap/alias rather than truncating a live table in place. Storage API aliases are useful for blue/green table swaps.

Use workspaces for SQL-heavy transforms. Keboola\StorageApi\Workspaces lets you create a transient database workspace, load selected tables, run SQL, and unload results back. This is usually faster and cleaner than pulling data into PHP, transforming, and re-uploading. Always delete workspaces in a finally block — they cost money and linger.

Use Components/configurations for orchestration metadata. If you are building extractor/writer-style integrations, create component configurations through the client rather than inventing your own config store. This keeps you compatible with Keboola runners and UI.

Escape hatch: raw API calls. When a convenience method is missing or lagging, use apiGet(), apiPost(), apiPut(), apiDelete() on the client. This is the intended extension point and is much safer than hand-rolling Guzzle calls, because you keep auth, retries, and URL construction.

Set runId and userAgent for observability. Client::setRunId() tags API calls/jobs so they can be traced in Keboola. Set a meaningful userAgent in client options so your application is identifiable in API logs.

Configure backoff and logging at construction. Pass backoffMaxTries, a PSR-3 logger, and userAgent in the client options. This is much better than sprinkling retry loops around individual calls.

Testing pattern. Unit-test your wrappers against mocked Client/resource classes. For integration tests, use a dedicated Keboola project and token with minimal permissions, create uniquely named buckets/tables per test run, and clean up in tearDown. Do not point tests at a shared production project.

Gotchas and Tips

  • This is a mirror, not the canonical repo. With 10 stars, zero listed dependents, and a read-only flag, do not judge maturity or support by this GitHub page. Check Packagist release history and Keboola's actual source/changelog before upgrading.
  • Async is not optional. Forgetting waitForJob() means your next step races the load. Likewise, waitForJob() itself can time out on very long jobs; use a generous max-tries/timeout and handle a still-running job explicitly.
  • 4xx errors are not retried. Backoff helps with 429/5xx, not with bad tokens, missing tables, or permission errors. Catch Keboola\StorageApi\ClientException, inspect getStatusCode() and the error string code, and map 404/409 to domain-specific handling.
  • Token scope is the usual cause of confusing 403s. Master tokens, project tokens, and component tokens have different capabilities (canManageBuckets, etc.). Run verifyToken() and log the permissions when debugging.
  • Host/region mismatches produce auth or 404 weirdness. The token is tied to a stack; passing the wrong url (e.g., a different region or connection.keboola.com vs an Azure stack) will fail in non-obvious ways. Make the host configurable per environment.
  • Memory blows up on getTableData() and naive CsvFile reads. Use TableExporter and sliced/direct uploads. Also watch CSV encoding, delimiter, enclosure, and header settings — mismatches surface as malformed rows or “no data” loads rather than clean errors.
  • CsvFile is file-backed. It is great for local temp files but awkward for streamed/generated data at scale. For generated data, consider writing to a temp file first or using the direct upload APIs.
  • Job success does not always mean clean data. Check warnings and result metrics. A load can succeed with skipped rows or type coercion warnings.
  • Clean up orphaned files and workspaces. Storage API files and workspaces persist and bill. Use ListFilesOptions/file APIs to prune old uploads, and always delete workspaces in finally.
  • Deprecations happen across majors. Method names and synchronous variants have changed historically (e.g., sync table writes giving way to async). Pin a minor version, read the changelog, and avoid relying on undocumented option arrays.
  • Extension points are limited but sufficient: raw api* methods, custom PSR-3 logger, userAgent, runId, and backoff settings. If you need more, wrap the client rather than subclassing it.
  • Do not store tokens in code or logs. The client will happily accept them; treat verifyToken() output and request logs as sensitive, and redact tokens in exception reporting.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route