Simple Speedtest exporter for Prometheus written in Python using the official CLI from Ookla
You can get all the documentation here
Speedtest Exporter made in python using the official speedtest bin
Home Page: https://docs.miguelndecarvalho.pt/projects/speedtest-exporter/
License: GNU General Public License v3.0
Simple Speedtest exporter for Prometheus written in Python using the official CLI from Ookla
You can get all the documentation here
Requirements
typoserverID
from geerlingguy/internet-monitoring#19
Allowing to test on a list of server-id would be a good idea to get a good picture on how your isp performs on different nodes / countries.
Thanks.
Has anyone integrated this speediest-exporter into a https://github.com/carlosedp/cluster-monitoring deployment.
I already have the cluster-monitoring running and working great but struggling to understand how to add the speediest exporter to it. thanks for any help.
Hello,
I deployed this application on my Home Server using Docker, and the results are slowers using this application rather than using the Speedtest-cli.
The first line is the output of this speedtest-exporter. I let it ran a few hours and the results are not changing. Bellow the first line, this is the output of the speedtest-cli I just downloaded for the test. You can see there's a huge difference of bandwidth between them.
I am running on Windows 11 21H2 with Docker version 20.10.7
Docker command to create the container: docker run -d --name=speedtest-exporter -p 9798:9798 --restart unless-stopped miguelndecarvalho/speedtest-exporter
Specify currently supported architecures supported by the Docker Image
I've been troubleshooting why my speed test has been coming up so spotty and inaccurate. I have been pulling 650 to 950 on the regular speedtest on my laptop.
Once first started it will hit 800 Mbps(ish).. then drops rappidly....
Running: sudo docker exec -it internet-monitoring_speedtest_1 speedtest -v
Speedtest by Ookla
[warning] Receive error: 104 (Connection reset by peer)
[error] Error: [0] Cannot read:
[warning] Write error: 32 (Broken pipe)
[warning] Receive error: 104 (Connection reset by peer)
[warning] Timeout occurred in connect.
[error] Error: [0] Cannot open socket
Latency: 7.34 ms (2.24 ms jitter)
Download: 648.97 Mbps [\ ] 0%
After It has finished:
Speedtest by Ookla
Latency: 6.20 ms (1.98 ms jitter)
[warning] Receive error: 11 (Resource temporarily unavailable)
[warning] Receive error: 11 (Resource temporarily unavailable)
[warning] Receive error: 11 (Resource temporarily unavailable)
[warning] Receive error: 11 (Resource temporarily unavailable)
[warning] Receive error: 11 (Resource temporarily unavailable)
Download: FAILED
[error] Cannot read:
I've tried running.. but this didn't seem to work.
docker run -d --network host --name speedtest-exporter miguelndecarvalho/speedtest-exporter:v3.1
** FYI I removed the Server Info / Location above **
Hello! In order to challenge my ISP and show them that they are outside the terms of my contract, I need to show that my speeds have been less than 50% the advertised speed, for 3 days running.
The easiest way to prove this is by sharing the Speedtest URL results, which are returned by the cli tool, such as:
…
Upload: 20.93 Mbps (data used: 11.3 MB)
Packet Loss: 0.0%
Result URL: https://www.speedtest.net/result/c/31dcab17-xxxx-xxxx-xxxx-xxxxxxxxxxxx
(URL obscured).
I'd love if this python script could catch and then log these URLs. That way I could import them into Loki, and correlate logs with metrics in time, in order to find the slow examples to share with my ISP.
Migrate docs to my website
This will permit bot from updating the base image, with the current Arg
the bot won't update the image.
Running on Raspberry Pi B
And raspbian
VERSION="10 (buster)"
Output looks like this:
pi@raspberrypi:~ $ time curl localhost:9798
curl: (7) Failed to connect to localhost port 9798: Connection refused
real 0m1.589s
user 0m0.142s
sys 0m0.111s
pi@raspberrypi:~ $ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
88c3e0943d3b miguelndecarvalho/speedtest-exporter "python -u exporter.…" About a minute ago Restarting (139) 15 seconds ago speedtest-exporter
pi@raspberrypi:~ $ time curl localhost:9798
curl: (56) Recv failure: Connection reset by peer
real 0m3.523s
user 0m0.099s
sys 0m0.090s
pi@raspberrypi:~ $ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
88c3e0943d3b miguelndecarvalho/speedtest-exporter "python -u exporter.…" 2 minutes ago Up 5 seconds (health: starting) 0.0.0.0:9798->9798/tcp, :::9798->9798/tcp speedtest-exporter
pi@raspberrypi:~ $ time curl localhost:9798
curl: (7) Failed to connect to localhost port 9798: Connection refused
real 0m0.202s
user 0m0.107s
sys 0m0.078s
pi@raspberrypi:~ $ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
88c3e0943d3b miguelndecarvalho/speedtest-exporter "python -u exporter.…" 2 minutes ago Restarting (139) 22 seconds ago speedtest-exporter
speedtest_up
I have this Docker container running as part of the geerlingguy/internet-pi project, which I'm using to help diagnose issues with my ISP. It's mostly working great, but sometimes (once/twice per day) it encounters the following error in the logs:
`Something went wrong
Protocol error: Did not receive HELLO
28/09/2021 20:15:14 - Server: 0 | Jitter: 0 ms | Ping: 0 ms | Download: 0.0 Mb/s | Upload:0.0 Mb/s`
It would be helpful to know what this means, because when I see this happen my internet connection is usually still available. I can visit speedtest.net on another device and run a speedtest, or I can trigger the container to run a speedtest by visiting http://localhost:9798/metrics and I get results.
In case it matters, I'm using the container to run a speedtest every 15 minutes from a Raspberry Pi 4 (8GB) (Raspberry Pi OS 64 bit) with a wired connection to a gigabit lan network. My ISP plan is 400 mbps download and 20 mbps upload, though I normally get closer to 480 down and 24 up.
Any advice on what could be causing this protocol error?
Hey after you changed back to env instead of args its not possible to pass ENV interval to the speedtest
Hello,
I've been using your speedtest-exporter in my personal first tests with Raspberry, it is even the first time for me in Python.
I want to specify a specific speed-test server to be used which I know is reliable.
In my docker-compose.yml
I've this portion of code:
speedtest:
tty: true
stdin_open: true
expose:
- 9798
ports:
- 9798:9798
image: miguelndecarvalho/speedtest-exporter
container-name: speedtest-exporter
environment:
#- SPEEDTEST_PORT= #optional
- SPEEDTEST_SEVER=11427
restart: always
networks:
- back-tier
But it seems not working, looking at the metrics of speedtest-exporter the SERVER being used is different.
What am I missing here?
Thanks
Use Waitress
wsgi production server instead of uWSGI
When running manually (not via Docker) on a RaspberryPi, I see this error on the /metrics endpoint:
File "src/exporter.py", line 79, in updateResults
r_server, r_jitter, r_ping, r_download, r_upload, r_status = runTest()
TypeError: cannot unpack non-iterable NoneType object
But the speedtest cli tool works fine:
pi@raspberrypi:~ $ speedtest
Retrieving speedtest.net configuration...
Testing from Virgin Media (82.25.24.40)...
Retrieving speedtest.net server list...
Selecting best server based on ping...
Hosted by Community Fibre Limited (London) [2.31 km]: 29.152 ms
Testing download speed................................................................................
Download: 28.14 Mbit/s
Testing upload speed......................................................................................................
Upload: 18.90 Mbit/s
This will make sense because of this #51
Args
will override all the Envs
Change default port to: 9798
Logs show
[2021-04-15 14:16:46.303] [error] Configuration - Cannot retrieve configuration document (0)
,[2021-04-15 14:16:46.304] [error] ConfigurationError - Could not retrieve or read configuration (Configuration)
,[2021-04-15 14:16:46.304] [error] ConfigurationError - Could not retrieve or read configuration (Configuration)
,{
, "type": "log",
, "timestamp": "2021-04-15T14:16:46Z",
, "message": "Configuration - Could not retrieve or read configuration (ConfigurationError)",
, "level": "error"
,}
,ERROR:Speedtest-Exporter:Exception on /metrics [GET]
,Traceback (most recent call last):
, File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2447, in wsgi_app
, response = self.full_dispatch_request()
, File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1952, in full_dispatch_request
, rv = self.handle_user_exception(e)
, File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1821, in handle_user_exception
, reraise(exc_type, exc_value, tb)
, File "/usr/local/lib/python3.9/site-packages/flask/_compat.py", line 39, in reraise
, raise value
, File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1950, in full_dispatch_request
, rv = self.dispatch_request()
, File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1936, in dispatch_request
, return self.view_functionsrule.endpoint
, File "/app/exporter.py", line 70, in updateResults
, r_server, r_jitter, r_ping, r_download, r_upload, r_status = runTest()
, File "/app/exporter.py", line 47, in runTest
, output = subprocess.check_output(cmd)
, File "/usr/local/lib/python3.9/subprocess.py", line 424, in check_output
, return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
, File "/usr/local/lib/python3.9/subprocess.py", line 528, in run
, raise CalledProcessError(retcode, process.args,
,subprocess.CalledProcessError: Command '['speedtest', '--format=json-pretty', '--progress=no', '--accept-license', '--accept-gdpr']' returned non-zero exit status 2.
,[2021-04-15 14:38:22.019] [error] Trying to get interface information on non-initialized socket.
,[2021-04-15 14:38:27.535] [error] Configuration - Couldn't resolve host name (HostNotFoundException)
,[2021-04-15 14:38:27.535] [error] Configuration - Cannot retrieve configuration document (0)
,[2021-04-15 14:38:27.536] [error] ConfigurationError - Could not retrieve or read configuration (Configuration)
,[2021-04-15 14:38:27.536] [error] ConfigurationError - Could not retrieve or read configuration (Configuration)
,{
, "type": "log",
, "timestamp": "2021-04-15T14:38:27Z",
, "message": "Configuration - Could not retrieve or read configuration (ConfigurationError)",
, "level": "error"
,}
,ERROR:Speedtest-Exporter:Exception on /metrics [GET]
,Traceback (most recent call last):
, File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2447, in wsgi_app
, response = self.full_dispatch_request()
, File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1952, in full_dispatch_request
, rv = self.handle_user_exception(e)
, File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1821, in handle_user_exception
, reraise(exc_type, exc_value, tb)
, File "/usr/local/lib/python3.9/site-packages/flask/_compat.py", line 39, in reraise
, raise value
, File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1950, in full_dispatch_request
, rv = self.dispatch_request()
, File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1936, in dispatch_request
, return self.view_functionsrule.endpoint
, File "/app/exporter.py", line 70, in updateResults
, r_server, r_jitter, r_ping, r_download, r_upload, r_status = runTest()
, File "/app/exporter.py", line 47, in runTest
, output = subprocess.check_output(cmd)
, File "/usr/local/lib/python3.9/subprocess.py", line 424, in check_output
, return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
, File "/usr/local/lib/python3.9/subprocess.py", line 528, in run
, raise CalledProcessError(retcode, process.args,
,subprocess.CalledProcessError: Command '['speedtest', '--format=json-pretty', '--progress=no', '--accept-license', '--accept-gdpr']' returned non-zero exit status 2.
,[2021-04-15 16:28:01.854] [error] Trying to get interface information on non-initialized socket.
,[2021-04-15 16:28:07.373] [error] Configuration - Couldn't resolve host name (HostNotFoundException)
,[2021-04-15 16:28:07.373] [error] Configuration - Cannot retrieve configuration document (0)
,[2021-04-15 16:28:07.374] [error] ConfigurationError - Could not retrieve or read configuration (Configuration)
,[2021-04-15 16:28:07.374] [error] ConfigurationError - Could not retrieve or read configuration (Configuration)
,{
, "type": "log",
, "timestamp": "2021-04-15T16:28:07Z",
, "message": "Configuration - Could not retrieve or read configuration (ConfigurationError)",
, "level": "error"
,}
,ERROR:Speedtest-Exporter:Exception on /metrics [GET]
,Traceback (most recent call last):
, File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2447, in wsgi_app
, response = self.full_dispatch_request()
, File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1952, in full_dispatch_request
, rv = self.handle_user_exception(e)
, File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1821, in handle_user_exception
, reraise(exc_type, exc_value, tb)
, File "/usr/local/lib/python3.9/site-packages/flask/_compat.py", line 39, in reraise
, raise value
, File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1950, in full_dispatch_request
, rv = self.dispatch_request()
, File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1936, in dispatch_request
, return self.view_functionsrule.endpoint
, File "/app/exporter.py", line 70, in updateResults
, r_server, r_jitter, r_ping, r_download, r_upload, r_status = runTest()
, File "/app/exporter.py", line 47, in runTest
, output = subprocess.check_output(cmd)
, File "/usr/local/lib/python3.9/subprocess.py", line 424, in check_output
, return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
, File "/usr/local/lib/python3.9/subprocess.py", line 528, in run
, raise CalledProcessError(retcode, process.args,
,subprocess.CalledProcessError: Command '['speedtest', '--format=json-pretty', '--progress=no', '--accept-license', '--accept-gdpr']' returned non-zero exit status 2.
,
This is my first issue on GitHub, so if I'm missing anything context or formatting wise, please correct me. I'm trying to force a specific speedtest server because there is one near me (32032) that is always slow. I tried using the
environment:
SPEEDTEST_SERVER=19299
in docker-compose.yml to force it to use the server I want.
speedtest:
tty: true
stdin_open: true
environment:
- SPEEDTEST_SERVER=19229
expose:
- 9798
ports:
- 9798:9798
image: miguelndecarvalho/speedtest-exporter
restart: always
networks:
- back-tier
It doesn't seem to be working because it's still using whatever server it wants according to the metrics.
# TYPE speedtest_server_id gauge
speedtest_server_id #14231.0
Sometimes the speedtest binary stalls and eventually waitress refuses to create more threads.
This results in no more tests being run and no metrics being presented to prometheus
The logs include:
WARNING:waitress.queue:Task queue depth is 1
WARNING:waitress.queue:Task queue depth is 2
WARNING:waitress.queue:Task queue depth is 3
WARNING:waitress.queue:Task queue depth is 4
WARNING:waitress.queue:Task queue depth is 5
WARNING:waitress.queue:Task queue depth is 6
WARNING:waitress.queue:Task queue depth is 7
WARNING:waitress.queue:Task queue depth is 8
WARNING:waitress.queue:Task queue depth is 9
Container shows multiple speedtests running:
When stalled speedtest processes are killed things return to normal.
A possible solution would be to have a timeout for the subprocess execution that would kill the thread if the speedtest was taking longer than expected.
Release v3.2.0
Hi,
I've encoutered a problem where speeds from the container are not representative of real speeds.
Left term: speeds in docker container
Right term: speeds with speedtest-cli executable running on windows 10
Both of them are running speedtest 1.0.0.2
Also notice this behavior on Ubuntu 20.04.1 LTS (GNU/Linux 5.4.0-70-generic x86_64) with Docker version 20.10.2, build 2291f61
Have i messed up something ? or is it expected ?
EDIT - Seems that Ookla app is working properly and that my internet is faster than I realized. Seems speedtest-cli is written in Python and can't get as high of a speed as the Ookla app.
Download speeds are being reported artificially high due to Ookla client 1.0.0.2 on Raspberry PI OS with Pi 4.
My internet circuit is 300Mbps download, yet the Speedtest-exporter using Ookla client 1.0.0.2 is consistently showing 600-700Mbps.
This is happening both inside the container, as well as when using Speedtest 1.0.0.2 directly from the main OS.
I discovered this after setting up https://github.com/geerlingguy/internet-pi which is using MiguelNdeCarvalho/speedtest-exporter.
It seems the latest Speedtest CLI program is significantly different (input parameters and output JSON), so I can't simply update the Dockerfile with the latest version of the Speedtest CLI.
Using a new Raspberry Pi 4 with 4GB of RAM and Raspberry Pi OS 11 (bullseye). Latest as of 2021-12-28.
pi@raspberrypi:/tmp $ cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 11 (bullseye)"
NAME="Raspbian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
------------------------------------------------------------------------------------
pi@raspberrypi:/tmp $ ./speedtest --version
Speedtest by Ookla 1.0.0.2 (5ae238b) Linux/arm-linux-musleabi 5.10.63-v7l+ arm/armv7l
The official command line client for testing the speed and performance
of your internet connection.
pi@raspberrypi:/tmp $ ./speedtest
Speedtest by Ookla
Server: Whitesky Communications LLC - Chicago, IL (id = 23097)
ISP: Comcast Cable
Latency: 10.71 ms (2.99 ms jitter)
Download: 700.53 Mbps (data used: 1.2 GB)
Upload: 20.16 Mbps (data used: 11.8 MB)
Packet Loss: 0.0%
Result URL: https://www.speedtest.net/result/c/528fdaec-cb46-44cd-a268-f74547da166f
=======================================================================================
pi@raspberrypi:/tmp $ speedtest --version
speedtest-cli 2.1.3
Python 3.9.2 (default, Mar 12 2021, 04:06:34) [GCC 10.2.1 20210110]
pi@raspberrypi:/tmp $ speedtest
Retrieving speedtest.net configuration...
Testing from Comcast Cable (73.22.57.XXX)...
Retrieving speedtest.net server list...
Selecting best server based on ping...
Hosted by Hivelocity (Chicago, IL) [54.34 km]: 15.817 ms
Testing download speed................................................................................
Download: 258.32 Mbit/s
Testing upload speed......................................................................................................
Upload: 18.31 Mbit/s
Add welcome print like we had back in the old days
OS is Ubuntu 20.04 running Docker version 19.03.12, build 48a66213fe.
I have tried this inside & outside of rancher, but the same error shows up in the logs.
Successfully started Speedtest Exporter on http://localhost:9112
Traceback (most recent call last):
File "src/exporter.py", line 59, in
run(PORT, SLEEP)
File "src/exporter.py", line 48, in run
test = run_speedtest()
File "src/exporter.py", line 29, in run_speedtest
output = subprocess.check_output(cmd)
File "/usr/local/lib/python3.8/subprocess.py", line 411, in check_output
return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
File "/usr/local/lib/python3.8/subprocess.py", line 512, in run
raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['speedtest', '--format=json-pretty', '--progress=no', '--accept-license', '--accept-gdpr']' returned non-zero exit status 2.
Successfully started Speedtest Exporter on http://localhost:9112
[2020-10-05 15:36:53.716] [error] Trying to get interface information on non-initialized socket.
Traceback (most recent call last):
File "src/exporter.py", line 59, in
run(PORT, SLEEP)
File "src/exporter.py", line 48, in run
test = run_speedtest()
File "src/exporter.py", line 29, in run_speedtest
output = subprocess.check_output(cmd)
File "/usr/local/lib/python3.8/subprocess.py", line 411, in check_output
return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
File "/usr/local/lib/python3.8/subprocess.py", line 512, in run
raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['speedtest', '--format=json-pretty', '--progress=no', '--accept-license', '--accept-gdpr']' returned non-zero exit status 2.
Successfully started Speedtest Exporter on http://localhost:9112
when I go to http://<ip_of_node>:9112, I get this:
python_gc_objects_collected_total{generation="0"} 274.0
python_gc_objects_collected_total{generation="1"} 66.0
python_gc_objects_collected_total{generation="2"} 0.0
python_gc_objects_uncollectable_total{generation="0"} 0.0
python_gc_objects_uncollectable_total{generation="1"} 0.0
python_gc_objects_uncollectable_total{generation="2"} 0.0
python_gc_collections_total{generation="0"} 35.0
python_gc_collections_total{generation="1"} 3.0
python_gc_collections_total{generation="2"} 0.0
python_info{implementation="CPython",major="3",minor="8",patchlevel="6",version="3.8.6"} 1.0
process_virtual_memory_bytes 2.2618112e+07
process_resident_memory_bytes 1.6310272e+07
process_start_time_seconds 1.60191257567e+09
process_cpu_seconds_total 0.8
process_open_fds 8.0
process_max_fds 1.048576e+06
speedtest_ping_latency_milliseconds 0.0
speedtest_download_bits_per_second 0.0
speedtest_upload_bits_per_second 0.0
seems like it is not running. I did add this as you suggested & that got rid of the above error: -e SPEEDTEST_SERVER=31309.
Hi,
I'm seeing rate limit errors when running this using the k8s-at-home
chart (located here: https://github.com/k8s-at-home/charts/tree/master/charts/stable/speedtest-exporter) ... I was originally executing from Prometheus every 60 seconds (the default scrape_interval
) - but even when changing this to be every 20 minutes, I still get the following in the logs:
speedtest-exporter-7bdb658f7b-bzk8x speedtest-exporter [2021-09-01 14:51:51.336] [error] Limit reached:
speedtest-exporter-7bdb658f7b-bzk8x speedtest-exporter
speedtest-exporter-7bdb658f7b-bzk8x speedtest-exporter <html>
speedtest-exporter-7bdb658f7b-bzk8x speedtest-exporter <head><title>429 Too Many Requests</title></head>
speedtest-exporter-7bdb658f7b-bzk8x speedtest-exporter <body>
speedtest-exporter-7bdb658f7b-bzk8x speedtest-exporter <center><h1>429 Too Many Requests</h1></center>
speedtest-exporter-7bdb658f7b-bzk8x speedtest-exporter <hr><center>openresty</center>
speedtest-exporter-7bdb658f7b-bzk8x speedtest-exporter </body>
speedtest-exporter-7bdb658f7b-bzk8x speedtest-exporter </html>
speedtest-exporter-7bdb658f7b-bzk8x speedtest-exporter
speedtest-exporter-7bdb658f7b-bzk8x speedtest-exporter 01/09/2021 14:51:51 - Server: 0 | Jitter: 0 ms | Ping: 0 ms | Download: 0.0 Mb/s | Upload:0.0 Mb/s
Any suggestions on how to handle this, please? :)
Updates on the documentation:
...
Hello,
I am trying to set up an internet-monitor (https://github.com/geerlingguy/internet-monitoring).
I found out, that the container "miguelndecarvalho/speedtest-exporter" is constantly restarting,
after some time i found this error:
2021-05-22T09:00:23.237123289Z Current thread 0xb6f42390 (most recent call first):
2021-05-22T09:00:23.237165881Z <no Python frame>
2021-05-22T09:00:51.062463283Z Fatal Python error: init_interp_main: can't initialize time
2021-05-22T09:00:51.068656543Z Python runtime state: core initialized
2021-05-22T09:00:51.068740690Z PermissionError: [Errno 1] Operation not permitted
I am running this project on a RaspberryPi 4GB with RaspberryPi OS 64x
I left everything at the default configuration.
Can anyone help me?
Thanks.
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.