Giter Club home page Giter Club logo

api-php-client's People

Contributors

ahocquard avatar akeneo-ci avatar clementgautier avatar damien-carcel avatar dependabot[bot] avatar docteurklein avatar doodoune avatar fitn avatar gwendalaubert avatar happymintyo avatar jeremybeaucousinakeneo avatar jorenvh avatar juliensnz avatar laurentpetard avatar levflavien avatar ludovictourman avatar mmetayer avatar momoss avatar mr-prud avatar nidup avatar nyholm avatar oallain avatar pchasle avatar peter279k avatar samirboulil avatar samokiss avatar tfehringer avatar tomglvng avatar tristanhofman avatar tseho avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

api-php-client's Issues

Bad Request - Unvalid JSON format

Hello,

I am currently facing an issue using the PHP Client.
string(121) "Search query parameter should be valid JSON. (see https://api.akeneo.com/php-client/exception.html#bad-request-exception)"
The involved JSON output from the Client is :
{"enabled":[{"operator":"=","value":true}],"completeness":[{"operator":"=","value":100,"scope":"site_web","locale":"fr_FR"}],"rang":[{"operator":"=","value":3,"locale":"fr_FR"}]}

This is the version I am using :
"akeneo/api-php-client": "^6.0",
PIM Version : 3.2.55

I saw in the docs that there could be some incompatibilties so I downgraded the client to 5.0 version.
I'm still facing the same issue.

The exception is caught when I run this line :
$product = $this->client->getProductApi()->all(4, ['search' => $searchFilters, 'scope' => 'site_web']);

Do you have any idea on this one ?
Regards,

HTTPs and auto-generated certificate

When using the cli with a PIM installed with an auto signed certificate, curl fails (needs to use an option to enable it).

"cURL error 51: SSL: no alternative certificate subject name matches target host name 'domainname.com  "

seeing the response of any upsertList() call

I'm using upsertList() in a number of areas (ProductModel, Category, AttributeOptions etc) and when I run it, I'm not getting a response. How would I know what item has been created/updated successfully and which have failed? Reading the API documentation suggests you should...

For example: https://api.akeneo.com/php-client/resources.html#upsert-a-list-of-product-models

foreach ($responseLines as $line) {
        echo $line['line'];
        echo $line['identifier'];
        echo $line['status_code'];
        if (isset($line['message'])) {
            echo $line['message'];
        }
    }

When I try this, there's nothing showing. When I print_r($responseLines) there's only the following:

Akeneo\Pim\ApiClient\Stream\UpsertResourceListResponse Object
(
    [bodyStream:protected] => GuzzleHttp\Psr7\Stream Object
        (
            [stream:GuzzleHttp\Psr7\Stream:private] => Resource id #131
            [size:GuzzleHttp\Psr7\Stream:private] => 
            [seekable:GuzzleHttp\Psr7\Stream:private] => 1
            [readable:GuzzleHttp\Psr7\Stream:private] => 1
            [writable:GuzzleHttp\Psr7\Stream:private] => 1
            [uri:GuzzleHttp\Psr7\Stream:private] => php://temp
            [customMetadata:GuzzleHttp\Psr7\Stream:private] => Array
                (
                )
        )

    [streamReader:protected] => Akeneo\Pim\ApiClient\Stream\LineStreamReader Object
        (
        )

    [lineNumber:protected] => 1
    [line:protected] => 
)

PHP client in docker

Hi, I have a question regarding running PHP-client inside docker. I a student who is fairly new to Docker and Akeneo so I am trying to figure out. My goal is to insert data in a database to PIM.

I downloaded PIM with Docker. And I was planning to have PHP-client inside PIM docker (specifically using fpm bash in the PIM docker).

So my question is if it is possible to have PHP-client run like this and insert data to PIM? Or is there a better way to achieve what I am trying to do (insert data from DB to PIM with Docker)?

Also, I am not sure where exactly I should put the PHP script and how to run it.

I would really appreciate your help!! Thank you in advance :)

Getting resources with a cursor results in a Unauthorized 401 error after the first pageSize has been reached

Hi there

PIM Version: 5.0.10

When using the api client as follows:

            $apiClient = $this->getApiClient($tenantMachineName);
            $attributes = $apiClient->getAttributeApi()->all(50);
            foreach ($attributes as $index => $attribute) {
                $data[$attribute['code']] = $attribute;
            }

after the first pageSize the following error occurs: Unauthorized (see https://api.akeneo.com/php-client/exception.html#unauthorized-exception)

the approach from above has been working since v1.7 (I have another installation running on v1.7 and the code runs flawlessly).

any help very much appreciated

BR wucherpfennig

How to autoload inside a Symphony project ?

Hello,

I'm trying to install api-php-client inside a Symfony 5 project an use in a Controller.

After intallation with :

composer require akeneo/api-php-client php-http/guzzle6-adapter:^2.0 http-interop/http-factory-guzzle:^1.0

I tried :

//... Other imports

use Akeneo\Pim\ApiClient\AkeneoPimClientBuilder;

class PimController extends AbstractController
{
  public function __construct()
  {
      $clientBuilder = new AkeneoPimClientBuilder(self::API_BASE_URL);
      // $this->apiClient = $clientBuilder->buildAuthenticatedByPassword(self::API_CLIENT, self::API_SECRET, self::API_USERNAME, self::API_PASSWORD);
  }
}

I Gote error:

Attempted to load class "AkeneoPimClientBuilder" from namespace "Akeneo\Pim\ApiClient".
Did you forget a "use" statement for another namespace?

Any suggestion ?

Thanks for your help !

[2.0.0] Create media file API returning 400 Bad Request

akeneo/api-php-client: v2.0.0
akeneo/pim-community-dev: v2.1.3
php-http/guzzle6-adapter: v1.1.1
guzzlehttp/guzzle: v6.3.3
php: v7.1.13

Hi,
When I run the following API call (POST /api/rest/v1/media-files) it returns 400 error (Bad Request)

$this->client->getProductMediaFileApi()->create(FULL_FILE_PATH, [
                'type' => 'product_model',
                'code' => MODEL_CODE,
                'attribute' => IMAGE_ATTRIBUTE_NAME,
                'scope' => null,
                'locale' => null,
            ]);

However, if I manually call the endpoint via a CURL request it works and the image can be viewed on the model from the frontend:

curl -X POST http://IP_ADDRESS/api/rest/v1/media-files \
    -H "Content-Type: multipart/form-data" \
    -H "Authorization: Bearer ACCESS_TOKEN" \
    -F product_model='{"code":MODEL_CODE, "attribute":IMAGE_ATTRIBUTE_NAME, "scope":null, "locale":null}' \
    -F file=@FULL_FILE_PATH

The API Client calls other endpoints without a problem such as:
POST /api/rest/v1/product

Not able to create product.

I am trying to create a product in akeneo using the below params.

$this->client->getProductApi()->create( 'wk_24_mb01', [ 'enabled' => true, 'family' => 'bag', 'categories' => [], 'groups' => [], 'parent'=> null, 'values' => [ 'product_name' => [ [ 'data' => 'top', 'locale' => 'en_US', 'scope' => null, ] ], 'price' => [ [ 'data' => [ [ 'amount' => '15.5', 'currency' => 'EUR', ], [ 'amount' => '15', 'currency' => 'USD', ], ], 'locale' => null, 'scope' => null, ], ] ] ] );

It returning validation failed error.
Please suggest me.

Thanks

Issue with "with_count" in conjunction with ListableResourceInterface

Hey everybody,

I'm trying to get all categories and include their count. Unfortunately, that's not possible right now because the CategoryApi does not support passing the $withCount variable in all(). I understand that's an issue there because all() is part of the ListableResourceInterface so you cannot adjust that without breaking BC.

However, why is it not allowed to pass ['with_count' => true]? It should work pretty straight forward by doing the following:

    /**
     * {@inheritdoc}
     */
    public function all($pageSize = 10, array $queryParameters = [])
    {
+        $withCount = false;
+
+        if (array_key_exists('with_count', $queryParameters)) {
+            $withCount = (bool) $queryParameters['with_count'];
+            unset($queryParameters['with_count']);
+        }

+        $firstPage = $this->listPerPage($pageSize, $withCount, $queryParameters);
-        $firstPage = $this->listPerPage($pageSize, false, $queryParameters);

        return $this->cursorFactory->createCursor($pageSize, $firstPage);
    }

Filters doesn't work for categories.

I have the 4.0 version installed (CE) and if I try to filter categories by any rules it just ignores the ?search query param!

For products it works fine, but not for categories.

Unable to get Token value

Hi,
I'm using Akeneo 2.0.16. I have installed Api PHP Client for community edition, created a sample bundle and added the below code in the controller. But I didn't get even the value for the token. Please assist me to resolve this issue.

<?php
namespace Sample\Bundle\ApiBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class DefaultController extends Controller
{
   public function indexAction()
   {
	
    $clientBuilder = new \Akeneo\Pim\ApiClient\AkeneoPimClientBuilder('http://127.0.0.1:8081/');
	$clientId = '1_32ch31okfu0w48gg0w0ck8ccooo8cswck0wsw44sc444kgc4cc';
	$secretKey = '8klh9ctn4s0s40g4sccgw4sowco0gws0w48cowcwog0wgw0w8';
    $client = $clientBuilder->buildAuthenticatedByPassword($clientId, $secretKey, 'admin', 'admin');
    echo " ***". $token = $client->getToken();
    $client->getRefreshToken();
    $category = $client->CategoryApi()->get('master');
    echo "<pre>"; print_r($category); // display "top"    
   }
}

IN operator not working for assets

While developing an importer for the assets I've bumped into a rather strange issue. The docs (GET THE LIST OF THE ASSETS OF A GIVEN ASSET FAMILY ) state that the endpoint supports filtering based on an asset code. But for some reason the stated syntax doesn't work with the API client.

For instance, the following url will always return an exception.
https://[instance-name].cloud.akeneo.com/api/rest/v1/asset-families/[asset-family-code]/assets?search=%7B%22code%22%3A%5B%7B%22operator%22%3A%22IN%22%2C%22value%22%3A%5B%221200x1200%22%2C%22vooraanzicht_2%22%5D%7D%5D%7D

{"code":422,"message":"The search filters have an invalid format.","errors":[{"property":"","message":"The property code is not defined and the definition does not allow additional properties"}]}

If I urldecode this uri it has the exact same syntax as the docs (here) show:
https://[instance-name].cloud.akeneo.com/api/rest/v1/asset-families/[asset-family-code]/assets?search={"code":[{"operator":"IN","value":["1200x1200","vooraanzicht_2"]}]}

Seems like something is not quite working, or I'm not understanding the docs.

Connecting to http://localhost:8080/ fails

I am trying to run the PHP-client inside the fpm container, but I cannot get it to connect to Akeneo PIM running on localhost:8080. When I test the connection on the host machine, the connection is made successfully. When I try to create a dummy product with $client->getProductApi()->create('top1', ['enabled' => true]);, I get the following error message:

PHP Fatal error:  Uncaught GuzzleHttp\Exception\ConnectException: cURL error 7: Failed to connect to localhost port 8080: Connection refused (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) in /srv/pim/client/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php:200
Stack trace:
#0 /srv/pim/client/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php(155): GuzzleHttp\Handler\CurlFactory::createRejection(Object(GuzzleHttp\Handler\EasyHandle), Array)
#1 /srv/pim/client/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php(105): GuzzleHttp\Handler\CurlFactory::finishError(Object(GuzzleHttp\Handler\CurlMultiHandler), Object(GuzzleHttp\Handler\EasyHandle), Object(GuzzleHttp\Handler\CurlFactory))
#2 /srv/pim/client/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(202): GuzzleHttp\Handler\CurlFactory::finish(Object(GuzzleHttp\Handler\CurlMultiHandler), Object(GuzzleHttp\Handler\EasyHandle), Object(GuzzleHttp\Handler\CurlFactory))
#3 /srv/pim/client/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(131): GuzzleHttp\Handler\CurlMultiHandler->processMessages()
#4 /srv/pim/client/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(146): GuzzleHttp\Handler\CurlMultiHandler->tick()
#5 /srv/pim/client/vendor/guzzlehttp/promises/src/Promise.php(246): GuzzleHttp\Handler\CurlMultiHandler->execute(true)
#6 /srv/pim/client/vendor/guzzlehttp/promises/src/Promise.php(223): GuzzleHttp\Promise\Promise->invokeWaitFn()
#7 /srv/pim/client/vendor/guzzlehttp/promises/src/Promise.php(267): GuzzleHttp\Promise\Promise->waitIfPending()
#8 /srv/pim/client/vendor/guzzlehttp/promises/src/Promise.php(225): GuzzleHttp\Promise\Promise->invokeWaitList()
#9 /srv/pim/client/vendor/guzzlehttp/promises/src/Promise.php(62): GuzzleHttp\Promise\Promise->waitIfPending()
#10 /srv/pim/client/vendor/php-http/guzzle6-adapter/src/Promise.php(96): GuzzleHttp\Promise\Promise->wait(false)
#11 /srv/pim/client/vendor/php-http/guzzle6-adapter/src/Client.php(52): Http\Adapter\Guzzle6\Promise->wait()
#12 /srv/pim/client/vendor/akeneo/api-php-client/src/Client/HttpClient.php(61): Http\Adapter\Guzzle6\Client->sendRequest(Object(GuzzleHttp\Psr7\Request))
#13 /srv/pim/client/vendor/akeneo/api-php-client/src/Api/AuthenticationApi.php(80): Akeneo\Pim\ApiClient\Client\HttpClient->sendRequest('POST', 'http://localhos...', Array, '{"grant_type":"...')
#14 /srv/pim/client/vendor/akeneo/api-php-client/src/Api/AuthenticationApi.php(46): Akeneo\Pim\ApiClient\Api\AuthenticationApi->authenticate('1_1wnzk19zm0n44...', '2zgx7mkxkq80o8c...', Array)
#15 /srv/pim/client/vendor/akeneo/api-php-client/src/Client/AuthenticatedHttpClient.php(53): Akeneo\Pim\ApiClient\Api\AuthenticationApi->authenticateByPassword('1_1wnzk19zm0n44...', '2zgx7mkxkq80o8c...', 'scraper_3968', 'c76a510ec')
#16 /srv/pim/client/vendor/akeneo/api-php-client/src/Client/ResourceClient.php(100): Akeneo\Pim\ApiClient\Client\AuthenticatedHttpClient->sendRequest('POST', 'http://localhos...', Array, '{"enabled":true...')
#17 /srv/pim/client/vendor/akeneo/api-php-client/src/Api/ProductApi.php(89): Akeneo\Pim\ApiClient\Client\ResourceClient->createResource('http://localhos...', Array, Array)
#18 /srv/pim/client/importProducts.php(120): Akeneo\Pim\ApiClient\Api\ProductApi->create('top1', Array)
#19 /srv/pim/client/importProducts.php(125): execute()
#20 {main}

Next Http\Client\Exception\NetworkException: cURL error 7: Failed to connect to localhost port 8080: Connection refused (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) in /srv/pim/client/vendor/php-http/guzzle6-adapter/src/Promise.php:122
Stack trace:
#0 /srv/pim/client/vendor/php-http/guzzle6-adapter/src/Promise.php(64): Http\Adapter\Guzzle6\Promise->handleException(Object(GuzzleHttp\Exception\ConnectException), Object(GuzzleHttp\Psr7\Request))
#1 /srv/pim/client/vendor/guzzlehttp/promises/src/Promise.php(203): Http\Adapter\Guzzle6\Promise->Http\Adapter\Guzzle6\{closure}(Object(GuzzleHttp\Exception\ConnectException))
#2 /srv/pim/client/vendor/guzzlehttp/promises/src/Promise.php(174): GuzzleHttp\Promise\Promise::callHandler(2, Object(GuzzleHttp\Exception\ConnectException), Array)
#3 /srv/pim/client/vendor/guzzlehttp/promises/src/RejectedPromise.php(40): GuzzleHttp\Promise\Promise::GuzzleHttp\Promise\{closure}(Object(GuzzleHttp\Exception\ConnectException))
#4 /srv/pim/client/vendor/guzzlehttp/promises/src/TaskQueue.php(47): GuzzleHttp\Promise\RejectedPromise::GuzzleHttp\Promise\{closure}()
#5 /srv/pim/client/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(119): GuzzleHttp\Promise\TaskQueue->run()
#6 /srv/pim/client/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(146): GuzzleHttp\Handler\CurlMultiHandler->tick()
#7 /srv/pim/client/vendor/guzzlehttp/promises/src/Promise.php(246): GuzzleHttp\Handler\CurlMultiHandler->execute(true)
#8 /srv/pim/client/vendor/guzzlehttp/promises/src/Promise.php(223): GuzzleHttp\Promise\Promise->invokeWaitFn()
#9 /srv/pim/client/vendor/guzzlehttp/promises/src/Promise.php(267): GuzzleHttp\Promise\Promise->waitIfPending()
#10 /srv/pim/client/vendor/guzzlehttp/promises/src/Promise.php(225): GuzzleHttp\Promise\Promise->invokeWaitList()
#11 /srv/pim/client/vendor/guzzlehttp/promises/src/Promise.php(62): GuzzleHttp\Promise\Promise->waitIfPending()
#12 /srv/pim/client/vendor/php-http/guzzle6-adapter/src/Promise.php(96): GuzzleHttp\Promise\Promise->wait(false)
#13 /srv/pim/client/vendor/php-http/guzzle6-adapter/src/Client.php(52): Http\Adapter\Guzzle6\Promise->wait()
#14 /srv/pim/client/vendor/akeneo/api-php-client/src/Client/HttpClient.php(61): Http\Adapter\Guzzle6\Client->sendRequest(Object(GuzzleHttp\Psr7\Request))
#15 /srv/pim/client/vendor/akeneo/api-php-client/src/Api/AuthenticationApi.php(80): Akeneo\Pim\ApiClient\Client\HttpClient->sendRequest('POST', 'http://localhos...', Array, '{"grant_type":"...')
#16 /srv/pim/client/vendor/akeneo/api-php-client/src/Api/AuthenticationApi.php(46): Akeneo\Pim\ApiClient\Api\AuthenticationApi->authenticate('1_1wnzk19zm0n44...', '2zgx7mkxkq80o8c...', Array)
#17 /srv/pim/client/vendor/akeneo/api-php-client/src/Client/AuthenticatedHttpClient.php(53): Akeneo\Pim\ApiClient\Api\AuthenticationApi->authenticateByPassword('1_1wnzk19zm0n44...', '2zgx7mkxkq80o8c...', 'scraper_3968', 'c76a510ec')
#18 /srv/pim/client/vendor/akeneo/api-php-client/src/Client/ResourceClient.php(100): Akeneo\Pim\ApiClient\Client\AuthenticatedHttpClient->sendRequest('POST', 'http://localhos...', Array, '{"enabled":true...')
#19 /srv/pim/client/vendor/akeneo/api-php-client/src/Api/ProductApi.php(89): Akeneo\Pim\ApiClient\Client\ResourceClient->createResource('http://localhos...', Array, Array)
#20 /srv/pim/client/importProducts.php(120): Akeneo\Pim\ApiClient\Api\ProductApi->create('top1', Array)
#21 /srv/pim/client/importProducts.php(125): execute()
#22 {main}
  thrown in /srv/pim/client/vendor/php-http/guzzle6-adapter/src/Promise.php on line 122

upsertList not working on Windows

upsertList uses LineStreamReader.php for response processing. Then LineStreamReader uses php constant PHP_EOL in order to detect multiple lines.
However, on Windows PHP_EOL is equal \r\n which breaks LineStreamReader.

Above issue occurs with configuration client - Windows <--> server - Linux.

Sorting!?

Why is it possible to do sorting with the PQB in Akeneo but the PHP client cannot do sorting on a search?

There is also absolutely no way to sort results as part of a search via the REST API.

Is there some reasoning behind this or is it a planned feature? This is kind of blocking us at the minute due to a feature required and the only way I can think of around it is to stop using the API or API client directly and do an import of all the 55k+ skus into the web servers MySQL database, which I would like to avoid as using Akeneo as the product API is currently working perfectly apart from this one feature.

I can do sorting on the front end, but then the results will change for every new page that is loaded (not ideal UX), and if I sort each page on the server side after searching then each new page will only be sorted individually. I am looking to sort the actual search results so the first page begins in the right order and subsequent page searches are starting at the right point (ideal UX).

Asset API

Are there any plans to support the Asset API through the client?

Can't filter product values on product/product models

I'd like to filter product values like explained in the API doc https://api.akeneo.com/documentation/filter.html#via-attributes.

Something like /api/rest/v1/products?attributes=id_sml

But when using the API client, it does not work :

$productModels = $this->apiClientFactory->getClient()->getProductModelApi()->all(
    50,
    [
        'search' => ['updated' => [['operator' => '>', 'value' => $updatedAt->format('Y-m-d H:i:s')]]],
        'attributes' => ['id_sml']
    ]
);

A ServerErrorHttpException is launched, with the message Internal Server Error (see https://api.akeneo.com/php-client/exception.html#server-exception).

I guess it's not supported by the API client. Which is a bit sad. Is it planned on the roadmap?

Or maybe I'm doing something wrong.

Filter products for a single vendor

Hello everyone,

maybe I don't understand the Akeneo API in general, but for my understanding it should be possible to get all products from a single vendor without getting all stored products and filtering afterwards (this takes a really long time). Like this:

$products = $client->getProductApi()->all();
foreach($products as $product) {
  // filter here
}

I tried to go the filter route like this:

$searchBuilder = new SearchBuilder();
$searchBuilder
    ->addFilter('vendor', '=', "[email protected]");
$searchFilters = $searchBuilder->getFilters();

$products = $client->getProductApi()->all(10, ['search' => $searchFilters]);

This does not work either, because for some reason Filter on property "vendor" is not supported or does not support operator "=".

Is there a way to do this, or am I not understanding the purpose of the Akeneo API in general?

Thanks in advance!

Redirection makes the cli fails

In case the PIM server answers a 302 (http to https for instance), the cli fails with the following exception (passing null in the paginator because the cli tries to json_decode an invalid content).

We should raise a proper exception when a 302 is encountered.

PHP Fatal error:  Uncaught TypeError: Argument 1 passed to Akeneo\Pim\Pagination\PageFactory::createPage() must be of the type array, null given, called in /opt/vendor/akeneo/api-php-client/src/Pagination/Page.php on line 141 and defined in /opt/vendor/akeneo/api-php-client/src/Pagination/PageFactory.php:30
Stack trace:
#0 /opt/vendor/akeneo/api-php-client/src/Pagination/Page.php(141): Akeneo\Pim\Pagination\PageFactory->createPage(NULL)
#1 /opt/vendor/akeneo/api-php-client/src/Pagination/Page.php(78): Akeneo\Pim\Pagination\Page->getPage('http://demo-saa...')
#2 /opt/vendor/akeneo/api-php-client/src/Pagination/ResourceCursor.php(60): Akeneo\Pim\Pagination\Page->getNextPage()
#3 /opt/src/Akeneo/ApiSandbox/Infrastructure/WebApi/LocaleRepositoryInitializer.php(21): Akeneo\Pim\Pagination\ResourceCursor->next()
#4 /opt/src/Akeneo/ApiSandbox/Infrastructure/Cli/GenerateProductsCommand.php(136): Akeneo\ApiSandbox\Infrastructure\WebApi\LocaleRepositoryInitializer->initialize(Object(Akeneo\ApiSandbox\Infrastructure\Database\InMemoryLocal in /opt/vendor/akeneo/api-php-client/src/Pagination/PageFactory.php on line 30

Fatal error: Uncaught TypeError: Argument 1 passed to Akeneo\Pim\Pagination\PageFactory::createPage() must be of the type array, null given, called in /opt/vendor/akeneo/api-php-client/src/Pagination/Page.php on line 141 and defined in /opt/vendor/akeneo/api-php-client/src/Pagination/PageFactory.php on line 30

TypeError: Argument 1 passed to Akeneo\Pim\Pagination\PageFactory::createPage() must be of the type array, null given, called in /opt/vendor/akeneo/api-php-client/src/Pagination/Page.php on line 141 in /opt/vendor/akeneo/api-php-client/src/Pagination/PageFactory.php on line 30

Filters doesn't work for categories

#251

->addFilter('is_root', '=', 'true')
->addFilter('parent', '=', 'master')

SearchBuilder is not work for categories

$searchBuilder = new SearchBuilder();
$searchBuilder->addFilter('is_root', '=', 'true');
$searchFilters = $searchBuilder->getFilters();

$list = $client->getCategoryApi()->all(100, ['search' => $searchFilters]);

error:

In HttpExceptionHandler.php line 92:

An exception occurred while executing ' WITH translation as (
SELECT category.code, JSON_OBJECTAGG(translation.locale, translation.label) as translations
FROM pim_catalog_category category
JOIN pim_catalog_category_translation translation ON translation.foreign_key = category.id
WHERE category.code IN (?)
GROUP BY category.code
)
SELECT
category.id,
category.code,
category.parent_id,
category.root as root_id,
category.updated,
translation.translations,
IF(?, category.value_collection, '') as value_collection
FROM
pim_catalog_category category
LEFT JOIN translation ON translation.code = category.code
WHERE category.code IN (?)
GROUP BY category.code' with params [[{"operator":"=","value":true}], false, [{"operator":"=","value":true}]]:

Warning: Array to string conversion (see https://api.akeneo.com/php-client/exception.html#server-exception)

Ability to extend PHP API Client

Hello Akeneo Team,

We created a custom entry point on Akeneo 2.0. Today, I would like to use php api client to work with this entry point but it seems that the client is "closed" to Akeneo services.

It could be cool to add the ability to extend the API with something like AkeneoPimClientBuilder::addEntryPoint(....) ? Or with some configuration files...

Best Regards,

Dam'.

HTTPS for next page

Hi there,

I'm connecting trough HTTPS but Akeneo always returns url's with http for example for the next page of results. Any idae how to handle this?

Best Regards

Add [\ReturnTypeWillChange] attribute to current and key methods in ResourceCursor class

If building something with the PHP API Client with the latest version of PHP, you will likely get the following errors:

Deprecated: Return type of Akeneo\Pim\ApiClient\Pagination\ResourceCursor::key() should either be compatible with Iterator::key(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /Users/joshuaguinn/Akeneo/Custom_Development_and_POCs/VPL - Classification by UNSPSC/vendor/akeneo/api-php-client/src/Pagination/ResourceCursor.php on line 56
joshuaguinn@Joshuas-Macbook-Pro VPL - Classification by UNSPSC % php application.php
PHP Deprecated:  Return type of Akeneo\Pim\ApiClient\Pagination\ResourceCursor::current() should either be compatible with Iterator::current(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /Users/joshuaguinn/Akeneo/Custom_Development_and_POCs/VPL - Classification by UNSPSC/vendor/akeneo/api-php-client/src/Pagination/ResourceCursor.php on line 32

Deprecated: Return type of Akeneo\Pim\ApiClient\Pagination\ResourceCursor::current() should either be compatible with Iterator::current(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /Users/joshuaguinn/Akeneo/Custom_Development_and_POCs/VPL - Classification by UNSPSC/vendor/akeneo/api-php-client/src/Pagination/ResourceCursor.php on line 32
PHP Deprecated:  Return type of Akeneo\Pim\ApiClient\Pagination\ResourceCursor::key() should either be compatible with Iterator::key(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /Users/joshuaguinn/Akeneo/Custom_Development_and_POCs/VPL - Classification by UNSPSC/vendor/akeneo/api-php-client/src/Pagination/ResourceCursor.php on line 56

While it doesn’t break anything, it is not fun to look at. The fix is as easy as going to the offending methods and add a #[\ReturnTypeWillChange] PHP 8 attribute at the top of the method like so:

    #[\ReturnTypeWillChange]
    public function current()
    {
        return $this->currentPage->getItems()[$this->currentIndex];
    }
    #[\ReturnTypeWillChange]
    public function key()
    {
        return $this->totalIndex;
    }

Doing this on the key and current methods in the ResourceCursor class cleared everything up for me, but it is likely the same for some of the other iterators.

Version information:

  • akeneo/api-php-client: latest stable version (pulled yesterday)
  • PHP: version 8.1

Screen Shot 2022-04-14 at 4 34 05 PM

ProductAPI fails with SKUs containing '/'

When trying to find a product using the Akeneo API Client (ProductAPI) it cannot handle product SKUs containing '/'. It confuses the slashes for part of the route

$client->getProductApi()->get('SKU/WITH/SLASHES');

request.ERROR: Uncaught PHP Exception Symfony\Component\HttpKernel\Exception\NotFoundHttpException: "No route found for "GET /api/rest/v1/products/SKU/WITH/SLASHES""

HTTP issue on Next page

While working on the imports, we noticed that the Categories, Options and Attribute imports did not import any data and stopped abruptly with a message "Found". On narrowing down the issue, we found that the "Found" message was actually an exception with HTTP code 302. The response body for HTTP code 302 was "Found" and hence this was printed on the import screen.
The “Found” exception that was thrown for categories, attribute and options import was caused while accessing data from the ‘Next’ page. The response received was 302 Found and it was considered as an Exception in PIM as RedirectionHttpException. We suspect the reason to be the HTTP client tries to redirect the http URL to https URL. The issue did not happen while fetching the first page content and it fetched up to the maximum limit 100 because the request for the first page had a https URL.

Please find below a screenshot of the request and response that we got for Page 2.
image

image

Below is the request and response that we got for Page 1:
image

image

We had fixed the issue by changing the url from http to https on \app\code\Akeneo\Pim\src\Pagination\Page.php : Line no: 134
image

After adding the above fix, we were able to retrieve data from all pages (records > 100 are split into pages) from the imports.

Can't install via Composer (php-http/guzzle6-adapter upgraded)

Hi,

currently you require php-http/httplug in your pakage and suggest php-http/guzzle6-adapter. This wont work anymore because they upgraded to 2.0.0. Please suggest php-http/guzzle6-adapter ^1.0.0 instead!

thanks :)


why it won't work:
php-http/guzzle6-adapter itself requires php-http/httplug. Since guzzle6-adapter@de1ebb7 they require version ^2.0 which creates a conflict with your version ^1.0 requirement.

Authentication requests are always executed

Hey everybody,

We're using the library to request data using Guzzle.
The issue we're having is that the Akeneo SDK is always executing authentication requests even though a request is actually already in the cache.
Here's what we're using:

$stack = HandlerStack::create();
$stack->push(new CacheMiddleware(new GreedyCacheStrategy(....)));

$httpClient = Client::createWithConfig(array_merge(['handler' => $stack], $config));

$builder = new AkeneoPimClientBuilder($baseUri);
$builder->setHttpClient($httpClient);
$api = $builder->buildAuthenticatedByPassword(...);

So in other words, because Akeneo does not send any http caching headers we do use the GreedyCacheStrategy to force greedy caching. We then set this client using the setHttpClient() method. However, the ->buildAuthenticatedByPassword() wraps this client and always executes an authentication request even though the inner client actually has a middleware that knows the response already from the cache. Thus we're executing a number of nonsense authentication requests all the time.

Is there any recommendation on how to implement caching on the SDK itself?

Error while updating API PHP Client

Hello,

I'm trying to upgrade the PHP client from 1.0 to 4.0. I've updated the composer.json this way :

"require": {
…
"akeneo/api-php-client-ee": "^4.0",
…
}

But then when launching composer update, I've an error that I don't understand :

Your requirements could not be resolved to an installable set of packages.

Problem 1
Conclusion: remove php-http/guzzle6-adapter v1.1.1
Conclusion: don't install akeneo/api-php-client-ee v4.0.2
Conclusion: don't install php-http/guzzle6-adapter v1.1.1
Conclusion: don't install akeneo/api-php-client v4.0.2|don't install php-http/guzzle6-adapter v1.1.0|keep php-http/httplug v1.1.0
Conclusion: remove php-http/httplug v1.1.0
Installation request for php-http/guzzle6-adapter ^1.1 -> satisfiable by php-http/guzzle6-adapter[v1.1.0, v1.1.1].
akeneo/api-php-client-ee v4.0.0 requires akeneo/api-php-client ^4.0 -> satisfiable by akeneo/api-php-client[v4.0.0, v4.0.1, v4.0.2].
akeneo/api-php-client-ee v4.0.1 requires akeneo/api-php-client ^4.0 -> satisfiable by akeneo/api-php-client[v4.0.0, v4.0.1, v4.0.2].
akeneo/api-php-client v4.0.1 requires php-http/httplug ^2.0 -> satisfiable by php-http/httplug[2.1.0, 2.2.0, v2.0.0].
akeneo/api-php-client v4.0.0 requires php-http/httplug ^2.0 -> satisfiable by php-http/httplug[2.1.0, 2.2.0, v2.0.0].
Can only install one of: php-http/httplug[v1.0.0, 2.1.0].
Can only install one of: php-http/httplug[v1.0.0, 2.2.0].
Can only install one of: php-http/httplug[v2.0.0, v1.0.0].
php-http/guzzle6-adapter v1.1.0 requires php-http/httplug ^1.0 -> satisfiable by php-http/httplug[v1.1.0, v1.0.0].
Conclusion: don't install php-http/httplug v1.1.0
Installation request for akeneo/api-php-client-ee ^4.0 -> satisfiable by akeneo/api-php-client-ee[v4.0.0, v4.0.1, v4.0.2].

If someone has an idea… thanks !

api-php-client calls undefined function in pim

Hello,

i use Akeneo Pim 5.0 with Api Client 6.0
With the following Code (taken from tutorial)

$client->getCategoryApi()->upsert('winter_collection', [ 'parent' => 'master', 'labels' => [ 'en_US' => 'Winter Collection', 'fr_FR' => 'Collection Hiver', ] ]);

i get always an error. However as far as it seems it is not my fault. This shows this error log:

[2022-10-18 20:45:14] php.CRITICAL: Uncaught Error: Call to undefined method Akeneo\Pim\Enrichment\Component\Category\Model\Category::getIdentifier() {"exception":"[object] (Error(code: 0): Call to undefined method Akeneo\\Pim\\Enrichment\\Component\\Category\\Model\\Category::getIdentifier() at /srv/pim/src/Elbenwald/CategoryBuilder/CategoryBuilder.php:152)"} [] [2022-10-18 20:45:14] request.CRITICAL: Uncaught PHP Exception Symfony\Component\ErrorHandler\Error\UndefinedMethodError: "Attempted to call an undefined method named "getIdentifier" of class "Akeneo\Pim\Enrichment\Component\Category\Model\Category"." at /srv/pim/src/Elbenwald/CategoryBuilder/CategoryBuilder.php line 152 {"exception":"[object] (Symfony\\Component\\Debug\\Exception\\FatalThrowableError(code: 0): Attempted to call an undefined method named \"getIdentifier\" of class \"Akeneo\\Pim\\Enrichment\\Component\\Category\\Model\\Category\". at /srv/pim/src/Elbenwald/CategoryBuilder/CategoryBuilder.php:152)"} [] [2022-10-18 20:45:14] doctrine.DEBUG: SELECT value FROM oro_config_value WHERE name = "language" AND section = "pim_ui" LIMIT 1 [] [] [2022-10-18 20:45:14] security.DEBUG: Invoked controller "FOS\RestBundle\Controller\TwigExceptionController::showAction". (SUB_REQUEST) [] [] [2022-10-18 20:45:15] request.CRITICAL: Uncaught PHP Exception Akeneo\Pim\ApiClient\Exception\ServerErrorHttpException: "Internal Server Error (see https://api.akeneo.com/php-client/exception.html#server-exception)" at /srv/pim/vendor/akeneo/api-php-client/src/Client/HttpExceptionHandler.php line 66 {"exception":"[object] (Akeneo\\Pim\\ApiClient\\Exception\\ServerErrorHttpException(code: 500): Internal Server Error (see https://api.akeneo.com/php-client/exception.html#server-exception) at /srv/pim/vendor/akeneo/api-php-client/src/Client/HttpExceptionHandler.php:66)"} [] [2022-10-18 20:45:15] security.DEBUG: Invoked controller "FOS\RestBundle\Controller\TwigExceptionController::showAction". (SUB_REQUEST) [] []

the function getIdentifier(); is not defined. How could this get resolved?
This failure also triggers only after execution. The category is upserted in Akeneo and only afterwards the Exception is thrown.

can't download php-api-client with composer (following the documentation instructions)

when I run:
composer require akeneo/api-php-client php-http/guzzle6-adapter

I get:
[InvalidArgumentException] Could not find package akeneo/api-php-client at any version for your minimum-stability (stable). Check the package spelling or your minimum-stability

php -v:
PHP 7.0.18-0ubuntu0.16.04.1 (cli) ( NTS ) Copyright (c) 1997-2017 The PHP Group Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies with Zend OPcache v7.0.18-0ubuntu0.16.04.1, Copyright (c) 1999-2017, by Zend Technologies with Xdebug v2.4.0, Copyright (c) 2002-2016, by Derick Rethans

composer -V:
Composer version 1.4.2 2017-05-17 08:17:52

UPDATE

Now I can install client with composer if specific version is set:

composer require akeneo/api-php-client:1.0.0-beta1 php-http/guzzle6-adapter

Cannot set image for a product

I have an attribute named 'thumbnail' for each product. I have images in a folder 'scraper/images.'
I am not sure how I should set an image for a product. Is there a constraint on file name or the path?
When I tried setting thumbnail via the path to the image as follows:

    $client->getProductApi()->upsert($product_id, [
        'values' => [
            'thumbnail' => [
                [
                    'data' => '/scraper/images/' . $product_name . '.jpeg',
                    'locale' => null,
                    'scope' => null
                ]
            ]
        ]
    ]);

I get the following error message:

PHP Fatal error:  Uncaught Akeneo\Pim\ApiClient\Exception\UnprocessableEntityHttpException: Property "thumbnail" expects a valid pathname as data, "/scraper/images/at.jpeg" given. Check the expected format on the API documentation. (see https://api.akeneo.com/php-client/exception.html#unprocessable-entity-exception) in /srv/pim/client/vendor/akeneo/api-php-client/src/Client/HttpExceptionHandler.php:58
Stack trace:
#0 /srv/pim/client/vendor/akeneo/api-php-client/src/Client/HttpClient.php(62): Akeneo\Pim\ApiClient\Client\HttpExceptionHandler->transformResponseToException(Object(GuzzleHttp\Psr7\Request), Object(GuzzleHttp\Psr7\Response))
#1 /srv/pim/client/vendor/akeneo/api-php-client/src/Client/AuthenticatedHttpClient.php(63): Akeneo\Pim\ApiClient\Client\HttpClient->sendRequest('PATCH', 'http://httpd:80...', Array, '{"values":{"thu...')
#2 /srv/pim/client/vendor/akeneo/api-php-client/src/Client/ResourceClient.php(142): Akeneo\Pim\ApiClient\Client\AuthenticatedHttpClient->sendRequest('PATCH', 'http://httpd:80...', Array, '{"values":{"thu...')
#3 /srv/pim/client/vendor/akeneo/api-php-client/src/Api/ProductApi.php(97): Akeneo\Pim\ApiClient\Client\ResourceClient->upsertResource('http://httpd:80...', Array, Array)
#4 /srv/pim/client/importProducts.php(306): Akeneo\Pim\ApiClient\Api\ProductApi->upsert('1', Array)
#5 /srv/pim/client/importProducts.php(354): createProduct(Object(PDO), Object(Akeneo\Pim\ApiClient\AkeneoPimClient), Array, 'Apple_Products')
#6 /srv/pim/client/importProducts.php(394): createProducts(Object(PDO), Object(Akeneo\Pim\ApiClient\AkeneoPimClient), 'Apple_Products')
#7 /srv/pim/client/importProducts.php(397): execute()
#8 {main}
  thrown in /srv/pim/client/vendor/akeneo/api-php-client/src/Client/HttpExceptionHandler.php on line 58

Media file "xxx" is not present on the filesystem.

Hello !

I have some issues with the api-php-client of Akeneo concerning some files and large requests.
I can manage to download a few media files (small ones) but with "large" media files (that can be more than 2mb sometimes) i sometimes have this following response :

Akeneo \ Pim \ ApiClient \ Exception \ NotFoundHttpException (404) Media file "0/6/6/3/0663baa0b395e8f7ec5d8c127f1c8f49ed4e70af.png" is not present on the filesystem.

With some large requests (list of 600 products for example) or the download of some media assets or documents assets (only the large one, small files seems to works) i have the following exception :
Invalid exception returned from Guzzle6 curl_multi_exec(): Unable to create temporary file, Check permissions in temporary files directory. (0)

Is this a problem relative to my host (Clevercloud) and the managing of the temporary files directory ?

auto switch to http from https with error

For some reason this switches to http from https.

  1. Configure client to use https url
  2. use a cursor paging, after the second page you get a http redirect error (as there is not http it redirects to https)
    3 the fist page worked find, its the second page that seems to want to go to http over https

Sample client call
`<?php
ini_set('display_errors', 1);
require_once 'vendor/autoload.php';
require_once('./env.php');

$clientBuilder = new \Akeneo\Pim\ApiClient\AkeneoPimClientBuilder($_ENV["AKENEO_SERVER"]);
$client = $clientBuilder->buildAuthenticatedByPassword($_ENV["AKENEO_API_CLIENT_ID"], $_ENV["AKENEO_API_SECRET"], $_ENV["AKENEO_API_USER"] , $_ENV["AKENEO_API_PASSWORD"]);

$searchBuilder = new \Akeneo\Pim\ApiClient\Search\SearchBuilder();

$searchBuilder
->addFilter('enabled', '=', true);

$searchFilters = $searchBuilder->getFilters();
$products = $client->getProductApi()->all(50,['search' => $searchFilters, 'scope' => 'Ecommerce']);

echo "starting:".PHP_EOL;
foreach ($products as $product) {
echo print_r($product).PHP_EOL;
}
`

Error message
PHP Fatal error: Uncaught Akeneo\Pim\ApiClient\Exception\RedirectionHttpException: Moved Permanently (see https://api.akeneo.com/php-client/exception.html#client-exception) in /Users/dankoz/cws-automation/vendor/akeneo/api-php-client/src/Client/HttpExceptionHandler.php:49 Stack trace: #0 /Users/dankoz/cws-automation/vendor/akeneo/api-php-client/src/Client/HttpClient.php(77): Akeneo\Pim\ApiClient\Client\HttpExceptionHandler->transformResponseToException(Object(GuzzleHttp\Psr7\Request), Object(GuzzleHttp\Psr7\Response)) #1 /Users/dankoz/cws-automation/vendor/akeneo/api-php-client/src/Client/AuthenticatedHttpClient.php(64): Akeneo\Pim\ApiClient\Client\HttpClient->sendRequest('GET', 'http://pim.x...', Array, NULL) #2 /Users/dankoz/cws-automation/vendor/akeneo/api-php-client/src/Pagination/Page.php(132): Akeneo\Pim\ApiClient\Client\AuthenticatedHttpClient->sendRequest('GET', 'http://pim.x...', Array) #3 /Users/dankoz/cws-automation/vendor/akeneo/api-php-client/src/Pagination/Page.php(76): Akeneo\Pim\ApiClient\Pagination\Page in /Users/dankoz/cws-automation/vendor/akeneo/api-php-client/src/Client/HttpExceptionHandler.php on line 49

Delete Products or Attributes (for test purposes)

Our team is trying to test a script that imports products (and catalog structure entities) into Akeneo. Is there an efficient or standard way to do this?

Our idea now is to test with a test DB and delete all that has been created by the test. But we are not sure if there are any delete functions provided Akeneo PHP client.

Cursor resource product api not returning all products after server issue

For product import we use the all() method of the api's which always worked perfectly with large catalog volumes (180k products, 35k categories) but since yesterday for the productApi it doesn't seem to return all the products anymore.

It most likely is related to the issue we had yesterday that disk space was 95% full causing ElasticSearch after cleaning up i have tried reindex, clear cache, reset elasticsearch indexes but nothing seems to help.

$searchFilters= ['enabled' => true] if (0 === $totalCount= $productApi->listPerPage(1,true, $searchFilters)->getCount()) { return false; } return $productApi->all(100, $searchFilters);

In above code snippet, $totalCount returns 76980 but all stops at 53858, could this be some kind of caching issue or something else i might need to reset?

Unable to set product weight

Updating a metric attribute (weight) with the following isn't working, am I missing something? The existing value gets removed but no new value is set.

'product_weight' => [ [ 'data' => [ [ 'amount' => '20', 'unit' => 'POUND', ], ], 'locale' => null, 'scope' => null, ], ],

Unexpected exception when instantiating class - error in Symfony 5.4 and PHP 8.1

Hey

Today out of nowhere i got error Unexpected exception when instantiating class. when i tried to create client class for my akeneo integrator app.

  • PHP: 8.1
  • Symfony: 5.4
$clientBuilder = new AkeneoPimClientBuilder($params->get('pim_url'));
$this->client = $clientBuilder->buildAuthenticatedByPassword(
    $params->get('pim_api_client_id'),
    $params->get('pim_api_client_secret'),
    $params->get('pim_api_user'),
    $params->get('pim_api_password')
);

image

Additional informations: The error appeared after i installed the Symfony bundle https://symfony.com/bundles/SensioFrameworkExtraBundle/current/index.html#installation.

I tried to remove vendors and composer.lock file and reinstall packages. Still error is visible.

Can somebody help me?

PHP 8.1 Deprecations

Hi,
Is it possible to start supporting PHP 8(.1)?
There are some deprecations I'd like to see resolved.

For instance:
User Deprecated: Method "Iterator::current()" might add "mixed" as a native return type declaration in the future. Do the same in implementation "Akeneo\Pim\ApiClient\Pagination\ResourceCursor" now to avoid errors or add an explicit @return annotation to suppress this message.

and:
Deprecated: http_build_query(): Passing null to parameter #2 ($numeric_prefix) of type string is deprecated

Maybe start a 5.0 branch?

Looking forward to this!

Consider updating PHPSpec package

As title, it will be failed on php-7.4 version when phpspec is ^5.0 version.

The related issue is available here.

And it should be good for php-7.4 version uses phpspec ^6.0 version.

To resolve this issue, I think we have two different ways:

  • Defining two phpspec version with ^5.0 || ^6.0 inside require block on composer.json.
    And using the composer update --prefer-dist --no-interaction during Travis CI build.
  • Removing composer.lock and define two phpspec version with ^5.0 || ^6.0 inside require block on composer.json.

Operator between filters for the search builder

Is there a possibility to specify the operator between filters when searching for products?

F.ex. if I have the search query "product title 123-456-789", I would like to search both product title and identifier for this string. If either one of those fields contains (part of) the search string it should be returned. Currently, by using the addFilter() method, I can only get products that contain (part of) this search string in both fields.

Since elastic search is used as underlying technology, this should surely be possible?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.