neoxygen / neo4j-neoclient Goto Github PK
View Code? Open in Web Editor NEWSimple PHP HttpClient for the Neo4j ReST API with Multi DB Support
License: MIT License
Simple PHP HttpClient for the Neo4j ReST API with Multi DB Support
License: MIT License
I'm using the symfony 2 framework and there is a clear:cache
command available there If there is a way within this library to clear the cached container, i will be able to hook this up by calling this method
Whenever I inject the neoxygen.neoclient
service, I get the following exception:
[Symfony\Component\Debug\Exception\ClassNotFoundException]
Attempted to load class "ServiceContainer" from namespace "Neoxygen\NeoClient".
Did you forget a "use" statement for another namespace?
The documentation is a little unclear on how to use the dependency injection services provided other than being able to configure it.
I'm using Symphony 2.7 and version 3.3.10 of this library.
IMO the parameters order for getPathBetween should be $client->getPathBetween($start, $end, $direction, $depth)
since it is almost always the case to have $direction
compared to $depth
. What do you think ?
Hi Christophe,
I wrote a server plugin and I want to call this new plugin using your bundle.
Is it possible? Do I need to create a new command (that extends AbstractCommand)?
One thing that would be really helpful here if we could be able to add the label identifier as well. i.e.
$start = ['label' => 'User', 'id' => 123];
$end = ['label' => 'Phone', 'id' => 987];
$paths = $client->getPathBetween($start, $end);
Reported issue
[3/08/15 11:06:07] giugnofabrizio: $query = "MATCH (a:Property {uid:{uid}}) RETURN a AS property,labels(a) AS labels";
$params = [];
$params['uid'] = $uid;
$resp = NeoClient::sendReadQuery($query,$params)->getRows();
[3/08/15 11:06:23] giugnofabrizio: ErrorException in ResponseFormatter.php line 320:
Undefined offset: 1
Hey, I'm having a very strange issue I think. The following code causes exceptions for me.
$relationship = $node->getSingleRelationship('USES', 'OUT');
return $relationship->getStartNode();
However, getting all the USES
relationships works without trouble. I can't quite figure out why the single relationship wont work. Especially since the getSingleRelationship method overloads the getRelationships method.
"error": {
"type": "Symfony\\Component\\Debug\\Exception\\FatalErrorException",
"message": "Call to a member function getStartNode() on a non-object",
...
}
Using getProperties(['prop'])
returns ['prop' => true]
instead of the actual value. i.e. ['prop' => 'value']
Composer output
Problem 1
- Installation request for symfony/filesystem 3.0.x-dev -> satisfiable by symfony/filesystem[3.0.x-dev].
- symfony/filesystem 3.0.x-dev requires php >=5.5.9 -> no matching package found.
Problem 2
- Installation request for symfony/filesystem dev-master -> satisfiable by symfony/filesystem[dev-master].
- symfony/filesystem dev-master requires php >=5.5.9 -> no matching package found.
Problem 3
- symfony/filesystem 3.0.x-dev requires php >=5.5.9 -> no matching package found.
- symfony/config 2.7.x-dev requires symfony/filesystem ~2.3|~3.0.0 -> satisfiable by symfony/filesystem[3.0.x-dev].
- Installation request for symfony/config 2.7.x-dev -> satisfiable by symfony/config[2.7.x-dev].
This is an example of an exception i get
[Neoxygen\NeoClient\Exception\Neo4jException]
Neo4j Exception with code "Neo.ClientError.Schema.ConstraintViolation" and message "Node 59 already exists with label user and property "username"=[flip111]"
It would be nice to have a specific exception for this. Maybe the class can be called ConstraintViolationException
. Then what i can do in the code is:
function createUser() {
try {
$client->sendCypherQuery('CREATE (n:user {username:"flip111"})');
} catch (ConstraintViolationException $e) {
// notify the user somehow the user already exist
}
// Other exceptions are not caught and can display a 500 Internal Server error page
}
It would require creating exception based on the exception code. (That would also require knowing all the possible exception codes, which i don't know where to find a list for)
Currently, it is not possible to use identifiers in the result to select nodes to work on, for e.g. :
MATCH (n:User)-[:FOLLOWS*2]->(fof) RETURN n, collect(fof) AS friendOfFriend;
with the above query you can not take only the friendOfFriend from the resultSet.
I want to refactor the response formatter and add a ->get
method to add this functionality.
What do you think @Mulkave ?
hello, i have installed and everything is fine except the response from neo4j (local) is very slow.
i wait about 3-5 second to get a response even it is very simple query ,can you solve it?
thanks
I understand that the formatter class acts parsing the data to improve the readibility.
If I want to extends the formatter and use a improved version that I made I can't use the method of the builder setResponseFormatterClass. I needed to change the ClientBuilder.php and add a return $this;
But my formatter class was not being used.
Am I missing something?
I tried the following:
$result = $client->sendCypherQuery('
CREATE (a:TEST {foo: {bar}})
RETURN a.foo
', array(
'bar' => array(1, 2, 3)
))->getResult();
This returns an object without errors, but the identifiers
key is also empty. It should contain an identifer a.foo
with value array(1, 2, 3)
, right? As that's what Neo4j returns when I try the same in the web client.
Im trying to return from the database nodes that some of them have the match and dome not.
because is return null its crash on Result class here :
public function addRelationshipToIdentifier($relationshipId, $identifier)
{
if (isset($this->identifiers[$identifier])) {
foreach ($this->identifiers[$identifier] as $rel) {
if ($rel->getId() === $relationshipId) {
return;
}
}
}
$this->identifiers[$identifier][] = $this->getRelationship($relationshipId);
}
it can be fix by adding check if $rel is not null.
i dont want to do that by myself (because future update)
there is a way to fix it ? or update it in next version
Would it be feasible to have $client->createIndex($labe, $properties)
and dropIndex($label, $property)
where $properties
can either be a string
of one prop or an array
of multiple props. Also applies to createConstraint
and dropConstraint
I tried using the response of $node->getId() as a variable to find another node:
$client->sendCypherQuery('
MATCH (a:TEST)
WHERE id(a) = {id}
RETURN a
', array(
'id' => $node->getId()
));
But I got the following error: Expected a propertycontainer or number here, but got: 1
Hi Christophe,
Looks like there is an issue with formatter.
$client = ClientBuilder::create()
->addDefaultLocalConnection()
->setAutoFormatResponse(true)
->build();
$query = "MATCH (member:Member {username:'member_1'}) RETURN member";
$result1 = $client->sendCypherQuery($query)->getResult();
$query = "MATCH (member:Member {username:'member_2'}) RETURN member";
$result2 = $client->sendCypherQuery($query)->getResult();
When I run first query and check result1 I see that there is only one node in it, which is the expected result. But after running second query, both result1 and result2 has 2 nodes (member_1 and member_2) in them.
Looks like formatter keeps its internal state between queries. There is a reset function in ResponseFormatter but I could not find any reference to it.
This issue might not be specific to Paths but to getNodesByLabel($label)
Consider this code:
// create related nodes
$q = 'CREATE (u:`User`:`Person` {name: {name}, email: {email}})-[:HAS]->(p:`Phone` {code: {code}, number: {number}}) RETURN u';
$params = ['name' => 'Abed Halawi', 'email' => '[email protected]', 'code' => 123, 'number' => 8612358];
$response = $client->sendCypherQuery($q, $params, null, array('graph'));
// find path
$pathResponse = $client->getPathbetween($start, $end);
$path = $formatter->format($pathResponse);
// get specific nodes
$path->getNodesByLabel('User:Person') // null
current($path->getNodesByLabel('User'))->getLabel(); // User
current($path->getNodesByLabel('Person'))->getLabel(); // User
current($path->getNodesByLabel('Phone'))->getLabel(); // Phone
hey there, I have installed neo4j and I have added this library in my project as well..
I am using these lines of code to connect to neo4j..
require 'C:/xampp/htdocs/purplle/application/libraries/neo4j-neoclient-master/src/ClientBuilder.php';
$client = new Neoxygen\NeoClient\ClientBuilder(array('hosts'=>"http://localhost:7474"));
$client->create();
$client->addConnection('default', 'http', 'localhost', 7474);
$client->build();
ClientBuilder is found but it is throwing me an error for Symfony...
I am not getting this..
Please help in this..
"name": "PHP User Deprecated Warning",
"message": "The ability to pass file names to the Symfony\Component\Yaml\Yaml::parse method is deprecated since version 2.2 and will be removed in 3.0. Pass the YAML contents of the file instead.",
"code": 16384,
"type": "yii\base\ErrorException",
class NeoClientCoreExtension extends AbstractExtension
{
public static function getAvailableCommands()
{
return Yaml::parse(DIR.'/../Resources/extensions/core_commands.yml');
class NeoClientCoreExtension extends AbstractExtension
{
public static function getAvailableCommands()
{
return Yaml::parse(file_get_contents(DIR.'/../Resources/extensions/core_commands.yml'));
Good day Everyone,
Am trying to work on neo4j graph database using php. I saw your amazing projects on github
https://github.com/neoxygen/neo4j-neoclient
Please I have install xampp and my php is running locally.
I have also installed neo4j graph database and its running locally too.
I have also install the projects via composer as per "composer require neoxygen/neoclient"
when I try to connect via your sample code below and print the version. it seems its not connecting. it throws error
Fatal error: Uncaught Neoxygen\NeoClient\Exception\HttpException: Error on Connection "default" with message "Client error: GET http://localhost:7474/db/data
resulted in a 401 Unauthorized
response: { "errors" : [ { "code" : "Neo.ClientError.Security.Unauthorized", "message" : "No authentication header su (truncated...) " in C:\xampp\htdocs\neo_oxygen\src\EventListener\HttpRequestEventSubscriber.php:74 Stack trace: #0 C:\xampp\htdocs\neo_oxygen\vendor\symfony\event-dispatcher\EventDispatcher.php(184): Neoxygen\NeoClient\EventListener\HttpRequestEventSubscriber->onHttpException(Object(Neoxygen\NeoClient\Event\HttpExceptionEvent), 'neoclient.http_...', Object(Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher)) #1 C:\xampp\htdocs\neo_oxygen\vendor\symfony\event-dispatcher\EventDispatcher.php(46): Symfony\Component\EventDispatcher\EventDispatcher->doDispatch(Array, 'neoclient.http_...', Object(Neoxygen\NeoClient\Event\HttpExceptionEvent)) #2 C:\xampp\htdocs\neo_oxygen\src\HttpClient\GuzzleHttpCl in C:\xampp\htdocs\neo_oxygen\src\EventListener\HttpRequestEventSubscriber.php on line 74
below is your connection Code
<?php
require_once 'vendor/autoload.php';
use Neoxygen\NeoClient\ClientBuilder;
$client = ClientBuilder::create()
->addConnection('default','http','localhost',7474)
->build();
$root = $client->getRoot();
//print_r($root);
$version = $client->getNeo4jVersion();
print_r($version);
very important,
My neo4j local database server has username: neo4j and password: neo65gbcAB
All I want to implement is how to
1.)Connect to my neo4j local database server
2.) create database eg Test_db via php
3.) insert, select, update and delete data from graph database using php. please can you also help me with that
Thanks
I assume the username and password are a requirement for authMode. Right now i have a small wrapper doing
if ($authUser !== null AND $authPassword !== null) {
$authMode = true;
} else {
$authMode = false;
}
is there any reason why this extra boolean is needed explicitly ?
The ability to export out to different formats for different applications.
Right now im getting like this fetal error when node is already exists while im trying to create a node like below example
Fatal error: Uncaught Neoxygen\NeoClient\Exception\Neo4jException: Neo4j Exception with code "Neo.ClientError.Schema.ConstraintViolation" and message "Node 10335 already exists with label Career and property "Name"=[Designer]" in D:\tobotob\admin\neo4j_sync\vendor\neoxygen\neoclient\src\Extension\AbstractExtension.php:117 Stack trace: #0 D:\tobotob\admin\neo4j_sync\vendor\neoxygen\neoclient\src\Extension\AbstractExtension.php(104): Neoxygen\NeoClient\Extension\AbstractExtension->checkResponseErrors(Array) #1 D:\tobotob\admin\neo4j_sync\vendor\neoxygen\neoclient\src\Extension\NeoClientCoreExtension.php(98): Neoxygen\NeoClient\Extension\AbstractExtension->handleHttpResponse(Object(Neoxygen\NeoClient\Request\Response)) #2 [internal function]: Neoxygen\NeoClient\Extension\NeoClientCoreExtension->sendCypherQuery('CREATE (n:Caree...') #3 D:\tobotob\admin\neo4j_sync\vendor\neoxygen\neoclient\src\Extension\ExtensionManager.php(53): call_user_func_array(Array, Array) #4 D:\tobotob\admin\neo4j_sync\vendor\neoxygen\neoclient\src\Cli in D:\tobotob\admin\neo4j_sync\vendor\neoxygen\neoclient\src\Extension\AbstractExtension.php on line 117
can u please tell me is their any way to proper error handeling method in cypher query
Thank you
pavan
Hello,
Any chance of this package supporting Guzzle 6?
I'm using Xampp with PHP 5.6.14 and I've just installed neo4jclient using composer. I've tried setting up neoclient with the following code as documented on the main page:
$client = ClientBuilder::create()
->addDefaultLocalConnection()
->build();
and I am getting the following exception. Any help would be appreciated :)
Fatal error: Uncaught exception 'InvalidArgumentException' with message 'Passing in the "body" request option as an array to send a POST request has been deprecated. Please use the "form_params" request option to send a application/x-www-form-urlencoded request, or a the "multipart" request option to send a multipart/form-data request.' in C:\xampp\htdocs\testapp\vendor\guzzlehttp\guzzle\src\Client.php:391 Stack trace: #0 C:\xampp\htdocs\testapp\vendor\guzzlehttp\guzzle\src\Client.php(117): GuzzleHttp\Client->invalidBody() #1 C:\xampp\htdocs\testapp\vendor\guzzlehttp\guzzle\src\Client.php(129): GuzzleHttp\Client->requestAsync('POST', 'http://localhos...', Array) #2 C:\xampp\htdocs\testapp\vendor\neoxygen\neoclient\src\HttpClient\GuzzleHttpClient.php(69): GuzzleHttp\Client->request('POST', 'http://localhos...', Array) #3 C:\xampp\htdocs\testapp\vendor\neoxygen\neoclient\src\Command\AbstractCommand.php(45): Neoxygen\NeoClient\HttpClient\GuzzleHttpClient->sendRequest(Object(Neoxygen\NeoClie in C:\xampp\htdocs\testapp\vendor\guzzlehttp\guzzle\src\Client.php on line 391
Here are the versions of the libraries installed:
>composer require neoxygen/neoclient
Using version ^3.3 for neoxygen/neoclient
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
- Installing psr/http-message (1.0)
Loading from cache
- Installing graphaware/neo4j-response-formatter (1.2.0)
Loading from cache
- Installing symfony/event-dispatcher (v2.7.6)
Loading from cache
- Installing symfony/dependency-injection (v2.7.6)
Loading from cache
- Installing symfony/filesystem (v2.7.6)
Loading from cache
- Installing symfony/config (v2.7.6)
Loading from cache
- Installing symfony/yaml (v2.7.6)
Loading from cache
- Installing psr/log (1.0.0)
Loading from cache
- Installing monolog/monolog (1.17.2)
Loading from cache
- Installing guzzlehttp/promises (1.0.3)
Loading from cache
- Installing guzzlehttp/psr7 (1.2.1)
Loading from cache
- Installing guzzlehttp/guzzle (6.1.0)
Loading from cache
- Installing neoxygen/neoclient (3.3.12)
Loading from cache
Hi Christophe, thanks for this library and keeping it up-to date with recent Neo4j updates.
I have one question regarding create queries. What is the best method to check whether query is successful or not. For example if there is an user with username=mehmet, first query will be successful but the second one will fail.
MATCH (user:User {username:'mehmet' })
CREATE (book:Book { title:'hobbit' })
CREATE (user)-[:READ]->(book)
MATCH (user:User {username:'invalid' })
CREATE (book:Book { title:'hobbit' })
CREATE (user)-[:READ]->(book)
When I check the sendCypherQuery() response I can't see any difference for these queries.
Of course I can add a return clause like "RETURN book.title" to the query and check its existence in the response to check result but I wanted to check whether is there a better method.
How to send params with query while sending query to the database. as in all the examples, i have seen that are fetching some thing and not sending any params with it. Could you guys please post and example explaining how i can do that?
I am trying to create a custom command to do a simple POST Rest command based on the documentation.
I am able to register and call the alias fine.
$this->neo4j = NeoClient\ClientBuilder::create()
->addConnection('default','http', 'localhost',7474, true, 'neo4j', 'neo4j')
->registerCommand('geomlink', 'Minds\Core\Data\Neo4j\Commands\GeomLink')
->setAutoFormatResponse(true)
->setDefaultTimeout(20)
->build();
I then get a fatal error when I run the invoke command
$this->neo4j->invoke($command);
error: Call to a member function buildRequest() on a non-object
Any ideas?
I noticed the readme doesn't really talk about params in sendCypherQuery. Is this like preparted statements in SQL?
Currently you have to use the YAML config if you want to set ha_mode parameter. A function such as 'setHAMode()' in the connection builder would be helpful.
Currently I'm getting errors thrown because I'm not using the YAML config.
neoxygen/neoclient/src/DependencyInjection/NeoClientExtension.php:64
I'm thinking about doing a PR for a couple of commands. For example neo4j:index:drop person email
to execute $client->dropIndex('Person','email');
. However there are two issues with this:
The lib uses DI, each command is passed the HttpClient in the injector.
Also the DIC call the registerCommand method for each command defined in the library and soon for registering your own commands ( setter injection ).
All this logic is done in the compiler passes.
Also, commands are declared as lazy services, meaning that at runtime it is a proxy class that is passed to the CommandManager, and the class is instantiated only when calling the command itself, so uncalled command classes will not be instantiated.
IMO the output should be something like:
[
'Label' => ['prop', 'another_prop', 'some_prop']
]
instead of:
[ {
"property_keys" : [ "name" ],
"label" : "User"
}, {
"property_keys" : [ "email" ],
"label" : "User"
} ]
The goal is to provide two new ways, configurable, for the master/slave query type distinction :
Query-Type: WRITE
?query_type=write
This would be super handful when using HA Proxy on top of the cluster
Doing this doesn't warn for wrong usage:
$client = ClientBuilder::create()
->addConnection('default','http','dev',7575)
->setAutoFormatResponse(true)
->build();
$query = [
'statement' => 'CREATE (individual:`Individual`) SET individual.updated_at_create = {updated_at_create}, individual.created_at_create = {created_at_create} RETURN individual',
'parameters' => [
'updated_at_create' => "2015-04-25 15:05:13",
'created_at_create' => "2015-04-25 15:05:13"
],
];
$response = $client->sendCypherQuery($query);
$body = $response->getBody();
where it should be instead:
$response = $client->sendCypherQuery($query['statement'], $query['parameters']);
Currently, there is two possibility to send multiple statements in one transaction :
The first one is good if you want to be able to manage the same transaction between different runtimes (which is a rare use cas)
The second I find it not really handy.
The approach is to have the following :
$tx = $client->prepareTransaction($conn = null);
$tx->addQuery($q, $p);
$tx->addQuery($q, $p);
$tx->commit();
using the Cypher transactional http endpoint /transaction/commit
there would be no http requests until commit is triggered.
Hi there
Sorry if this isn't a bug as such, but I'm having a lot of difficulty simply pulling down all nodes and relationships, so that I can JSON encode this and send to a JS library. I've tried several options, but not hit on the right thing.
// get all nodes and relationships
$query = 'MATCH (n)-[r]->(m) RETURN n,r,m;';
$response = $neo->sendCypherQuery($query);
// this has all the data
$response->getResult();
// but this is an empty object
json_encode($response->getResult()); // {}
// these have subarrays of n, r, and m form the query, but nothing to link them to each other
$response->getRows();
// this looks great, contains all the data...
$response->getResult()->getRelationships();
// ... but json encoding leaves us with empty objects
json_encode($response->getResult()->getRelationships()) // {"19":{},"20":{},"21":{},"22":{}}
I'm trying to follow the data viz guide (http://neo4j.com/developer/guide-data-visualization/). Does the neoclient provide anything out of the box to pull out standard php arrays or json, or do I need to look into running transformers on my data?
Thanks!
Hi, i have use Neoxygen\NeoClient in my project , the code and website is hosted in godaddy, now i want to config from godaddy to grapheendb db .. im getting the error while connecting ...can u please help me out...
my config file code looks like this in godaddy
addConnection('default', **'http',** 'tobotob.sb02.stations.graphenedb.com', 24789, true, 'tobotob', 'TNhMM7Oec6X6YQ6DUqTO') ->setDefaultTimeout(20) ->setAutoFormatResponse(true) -> build(); ?>below one is the error im getting
Fatal error: Uncaught exception 'Neoxygen\NeoClient\Exception\HttpException' with message 'Error on Connection "default" with message "cURL error 7: Failed to connect to tobotob.sb02.stations.graphenedb.com port 24789: Connection refused (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)"' in /home/balavariyam/public_html/php/vendor/neoxygen/neoclient/src/EventListener/HttpRequestEventSubscriber.php:74 Stack trace: #0 [internal function]: Neoxygen\NeoClient\EventListener\HttpRequestEventSubscriber->onHttpException(Object(Neoxygen\NeoClient\Event\HttpExceptionEvent), 'neoclient.http_...', Object(Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher)) #1 /home/balavariyam/public_html/php/vendor/symfony/event-dispatcher/EventDispatcher.php(181): call_user_func(Array, Object(Neoxygen\NeoClient\Event\HttpExceptionEvent), 'neoclient.http_...', Object(Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher)) #2 /home/balavariyam/public_html/php/vendor/symfony/event-dispatcher/EventDispatcher.php(46): Symfo in /home/balavariyam/public_html/php/vendor/neoxygen/neoclient/src/EventListener/HttpRequestEventSubscriber.php on line 74
What's the possibility of having $listIndex()
when not passed any label to list all the indexes as:
[
'LabelOne' => ['prop_1', 'prop_2'],
'LabelTwo' => ['another_prop', 'some_prop']
]
Hi,
I am trying to run this piece of code (similar to a problem I have found here):
$query = "match (i:institutions)-[:worksAt]-(n:persons) WHERE toLower(i.name) CONTAINS toLower('moldova') return n";
$neo = $this->client->sendReadQuery($query);
$results = $this->client->getResult();
//tried this too:
//$results = $neo->getResult();
foreach ($results->getNodes() as $node)
{
$nodes[] = [
'name' => $node->getProperty('name'),
'id' => $node->getId()
];
}
When I do print_r on $neo right after sendReadQuery, I can see the object, and the result of the query is there, just one row. Problem is, $results is emty, it is not an object.
I have tried getRows(), getTableFormat(), all sort of combinations, nothing works. getResponse returns me that same object with which none of the functions work.
All I want to do is get all the nodes out with their properties in some sort of array.
It must be something really simple I am missing out.
Thanks,
Ivan
Currently this is the output of the getConstraints method :
Array
(
[0] => Array
(
[property_keys] => Array
(
[0] => neogen_id
)
[label] => Person
[type] => UNIQUENESS
)
[1] => Array
(
[property_keys] => Array
(
[0] => neogen_id
)
[label] => Channel
[type] => UNIQUENESS
)
)
getUniqueConstraints
label => array('prop1','prop2')
outputThe following line:
$value = isset($this->properties[$name]) ?: null;
will always evaluate to true or null.
Leaving out the middle part of PHP's ternary operator will make it equal to the first part, which is a boolean. I can send in a pull request, but I don't know where and how you would want those.
The following should work:
$value = isset($this->properties[$name]) ? $this->properties[$name] : null;
Should this work?
return $this->neo4j->sendCypherQuery('MATCH (n:{ myType }) RETURN n ORDER BY n.name',['myType' => $myParam]);
Where $this is the php neo4j object and $myParam is the parameter passed into the function.
Because if it does, this will give an error message at position 10 (the { in the query). So my suspicion is that the parameter is not parsed.
Hi,
With the last 2.1.* version I noticed a "sent ga" in my API's responses. That way, I have discovered that you send data to Google Analytics. Is there an explanation for this, and is there a way to disable this?
I saw that with the 2.2 branch, data is sent to your own website. Same question as for the 2.1, is there any way to disable it?
Thank you
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.