Skip to content

Commit be76451

Browse files
✨ add support for model search (#193)
1 parent c96d38b commit be76451

9 files changed

Lines changed: 364 additions & 2 deletions

File tree

src/V2/Client.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Mindee\V2\Http\MindeeApiV2;
1313
use Mindee\V2\Parsing\Inference\BaseResponse;
1414
use Mindee\V2\Parsing\Job\JobResponse;
15+
use Mindee\V2\Parsing\Search\SearchResponse;
1516

1617
/**
1718
* Mindee Client V2.
@@ -32,7 +33,7 @@ class Client
3233
*/
3334
public function __construct(?string $apiKey = null)
3435
{
35-
$this->mindeeApi = new MindeeApiV2($apiKey ?: getenv('MINDEE_V2_API_KEY'));
36+
$this->mindeeApi = new MindeeApiV2($apiKey ?: (getenv('MINDEE_V2_API_KEY') ?: null));
3637
}
3738

3839
/**
@@ -159,4 +160,15 @@ public function enqueueAndGetResult(
159160
. ($pollingOptions->delaySec * $retryCounter) . " seconds"
160161
);
161162
}
163+
164+
/**
165+
* Searches for a list of available models for the given API key.
166+
* @param string|null $modelName Optional model name to filter by.
167+
* @param string|null $modelType Optional model type to filter by.
168+
* @return SearchResponse The list of models matching the criteria.
169+
*/
170+
public function searchModels(?string $modelName = null, ?string $modelType = null): SearchResponse
171+
{
172+
return $this->mindeeApi->searchModels($modelName, $modelType);
173+
}
162174
}

src/V2/Http/MindeeApiV2.php

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Mindee\V2\Parsing\Error\ErrorResponse;
2323
use Mindee\V2\Parsing\Inference\BaseResponse;
2424
use Mindee\V2\Parsing\Job\JobResponse;
25+
use Mindee\V2\Parsing\Search\SearchResponse;
2526
use ReflectionClass;
2627
use ReflectionException;
2728
use ReflectionProperty;
@@ -106,7 +107,7 @@ public function __construct(?string $apiKey)
106107
throw new MindeeException(
107108
"Missing API key for call,"
108109
. " check your Client configuration.You can set this using the "
109-
. API_KEY_ENV_NAME . ' environment variable.',
110+
. API_V2_KEY_ENV_NAME . ' environment variable.',
110111
ErrorCode::USER_INPUT_ERROR
111112
);
112113
}
@@ -386,4 +387,44 @@ private function checkValidResponse(array $result): void
386387
throw new MindeeV2HttpUnknownException(json_encode($result, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
387388
}
388389
}
390+
391+
/**
392+
* @return array<string, integer|float|string|bool|null|array<mixed>> Server response.
393+
*/
394+
private function reqGetSearchModels(?string $modelName = null, ?string $modelType = null): array
395+
{
396+
$url = $this->baseUrl . "/v2/search/models";
397+
$params = [];
398+
if ($modelName) {
399+
$params['name'] = $modelName;
400+
}
401+
if ($modelType) {
402+
$params['model_type'] = $modelType;
403+
}
404+
if (!empty($params)) {
405+
$url .= '?' . http_build_query($params);
406+
}
407+
408+
$ch = $this->initChannel();
409+
curl_setopt($ch, CURLOPT_URL, $url);
410+
curl_setopt($ch, CURLOPT_HTTPGET, true);
411+
412+
$resp = [
413+
'data' => curl_exec($ch),
414+
'code' => curl_getinfo($ch, CURLINFO_HTTP_CODE),
415+
];
416+
curl_close($ch);
417+
return $resp;
418+
}
419+
420+
/**
421+
* Retrieves a list of models based on criteria.
422+
* @param string|null $modelName Optional model name to filter by.
423+
* @param string|null $modelType Optional model type to filter by.
424+
* @return SearchResponse The list of models matching the criteria.
425+
*/
426+
public function searchModels(?string $modelName = null, ?string $modelType = null): SearchResponse
427+
{
428+
return $this->processResponse(SearchResponse::class, $this->reqGetSearchModels($modelName, $modelType));
429+
}
389430
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Mindee\V2\Parsing\Search;
6+
7+
use Stringable;
8+
9+
/**
10+
* Model webhook information.
11+
*/
12+
class ModelWebhook implements Stringable
13+
{
14+
/**
15+
* @var string ID of the webhook.
16+
*/
17+
public string $id;
18+
/**
19+
* @var string Name of the webhook.
20+
*/
21+
public string $name;
22+
/**
23+
* @var string URL of the webhook.
24+
*/
25+
public string $url;
26+
27+
/**
28+
* @param array<string, int|float|string|bool|null|array<array-key, mixed>> $rawResponse
29+
*/
30+
public function __construct(array $rawResponse)
31+
{
32+
$this->id = $rawResponse['id'];
33+
$this->name = $rawResponse['name'];
34+
$this->url = $rawResponse['url'];
35+
}
36+
37+
public function __toString(): string
38+
{
39+
return ":Name: $this->name\n"
40+
. ":ID: $this->id\n"
41+
. ":URL: $this->url\n";
42+
}
43+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Mindee\V2\Parsing\Search;
6+
7+
use Stringable;
8+
9+
/**
10+
* Pagination metadata.
11+
*/
12+
class Pagination implements Stringable
13+
{
14+
/**
15+
* @var integer Number of items per page.
16+
*/
17+
public int $perPage;
18+
/**
19+
* @var integer 1-indexed page number.
20+
*/
21+
public int $page;
22+
/**
23+
* @var integer Total number of items.
24+
*/
25+
public int $totalItems;
26+
/**
27+
* @var integer Total number of pages.
28+
*/
29+
public int $totalPages;
30+
31+
/**
32+
* @param array<string, int|float|string|bool|null|array<array-key, mixed>> $rawResponse Raw server response array.
33+
*/
34+
public function __construct(array $rawResponse)
35+
{
36+
$this->perPage = $rawResponse['per_page'];
37+
$this->page = $rawResponse['page'];
38+
$this->totalItems = $rawResponse['total_items'];
39+
$this->totalPages = $rawResponse['total_pages'];
40+
}
41+
42+
/**
43+
* @return string String representation.
44+
*/
45+
public function __toString(): string
46+
{
47+
return ":Per Page: $this->perPage\n"
48+
. ":Page: $this->page\n"
49+
. ":Total Items: $this->totalItems\n"
50+
. ":Total Pages: $this->totalPages\n";
51+
}
52+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Mindee\V2\Parsing\Search;
6+
7+
use Stringable;
8+
9+
/**
10+
* Individual model information.
11+
*/
12+
class SearchModel implements Stringable
13+
{
14+
/**
15+
* @var string Model ID.
16+
*/
17+
public string $id;
18+
/**
19+
* @var string Model name.
20+
*/
21+
public string $name;
22+
/**
23+
* @var string Model type.
24+
*/
25+
public string $modelType;
26+
/**
27+
* @var array<ModelWebhook> List of webhooks associated with the model.
28+
*/
29+
public array $webhooks;
30+
31+
/**
32+
* @param array<string, int|float|string|bool|null|array<array-key, mixed>> $rawResponse Raw server response array.
33+
*/
34+
public function __construct(array $rawResponse)
35+
{
36+
$this->id = $rawResponse['id'];
37+
$this->name = $rawResponse['name'];
38+
$this->modelType = $rawResponse['model_type'];
39+
$this->webhooks = array_map(
40+
static fn($webhook) => new ModelWebhook($webhook),
41+
$rawResponse['webhooks'] ?? []
42+
);
43+
}
44+
45+
/**
46+
* @return string String representation.
47+
*/
48+
public function __toString(): string
49+
{
50+
return ":Name: $this->name\n"
51+
. ":ID: $this->id\n"
52+
. ":Model Type: $this->modelType\n"
53+
. ":Webhooks: " . implode(', ', array_map(static fn($webhook) => $webhook->name, $this->webhooks)) . "\n";
54+
}
55+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Mindee\V2\Parsing\Search;
6+
7+
use ArrayObject;
8+
use Stringable;
9+
10+
use function count;
11+
12+
/**
13+
* Array of search models.
14+
* @extends ArrayObject<int, SearchModel>
15+
*/
16+
class SearchModels extends ArrayObject implements Stringable
17+
{
18+
/**
19+
* @param array<array<string, int|float|string|bool|null|array<array-key, mixed>>> $prediction Raw prediction.
20+
*/
21+
public function __construct(array $prediction)
22+
{
23+
$models = array_map(static fn($entry) => new SearchModel($entry), $prediction);
24+
25+
parent::__construct($models);
26+
}
27+
28+
/**
29+
* Default string representation.
30+
*/
31+
public function __toString(): string
32+
{
33+
if ($this->count() === 0) {
34+
return "\n";
35+
}
36+
37+
$lines = [];
38+
foreach ($this as $model) {
39+
$lines[] = "* :Name: " . $model->name;
40+
$lines[] = " :ID: " . $model->id;
41+
$lines[] = " :Model Type: " . $model->modelType;
42+
$lines[] = " :Webhooks: " . count($model->webhooks);
43+
}
44+
45+
return implode("\n", $lines) . "\n";
46+
}
47+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Mindee\V2\Parsing\Search;
6+
7+
use Mindee\V2\Parsing\Inference\BaseResponse;
8+
use Stringable;
9+
10+
/**
11+
* Models search response.
12+
*/
13+
class SearchResponse extends BaseResponse implements Stringable
14+
{
15+
/**
16+
* @var SearchModels Parsed search payload.
17+
*/
18+
public SearchModels $models;
19+
20+
/**
21+
* @var Pagination Pagination metadata for the search results.
22+
*/
23+
public Pagination $pagination;
24+
25+
/**
26+
* @param array<string, int|float|string|bool|null|array<array-key, mixed>> $rawResponse Raw server response array.
27+
*/
28+
public function __construct(array $rawResponse)
29+
{
30+
parent::__construct($rawResponse);
31+
$this->models = new SearchModels($rawResponse['models']);
32+
$this->pagination = new Pagination($rawResponse['pagination']);
33+
}
34+
35+
/**
36+
* @return string String representation.
37+
*/
38+
public function __toString(): string
39+
{
40+
return implode("\n", [
41+
'Models',
42+
'######',
43+
(string) $this->models,
44+
'Pagination Metadata',
45+
'###################',
46+
(string) $this->pagination,
47+
'',
48+
]);
49+
}
50+
}

tests/V2/ClientV2Test.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ public function testInferenceLoadsLocally(): void
139139
'Supplier name mismatch'
140140
);
141141
}
142+
142143
public function testInvalidBaseUrlRaisesMindeeException(): void
143144
{
144145
$this->expectException(MindeeException::class);
@@ -159,4 +160,21 @@ public function testInvalidBaseUrlRaisesMindeeException(): void
159160
}
160161
}
161162
}
163+
164+
public function testInvalidApiKeyRaisesMindeeException(): void
165+
{
166+
$original = getenv('MINDEE_V2_API_KEY') ?: null;
167+
putenv('MINDEE_V2_API_KEY=');
168+
$this->expectException(MindeeException::class);
169+
$this->expectExceptionMessage('Missing API key for call, check your Client configuration.You can set this using the MINDEE_V2_API_KEY environment variable.');
170+
try {
171+
$client = new Client();
172+
} finally {
173+
if (null === $original) {
174+
putenv('MINDEE_V2_API_KEY');
175+
} else {
176+
putenv('MINDEE_V2_API_KEY=' . $original);
177+
}
178+
}
179+
}
162180
}

0 commit comments

Comments
 (0)