https://github.com/brd6/tinybird-sdk-php
https://github.com/brd6/tinybird-sdk-php
Last synced: 5 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/brd6/tinybird-sdk-php
- Owner: brd6
- License: mit
- Created: 2025-12-10T15:09:52.000Z (6 months ago)
- Default Branch: main
- Last Pushed: 2025-12-11T18:18:28.000Z (6 months ago)
- Last Synced: 2025-12-12T20:45:26.583Z (6 months ago)
- Language: PHP
- Size: 87.9 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Codeowners: .github/CODEOWNERS
Awesome Lists containing this project
README
Tinybird SDK for PHP
PHP SDK for the [Tinybird API](https://www.tinybird.co) — the real-time data platform for developers. Build low-latency, high-concurrency analytics APIs over any data source in minutes. Ingest millions of events per second, query with SQL, and publish endpoints instantly.
## Synopsis
```php
// Ingest → Query → Results
$tinybird = Client::create('p.your_token');
$tinybird->events()->send('clicks', ['user' => 'alice', 'page' => '/home']);
$result = $tinybird->query()->sql('SELECT count() FROM clicks');
// → {"data":[{"count()":1}],"rows":1}
```
## Features
- **High-frequency ingestion** — Send millions of events per second via Events API
- **Schema generation** — Analyze files to generate Data Source schemas
- **Sub-second queries** — Execute SQL queries with instant results
- **Concurrent requests** — Batch multiple queries for parallel execution
- **Multi-region support** — EU, US, AWS, GCP, and custom deployments
- **Built-in retry logic** — Automatic retry with exponential backoff
- **PSR-18 compatible** — Works with Symfony, Guzzle, or any HTTP client
- **Type-safe resources** — Full PHP 8.1+ support with strict types
## Installation
Install this package using [Composer](https://getcomposer.org):
```bash
composer require brd6/tinybird-sdk-php
```
This package uses [PSR-18](https://www.php-fig.org/psr/psr-18/) HTTP client abstraction. You can use any compatible HTTP client. For quick setup with Symfony HTTP client:
```bash
composer require brd6/tinybird-sdk-php symfony/http-client nyholm/psr7
```
## Quick Start
```php
use Brd6\TinybirdSdk\Client;
// Create client (uses EU region by default)
$tinybird = Client::create('p.your_token_here');
// Ingest events
$tinybird->events()->send('events', [
['timestamp' => '2025-01-01 00:00:00', 'event' => 'page_view', 'user_id' => 'user_123'],
['timestamp' => '2025-01-01 00:00:01', 'event' => 'click', 'user_id' => 'user_456'],
]);
// Query with SQL
$result = $tinybird->query()->sql('SELECT count() FROM events');
// Call a Pipe endpoint
$result = $tinybird->pipes()->query('analytics_endpoint', ['date_from' => '2025-01-01']);
```
### Region Selection
```php
use Brd6\TinybirdSdk\Client;
use Brd6\TinybirdSdk\Enum\Region;
// US East
$tinybird = Client::forRegion('p.your_token', Region::GCP_US_EAST4);
// AWS EU Central
$tinybird = Client::forRegion('p.your_token', Region::AWS_EU_CENTRAL_1);
// Tinybird Local
$tinybird = Client::local('your_local_token');
// Custom port
$tinybird = Client::local('your_local_token', 8080);
```
### Custom Endpoint
For private deployments or custom domains:
```php
use Brd6\TinybirdSdk\Client;
use Brd6\TinybirdSdk\ClientOptions;
$options = (new ClientOptions())
->setToken('your_token')
->setBaseUrl('https://your-custom-endpoint.com');
$tinybird = new Client($options);
```
## Usage
### Analyze API
Analyze files to generate Tinybird Data Source schemas. Useful before creating `.datasource` files.
```php
// Analyze NDJSON records
$result = $tinybird->analyze()->analyzeRecords([
['timestamp' => '2025-01-01 00:00:00', 'event' => 'page_view', 'user_id' => 'user_123'],
['timestamp' => '2025-01-01 00:00:01', 'event' => 'click', 'user_id' => 'user_456'],
]);
// Get the generated schema (ready for .datasource files)
echo $result->getSchema();
// Output: timestamp DateTime `json:$.timestamp`, event String `json:$.event`, ...
// Inspect analyzed columns
foreach ($result->columns as $col) {
echo "{$col->name}: {$col->recommendedType}";
if ($col->presentPct < 1) {
echo " (nullable)";
}
}
// Analyze a remote file
$result = $tinybird->analyze()->analyzeUrl('https://example.com/data.ndjson');
// Analyze raw content
$result = $tinybird->analyze()->analyzeContent($csvContent);
```
### Events API
High-frequency data ingestion optimized for real-time analytics. This is the recommended way to ingest data in Tinybird Forward workspaces.
```php
// Send single event
$result = $tinybird->events()->send('events', [
'timestamp' => '2025-01-01 00:00:00',
'event' => 'page_view',
'user_id' => 'user_123',
]);
// Send batch events
$result = $tinybird->events()->send('events', [
['timestamp' => '2025-01-01 00:00:00', 'event' => 'page_view', 'user_id' => 'user_123'],
['timestamp' => '2025-01-01 00:00:01', 'event' => 'click', 'user_id' => 'user_456'],
]);
// Check result
echo $result->successfulRows; // Rows ingested
echo $result->quarantinedRows; // Rows failed validation
// Send raw NDJSON
$tinybird->events()->sendRaw('events', $ndjsonString);
```
### Data Sources
Read Data Source information and metadata.
```php
// List all Data Sources
$datasources = $tinybird->dataSources()->list();
foreach ($datasources as $ds) {
echo $ds->name;
echo $ds->getRowCount();
echo $ds->getBytes();
}
// Get Data Source details
$info = $tinybird->dataSources()->retrieve('events');
echo $info->id;
echo $info->name;
echo $info->type;
echo $info->createdAt;
// Access columns
foreach ($info->columns as $column) {
echo $column->name;
echo $column->type;
}
// Get quarantine data
$quarantine = $tinybird->dataSources()->quarantine('events');
```
> **Note:** For schema changes, use the Tinybird CLI (`tb deploy`). See [Tinybird Forward documentation](https://www.tinybird.co/docs/forward).
### Query API
Execute raw SQL queries against your Data Sources.
```php
// Simple query
$result = $tinybird->query()->sql('SELECT count() FROM events');
echo $result->rows;
echo $result->data[0]['count()'];
// Query with parameters
$result = $tinybird->query()->sql(
'SELECT * FROM events WHERE user_id = {user_id:String} LIMIT {limit:Int32}',
['user_id' => 'user_123', 'limit' => 100]
);
// Access results
foreach ($result->data as $row) {
echo $row['event'];
}
// Query statistics
echo $result->getElapsedTime();
echo $result->getRowsRead();
echo $result->getBytesRead();
```
#### Batch Queries
Execute multiple SQL queries concurrently for better performance:
```php
// Run multiple queries in parallel
$results = $tinybird->query()->batchSql([
'total_users' => 'SELECT count() FROM users',
'active_today' => 'SELECT count() FROM events WHERE date = today()',
'revenue' => 'SELECT sum(amount) FROM orders',
]);
// Access individual results
foreach ($results as $key => $result) {
if ($result->isSuccess()) {
echo "{$key}: " . $result->getData()->data[0];
} else {
echo "{$key} failed: " . $result->getException()->getMessage();
}
}
// Or get data directly
$totalUsers = $results['total_users']->getData()->data[0]['count()'];
```
### Pipes API
Query published API Endpoints and list Pipes.
```php
// List Pipes
$pipes = $tinybird->pipes()->list();
// Query a Pipe endpoint
$result = $tinybird->pipes()->query('my_analytics_endpoint', [
'start_date' => '2025-01-01',
'end_date' => '2025-12-31',
'limit' => 1000,
]);
foreach ($result->data as $row) {
// Process results
}
```
#### Batch Pipe Queries
Query multiple Pipe endpoints concurrently:
```php
// Simple: key is pipe name
$results = $tinybird->pipes()->batchQuery([
'user_stats' => ['date' => '2025-01-01'],
'event_counts' => ['type' => 'click'],
]);
// Query same pipe multiple times using # alias
$results = $tinybird->pipes()->batchQuery([
'user_stats#jan' => ['date' => '2025-01-01'],
'user_stats#feb' => ['date' => '2025-02-01'],
'user_stats#mar' => ['date' => '2025-03-01'],
]);
// Handle results with error isolation
foreach ($results as $key => $result) {
if ($result->isSuccess()) {
$data = $result->getData();
echo "{$key}: {$data->rows} rows";
} else {
// Individual failures don't affect other queries
echo "{$key} failed: " . $result->getException()->getMessage();
}
}
```
### Jobs API
Monitor and manage background jobs (imports, populates, copies).
```php
use Brd6\TinybirdSdk\RequestParameters\ListJobsParams;
use Brd6\TinybirdSdk\Enum\JobStatus;
// List recent jobs
$jobs = $tinybird->jobs()->list();
// Filter by status
$jobs = $tinybird->jobs()->list(new ListJobsParams(status: JobStatus::DONE));
// Get job details
$job = $tinybird->jobs()->retrieve($jobId);
echo $job->status; // waiting, working, done, error
// Cancel a running job
$tinybird->jobs()->cancel($jobId);
```
### Environment Variables API
Manage workspace variables for use in Pipes.
```php
// List all variables
$vars = $tinybird->variables()->list();
// Create a variable
$var = $tinybird->variables()->create('API_KEY', 'secret_value');
// Update a variable
$tinybird->variables()->update('API_KEY', 'new_value');
// Delete a variable
$tinybird->variables()->remove('API_KEY');
```
### Tokens API
Manage workspace tokens for authentication.
```php
use Brd6\TinybirdSdk\RequestParameters\CreateTokenParams;
// List all tokens
$tokens = $tinybird->tokens()->list();
// Create a token with scopes
$token = $tinybird->tokens()->create(new CreateTokenParams(
name: 'my_token',
scopes: ['PIPES:READ', 'DATASOURCES:READ'],
));
// Refresh (rotate) a token
$newToken = $tinybird->tokens()->refresh('my_token');
// Delete a token
$tinybird->tokens()->remove('my_token');
```
### Sink Pipes API
Export data to object stores (S3, GCS).
```php
use Brd6\TinybirdSdk\RequestParameters\CreateSinkParams;
// Create a sink pipe
$pipe = $tinybird->sinkPipes()->create($pipeId, $nodeId, new CreateSinkParams(
connection: 's3://bucket/path',
path: 'exports/',
));
// Trigger a sink export
$result = $tinybird->sinkPipes()->trigger($pipeId);
// Get S3 integration settings
$settings = $tinybird->sinkPipes()->getS3Settings();
```
### Error Handling
```php
use Brd6\TinybirdSdk\Exception\ApiException;
use Brd6\TinybirdSdk\Exception\AuthenticationException;
use Brd6\TinybirdSdk\Exception\RateLimitException;
use Brd6\TinybirdSdk\Exception\RequestTimeoutException;
try {
$result = $tinybird->pipes()->query('my_endpoint');
} catch (AuthenticationException $e) {
// Invalid or expired token (401/403)
// Includes helpful suggestions for region mismatches
} catch (RateLimitException $e) {
// Too many requests (429)
$retryAfter = $e->getRetryAfter();
$limit = $e->getRateLimitLimit();
$remaining = $e->getRateLimitRemaining();
} catch (RequestTimeoutException $e) {
// Request timed out
} catch (ApiException $e) {
// Other API errors
$code = $e->getCode();
$message = $e->getMessage();
$response = $e->getResponse();
}
```
## Regions
| Region | Enum | API Base URL |
|--------|------|--------------|
| GCP Europe West 3 (default) | `Region::GCP_EUROPE_WEST3` | `https://api.tinybird.co` |
| GCP Europe West 2 | `Region::GCP_EUROPE_WEST2` | `https://api.europe-west2.gcp.tinybird.co` |
| GCP US East 4 | `Region::GCP_US_EAST4` | `https://api.us-east.tinybird.co` |
| GCP North America | `Region::GCP_NORTHAMERICA_NORTHEAST2` | `https://api.northamerica-northeast2.gcp.tinybird.co` |
| AWS EU Central 1 | `Region::AWS_EU_CENTRAL_1` | `https://api.eu-central-1.aws.tinybird.co` |
| AWS EU West 1 | `Region::AWS_EU_WEST_1` | `https://api.eu-west-1.aws.tinybird.co` |
| AWS US East 1 | `Region::AWS_US_EAST_1` | `https://api.us-east.aws.tinybird.co` |
| AWS US West 2 | `Region::AWS_US_WEST_2` | `https://api.us-west-2.aws.tinybird.co` |
| Local | `Region::LOCAL` | `http://localhost:7181` |
## Configuration
```php
use Brd6\TinybirdSdk\Client;
use Brd6\TinybirdSdk\ClientOptions;
use Brd6\TinybirdSdk\Enum\Region;
$options = (new ClientOptions())
->setToken(getenv('TINYBIRD_TOKEN'))
->setRegion(Region::AWS_EU_CENTRAL_1)
->setTimeout(120)
->setCompression(true)
->setRetryMaxRetries(5)
->setRetryDelayMs(1000)
->setRetryBackoffMultiplier(3);
$tinybird = new Client($options);
```
| Option | Default | Description |
|--------|---------|-------------|
| `token` | `''` | Tinybird API token |
| `region` | `Region::GCP_EUROPE_WEST3` | API region |
| `baseUrl` | `https://api.tinybird.co` | Custom API endpoint |
| `timeout` | `60` | Request timeout in seconds |
| `compression` | `false` | Enable gzip compression |
| `apiVersion` | `v0` | API version |
| `httpClient` | auto-discovered | Custom PSR-18 HTTP client |
| `retryMaxRetries` | `3` | Maximum retry attempts |
| `retryDelayMs` | `2000` | Initial retry delay (ms) |
| `retryBackoffMultiplier` | `2` | Backoff multiplier |
## API Reference
| Endpoint | Methods |
|----------|---------|
| `analyze()` | `analyzeContent()`, `analyzeRecords()`, `analyzeUrl()` |
| `events()` | `send()`, `sendRaw()`, `sendJson()` |
| `dataSources()` | `list()`, `retrieve()`, `quarantine()` |
| `query()` | `sql()`, `batchSql()` |
| `pipes()` | `list()`, `retrieve()`, `query()`, `batchQuery()`, `getData()`, `explain()` |
| `jobs()` | `list()`, `retrieve()`, `cancel()` |
| `variables()` | `list()`, `retrieve()`, `create()`, `update()`, `remove()` |
| `tokens()` | `list()`, `retrieve()`, `create()`, `createJwt()`, `update()`, `refresh()`, `remove()` |
| `sinkPipes()` | `create()`, `remove()`, `trigger()`, `getS3Settings()`, `getGcsCredentials()` |
## Examples
See the [examples](./examples) directory for complete working examples:
- [Quick Start](./examples/quick-start) — Basic SDK usage
- [Analyze API](./examples/analyze) — Schema inference
- [Batch Queries](./examples/batch-queries) — Concurrent query execution
- [Data Sources](./examples/datasources) — List and inspect Data Sources
- [Events API](./examples/events) — High-frequency ingestion
- [Jobs API](./examples/jobs) — Monitor background jobs
- [Pipes API](./examples/pipes) — Query API Endpoints
- [Tokens API](./examples/tokens) — Token management
- [Variables API](./examples/variables) — Environment variables
## Documentation
- [Tinybird API Reference](https://www.tinybird.co/docs/api-reference)
- [Tinybird Forward Documentation](https://www.tinybird.co/docs/forward)
## Contributing
Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md).