Skip to content

Commit 4ca0a36

Browse files
committed
decouple guzzle
1 parent 4f906ea commit 4ca0a36

12 files changed

Lines changed: 180 additions & 155 deletions

composer.json

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@
88
"psr/http-client": "^1.0",
99
"psr/http-message": "^1.0|^2.0",
1010
"psr/log": "^1.0|^2.0|^3.0",
11-
"guzzlehttp/guzzle": "^7.5",
12-
"guzzlehttp/psr7": "^2.0",
13-
"webmozart/assert": "^1.11"
11+
"webmozart/assert": "^1.11",
12+
"psr/http-factory": "^1.0",
13+
"php-http/discovery": "^1.19"
1414
},
1515
"require-dev": {
1616
"phpunit/phpunit": "^10.0",
1717
"mockery/mockery": "^1.5",
18-
"openai-php/client": "^0.3.5",
19-
"hkulekci/cohere": "dev-main",
20-
"phpunit/php-code-coverage": "^10.1@dev"
18+
"phpunit/php-code-coverage": "^10.1@dev",
19+
"nyholm/psr7": "^1.8@dev",
20+
"symfony/http-client": "^6.0|^7.0"
2121
},
2222
"autoload": {
2323
"psr-4": {
@@ -38,5 +38,10 @@
3838
"scripts": {
3939
"test": "vendor/bin/phpunit --display-warnings --display-deprecations",
4040
"coverage": "vendor/bin/phpunit --display-warnings --display-deprecations --coverage-html coverage/"
41+
},
42+
"config": {
43+
"allow-plugins": {
44+
"php-http/discovery": false
45+
}
4146
}
4247
}

src/ClientInterface.php

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,9 @@
55
*/
66
namespace Qdrant;
77

8-
use Qdrant\Endpoints\Cluster;
9-
use Qdrant\Endpoints\Collections;
10-
use Qdrant\Endpoints\Service;
11-
use Qdrant\Endpoints\Snapshots;
12-
use Qdrant\Http\HttpClientInterface;
8+
use Psr\Http\Message\RequestInterface;
139

14-
interface ClientInterface extends HttpClientInterface
10+
interface ClientInterface
1511
{
16-
public function collections(string $collectionName = null): Collections;
17-
18-
public function snapshots(): Snapshots;
19-
20-
public function cluster(): Cluster;
21-
22-
public function service(): Service;
12+
public function execute(RequestInterface $request): Response;
2313
}

src/Config.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,22 @@
1010

1111
class Config
1212
{
13-
1413
protected ?string $apiKey = null;
1514

1615
public function __construct(protected string $host, protected int $port = 6333)
1716
{
1817
}
1918

19+
public function getHost()
20+
{
21+
return $this->host;
22+
}
23+
24+
public function getPort()
25+
{
26+
return $this->port;
27+
}
28+
2029
public function getDomain(): string
2130
{
2231
return $this->host . ':' . $this->port;

src/Endpoints/AbstractEndpoint.php

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,16 @@
77
*/
88
namespace Qdrant\Endpoints;
99

10-
use GuzzleHttp\Psr7\HttpFactory;
11-
use GuzzleHttp\Psr7\Query;
10+
use Http\Discovery\Psr17FactoryDiscovery;
1211
use Psr\Http\Message\RequestInterface;
12+
use Qdrant\ClientInterface;
1313
use Qdrant\Exception\InvalidArgumentException;
14-
use Qdrant\Http\HttpClientInterface;
1514

1615
abstract class AbstractEndpoint
1716
{
1817
protected ?string $collectionName = null;
1918

20-
public function __construct(protected HttpClientInterface $client)
19+
public function __construct(protected ClientInterface $client)
2120
{
2221
}
2322

@@ -42,18 +41,20 @@ public function getCollectionName(): string
4241

4342
protected function queryBuild(array $params): string
4443
{
45-
if ($params) {
46-
return '?' . Query::build($params);
44+
$p = [];
45+
foreach ($params as $k => $v) {
46+
$p[] = urldecode($k) . "=" . urlencode($v);
4747
}
48-
return '';
48+
49+
return '?' . implode('&', $p);
4950
}
5051

5152
/**
5253
* @throws InvalidArgumentException
5354
*/
5455
protected function createRequest(string $method, string $uri, array $body = []): RequestInterface
5556
{
56-
$httpFactory = new HttpFactory();
57+
$httpFactory = Psr17FactoryDiscovery::findRequestFactory();
5758
$request = $httpFactory->createRequest($method, $uri);
5859
if ($body) {
5960
try {

src/Http/Builder.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
/**
3+
* Builder
4+
*
5+
* @since Jan 2024
6+
* @author Haydar KULEKCI <haydarkulekci@gmail.com>
7+
*/
8+
9+
namespace Qdrant\Http;
10+
11+
use Http\Discovery\Psr18ClientDiscovery;
12+
use Psr\Http\Client\ClientInterface;
13+
use Qdrant\Config;
14+
15+
class Builder
16+
{
17+
protected ClientInterface $baseClient;
18+
19+
public function getClient(): ClientInterface
20+
{
21+
if (empty($this->baseClient)) {
22+
$this->baseClient = Psr18ClientDiscovery::find();
23+
}
24+
25+
return $this->baseClient;
26+
}
27+
28+
public function build(Config $config): Transport
29+
{
30+
return new Transport(
31+
$this->getClient(),
32+
$config
33+
);
34+
}
35+
}

src/Http/GuzzleClient.php

Lines changed: 0 additions & 70 deletions
This file was deleted.

src/Http/HttpClientInterface.php

Lines changed: 0 additions & 15 deletions
This file was deleted.

src/Http/Transport.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
/**
3+
* Transport.php
4+
*
5+
* @since Jan 2024
6+
* @author Haydar KULEKCI <haydarkulekci@gmail.com>
7+
*/
8+
9+
namespace Qdrant\Http;
10+
11+
use Psr\Http\Client\ClientInterface;
12+
use Psr\Http\Message\RequestInterface;
13+
use Psr\Http\Message\ResponseInterface;
14+
use Qdrant\Config;
15+
16+
class Transport implements ClientInterface
17+
{
18+
public function __construct(
19+
private readonly ClientInterface $client,
20+
private readonly Config $config
21+
)
22+
{
23+
}
24+
25+
private function prepareHeaders(RequestInterface $request): RequestInterface
26+
{
27+
$request = $request->withHeader('content-type', 'application/json')
28+
->withHeader('accept', 'application/json')
29+
->withUri(
30+
$request->getUri()
31+
->withHost($this->config->getHost())
32+
->withPort($this->config->getPort())
33+
->withScheme('http')
34+
);
35+
36+
if ($this->config->getApiKey()) {
37+
$request = $request->withHeader('api-key', $this->config->getApiKey());
38+
}
39+
40+
return $request;
41+
}
42+
43+
public function sendRequest(RequestInterface $request): ResponseInterface
44+
{
45+
$request = $this->prepareHeaders($request);
46+
47+
return $this->client->sendRequest($request);
48+
}
49+
}

src/Qdrant.php

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,42 +5,58 @@
55
*/
66
namespace Qdrant;
77

8+
use Psr\Http\Client\RequestExceptionInterface;
89
use Psr\Http\Message\RequestInterface;
910
use Qdrant\Endpoints\Cluster;
1011
use Qdrant\Endpoints\Collections;
1112
use Qdrant\Endpoints\Service;
1213
use Qdrant\Endpoints\Snapshots;
13-
use Qdrant\Http\HttpClientInterface;
14+
use Qdrant\Http\Transport;
1415

1516
class Qdrant implements ClientInterface
1617
{
17-
18-
public function __construct(private HttpClientInterface $client)
18+
public function __construct(private readonly Transport $transport)
1919
{
2020
}
2121

2222
public function collections(string $collectionName = null): Collections
2323
{
24-
return (new Collections($this->client))->setCollectionName($collectionName);
24+
return (new Collections($this))->setCollectionName($collectionName);
2525
}
2626

2727
public function snapshots(): Snapshots
2828
{
29-
return new Snapshots($this->client);
29+
return new Snapshots($this);
3030
}
3131

3232
public function cluster(): Cluster
3333
{
34-
return new Cluster($this->client);
34+
return new Cluster($this);
3535
}
3636

3737
public function service(): Service
3838
{
39-
return new Service($this->client);
39+
return new Service($this);
4040
}
4141

4242
public function execute(RequestInterface $request): Response
4343
{
44-
return $this->client->execute($request);
44+
try {
45+
$res = $this->transport->sendRequest($request);
46+
47+
return new Response($res);
48+
} catch (RequestExceptionInterface $e) {
49+
var_dump('RequestException', $e->getMessage(), $request); exit();
50+
/*$statusCode = $e->getResponse()->getStatusCode();
51+
if ($statusCode >= 400 && $statusCode < 500) {
52+
$errorResponse = new Response($e->getResponse());
53+
throw (new InvalidArgumentException($e->getMessage(), $statusCode))
54+
->setResponse($errorResponse);
55+
} elseif ($statusCode >= 500) {
56+
$errorResponse = new Response($e->getResponse());
57+
throw (new ServerException($e->getMessage(), $statusCode))
58+
->setResponse($errorResponse);
59+
}*/
60+
}
4561
}
4662
}

tests/Integration/AbstractIntegration.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Qdrant\Config;
1111
use Qdrant\Endpoints\Collections;
1212
use Qdrant\Exception\InvalidArgumentException;
13+
use Qdrant\Http\Builder;
1314
use Qdrant\Http\GuzzleClient;
1415
use Qdrant\Http\HttpClientInterface;
1516
use Qdrant\Models\Request\CreateCollection;
@@ -18,14 +19,15 @@
1819

1920
abstract class AbstractIntegration extends TestCase
2021
{
21-
protected HttpClientInterface $client;
22+
protected Qdrant $client;
2223
private ?Collections $collections = null;
2324

2425
protected function setUp(): void
2526
{
2627
parent::setUp();
27-
$config = (new Config('http://127.0.0.1'));
28-
$this->client = new GuzzleClient($config);
28+
$config = (new Config('127.0.0.1'));
29+
$transform = (new Builder())->build($config);
30+
$this->client = new Qdrant($transform);
2931
}
3032

3133
/**

0 commit comments

Comments
 (0)