Skip to content

Instantly share code, notes, and snippets.

@ksn135
Created November 8, 2019 10:43
Show Gist options
  • Save ksn135/92d7fb2235749e15401bfc2d71155950 to your computer and use it in GitHub Desktop.
Save ksn135/92d7fb2235749e15401bfc2d71155950 to your computer and use it in GitHub Desktop.
Service class to communicate with entera.pro API
<?php
/**
* This file is part of the Comedy Club Production informational system package.
*
* (c) Serg N. Kalachev <serg@kalachev.ru>, Telegram @ksn135
*
* Copyright 2019 Serg N. Kalachev <serg@kalachev.ru>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Ksn135\CompanyBundle\Services;
use GuzzleHttp\Client;
use Psr\Http\Message\ResponseInterface;
/**
* EnteraProService
*
* Service class to communicate with entera.pro API
*
* Usage example:
* try {
* $api = new EnteraProService("ivanov@mail.com", "P@ssw0rd");
* $recognitionTaskId = $api->createRecognitionTask($filepath, $api->getDefaultSpaceId());
* ...
* if ('RECOGNIZED' === $api->getRecognitionTaskState($recognitionTaskId)) {
* $docIds = $api->getRecognitionTaskDocumentIds($recognitionTaskId);
* foreach($docIds as $docId) {
* $document = $api->getDocument($docId);
* ...
* }
* }
* }
* catch(\Exception $e) {
* ...
* }
*
* @version 0.1
* @author Serg N. Kalachev <serg@kalachev.ru>
* @link https://app.entera.pro/api/specification API docs
* @license https://tldrlegal.com/license/mit-license MIT
*/
class EnteraProService extends Client
{
/** Constants */
const BASE_URI = 'https://app.entera.pro/api/v1/';
const AUTH_URI = 'https://id.entera.pro/api/v1/login';
const MIN_BALANCE = 10;
/** @var string default space id */
private $defaultSpaceId = null;
/**
* Constructor
* @param string $login
* @param string $password
* @param integer $minBalance check for minimum balance before continue
*/
public function __construct($login, $password, $minBalance = self::MIN_BALANCE)
{
parent::__construct([
'cookies' => true,
'base_uri' => self::BASE_URI,
'timeout' => 2.0,
]);
// get coookie ENTERA_JWT and put it in jar
$this->checkResponse($this->post(self::AUTH_URI, [
'json' => [
"login" => $login,
"password" => $password
]
]));
// get user info and set default spaceId
$answer = $this->checkResponse($this->get('currentUser'));
$this->defaultSpaceId = $answer['user']['spaces'][0]['id'] ?? null;
if (($answer['user']['spaces'][0]['balance'] ?? 0) < $minBalance) {
throw new \LogicException("Not enough balance (< $minBalance) to continue");
}
}
/**
* Check response for validity
* @param \Psr\Http\Message\ResponseInterface $response
* @throws \LogicException if smth wrong
* @return array json response
*/
public function checkResponse(ResponseInterface $response) {
if ($response->getStatusCode() != 200) {
throw new \LogicException('Wrong response status code, must be 200');
}
$answer = json_decode((string)$response->getBody(), true);
if (!$answer) {
throw new \LogicException('Can not decode response body, must be json string');
}
if (!($answer['result'] ?? false)) {
throw new \LogicException('Wrong response body result attribute, must be true');
}
return $answer;
}
/**
* Create new recognition task
* @param string $filepath existing file to upload and recognize on server
* @param string $spaceId optional, by default used first space in user profile
* @throws \LogicException if smth wrong
* @return string guid of task
*/
public function createRecognitionTask($filepath, $spaceId = null)
{
if (!file_exists($filepath) || !is_readable($filepath)) {
throw new \LogicException("Can't open file '$filepath'");
}
if (!$spaceId) $spaceId = $this->defaultSpaceId;
if (!$spaceId) {
throw new \LogicException("You must specify spaceId");
}
$answer = $this->checkResponse($this->post('recognitionTasks', [
'query' => ['spaceId' => $spaceId ?: $this->defaultSpaceId],
'multipart' => [
[
'name' => 'file',
'contents' => fopen($filepath, 'r')
],
]
]));
return $answer['recognitionTask']['id'] ?? null;
}
/**
* Get recognition task itself by guid from server
* @param string $recognitionTaskId guid of task
* @throws \LogicException if smth wrong
* @return array task
*/
public function getRecognitionTask($recognitionTaskId)
{
return $this->checkResponse($this->get("recognitionTasks/$recognitionTaskId"));
}
/**
* Get recognition task state by guid from server
* @param string $recognitionTaskId guid of task
* @throws \LogicException if smth wrong
* @return string state
*/
public function getRecognitionTaskState($recognitionTaskId)
{
$answer = $this->getRecognitionTask($recognitionTaskId);
return $answer['recognitionTask']['state'] ?? 'ERROR';
}
/**
* Get recognition task itself by guid from server
* @param string $recognitionTaskId guid of task
* @throws \LogicException if smth wrong
* @return array task
*/
public function getRecognitionTaskDocuments($recognitionTaskId)
{
$answer = $this->getRecognitionTask($recognitionTaskId);
if (($answer['recognitionTask']['state'] ?? 'ERROR') != 'RECOGNIZED') return [];
return $answer['recognitionTask']['documents'] ?? [];
}
/**
* Get recognition task recognized documents ids
* @param string $recognitionTaskId guid of task
* @throws \LogicException if smth wrong
* @return array list of document ids
*/
public function getRecognitionTaskDocumentIds($recognitionTaskId)
{
$answer = $this->getRecognitionTask($recognitionTaskId);
if (($answer['recognitionTask']['state'] ?? 'ERROR') != 'RECOGNIZED') return [];
return array_filter(array_map(
function($data) { return $data['id'] ?? null; },
$answer['recognitionTask']['documents'] ?? []
));
}
/**
* Get recognized document by guid
* @param string $documentId guid of document
* @throws \LogicException if smth wrong
* @return array document
*/
public function getDocument($documentId)
{
return $this->checkResponse($this->get("documents/$documentId"));
}
/**
* Get default space Id
* @return string
*/
public function getDefaultSpaceId()
{
return $this->defaultSpaceId;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment