Giter Site home page Giter Site logo

mixpanel-php's Introduction

Mixpanel PHP Library Build Status

This library provides an API to track events and update profiles on Mixpanel.

Install with Composer

Add mixpanel/mixpanel-php as a dependency and run composer update

"require": {
    ...
    "mixpanel/mixpanel-php" : "2.*"
    ...
}

Now you can start tracking events and people:

<?php
// import dependencies
require 'vendor/autoload.php';

// get the Mixpanel class instance, replace with your project token
$mp = Mixpanel::getInstance("MIXPANEL_PROJECT_TOKEN");

// track an event
$mp->track("button clicked", array("label" => "sign-up")); 

// create/update a profile for user id 12345
$mp->people->set(12345, array(
    '$first_name'       => "John",
    '$last_name'        => "Doe",
    '$email'            => "[email protected]",
    '$phone'            => "5555555555",
    "Favorite Color"    => "red"
));

Install Manually

  1. Download the Mixpanel PHP Library
  2. Extract the zip file to a directory called "mixpanel-php" in your project root
  3. Now you can start tracking events and people:
<?php
// import Mixpanel
require 'mixpanel-php/lib/Mixpanel.php';

// get the Mixpanel class instance, replace with your project token
$mp = Mixpanel::getInstance("MIXPANEL_PROJECT_TOKEN");

// track an event
$mp->track("button clicked", array("label" => "sign-up"));

// create/update a profile for user id 12345
$mp->people->set(12345, array(
    '$first_name'       => "John",
    '$last_name'        => "Doe",
    '$email'            => "[email protected]",
    '$phone'            => "5555555555",
    "Favorite Color"    => "red"
));

Production Notes

By default, data is sent using ssl over cURL. This works fine when you're tracking a small number of events or aren't concerned with the potentially blocking nature of the PHP cURL calls. However, this isn't very efficient when you're sending hundreds of events (such as in batch processing). Our library comes packaged with an easy way to use a persistent socket connection for much more efficient writes. To enable the persistent socket, simply pass 'consumer' => 'socket' as an entry in the $options array when you instantiate the Mixpanel class. Additionally, you can contribute your own persistence implementation by creating a custom Consumer.

Testing

mixpanel-php uses phpunit as the testing framework. Please ensure that composer is up to date. To run tests, execute composer run-script unit-tests on the root directory.

Documentation

For further examples and options checkout out the "examples" folder

Changelog

Version 2.11.0

  • Fix identify regex for $anon_id
  • Fix PHP 8.2 deprecation warning

Version 2.10.0

  • send millisecond precision timestamps

Version 2.9.0

  • update regex for $anon_id check
  • Group Analytics Support
  • Fix PHP 8.1 deprecation warning
  • PHP 7.4 compatibility

Version 2.8.1

  • Updated $anon_id regex in identify method to support all Mixpanel distinct IDs

Version 2.8.0

  • Added $anon_id parameter to identify method, and a track call when parameter exists and is in UUID v4 format
  • Change parameter names for createAlias method to $distinct_id and $alias
  • Prevent unnecessary call to _encode on non-forked CurlConsumer
  • make sure 'Connection' exists before accessing it

Version 2.7.0:

Version 2.6.2:

  • Added support for $ignore_time
  • Cleaned up some comments to be more clear

Version 2.6.1:

  • Fixed bug in SocketConsumer timeout

Version 2.6:

  • Updated default for connect_timeout in SocketConsumer to be 5

Version 2.5:

  • timeout option now refers to CURLOPT_TIMEOUT instead of CURLOPT_CONNECTTIMEOUT in non-forked cURL calls, it has been removed from the SocketConsumer in favor of a new connect_timeout option.
  • Added a new connect_timeout option for CURLOPT_CONNECTTIMEOUT in non-forked cURL calls (CurlConsumer) and the socket timeout (SocketConsumer)
  • Set default timeout (CURLOPT_TIMEOUT) to 30 seconds in non-forked cURL calls
  • Set default connection timeoute (CURLOPT_CONNECTTIMEOUT) to 5 seconds in non-forked cURL calls
  • We now pass cURL errors from non-forked cURL calls to _handle_error with the curl errno and message

Version 2.4:

  • Fixed a bug where passing the integer 0 for the ip parameter would be ignored

Version 2.1 - 2.3:

  • Broken releases

Version 2.0:

  • Changed the default consumer to be 'curl' (CurlConsumer)
  • Changed the default setting of 'fork' to false in the Curl Consumer. This means that by default, events and profile updates are sent synchronously using the PHP cURL lib when using the Curl Consumer.
  • 'createAlias' uses the CurlConsumer with 'fork' explicitly set to false (as we need this to be synchronous) instead of the SocketConsumer.
  • Fixed bug where max_queue_size was never read

mixpanel-php's People

Contributors

andrey-yantsen avatar andypasztirak avatar argenisf avatar csiden avatar dmvdbrugge avatar evan-burrell avatar jaredmixpanel avatar jbboehr avatar jbwyme avatar manuelflara avatar orkin avatar santigracia avatar starred-gijs avatar tugcaeker avatar zakj avatar zeedann 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  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  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

mixpanel-php's Issues

PHP not executed when not run from a browser

It could be me, or my unfamiliarity with the framework, but I found that Mixpanel's PHP code doesn't seem to actually call events if the code is not run from a browser (in my case I have a web service that is called by a client app). For example:

<?php
    require_once(MY_MIXPANEL_PATH . '/Mixpanel.php');
    $mp = Mixpanel::getInstance("MY_TOKEN");
    $mp->track("Test Event");
?>

This works fine if I load this code in my browser, but if I execute it using a Unix php command or anything else that doesn't use a browser, nothing ever gets saved to the Mixpanel API, as if the code was never run. In debugging the code, it throws no errors and has a valid $mp object.

Can you please provide some guidance?

Support custom instantiation for custom message consumers

Right now, I've written my own message consumer which pushes events to a Redis queue. In order to do that, I'd like to be able to supply the Redis client dependency through constructor injection, but since I can only provide the class string for my message consumer, this isn't possible. Something like this would be nice:

$customConsumer = new My\Project\CustomConsumer($options, $redisClient);

$mp = new Mixpanel("MIXPANEL_PROJECT_TOKEN", array(
    "debug"             => true,
    "max_batch_size"    => 1,
    "consumers"         => array("ob" => $customConsumer),
    "consumer"          => "ob"
));

If there is a better way of dealing with custom consumer dependencies, I'd love to know!

Undefined index: Connection

Since upgrading to 2.7 we are seeing a large amount of errors when calling createAlias when using the socket consumer.

if ($headers['Connection'] == "close") {

The error shows that the header doesn't actually contain the Connection header so the above line blows up.

Error stack:

ErrorException
Undefined index: Connection

in SocketConsumer.php line 292
at HandleExceptions->handleError(8, 'Undefined index: Connection', '/var/app/current/vendor/mixpanel/mixpanel-php/lib/ConsumerStrategies/SocketConsumer.php', 292,array('response' => 'HTTP/1.1 200 OK access-control-allow-credentials: true access-control-allow-headers: X-Requested-With access-control-allow-methods: GET, POST, OPTIONS access-control-allow-origin: * access-control-expose-headers: X-MP-CE-Backoff access-control-max-age: 1728000 cache-control: no-cache, no-store content-type: application/json date: Fri, 30 Aug 2019 14:12:40 GMT content-length: 1 x-envoy-upstream-service-time: 8 server: envoy Via: 1.1 google Alt-Svc: clear 1', 'lines' =>array('HTTP/1.1 200 OK ', 'access-control-allow-credentials: true ', 'access-control-allow-headers: X-Requested-With ', 'access-control-allow-methods: GET, POST, OPTIONS ', 'access-control-allow-origin: * ', 'access-control-expose-headers: X-MP-CE-Backoff ', 'access-control-max-age: 1728000 ', 'cache-control: no-cache, no-store ', 'content-type: application/json ', 'date: Fri, 30 Aug 2019 14:12:40 GMT ', 'content-length: 1 ', 'x-envoy-upstream-service-time: 8 ', 'server: envoy ', 'Via: 1.1 google ', 'Alt-Svc: clear ', ' ', '1'), 'headers' => array('access-control-allow-credentials' => 'true', 'access-control-allow-headers' => 'X-Requested-With', 'access-control-allow-methods' => 'GET, POST, OPTIONS', 'access-control-allow-origin' => '*', 'access-control-expose-headers' => 'X-MP-CE-Backoff', 'access-control-max-age' => '1728000', 'cache-control' => 'no-cache, no-store', 'content-type' => 'application/json', 'content-length' => '1', 'x-envoy-upstream-service-time' => '8', 'server' => 'envoy', 'Via' => '1.1 google', 'Alt-Svc' => 'clear'), 'line' => '1', 'kvsplit' =>array('1'), 'header' => 'Alt-Svc', 'value' => ' clear ', 'line_one_exploded' => array('HTTP/1.1', '200', 'OK '), 'status' => '200', 'body' => '1'))in SocketConsumer.php line 292
at ConsumerStrategies_SocketConsumer->handleResponse('HTTP/1.1 200 OK access-control-allow-credentials: true access-control-allow-headers: X-Requested-With access-control-allow-methods: GET, POST, OPTIONS access-control-allow-origin: * access-control-expose-headers: X-MP-CE-Backoff access-control-max-age: 1728000 cache-control: no-cache, no-store content-type: application/json date: Fri, 30 Aug 2019 14:12:40 GMT content-length: 1 x-envoy-upstream-service-time: 8 server: envoy Via: 1.1 google Alt-Svc: clear 1')in SocketConsumer.php line 252
at ConsumerStrategies_SocketConsumer->_write(resource, false)in SocketConsumer.php line 122
at ConsumerStrategies_SocketConsumer->persist(array(array('event' => '$create_alias', 'properties' => array('distinct_id' => '[email protected]', 'alias' => 12345, 'token' => 'cb6d5071c8435dfd1eb3edbb9c895bd3'))))in MixpanelEvents.php line 155
at Producers_MixpanelEvents->createAlias('[email protected]', 12345)in Mixpanel.php line 300
at Mixpanel->createAlias('[email protected]', 12345)in UpdateUserData.php line 96

Mixpanel autoload?

I've installed the PHP library via Composer and I noticed that Mixpanel is set to load automatically when the composer autoloader is loaded, from composer.json:

"autoload": {
"files": ["lib/Mixpanel.php"]
}

This is not ideal because the Mixpanel class and all dependencies get automatically loaded all the time in my application, even if I want to do something completely unrelated to mixpanel. Perhaps using psr-0 or classmap would be a better solution? This would mean the class is only loaded when first used and additionally you will not need to manually require other classes in your library as you currently do.

Errors handling and retry, is it possible?

Hello, we've got a problem last night that our server's IP was blocked by google cloud platform (which mixpanel is hosted on) so all our events since yesterday 12pm till this morning were lost (403 error, more details here), not a huge deal on our scale, but we want to prevent it from happening in the future.

So the question - is it possible to configure mixpanel to throw an error if delivery wasn't successful? That would help a lot because we send events from symfony queue worker and if they will fail - it will automatically retry to process them after some delay, while right now they were just silently suppressed

How to use the import endpoint

I don't see a method for using the import endpoint in order to import data that is older than 5 days. My apologies if the method exists and I am just missing it.

class Base_MixpanelBase duplicate causing PHP Fatal Error.

PHP Fatal error: Cannot declare class Base_MixpanelBase, because the name is already in use in wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/lib/Base/MixpanelBase.php on line 8

Found the issue, the class "Base_MixpanelBase" is being used within another plugin "wordpress-23-related-posts-plugin" Once I found the second instance of "Base_MixpanelBase" in that plugin. I disabled it and the site came up fine. Maybe change the name of the class to something else? I think other people would have this same issue if they have these two plugins installed together:

wordpress-23-releated-posts-plugin
wp-smushit

License type inconsistent

The LICENSE file states a license of type "APACHE Version 2.0"
The composer.json file has "MIT" as a license.

Please clarify which one it is.

PHP 8.1 Deprecation warning

With PHP 8.1 curl_multi_exec(): Passing null to parameter #2 ($still_running) of type int is deprecated warning is present.

Seems to be fixed in this PR: #65

No 'alias' api

I don't find any 'alias' api. I want to use Mixpanel PHP api in background coming from an email pixel.
Without giving it an alias distinct_id, I cannot move forward.

Is this still supported?

I would just like to ask if this is still updated and supported?
It doesn't look like there are much activity, both in the code and the issues/pull requests :)

And would this package work with php7?

track method returning null

I am using the same method but i am getting NULL when doing

var_dump( $mp->track("login"));

Also no when i go to mixpanel dashboard it says "WE HAVEN'T RECEIVED ANY EVENTS FROM YOU YET." and ask me to setup. When i go to setup it shows me only android and iphone. I am running this from localhost is it fine ?

Disable referrer and URL being sent for events

The Mixpanel PHP client library is automatically sending the Referrer and Url properties when I track events. Is there a way to disable this? The URLs contain potentially sensitive info I'd rather not share with third parties.

PHPUnit is incompatible with PHP 8.1

Mixpanel PHP-SDK currently uses PHPUnit 5.6.*. This version is incompatible with PHP 7.4 or higher. It is recommended to migrate PHPUnit to a current version, at least PHPUnit 8, better would be version 10. https://phpunit.de/supported-versions.html

This should only be relevant for development and should not break anything from the usage perspective.

If this is wanted, I would be open to create a PR for that. Please let me know.

[IMPORTANT] $ignore_time not implemented

Hi, ( ping @jbwyme )

The '$ignore_time' parameter referenced here https://mixpanel.com/help/reference/http is implemented in the ruby gem but not in this php lib here :/

@mixpanel.set({ :distinct_id => 'john-doe', :ignore_time => true }, { :age => 31, :email => '[email protected]' })

I don't know what you've done with the Last Seen behavior it seems like all calls are updating it now, it was not like this one month before ~

So please update this quickly, it's really a PITA, with this default behavior we can't use MixPanel correctly because we don't know the last seen date, it's overrided each time..... And the best the last seen data is lost for ever !

Max Queue Size Option Not Being Used.

It appears that in the enqueue function within MixpanelBaseProducer.php, the flush functionality only ever happens as a result of the protected _max_queue_size variable which is set to 1000. This happening despite there being support for setting a custom max_queue_size value in the MixpanelBase.php constuctor which is never actually referenced as one would expect to be happening.

Getting currently assigned random ID

Hello,

I'm starting out with Mixpanel. I'm currently facing the issue that starting the funnel a user is not logged in, and once he logs in, I cannot link both events together.

I've read on using alias, I've also seen the example php file about aliasing in this repository. However I don't understand how to get the original_id that Mixpanel randomly created for the not logged in user.

Thank you,

This library doesn't appear to be compatible with Identity Merge

Since our account upgraded to the new ID Merge Mixpanel, createAlias did not appear to function, or even register in the live data in Mixpanel.

e.g.
$mixpanel->createAlias($original_id, $wf_user_distinct_id);

doesn't result in an alias'd account or generate a Create Alias event in Mixpanel

$data = array(
			'event' => '$create_alias'
		,	'properties' => array(
				'distinct_id' => $original_id
			,	'alias' => $wf_user_distinct_id
			, 	'token' => '...'
		)
	);

and sending it over to api.mixpanel/track works totally fine

cURL response "upstream connect error or disconnect\/reset before headers"

Hi,
I sometimes have a problem when I want to create an alias for a user.

$mp = Mixpanel::getInstance("MIXPANEL_PROJECT_TOKEN", [
        'error_callback' => function($code, $msg){},
        'connect_timeout' => 20
    ]);
$mp->createAlias($distinct_id, $user_id);
$mp->flush();

In my function error_callback, the data comes in "code: 0; msg: upstream connect error or disconnect/reset before headers".

Does this problem affect my server or api.mixpanel.com? How to solve this problem for me?

Library doesn't work with Laravel Framework (artisan queue:work)

Hi,

My name is Steve and I'm using Mixpanel for my company.

I emailed you because I need help.

My company uses Laravel Framework for API and Mixpanel for tracking.

It seems like mixpanel-php doesn't work with laravel Job.

I use track function inside laravel job which is running by php artisan queue:work

and I found that in Producer - Consumer model of mixpanel-php, Pruducer works correctly and put message in queue, but Consumer dosen't work so that queue is keep increasing.

I try making queue reach max size which is 1000 and it worked becase of force flush.

I want to see the events realtime so cannot wait until queue reaches max size.

Is there any way to make consumer of mixpanel-php work on laravel job environment?

Thanks.

Make max_attempts value configurable in MixpanelBaseProducer destructor

The destructor from MixpanelBaseProduce is configured to retry 10 times before giving up but this can take a really long time in certain circumstances. For example, during today's API outage, it took around 2-3 seconds for each failure to register before moving on, so the entire retry cycle added around 20 to 30 seconds to the PHP script's lifetime.

That value should be configurable trough the options passed to Mixpanel::getInstance() to offer better flexibility in the way tracking is implemented.

Mixpanel does not comply with PSR-4

Mixpanel should be in its own namespace in order to comply:

https://www.php-fig.org/psr/psr-4/

A fully qualified class name has the following form:

\<NamespaceName>(\<SubNamespaceNames>)*\<ClassName>

  • The fully qualified class name MUST have a top-level namespace name, also known as a “vendor namespace”.
  • The fully qualified class name MAY have one or more sub-namespace names.
  • The fully qualified class name MUST have a terminating class name.
  • Underscores have no special meaning in any portion of the fully qualified class name.
  • Alphabetic characters in the fully qualified class name MAY be any combination of lower case and upper case.
  • All class names MUST be referenced in a case-sensitive fashion.

dd() making the package non-usable

There is a dump('proof') and a dd('stop') in the enqueue function which begins in MixpanelBaseProducer.php file, line 185 and it blocks the track() method

edit: Sorry I might have used a modified repo from a coworker without knowing it, there is no issue with this.

Socket connection fails with SSL error

exception 'ErrorException' with message 'fwrite(): SSL operation failed with code 1. OpenSSL Error messages:
error:1409F07F:SSL routines:SSL3_WRITE_PENDING:bad write retry' in /srv/levers/releases/20130919161055/vendor/mixpanel/mixpanel-php/lib/ConsumerStrategies/SocketConsumer.php:210

Solution: http://stackoverflow.com/questions/2997218/why-am-i-getting-error1409f07fssl-routinesssl3-write-pending-bad-write-retr

I may try to get a pull request up, but I don't usually deal with sockets (I just use Guzzle).

Global namespace pollution

Is there a reason that the this lib is designed to pollute the global namespace? It would be much cleaner if the lib was Mixpanel\Mixpanel or MixPanel\MixpanelClient and then users can alias the instance. I know it seems easy to just drop in a use Mixpanel and off you go but I would prefer being able to alias it and use my own local Mixpanel to override and extend the library.

https://github.com/jbboehr/mixpanel-php/commit/b7588810fdee78e51edba8eaa2a8f24c845f16ee
This is a good commit that helps conform the library to PSR and bring it into the modern era of php :)

Undefined offset: 1

We're running a queue and for some jobs we send events to mixpanel (for example to know when an email was sent to a user). In order to do this and ensure that the events are sent at the end of the job we have added the following into a ServiceProvider:

       Queue::after(function (JobProcessed $event) {
            $mixpanel = App::get(Mixpanel::class);
            $mixpanel->flush();
        });

Sometimes, when the app calls flush we see the following error:

[2020-06-19 10:01:23] production.ERROR: Undefined offset: 1 {"exception":"[object] (ErrorException(code: 0): Undefined offset: 1 at /var/app/current/vendor/mixpanel/mixpanel-php/lib/ConsumerStrategies/SocketConsumer.php:286)
[stacktrace]
#0 /var/app/current/vendor/mixpanel/mixpanel-php/lib/ConsumerStrategies/SocketConsumer.php(286): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleError(8, 'Undefined offse...', '/var/app/curren...', 286, Array)
#1 /var/app/current/vendor/mixpanel/mixpanel-php/lib/ConsumerStrategies/SocketConsumer.php(252): ConsumerStrategies_SocketConsumer->handleResponse('')
#2 /var/app/current/vendor/mixpanel/mixpanel-php/lib/ConsumerStrategies/SocketConsumer.php(122): ConsumerStrategies_SocketConsumer->_write(Resource id #990, false)
#3 /var/app/current/vendor/mixpanel/mixpanel-php/lib/Producers/MixpanelBaseProducer.php(219): ConsumerStrategies_SocketConsumer->persist(Array)
#4 /var/app/current/vendor/mixpanel/mixpanel-php/lib/Producers/MixpanelBaseProducer.php(119): Producers_MixpanelBaseProducer->_persist(Array)
#5 /var/app/current/vendor/mixpanel/mixpanel-php/lib/Mixpanel.php(182): Producers_MixpanelBaseProducer->flush(50)
#6 /var/app/current/app/Providers/AppServiceProvider.php(114): Mixpanel->flush()
#7 /var/app/current/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(369): App\\Providers\\AppServiceProvider->App\\Providers\\{closure}(Object(Illuminate\\Queue\\Events\\JobProcessed))
#8 /var/app/current/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(218): Illuminate\\Events\\Dispatcher->Illuminate\\Events\\{closure}('Illuminate\\\\Queu...', Array)
#9 /var/app/current/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(526): Illuminate\\Events\\Dispatcher->dispatch('Illuminate\\\\Queu...')
#10 /var/app/current/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(358): Illuminate\\Queue\\Worker->raiseAfterJobEvent('redis', Object(Illuminate\\Queue\\Jobs\\RedisJob))

It seems to be that in the handle_response method of the SocketConsumer the code expects a response that includes a space, but clearly that's not happening as $line_one_exploded doesn't have more than 1 value.

$status = $line_one_exploded[1];

How to catch exceptions?

How can I handle exceptions? Image Mixpanel goes down and I want to catch the exception on calling $mixpanel->people->set(1, $data); How can I find out whether it succeeded or not?

Parallel curl implementation

It would be nice to see this running multiple curl requests in parallel, rather than waiting for each one to finish before starting the next (using curl_multi_exec approach). This could add some great performance, especially when firing off a lot of analytics calls out.

Tests in Forked Project not working

Even though I ran composer install the tests are not running when using phpunit. It seams like they cannot even run as there is no phpunit.xml configuration file and no phpunit bootup file where you could autoload anything using composer.

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.