Skip to content

Commit

Permalink
Move API key in request header and change body to json format (#89)
Browse files Browse the repository at this point in the history
- also add examples for live testing and development scenarios
  • Loading branch information
cougargit committed Feb 5, 2025
1 parent a90d66f commit ee611cc
Show file tree
Hide file tree
Showing 37 changed files with 820 additions and 875 deletions.
14 changes: 14 additions & 0 deletions example/retrieve_usage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

require_once __DIR__ . '/../vendor/autoload.php';

use Scn\DeeplApiConnector\DeeplClientFactory;

$apiKey = 'your-api-key';

$usage = DeeplClientFactory::create($apiKey)
->getUsage();

var_dump($usage);
73 changes: 73 additions & 0 deletions example/translate_file.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php

declare(strict_types=1);

require_once __DIR__ . '/../vendor/autoload.php';

use Scn\DeeplApiConnector\DeeplClientFactory;
use Scn\DeeplApiConnector\Model\FileSubmissionInterface;
use Scn\DeeplApiConnector\Model\FileTranslationConfig;

$apiKey = 'your-api-key';

$deepl = DeeplClientFactory::create($apiKey);

$fileTranslationConfig = new FileTranslationConfig(
'Das ist ein Test',
'testfile.txt',
'EN',
'DE',
);
/**
* 1. We request a new translation with an FileTranslationConfig
*/
/** @var FileSubmissionInterface $fileSubmission */
$fileSubmission = $deepl->translateFile($fileTranslationConfig);

/**
* Result look like a FileSubmission instance
*
* class Scn\DeeplApiConnector\Model\FileSubmission#22 (2) {
* private string $documentId => "<DOCUMENT_ID>"
* private string $documentKey => "<DOCUMENT_KEY>"
* }
*/
var_dump($fileSubmission);

/**
* We can simulate this by using our own instance with valid values:
* $fileSubmission = (new FileSubmission())
* ->setDocumentId('<DOCUMENT_ID>')
* ->setDocumentKey('<DOCUMENT_KEY>');
*/


/** 2. We request in a queue logic the translation status with the Submission instance **/
sleep(15);
$translationStatus = $deepl->getFileTranslationStatus($fileSubmission);

/**
* Result look like a FileTranslationStatus instance
*
* if the 'status' property value is 'done' we can get the fileTranslation
*
* class Scn\DeeplApiConnector\Model\FileTranslationStatus#43 (4) {
* private string $documentId => "<DOCUMENT_ID>"
* private string $status => "translating"
* .....
* }
*/
var_dump($translationStatus);


/** 3. We request in a queue logic the translation status with the Submission instance **/
$response = $deepl->getFileTranslation($fileSubmission);

/**
* Result look like a FileTranslation instance
*
* class Scn\DeeplApiConnector\Model\FileTranslation#26 (1) {
* private string $content => "This is a test"
* }
*/
var_dump($response);
65 changes: 44 additions & 21 deletions src/DeeplClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,30 @@

class DeeplClient implements DeeplClientInterface
{
private const DEEPL_PAID_BASE_URI = 'https://api.deepl.com';
private const DEEPL_FREE_BASE_URI = 'https://api-free.deepl.com';

private string $apiKey;
private DeeplRequestFactoryInterface $deeplRequestFactory;

private ClientInterface $httpClient;

private RequestFactoryInterface $requestFactory;

public function __construct(
string $apiKey,
DeeplRequestFactoryInterface $deeplRequestFactory,
ClientInterface $httpClient,
RequestFactoryInterface $requestFactory
RequestFactoryInterface $requestFactory,
) {
$this->apiKey = $apiKey;
$this->deeplRequestFactory = $deeplRequestFactory;
$this->httpClient = $httpClient;
$this->requestFactory = $requestFactory;
}

/**
* Return Usage of API- Key
* Return Usage of API-Key
* Possible Return:.
*
* Usage
Expand All @@ -62,7 +68,7 @@ public function __construct(
public function getUsage(): ResponseModelInterface
{
return (new Usage())->hydrate(
$this->executeRequest($this->deeplRequestFactory->createDeeplUsageRequestHandler())
$this->executeRequest($this->deeplRequestFactory->createDeeplUsageRequestHandler()),
);
}

Expand All @@ -79,7 +85,7 @@ public function getUsage(): ResponseModelInterface
public function getTranslation(TranslationConfigInterface $translation): ResponseModelInterface
{
return (new Translation())->hydrate($this->executeRequest(
$this->deeplRequestFactory->createDeeplTranslationRequestHandler($translation)
$this->deeplRequestFactory->createDeeplTranslationRequestHandler($translation),
));
}

Expand All @@ -98,38 +104,38 @@ public function translate(string $text, string $target_language): ResponseModelI
public function translateFile(FileTranslationConfigInterface $fileTranslation): ResponseModelInterface
{
return (new FileSubmission())->hydrate($this->executeRequest(
$this->deeplRequestFactory->createDeeplFileSubmissionRequestHandler($fileTranslation)
$this->deeplRequestFactory->createDeeplFileSubmissionRequestHandler($fileTranslation),
));
}

public function translateBatch(array $text, string $targetLanguage): ResponseModelInterface
{
return (new BatchTranslation())->hydrate($this->executeRequest(
$this->deeplRequestFactory->createDeeplBatchTranslationRequestHandler(
new BatchTranslationConfig($text, $targetLanguage)
new BatchTranslationConfig($text, $targetLanguage),
)
));
}

public function getFileTranslationStatus(FileSubmissionInterface $fileSubmission): ResponseModelInterface
{
return (new FileTranslationStatus())->hydrate($this->executeRequest(
$this->deeplRequestFactory->createDeeplFileTranslationStatusRequestHandler($fileSubmission)
$this->deeplRequestFactory->createDeeplFileTranslationStatusRequestHandler($fileSubmission),
));
}

public function getFileTranslation(FileSubmissionInterface $fileSubmission): ResponseModelInterface
{
return (new FileTranslation())->hydrate($this->executeRequest(
$this->deeplRequestFactory->createDeeplFileTranslationRequestHandler($fileSubmission)
$this->deeplRequestFactory->createDeeplFileTranslationRequestHandler($fileSubmission),
));
}

public function getSupportedLanguages(): ResponseModelInterface
{
return (new SupportedLanguages())->hydrate(
$this->executeRequest(
$this->deeplRequestFactory->createDeeplSupportedLanguageRetrievalRequestHandler()
$this->deeplRequestFactory->createDeeplSupportedLanguageRetrievalRequestHandler(),
)
);
}
Expand All @@ -138,7 +144,7 @@ public function getGlossariesSupportedLanguagesPairs(): ResponseModelInterface
{
return (new GlossariesSupportedLanguagesPairs())->hydrate(
$this->executeRequest(
$this->deeplRequestFactory->createDeeplGlossariesSupportedLanguagesPairsRetrievalRequestHandler()
$this->deeplRequestFactory->createDeeplGlossariesSupportedLanguagesPairsRetrievalRequestHandler(),
)
);
}
Expand All @@ -147,7 +153,7 @@ public function getGlossariesList(): ResponseModelInterface
{
return (new Glossaries())->hydrate(
$this->executeRequest(
$this->deeplRequestFactory->createDeeplGlossariesListRetrievalRequestHandler()
$this->deeplRequestFactory->createDeeplGlossariesListRetrievalRequestHandler(),
)
);
}
Expand Down Expand Up @@ -194,20 +200,23 @@ private function executeRequest(DeeplRequestHandlerInterface $requestHandler): s
$request = $this->requestFactory
->createRequest(
$requestHandler->getMethod(),
sprintf('%s%s', $this->deeplRequestFactory->getDeeplBaseUri(), $requestHandler->getPath())
sprintf('%s%s', $this->getDeeplBaseUri(), $requestHandler->getPath()),
)
->withHeader(
'Authorization',
$this->getAuthHeader(),
)
->withHeader(
'Content-Type',
$requestHandler->getContentType()
$requestHandler->getContentType(),
)
->withBody($requestHandler->getBody());

if ($requestHandler->getAuthHeader() !== null) {
$request = $request->withHeader('Authorization', $requestHandler->getAuthHeader());
}
->withBody(
$requestHandler->getBody(),
);

if ($requestHandler->getAcceptHeader() !== null) {
$request = $request->withHeader('Accept', $requestHandler->getAcceptHeader());
$acceptHeader = $requestHandler->getAcceptHeader();
if ($acceptHeader !== null) {
$request = $request->withHeader('Accept', $acceptHeader);
}

try {
Expand All @@ -216,7 +225,7 @@ private function executeRequest(DeeplRequestHandlerInterface $requestHandler): s
throw new RequestException(
$exception->getMessage(),
$exception->getCode(),
$exception
$exception,
);
}

Expand Down Expand Up @@ -253,4 +262,18 @@ private function executeRequest(DeeplRequestHandlerInterface $requestHandler): s
/** @var stdClass $result */
return $result;
}

private function getAuthHeader(): string
{
return sprintf('DeepL-Auth-Key %s', $this->apiKey);
}

private function getDeeplBaseUri(): string
{
if (str_contains($this->apiKey, ':fx')) {
return self::DEEPL_FREE_BASE_URI;
}

return self::DEEPL_PAID_BASE_URI;
}
}
2 changes: 1 addition & 1 deletion src/DeeplClientFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ public static function create(
StreamFactoryInterface $streamFactory = null
): DeeplClientInterface {
return new DeeplClient(
$authKey,
new DeeplRequestFactory(
$authKey,
$streamFactory ?? Psr17FactoryDiscovery::findStreamFactory()
),
$httpClient ?? Psr18ClientDiscovery::find(),
Expand Down
6 changes: 3 additions & 3 deletions src/Handler/AbstractDeeplHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@

abstract class AbstractDeeplHandler implements DeeplRequestHandlerInterface
{
public function getAuthHeader(): ?string
public function getAcceptHeader(): ?string
{
return null;
}

public function getAcceptHeader(): ?string
public function getContentType(): string
{
return null;
return 'application/json';
}
}
51 changes: 19 additions & 32 deletions src/Handler/DeeplBatchTranslationRequestHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,14 @@ final class DeeplBatchTranslationRequestHandler extends AbstractDeeplHandler
private const SEPARATOR = ',';
public const API_ENDPOINT = '/v2/translate';

private string $authKey;

private StreamFactoryInterface $streamFactory;

private BatchTranslationConfigInterface $translation;

public function __construct(
string $authKey,
StreamFactoryInterface $streamFactory,
BatchTranslationConfigInterface $translation
BatchTranslationConfigInterface $translation,
) {
$this->authKey = $authKey;
$this->streamFactory = $streamFactory;
$this->translation = $translation;
}
Expand All @@ -44,37 +40,28 @@ public function getPath(): string

public function getBody(): StreamInterface
{
$query = http_build_query(
array_filter(
[
'target_lang' => $this->translation->getTargetLang(),
'tag_handling' => implode(
self::SEPARATOR,
$this->translation->getTagHandling()
),
'non_splitting_tags' => implode(
self::SEPARATOR,
$this->translation->getNonSplittingTags()
),
'ignore_tags' => implode(self::SEPARATOR, $this->translation->getIgnoreTags()),
'split_sentences' => $this->translation->getSplitSentences(),
'preserve_formatting' => $this->translation->getPreserveFormatting(),
'glossary_id' => $this->translation->getGlossaryId(),
'auth_key' => $this->authKey,
]
)
);
$body = array_filter([
'target_lang' => $this->translation->getTargetLang(),
'tag_handling' => implode(
self::SEPARATOR,
$this->translation->getTagHandling(),
),
'non_splitting_tags' => implode(
self::SEPARATOR,
$this->translation->getNonSplittingTags(),
),
'ignore_tags' => implode(self::SEPARATOR, $this->translation->getIgnoreTags()),
'split_sentences' => $this->translation->getSplitSentences(),
'preserve_formatting' => $this->translation->getPreserveFormatting(),
'glossary_id' => $this->translation->getGlossaryId(),
'text' => [],
]);

// add the text parameters separately as http_build_query would create `text[]` params
foreach ($this->translation->getText() as $text) {
$query .= '&text=' . $text;
$body['text'][] = $text;
}

return $this->streamFactory->createStream($query);
}

public function getContentType(): string
{
return 'application/x-www-form-urlencoded';
return $this->streamFactory->createStream(json_encode($body, JSON_THROW_ON_ERROR));
}
}
Loading

0 comments on commit ee611cc

Please sign in to comment.