{"id":16440608,"url":"https://github.com/darrynten/clarifai-php","last_synced_at":"2025-03-21T04:33:38.689Z","repository":{"id":56962594,"uuid":"81358266","full_name":"darrynten/clarifai-php","owner":"darrynten","description":"Clarifai API client for PHP","archived":false,"fork":false,"pushed_at":"2018-03-28T22:08:51.000Z","size":176,"stargazers_count":25,"open_issues_count":3,"forks_count":15,"subscribers_count":12,"default_branch":"dev","last_synced_at":"2025-03-17T21:42:34.362Z","etag":null,"topics":["ai","api","clarifai","client","image-recognition","machine-learning","php"],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/darrynten.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-02-08T17:48:02.000Z","updated_at":"2024-04-07T10:06:15.000Z","dependencies_parsed_at":"2022-08-21T05:40:18.409Z","dependency_job_id":null,"html_url":"https://github.com/darrynten/clarifai-php","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darrynten%2Fclarifai-php","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darrynten%2Fclarifai-php/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darrynten%2Fclarifai-php/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darrynten%2Fclarifai-php/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/darrynten","download_url":"https://codeload.github.com/darrynten/clarifai-php/tar.gz/refs/heads/dev","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244738841,"owners_count":20501923,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","api","clarifai","client","image-recognition","machine-learning","php"],"created_at":"2024-10-11T09:12:33.614Z","updated_at":"2025-03-21T04:33:38.405Z","avatar_url":"https://github.com/darrynten.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# clarifai-php\n\n![Travis Build Status](https://travis-ci.org/darrynten/clarifai-php.svg?branch=master)\n![StyleCI Status](https://styleci.io/repos/81687310/shield?branch=master)\n[![codecov](https://codecov.io/gh/darrynten/clarifai-php/branch/master/graph/badge.svg)](https://codecov.io/gh/darrynten/clarifai-php)\n![Packagist Version](https://img.shields.io/packagist/v/darrynten/clarifai-php.svg)\n![MIT License](https://img.shields.io/github/license/darrynten/clarifai-php.svg)\n\n[Clarifai API](https://developer.clarifai.com/docs/) client for PHP\n\nThis is a 100% fully unit tested and (mostly) fully featured unofficial PHP\nclient for Clarifai\n\n\u003e Clarifai is an artificial intelligence company that excels in visual\nrecognition, solving real-world problems for businesses and developers\nalike.\n\n```bash\ncomposer require darrynten/clarifai-php\n```\n\nPHP 7.0+\n\n## Basic use\n\nThe API is rather simple, and consists of Inputs, Concepts and Models.\n\n### Definitions\n\n#### Inputs\n\nYou send inputs (images) to the service and it returns predictions. In\naddition to receiving predictions on inputs, you can also 'save' inputs\nand their predictions to later search against. You can also 'save' inputs\nwith concepts to later train your own model.\n\n#### Model\n\nClarifai provides many different models that 'see' the world differently.\nA model contains a group of concepts. A model will only see the concepts\nit contains.\n\nThere are times when you wish you had a model that sees the world the way\nyou see it. The API allows you to do this. You can create your own model\nand train it with your own images and concepts. Once you train it to see\nhow you would like it to see, you can then use that model to make\npredictions.\n\nYou do not need many images to get started. We recommend starting with 10\nand adding more as needed.\n\n#### Concepts\n\nConcepts play an important role in creating your own models using your\nown concepts. Concepts also help you search for inputs.\n\nWhen you add a concept to an input, you need to indicate whether the\nconcept is present in the image or if it is not present.\n\n## Features\n\nThis is the basic outline of the project and is a work in progress.\n\nCheckboxes have been placed at each section, please check them off\nin this readme when submitting a pull request for the features you\nhave covered.\n\n### Application base\n\n* Guzzle is used for the communications\n* The library has 100% test coverage\n* The library supports framework-agnostic caching so you don't have to\nworry about which framework your package that uses this package is going\nto end up in.\n\nThe client is not 100% complete and is a work in progress, details below.\n\nThe structure is heavily inspired by [The official JS client](https://github.com/Clarifai/clarifai-javascript)\n\n### Authentication\n\nAccess is handled via oauth2.\n\nYou would need to initialise the client with your Client ID and Secret.\n\n```php\n$this-\u003eclarifai = new Clarifai('clientId', 'clientSecret');\n```\n\n### Predict\n\nThis is a basic library usage example that uses a predict call. The model name is `aaa03c23b3724a16a56b629203edc62c`\n\n```php\n\ninclude 'vendor/autoload.php';\n\n$clarifai = new \\DarrynTen\\Clarifai\\Clarifai(\n    CLIENT_ID,\n    CLIENT_SECRET\n);\n\n$modelResult = $clarifai-\u003egetModelRepository()-\u003epredictUrl(\n    'https://samples.clarifai.com/metro-north.jpg',\n    \\DarrynTen\\Clarifai\\Repository\\ModelRepository::GENERAL\n);\n\necho json_encode($modelResult);\n\n```\n\nThe response (abridged) would be:\n\n```js\n{\n  \"status\":{\n     \"code\":10000,\n     \"description\":\"Ok\"\n  },\n  \"outputs\":[\n     {\n        \"id\":\"db1b183a95a042d3bd873f8ca69ae2e6\",\n        \"status\":{\n           \"code\":10000,\n           \"description\":\"Ok\"\n        },\n        \"created_at\":\"2017-02-14T03:18:54.548733Z\",\n        \"model\":{\n           \"name\":\"general-v1.3\",\n           \"id\":\"aaa03c23b3724a16a56b629203edc62c\",\n           \"created_at\":\"2016-03-09T17:11:39.608845Z\",\n           \"app_id\":null,\n           \"output_info\":{\n              \"message\":\"Show output_info with: GET \\/models\\/{model_id}\\/output_info\",\n              \"type\":\"concept\"\n           },\n           \"model_version\":{\n              \"id\":\"aa9ca48295b37401f8af92ad1af0d91d\",\n              \"created_at\":\"2016-07-13T01:19:12.147644Z\",\n              \"status\":{\n                 \"code\":21100,\n                 \"description\":\"Model trained successfully\"\n              }\n           }\n        },\n        \"input\":{\n           \"id\":\"db1b183a95a042d3bd873f8ca69ae2e6\",\n           \"data\":{\n              \"image\":{\n                 \"url\":\"https:\\/\\/samples.clarifai.com\\/metro-north.jpg\"\n              }\n           }\n        },\n        \"data\":{\n           \"concepts\":[\n              {\n                 \"id\":\"ai_HLmqFqBf\",\n                 \"name\":\"\\u043f\\u043e\\u0435\\u0437\\u0434\",\n                 \"app_id\":null,\n                 \"value\":0.9989112\n              },\n              // and several others\n              {\n                 \"id\":\"ai_VSVscs9k\",\n                 \"name\":\"\\u0442\\u0435\\u0440\\u043c\\u0438\\u043d\\u0430\\u043b\",\n                 \"app_id\":null,\n                 \"value\":0.9230834\n              }\n           ]\n        }\n     }\n  ]\n}\n```\n\nThis can happen either with an image URL:\n\n```php\n    $modelResult = $clarifai-\u003egetModelRepository()-\u003epredictPath(\n        '/user/images/image.png',\n        \\DarrynTen\\Clarifai\\Repository\\ModelRepository::GENERAL\n    );\n```\n\nor b64 encoded data:\n\n```php\n    $modelResult = $clarifai-\u003egetModelRepository()-\u003epredictEncoded(\n        ENCODED_IMAGE_HASH,\n        \\DarrynTen\\Clarifai\\Repository\\ModelRepository::GENERAL\n    );\n```\n\n## Documentation\n\nThis will eventually fully mimic the documentation available on the site.\nhttps://developer.clarifai.com/guide\n\nEach section must have a short explaination and some example code like on\nthe API docs page.\n\nChecked off bits are complete.\n\n- [x] Inputs\n  - [x] Add\n  - [x] Add with Concepts\n  - [x] Add with Custom Metadata\n  - [x] Add with Crop\n  - [x] Get Inputs\n  - [x] Get Input Status\n  - [x] Update Input with Concepts\n  - [x] Delete Concepts from Input\n  - [x] Bulk Update Inputs with Concepts\n  - [x] Bulk Delete Concepts from Input List\n  - [x] Delete Input by ID\n  - [x] Delete Input List\n  - [x] Delete All Inpits\n- [x] Models\n  - [x] Create Model\n  - [x] Create Model With Concepts\n  - [x] Add Concepts to a Model\n  - [x] Remove Concept from Model\n  - [x] Update Model Name and Configuration\n  - [x] Get Models\n  - [x] Get Model by ID\n  - [x] Get Model Output Info by ID\n  - [x] List Model Versions\n  - [x] Get Model Version by ID\n  - [x] Get Model Training Inputs\n  - [x] Get Model Training Inputs by Version\n  - [x] Delete Model\n  - [x] Delete Model Version\n  - [x] Delete All Models\n  - [x] Train Model\n  - [x] Predict With Model\n- [x] Searches\n  - [x] Search Model by Name and Type\n  - [x] Search by Predicted Concepts\n  - [x] Search by User Supplied Concept\n  - [x] Search by Custom Metadata\n  - [x] Search by Reverse Image\n  - [x] Search Match URL\n  - [x] Search by Concept and Prediction\n  - [x] Search ANDing\n- [x] Pagination\n- [x] Patching\n  - [x] Merge\n  - [x] Remove\n  - [x] Overwrite\n- [ ] Batch Requests\n- [ ] Languages\n\n## Inputs\n\nThe API is built around a simple idea. You send inputs (images) to the service\nand it returns predictions. In addition to receiving predictions on inputs, you\ncan also 'save' inputs and their predictions to later search against. You can\nalso 'save' inputs with concepts to later train your own model.\n\n### Add Inputs\n\nYou can add inputs one by one or in bulk. If you do send bulk, you are limited\nto sending 128 inputs at a time.\n\nImages can either be publicly accessible URLs or file bytes. If you are sending\nfile bytes, you must use base64 encoding.\n\nYou are encouraged to send inputs with your own id. This will help you later\nmatch the input to your own database. If you do not send an id, one will be\ncreated for you.\n\n#### Add an input using a publicly accessible URL\n\n```php\n    $input = new Input();\n    $input-\u003esetImage('https://samples.clarifai.com/metro-north.jpg')-\u003eisUrl();\n    $inputResult = $clarifai-\u003egetInputRepository()-\u003eadd($input);\n```\n\n#### Add an input using local path to image\n\n```php\n    $input = new Input();\n    $input-\u003esetImage('/samples.clarifai.com/metro-north.jpg')-\u003eisPath();\n    $inputResult = $clarifai-\u003egetInputRepository()-\u003eadd($input);\n```\n\n#### Add an input using bytes\n\nThe data must be base64 encoded. When you add a base64 image to our servers, a\ncopy will be stored and hosted on our servers. If you already have an image\nhosting service we recommend using it and adding images via the url parameter.\n\n```php\n    $input = new Input();\n    $input-\u003esetImage(ENCODED_IMAGE_HASH)-\u003eisEncoded();\n    $inputResult = $clarifai-\u003egetInputRepository()-\u003eadd($input);\n```\n\n#### Add multiple inputs with ids\n\n```php\n    $input1 = new Input();\n    $input1-\u003esetImage('https://samples.clarifai.com/metro-north.jpg')-\u003eisUrl()-\u003esetId('id1');\n    $input2 = new Input();\n    $input2-\u003esetImage('https://samples.clarifai.com/puppy.jpeg')-\u003eisUrl()-\u003esetId('id2');\n    $inputResult = $clarifai-\u003egetInputRepository()-\u003eadd([$input1, $input2]);\n```\n\n#### Add inputs with concepts\n\n```php\n    $concept = new Concept();\n    $concept-\u003esetId('boscoe')-\u003esetValue(true);\n\n    $input = new Input();\n    $input-\u003esetImage('https://samples.clarifai.com/puppy.jpeg')-\u003eisUrl()\n        -\u003esetConcepts([$concept]);\n\n    $inputResult = $clarifai-\u003egetInputRepository()-\u003eadd($input);\n```\n\n#### Add input with metadata\n\nIn addition to adding an input with concepts, you can also add an input with\ncustom metadata. This metadata will then be searchable. Metadata can be any\narbitrary JSON.\n\n```php\n    $input = new Input();\n    $input-\u003esetImage('https://samples.clarifai.com/metro-north.jpg')-\u003eisUrl()\n        -\u003esetMetaData([['key' =\u003e 'value', 'list' =\u003e [1, 2, 3]]);\n    $inputResult = $clarifai-\u003egetInputRepository()-\u003eadd($input);\n```\n\n#### Add input with a crop\n\nWhen adding an input, you can specify crop points. The API will crop the image\nand use the resulting image. Crop points are given as percentages from the top\nleft point in the order of top, left, bottom and right.\n\nAs an example, if you provide a crop as `0.2, 0.4, 0.3, 0.6` that means the\ncropped image will have a top edge that starts 20% down from the original top\nedge, a left edge that starts 40% from the original left edge, a bottom edge\nthat starts 30% from the original top edge and a right edge that starts 60% from\nthe original left edge.\n\n```php\n    $input = new Input();\n    $input-\u003esetImage('https://samples.clarifai.com/metro-north.jpg')-\u003eisUrl()\n        -\u003esetCrop([0.2, 0.4, 0.3, 0.6]);\n    $inputResult = $clarifai-\u003egetInputRepository()-\u003eadd($input);\n```\n\n#### Get Inputs\n\nYou can list all the inputs (images) you have previously added either for search\nor train.\n\nIf you added inputs with concepts, they will be returned in the response as well.\n\n```php\n    $inputResult = $clarifai-\u003egetInputRepository()-\u003eget();\n```\n\n#### Get Input by Id\n\nIf you'd like to get a specific input by id, you can do that as well.\n\n```php\n    $inputResult = $clarifai-\u003egetInputRepository()-\u003egetById('id');\n```\n\n#### Get Inputs Status\n\nIf you add inputs in bulk, they will process in the background. You can get the\nstatus of all your inputs (processed, to_process and errors) like this:\n\n```php\n    $inputResult = $clarifai-\u003egetInputRepository()-\u003egetStatus();\n```\n\n#### Update input with concepts\n\nTo update an input with a new concept, or to change a concept value from true/false, you can do that:\n\n```php\n    $concept1 = new Concept();\n    $concept1-\u003esetId('tree')-\u003esetValue(true);\n    \n    $concept2 = new Concept();\n    $concept2-\u003esetId('water')-\u003esetValue(false);\n\n    $modelResult = $clarifai-\u003egetInputRepository()-\u003emergeInputConcepts([$inputId =\u003e [$concept1, $concept2]]);\n```\n\n#### Delete concepts from input\n\nTo remove concepts that were already added to an input, you can do this:\n\n```php\n    $concept1 = new Concept();\n    $concept1-\u003esetId('mattid2')-\u003esetValue(true);\n    \n    $concept2 = new Concept();\n    $concept2-\u003esetId('ferrari')-\u003esetValue(false);\n\n    $modelResult = $clarifai-\u003egetInputRepository()-\u003edeleteInputConcepts([$inputId =\u003e [$concept1, $concept2]]);\n```\n\n#### Bulk update inputs with concepts\n\nYou can update an existing input using its Id. This is useful if you'd like to add concepts to an input after its already been added.\n\n```php\n    $concept1 = new Concept();\n    $concept1-\u003esetId('tree')-\u003esetValue(true);\n    \n    $concept2 = new Concept();\n    $concept2-\u003esetId('water')-\u003esetValue(false);\n    \n    $concept3 = new Concept();\n    $concept3-\u003esetId('mattid2')-\u003esetValue(true);\n    \n    $concept4 = new Concept();\n    $concept4-\u003esetId('ferrari')-\u003esetValue(false);\n\n    $modelResult = $clarifai-\u003egetInputRepository()-\u003emergeInputConcepts(\n        [\n            $inputId1 =\u003e [$concept1, $concept2],\n            $inputId2 =\u003e [$concept3, $concept4],\n        ]\n    );\n```\n\n#### Bulk delete concepts from list of inputs\n\nYou can bulk delete multiple concepts from a list of inputs:\n\n```php\n    $concept1 = new Concept();\n    $concept1-\u003esetId('tree')-\u003esetValue(true);\n    \n    $concept2 = new Concept();\n    $concept2-\u003esetId('water')-\u003esetValue(false);\n    \n    $concept3 = new Concept();\n    $concept3-\u003esetId('mattid2')-\u003esetValue(true);\n    \n    $concept4 = new Concept();\n    $concept4-\u003esetId('ferrari')-\u003esetValue(false);\n\n    $modelResult = $clarifai-\u003egetInputRepository()-\u003edeleteInputConcepts(\n        [\n            $inputId1 =\u003e [$concept1, $concept2],\n            $inputId2 =\u003e [$concept3, $concept4],\n        ]\n    );\n```\n\n#### Delete Input By Id\n\nYou can delete a single input by id\n\n```php\n    $inputResult = $clarifai-\u003egetInputRepository()-\u003edeleteById('id');\n```\n\n#### Delete A List Of Inputs\n\nYou can also delete multiple inputs in one API call. This will happen\nasynchronously.\n\n```php\n    $inputResult = $clarifai-\u003egetInputRepository()-\u003edeleteByIdArray(['id1', 'id2']);\n```\n\n#### Delete All Inputs\n\nIf you would like to delete all inputs from an application, you can do that as\nwell. This will happen asynchronously.\n\n```php\n    $inputResult = $clarifai-\u003egetInputRepository()-\u003edeleteAll();\n```\n\n## Models\n\nThere are many methods to work with models.\n\n#### Create Model\n\nYou can create your own model and train it with your own images and concepts. Once you train it to see how you would like it to see, you can then use that model to make predictions.\n\nWhen you create a model you give it a name and an id. If you don't supply an id, one will be created for you. All models must have unique ids.\n\n```php\n    $model = new Model();\n    $model-\u003esetId('petsID');\n    $modelResult = $clarifai-\u003egetModelRepository()-\u003ecreate($model);\n```\n\n#### Create Model with Concepts\n\nYou can also create a model and initialize it with the concepts it will contain. You can always add and remove concepts later.\n\n```php\n    $concept = new Concept();\n    $concept-\u003esetId('boscoe');\n\n    $model= new Model();\n    $model-\u003esetId('petsId')\n        -\u003esetConcepts([$concept])\n        -\u003esetConceptsMutuallyExclusive(false)\n        -\u003esetClosedEnvironment(false);\n\n    $modelResult = $clarifai-\u003egetModelRepository()-\u003ecreate($model);\n```\n\n#### Add Concepts To A Model\n\nYou can add concepts to a model at any point. As you add concepts to inputs, you may want to add them to your model.\n\n```php\n    $concept = new Concept();\n    $concept-\u003esetId('dogs');\n\n    $modelResult = $clarifai-\u003egetModelRepository()-\u003emergeModelConcepts([$modelId =\u003e [$concept]]);\n```\n\n#### Remove Concepts From A Model\n\nConversely, if you'd like to remove concepts from a model, you can also do that.\n\n```php\n    $concept = new Concept();\n    $concept-\u003esetId('dogs');\n\n    $modelResult = $clarifai-\u003egetModelRepository()-\u003edeleteModelConcepts([$modelId =\u003e [$concept]]);\n```\n\n#### Update Model Name and Configuration\n\nHere we will change the model name to 'newname' and the model's configuration to have concepts_mutually_exclusive=true and closed_environment=true.\n\n```php\n    $model-\u003esetName('newname')\n        -\u003esetClosedEnvironment(true)\n        -\u003esetConceptsMutuallyExclusive(true);\n\n    $modelResult = $clarifai-\u003egetModelRepository()-\u003eupdate($model);\n```\n\n#### Get Models\n\nTo get a list of all models including models you've created as well as public models\n\n```php\n    $modelResult = $clarifai-\u003egetModelRepository()-\u003eget();\n```\n\n#### Get Model By Id\n\nAll models have unique Ids. You can get a specific model by its id:\n\n```php\n    $modelResult = $clarifai-\u003egetModelRepository()-\u003egetById($modelId);\n```\n\n#### Get Model Output Info By Id\n\nThe output info of a model lists what concepts it contains.\n\n```php\n    $modelResult = $clarifai-\u003egetModelRepository()-\u003egetOutputInfoById($modelId);\n```\n\n#### List Model Versions\n\nEvery time you train a model, it creates a new version. You can list all the versions created.\n\n```php\n    $modelResult = $clarifai-\u003egetModelRepository()-\u003egetModelVersions($modelId);\n```\n\n#### Get Model Version By Id\n\nTo get a specific model version, you must provide the modelId as well as the versionId. You can inspect the model version status to determine if your model is trained or still training.\n\n```php\n    $modelResult = $clarifai-\u003egetModelRepository()-\u003egetModelVersionById($modelId, $versionId);\n```\n\n#### Get Model Training Inputs\n\nYou can list all the inputs that were used to train the model.\n\n```php\n    $modelResult = $clarifai-\u003egetModelRepository()-\u003egetTrainingInputsById($modelId);\n```\n\n#### Get Model Training Inputs By Version\n\nYou can also list all the inputs that were used to train a specific model version.\n\n```php\n    $modelResult = $clarifai-\u003egetModelRepository()-\u003egetTrainingInputsByVersion($modelId, $versionId);\n```\n\n#### Delete A Model\n\nYou can delete a model using the modelId.\n\n```php\n    $modelResult = $clarifai-\u003egetModelRepository()-\u003edeleteById($modelId);\n```\n\n#### Delete A Model Version\n\nYou can also delete a specific version of a model with the modelId and versionId.\n\n```php\n    $modelResult = $clarifai-\u003egetModelRepository()-\u003edeleteVersionById($modelId, $versionId);\n```\n\n#### Delete All Models\n\nIf you would like to delete all models associated with an application, you can also do that. Please proceed with caution as these cannot be recovered.\n\n```php\n    $modelResult = $clarifai-\u003egetModelRepository()-\u003edeleteAll();\n```\n\n#### Train A Model\n\nWhen you train a model, you are telling the system to look at all the images with concepts you've provided and learn from them. This train operation is asynchronous. It may take a few seconds for your model to be fully trained and ready.\n\nNote: you can repeat this operation as often as you like. By adding more images with concepts and training, you can get the model to predict exactly how you want it to.\n\n```php\n    $modelResult = $clarifai-\u003egetModelRepository()-\u003etrain($id);\n```\n\n#### Search Models By Name And Type\n\nYou can search all your models by name and type of model.\n\n```php\n    $modelResult = $clarifai-\u003egetSearchModelRepository()-\u003esearchByNameAndType($modelName, 'concept');\n```\n\n## Searches\n\n#### Search By Predicted Concepts\n\nWhen you add an input, it automatically gets predictions from the general model. You can search for those predictions.\n\n```php\n    $concept1 = new Concept();\n    $concept1-\u003esetName('dog')-\u003esetValue(true);\n    \n    $concept2 = new Concept();\n    $concept2-\u003esetName('cat');\n        \n    $inputResult = $clarifai-\u003egetSearchInputRepository()-\u003esearchByPredictedConcepts([$concept1, $concept2]);\n```\n\n#### Search By User Supplied Concept\n\nAfter you have added inputs with concepts, you can search by those concepts.\n\n```php\n    $concept1 = new Concept();\n    $concept1-\u003esetName('dog');\n    \n    $concept2 = new Concept();\n    $concept2-\u003esetName('cat');\n        \n    $inputResult = $clarifai-\u003egetSearchInputRepository()-\u003esearchByUserSuppliedConcepts([$concept1, $concept2]);\n```\n\n#### Search By Custom Metadata\n\nAfter you have added inputs with custom metadata, you can search by that metadata.\n\n```php\n    $metadata = ['key'=\u003e 'value'];\n\n    $inputResult = $clarifai-\u003egetSearchInputRepository()-\u003esearchByCustomMetadata([$metadata]);\n```\n\n#### Search By Reverse Image\n\nYou can use images to do reverse image search on your collection. The API will return ranked results based on how similar the results are to the image you provided in your query.\n\n```php\n    $input = new Input();\n    $input-\u003esetImage('https://samples.clarifai.com/metro-north.jpg');\n        \n    $inputResult = $clarifai-\u003egetSearchInputRepository()-\u003esearchByReversedImage([$input]);\n```\n\n#### Search Match Url\n\nYou can also search for an input by URL.\n\n```php\n    $input = new Input();\n    $input-\u003esetImage('https://samples.clarifai.com/metro-north.jpg');\n        \n    $inputResult = $clarifai-\u003egetSearchInputRepository()-\u003esearchByMatchUrl([$input]);\n```\n\n#### Search By Concept And Predictions\n\nYou can combine a search to find inputs that have concepts you have supplied as well as predictions from your model.\n\n```php\n    $concept1 = new Concept();\n    $concept1-\u003esetName('dog');\n    \n    $concept2 = new Concept();\n    $concept2-\u003esetName('cat');\n        \n    $inputResult = $clarifai-\u003egetSearchInputRepository()-\u003esearch(\n        [\n            \\DarrynTen\\Clarifai\\Repository\\SearchInputRepository::INPUT_CONCEPTS =\u003e [$concept1],\n            \\DarrynTen\\Clarifai\\Repository\\SearchInputRepository::OUTPUT_CONCEPTS =\u003e [$concept2]\n        ]\n    );\n```\n\n#### Search ANDing\n\nYou can also combine searches using AND.\n\n```php\n    $concept1 = new Concept();\n    $concept1-\u003esetName('dog');\n    \n    $concept2 = new Concept();\n    $concept2-\u003esetName('cat');\n    \n    $input = new Input();\n    $input-\u003esetImage('https://samples.clarifai.com/metro-north.jpg');\n    \n    $metadata = ['key' =\u003e 'value'];\n        \n    $inputResult = $clarifai-\u003egetSearchInputRepository()-\u003esearch(\n        [\n            SearchInputRepository::INPUT_CONCEPTS =\u003e [$concept1],\n            SearchInputRepository::OUTPUT_CONCEPTS =\u003e [$concept2],\n            SearchInputRepository::IMAGE =\u003e [$input],\n            SearchInputRepository::METADATA =\u003e [$metadata],\n        ]\n    );\n```\n\n## Pagination\n\nMany API calls are paginated. You can provide page and per_page params to the API. In the example below we are getting all inputs and specifying to start at page 2 and get back 20 results per page.\n\n```php\n    $inputResult = $clarifai-\u003egetInputRepository()-\u003esetPage(2)-\u003esetPerPage(20)-\u003eget();\n```\n\n## Patching(Only for Concepts)\n\nWe designed PATCH to work over multiple resources at the same time (bulk) and be flexible enough for all your needs to minimize round trips to the server. Therefore it might seem a little different to any PATCH you've seen before, but it's not complicated. All three actions that are supported do overwrite by default, but have special behaviour for lists of objects (for example lists of concepts).\n\n#### Merge\n\nMerge action will overwrite a key:value with key:new_value or append to an existing list of values, merging dictionaries that match by a corresponding id field.\n\nIn the following examples A is being patched into B to create the Result:\n\n```\n  *Merges different key:values*\n  A = `{\"a\":[1,2,3]}`\n  B = `{\"blah\":true}`\n  Result = `{\"blah\":true, \"a\":[1,2,3]}`\n  \n  *For id lists, merge will append*\n  A = `{\"a\":[{\"id\": 1}]}`\n  B = `{\"a\":[{\"id\": 2}]}`\n  Result = `{\"a\":[{\"id\": 2}, {\"id\":1}]}`\n  \n  *Simple merge of key:values and within a list*\n  A = `{\"a\":[{\"id\": \"1\", \"other\":true}], \"blah\":1}`\n  B = `{\"a\":[{\"id\": \"2\"},{\"id\":\"1\", \"other\":false}]}`\n  Result = `{\"a\":[{\"id\": \"2\"},{\"id\": \"1\"}], \"blah\":1}`\n  \n  *Different types should overwrite fine*\n  A = `{\"a\":[{\"id\": \"1\"}], \"blah\":1}`\n  B = `{\"a\":[{\"id\": \"2\"}], \"blah\":\"string\"}`\n  Result = `{\"a\":[{\"id\": \"2\"},{\"id\": \"1\"}], \"blah\":1}`\n  \n  *Deep merge, notice the \"id\":\"1\" matches, so those dicts are merged in the list*\n  A = `{\"a\":[{\"id\": \"1\",\"hey\":true}], \"blah\":1}`\n  B = `{\"a\":[{\"id\": \"1\",\"foo\":\"bar\",\"hey\":false},{\"id\":\"2\"}], \"blah\":\"string\"}`\n  Result = `{\"a\":[{\"hey\":true,\"id\": \"1\",\"foo\":\"bar\"},{\"id\":\"2\"}], \"blah\":1}`\n  \n  *For non-id lists, merge will append*\n  A = `{\"a\":[{\"blah\": \"1\"}], \"blah\":1}`\n  B = `{\"a\":[{\"blah\": \"2\"}], \"blah\":\"string\"}`\n  Result = `{\"a\":[{\"blah\": \"2\"}, {\"blah\":\"1\"}], \"blah\":1}`\n  \n  *For non-id lists, merge will append*\n  A = `{\"a\":[{\"blah\": \"1\"}], \"blah\":1, \"dict\":{\"a\":1,\"b\":2}}`\n  B = `{\"a\":[{\"blah\": \"2\"}], \"blah\":\"string\"}`\n  Result = `{\"a\":[{\"blah\": \"2\"}, {\"blah\":\"1\"}], \"blah\":1, \"dict\":{\"a\":1,\"b\":2}}`\n  \n  *Simple overwrite root element*\n  A = `{\"key1\":true}`\n  B = `{\"key1\":{\"key2\":\"value2\", \"key3\":\"value3\"}}`\n  Result = `{\"key1\":true}`\n  \n  *Overwrite a sub element*\n  A = `{\"key1\":{\"key2\":true}}`\n  B = `{\"key1\":{\"key2\":\"value2\", \"key3\":\"value3\"}}`\n  Result = `{\"key1\":{\"key2\":true, \"key3\":\"value3\"}}`\n  \n  *Merge a sub element*\n  A = `{\"key1\":{\"key2\":{\"key4\":\"value4\"}}}`\n  B = `{\"key1\":{\"key2\":\"value2\", \"key3\":\"value3\"}}`\n  Result = `{\"key1\":{\"key2\":{\"key4\":\"value4\"}, \"key3\":\"value3\"}}`\n  \n  *Merge multiple trees*\n  A = `{\"key1\":{\"key2\":{\"key9\":\"value9\"}, \"key3\":{\"key4\":\"value4\", \"key10\":[1,2,3]}}, \"key6\":{\"key11\":\"value11\"}}`\n  B = `{\"key1\":{\"key2\":\"value2\", \"key3\":{\"key4\":{\"key5\":\"value5\"}}}, \"key6\":{\"key7\":{\"key8\":\"value8\"}}}`\n  Result = `{\"key1\":{\"key2\":{\"key9\":\"value9\"}, \"key3\":{\"key4\":\"value4\", \"key10\":[1,2,3]}}, \"key6\":{\"key7\":{\"key8\":\"value8\"}, \"key11\":\"value11\"}}`\n  \n  *Merge {} element will replace*\n  A = `{\"key1\":{\"key2\":{}}}`\n  B = `{\"key1\":{\"key2\":\"value2\", \"key3\":\"value3\"}}`\n  Result = `{\"key1\":{\"key2\":{}, \"key3\":\"value3\"}}`\n  \n  *Merge a null element does nothing*\n  A = `{\"key1\":{\"key2\":null}}`\n  B = `{\"key1\":{\"key2\":\"value2\", \"key3\":\"value3\"}}`\n  Result = `{\"key1\":{\"key2\":\"value2\", \"key3\":\"value3\"}}`\n  \n  *Merge a blank list [] will replace root element*\n  A = `{\"key1\":[]}`\n  B = `{\"key1\":{\"key2\":\"value2\", \"key3\":\"value3\"}}`\n  Result = `{\"key1\":[]}`\n  \n  *Merge a blank list [] will replace single element*\n  A = `{\"key1\":{\"key2\":[]}}`\n  B = `{\"key1\":{\"key2\":\"value2\", \"key3\":\"value3\"}}`\n  Result = `{\"key1\":{\"key2\":[], \"key3\":\"value3\"}}`\n  \n  *Merge a blank list [] will remove nested objects*\n  A = `{\"key1\":{\"key2\":[{\"key3\":\"value3\"}]}}`\n  B = `{\"key1\":{\"key2\":{\"key3\":\"value3\"}}}`\n  Result = `{\"key1\":{\"key2\":[{\"key3\":\"value3\"}]}}`\n  \n  *Merge an existing list with some other struct*\n  A = `{\"key1\":{\"key2\":{\"key3\":[{\"key4\":\"value4\"}]}}}`\n  B = `{\"key1\":{\"key2\":[]}}`\n  Result = `{\"key1\":{\"key2\":{\"key3\":[{\"key4\":\"value4\"}]}}}`\n```\n\n#### Remove\n\nRemove action will overwrite a key:value with key:new_value or delete anything in a list that matches the provided values' ids.\n\nIn the following examples A is being patched into B to create the Result:\n```\n  *Remove from list*\n  A = `{\"a\":[{\"id\": \"1\"}], \"blah\":1}`\n  B = `{\"a\":[{\"id\": \"2\"},{\"id\": \"3\"}, {\"id\":\"1\"}], \"blah\":\"string\"}`\n  Result = `{\"a\":[{\"id\": \"2\"},{\"id\":\"3\"}], \"blah\":1}`\n  \n  *For non-id lists, remove will append*\n  A = `{\"a\":[{\"blah\": \"1\"}], \"blah\":1}`\n  B = `{\"a\":[{\"blah\": \"2\"}], \"blah\":\"string\"}`\n  Result = `{\"a\":[{\"blah\": \"2\"}, {\"blah\":\"1\"}], \"blah\":1}`\n  \n  *Empty out a nested dictionary*\n  A = `{\"key1\":{\"key2\":true}}`\n  B = `{\"key1\":{\"key2\":\"value2\"}}`\n  Result = `{\"key1\":{}}`\n  \n  *Remove the root element, should be empty*\n  A = `{\"key1\":true}`\n  B = `{\"key1\":{\"key2\":\"value2\", \"key3\":\"value3\"}}`\n  Result = `{}`\n  \n  *Remove a sub element*\n  A = `{\"key1\":{\"key2\":true}}`\n  B = `{\"key1\":{\"key2\":\"value2\", \"key3\":\"value3\"}}`\n  Result = `{\"key1\":{\"key3\":\"value3\"}}`\n  \n  *Remove a multiple sub elements*\n  A = `{\"key1\":{\"key2\":{\"key3\":true}, \"key4\":true}}`\n  B = `{\"key1\":{\"key2\":{\"key3\":{\"key5\":\"value5\"}}, \"key4\":{\"key6\":{\"key7\":\"value7\"}}}}`\n  Result = `{\"key1\":{\"key2\":{}}}`\n  \n  *Remove one of the root elements if there are more than one*\n  A = `{\"key1\":true}`\n  B = `{\"key1\":{\"key2\":\"value2\", \"key3\":\"value3\"}, \"key4\":[\"a\", \"b\", \"c\"]}`\n  Result = `{\"key4\":[\"a\", \"b\", \"c\"]}`\n  \n  *Remove with false should over write*\n  A = `{\"key1\":{\"key2\":false, \"key3\":true}, \"key4\":false}`\n  B = `{\"key1\":{\"key2\":\"value2\", \"key3\":\"value3\"}, \"key4\":[{\"key5\":\"value5\", \"key6\":\"value6\"}, {\"key7\": \"value7\"}]}`\n  Result = `{\"key1\":{\"key2\":false}, \"key4\":false}`\n  \n  *Only objects with id's can be put into lists*\n  A = `{\"key1\":[{\"key2\":true}]}`\n  B = `{\"key1\":[{\"key2\":\"value2\"}, {\"key3\":\"value3\"}]}`\n  Result = `{}`\n  \n  *Elements with {} should do nothing*\n  A = `{\"key1\":{}}`\n  B = `{\"key1\":{\"key2\":\"value2\", \"key3\":\"value3\"}}`\n  Result = `{\"key1\":{\"key2\":\"value2\", \"key3\":\"value3\"}}`\n  \n  *Elements with nil should do nothing*\n  A = `{\"key1\":{\"key2\":null}}`\n  B = `{\"key1\":{\"key2\":\"value2\", \"key3\":\"value3\"}}`\n  Result = `{\"key1\":{\"key2\":\"value2\", \"key3\":\"value3\"}}`\n```\n\n#### Overwrite\n\nOverwrite action will overwrite a key:value with key:new_value or overwrite a list of values with the new list of values. In most cases this is similar to merge action.\n\nIn the following examples A is being patched into B to create the Result:\n\n```\n  *Overwrite whole list*\n  A = `{\"a\":[{\"id\": \"1\"}], \"blah\":1}`\n  B = `{\"a\":[{\"id\": \"2\"}], \"blah\":\"string\"}`\n  Result = `{\"a\":[{\"id\": \"1\"}], \"blah\":1}`\n  \n  *For non-id lists, overwrite will overwrite whole list*\n  A = `{\"a\":[{\"blah\": \"1\"}], \"blah\":1}`\n  B = `{\"a\":[{\"blah\": \"2\"}], \"blah\":\"string\"}`\n  Result = `{\"a\":[{\"blah\": \"1\"}], \"blah\":1}`\n```\n\n# Roadmap\n\n- [x] Train\n  - [x] Add Image with Concepts\n  - [x] Create a Model\n  - [x] Train a Model\n  - [x] Predict with a Model\n- [ ] Search\n  - [ ] Add Image to Search\n  - [ ] Search by Concept\n  - [ ] Reverse Image Search\n- [ ] Applications\n- [ ] Languages\n\n## Public Model IDs\n\n- General - aaa03c23b3724a16a56b629203edc62c\n- Food - bd367be194cf45149e75f01d59f77ba7\n- Travel - eee28c313d69466f836ab83287a54ed9\n- NSFW - e9576d86d2004ed1a38ba0cf39ecb4b1\n- Weddings - c386b7a870114f4a87477c0824499348\n- Colour - eeed0b6733a644cea07cf4c60f87ebb7\n- Face Detection - a403429f2ddf4b49b307e318f00e528b\n- Apparel - e0be3b9d6a454f0493ac3a30784001ff\n- Celebrity - e466caa0619f444ab97497640cefc4dc\n\n## Supported Images\n\n* JPEG\n* PNG\n* TIFF\n* BMP\n\n## Caching\n\nBecause these are expensive calls (time and money) some of them can\nbenefit from being cached. All caching should be off by default and only\nused if explicity set.\n\nThese run through the `darrynten/any-cache` package, and no extra config\nis needed. Please ensure that any features that include caching have it\nbe optional and initially set to `false` to avoid unexpected behaviour.\n\n## Contributing and Testing\n\nThere is currently 100% test coverage in the project, please ensure that\nwhen contributing you update the tests. For more info see CONTRIBUTING.md\n\nWe would love help getting decent documentation going, please get in touch\nif you have any ideas.\n\n## Acknowledgements\n\n* [Dmitry Semenov](https://github.com/mxnr) for jumping on board.\n* [Andrei Voitik](https://github.com/vojtik) for all his great input.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdarrynten%2Fclarifai-php","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdarrynten%2Fclarifai-php","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdarrynten%2Fclarifai-php/lists"}