Installation
Run composer require codibly/databricks-bundle in your Symfony3 project root.
Ensure guzzlehttp/guzzle is installed (required for HTTP requests).
Enable the Bundle
Register new Codibly\DatabricksBundle\CodiblyDatabricksBundle() in app/AppKernel.php under registerBundles().
Configure the Driver
Add the bundle configuration to app/config/config.yml:
codibly_databricks:
driver: guzzle
host: "https://<your-databricks-instance>.cloud.databricks.com"
token: "%env(DATABRICKS_TOKEN)%" # Store token in .env
First Use Case
Inject the DatabricksClient service into a controller/service and call methods like:
use Codibly\DatabricksBundle\Client\DatabricksClientInterface;
class MyController extends Controller
{
public function runJob(DatabricksClientInterface $client)
{
$response = $client->jobs()->runNow(123); // Replace 123 with job ID
return new Response(json_encode($response));
}
}
Resources/doc/index.md in the bundle or Symfony’s hosted docs.src/Client/ for available methods (e.g., JobsClient, ClustersClient).Resources/config/services.yml for service definitions.Job Management
jobs()->create() with a JSON payload defining the job (e.g., notebook ID, parameters).
$payload = [
'new_cluster' => ['spark_version' => '7.3.x-scala2.11'],
'notebook_task' => ['notebook_path' => '/path/to/notebook']
];
$client->jobs()->create($payload);
jobs()->get(123) or listen to webhooks (implement DatabricksWebhookListener).Cluster Operations
clusters()->create() and clusters()->delete().
$cluster = $client->clusters()->create(['spark_version' => '7.3.x-scala2.11']);
$client->clusters()->delete($cluster['cluster_id']);
Data Operations
sql()->statements() for ad-hoc queries.
$result = $client->sql()->statements()->run(
'SELECT * FROM my_table',
123 // Warehouse ID
);
Webhooks
DatabricksWebhookListener and bind it to the databricks.webhook event in services.yml:
services:
App\EventListener\DatabricksWebhookListener:
tags:
- { name: 'kernel.event_listener', event: 'databricks.webhook', method: 'onWebhook' }
token) in .env and reference via %env(DATABRICKS_TOKEN)%.GuzzleHttp\HandlerStack) for transient failures.DatabricksClientInterface to log requests/responses:
$client->setLogger($logger); // If supported; otherwise, log manually.
Deprecated Bundle
guzzlehttp/guzzle:^7.0) if critical features are missing.Token Management
config.yml is insecure. Always use .env and restrict file permissions (chmod 600 .env).Rate Limiting
429 Too Many Requests by:
GuzzleHttp\RetryMiddleware).Webhook Delays
job_id and run_id to deduplicate events in your listener.Cluster Auto-Termination
if ($client->clusters()->get($clusterId)['state'] === 'TERMINATED') {
$client->clusters()->create($clusterConfig);
}
$stack = HandlerStack::create();
$stack->push(Middleware::tap(function ($request) {
\Log::debug('Databricks Request:', ['url' => $request->getUri(), 'body' => $request->getBody()]);
}));
$client->setHandler($stack);
200 OK with errors in the response body. Always check:
$response = $client->jobs()->runNow(123);
if (isset($response['errors'])) {
throw new \RuntimeException($response['errors'][0]['message']);
}
Custom Clients
Extend Codibly\DatabricksBundle\Client\AbstractClient to add domain-specific methods:
class MyCustomClient extends AbstractClient {
public function customMethod() {
return $this->request('POST', '/api/2.0/custom-endpoint', ['data' => 'value']);
}
}
Register the service in services.yml:
services:
App\Client\MyCustomClient:
arguments: ['@codibly_databricks.client']
Event Dispatching Trigger Symfony events for critical actions (e.g., job completion):
$dispatcher->dispatch(new DatabricksJobEvent($jobId, $runId), 'databricks.job.completed');
Mocking for Tests
Use Guzzle’s MockHandler to simulate API responses:
$mock = new MockHandler([
new Response(200, [], json_encode(['run_id' => 456])),
]);
$client->setHandler(new HandlerStack($mock));
guzzle, but you can swap drivers by implementing Codibly\DatabricksBundle\Client\DriverInterface and updating services.yml.config.yml:
codibly_databricks:
guzzle_options:
proxy: 'http://proxy.example.com:8080'
How can I help you explore Laravel packages today?