ipinfo / cli Goto Github PK
View Code? Open in Web Editor NEWOfficial Command Line Interface for the IPinfo API (IP geolocation and other types of IP data)
Home Page: https://ipinfo.io/
License: Apache License 2.0
Official Command Line Interface for the IPinfo API (IP geolocation and other types of IP data)
Home Page: https://ipinfo.io/
License: Apache License 2.0
Another utility that it'd be great to add to the cli is the ability to convert from cidr to start,end ranges. We commonly do this internally at IPinfo, and our customers sometimes need to do it with our data exports too.
Eg. input:
1.1.1.0,1.1.1.255,other data
Output:
1.1.1.0/24,other data
And vice versa. Should probably support a different range sepator too (eg. 1.1.1.0-1.1.1.255).
In the initial version we won't have proper shell auto-completion.
There exist some completion frameworks in Golang but they were too buggy and/or didn't support our flag format.
Most preferable would be finding a tool that auto-generates some completion script in whatever language (doesn't have to be Golang), and we include it in the package.
The documentation is unclear.
How to get Json output?
ipinfo -j myip
doesn't work.
How to get one field?
ipinfo -f City myip
doesn't work.
goroutine 1 [running]:
encoding/binary.bigEndian.Uint32(...)
/usr/lib/go-1.17/src/encoding/binary/binary.go:112
github.com/ipinfo/cli/lib.IPFromStdIP({0x0, 0xc00001c180, 0x827dae})
/go/pkg/mod/github.com/ipinfo/[email protected]/lib/ip.go:24 +0x45
github.com/ipinfo/cli/lib.CmdGrepIP.func1({0x7fff8e9fa9fa, 0x13}, {0x82db00, 0xc000010550})
/go/pkg/mod/github.com/ipinfo/[email protected]/lib/cmd_grepip.go:265 +0x766
github.com/ipinfo/cli/lib.CmdGrepIP.func2({0x7fff8e9fa9fa, 0x13})
/go/pkg/mod/github.com/ipinfo/[email protected]/lib/cmd_grepip.go:326 +0x5f
github.com/ipinfo/cli/lib.CmdGrepIP({0x1, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1}, {0xc000071a20, 0x1, ...}, ...)
/go/pkg/mod/github.com/ipinfo/[email protected]/lib/cmd_grepip.go:343 +0x8a2
main.cmdGrepIP()
/go/pkg/mod/github.com/ipinfo/[email protected]/ipinfo/cmd_grepip.go:65 +0x105
main.main()
/go/pkg/mod/github.com/ipinfo/[email protected]/ipinfo/main.go:55 +0x1ef
There's actually so many features in the CLI so far for different commands that it's not reasonable to lay everything out in the README or in the inlined -h
/--help
output.
We should create man pages for individual commands which go into full details of what's possible and which can be accessible in these two ways:
$ man 1 ipinfo-<subcommand>
$ ipinfo <subcommand> --help
This is similar to what git does, e.g.:
$ man 1 git-init
$ git init --help
Need to also figure out how this works in a PowerShell (windows) environment.
Allow toggling the cache on or off, globally or per run.
This requires saving the setting in a file somewhere. We should use boltdb to store all settings, including the token, as a key/value pair.
Right now we're not allowing specifying CIDRs+ranges+IPs at the same time, e.g. this doesn't work:
$ ipinfo bulk 1.1.1.1 8.8.8.0/24
The main reason this was hard to do is because we allow specifying ranges as <ip_start> <ip_end>
, which is hard to distinguish from 2 normal IPs.
To fix this, just change IP range format to be <ip_start>-<ip_end>
, and so any <ip1> <ip2>
form is just 2 IPs.
We should implement a file-based cache with a relatively low TTL so that users can save on their quota for repeatedly asking for the same data, especially in batch operations.
The TTL and such details should be configurable if possible.
The cache should be ignorable by a flag on any command that uses the cache.
Some nested cache management subcommands should exist to e.g. clear the cache.
CLI currently lets you paste in an existing API token. It'd be awesome if it supported signing up for a new token and creating an account from the CLI. Would need some web changes, and not needed for v1, but we should think through what this flow might look like.
Presently the utility would just return an IP defined at the start of a CIDR block or the IPs on either end of an IP range.
It would be great to have options that match these formats, or have such a functionality be the default.
Originally tracking this work in #3 but splitting this out as a more specific issue.
Allow users to download and get automatic updates for our binaries via Linux distribution package managers such as:
The package's feature set looks and feels ready for a v1 release. But we need to do the following:
Right after the repo is public, we can:
There may be things you guys have planned @coderholic @kennethkhaw like a blog or something. I'm not in the loop on that so, if that's a blocker let me know.
Make it easier to get a single field for IPs.
Eg. if I want to get the hostname for some IPs I need to do this currently:
$ echo -e "8.8.8.8\n1.1.1.1" | ./ipinfo bulk | jq -r '.[] | .hostname'
one.one.one.one
dns.google
It'd be easier for the user to do something like:
$ echo -e "8.8.8.8\n1.1.1.1" | ./ipinfo hostname'
8.8.8.8,one.one.one.one
1.1.1.1,dns.google
We could support a few key fields, or make a generic jq style lookup key (so hostname, asn.asn, company.type etc)
The cli says the login was successful whether the token is valid or not.
Steps to reproduce:
ipinfo login
Write any random string. The CLI does not validate it. It will say the token was configured.
ipinfo 1.1.1.1
The CLI informs the credentials and the token is incorrect, even though the login
subcommand previously informed the token is correct.
Installing the program is not creating ipinfo
folder inside .config
folder by default that results a cache error
$ ipinfo 8.8.8.8
warn: cache will not be used: error opening database: open /home/umar/.config/ipinfo/cache.boltdb: no such file or directoryCore
- IP 8.8.8.8
- Anycast true
- Hostname dns.google
- City Mountain View
- Region California
- Country United States (US)
- Location 37.4056,-122.0775
- Organization AS15169 Google LLC
- Postal 94043
- Timezone America/Los_Angeles
Couldn't find anywhere that we're currently setting the user agent.
We should set it to something like IPinfoCli/$version
. We could include additional system too, so we can track usage across OS etc. The stripe npm package does uname -a
on the first initialization and adds those details to the useragent (see https://github.com/stripe/stripe-node/blob/c85a597f15a225c3b52f90224b4749ad138a9a8c/lib/stripe.js#L427) - not sure we need all those details, but we could do something similar
Reported via twitter: https://twitter.com/philBE2/status/1395060460127494147
$ ipinfo as15169
err: GET https://ipinfo.io/AS15169: 401 { }
$ ipinfo AS15169
err: GET https://ipinfo.io/AS15169: 401 { }
https://ipinfo.io/AS15169 is a legit ASN
I have a proxy set up on my machine, with a global http_proxy env variable so i can fetch ipinfo via curl
is there a way to make the ipinfo cli tool go through the proxy?
Examples include:
2001:2030:21:18f::27dc
2001:2030:21:1a0::27dc
2001:2030:21:1a1::27dc
2001:2030:21:1a6::27dc
2001:2030:21:1b5::27dc
2001:2030:22::3e73:fdca
2001:2030:22::3e73:fde8
2001:4998:64:800::6000
2001:4998:64:800::6001
2400:3200:1500::f9
2401:8700:ff04::28
2401:b180:2000:30::2e
2401:b180:2000:50::e
2401:b180:2000:60::13
2401:b180:2000:80::10
2401:b180:7003::1fb
2401:b180:7003::8c
2402:4e00:40:40::2:30f
2402:4e00:8020:2::53
2402:4e00:8030:1::83
2402:4e00:8030:1::84
2408:4001:f00::117
2408:4001:f00::135
2408:4001:f00::19
2408:4001:f00::1af
2408:4001:f00::1b7
2408:4001:f00::1c9
2408:4001:f00::1fa
2408:4001:f00::20d
2408:4001:f00::21
2408:4001:f00::251
2408:4001:f00::289
2408:4001:f00::29f
2408:4001:f00::2ea
2408:4001:f00::2f
2408:4001:f00::b4
2408:4001:f10::fd
2408:4002:1f10::109
2408:4004:1f8::1a1
2408:80f1:100:1010::29
2408:80f1:100:1010::d
2408:80f1:21:4013::84
2408:80f1:21:4013::88
2408:80f1:31:10::4f
2408:8711:10:10::55
2408:8752:0:2:30::1
2408:8752:0:2:30::2
2408:8752:0:2:30::3
2408:8752:0:2:30::4
2408:8752:0:30:30::1
2408:8752:0:30:30::2
2408:8752:0:e:30::1
2408:8752:0:e:30::2
2408:8752:0:e:30::4
2408:8756:3af0:10::16a
240d:c040:0:40::116
240d:c040:1:40::11d
240e:83:201:110::7
240e:83:201:4d10::3df9
240e:b1:a810:1800::6a75:d82a
240e:ff:f101:10::1a0
240e:ff:f101:10::1a3
2600:1409:7800::17dd:df12
2600:1409:7800::17dd:df39
2600:1409:9800:784::27dc
2600:1409:9800:786::27dc
2600:1409:9800:788::27dc
2600:1409:9800:78a::27dc
2600:1409:9800:78c::27dc
2600:3c02::f03c:91ff:fee2:5b0f
2604:980:7002:6::2c
2604:980:7002:6::2d
2606:4700:3033::6815:4699
2606:4700:3033::ac43:a864
2606:ae80:1451:22::820
2607:a400:2:b::4
2607:f8b0:400a:801::2008
2607:f8b0:400a:801::200e
2607:f8b0:400a:80a::2001
2607:f8b0:400a:80b::2002
2607:f8b0:400a:80b::2006
2620:1ec:46::70
2620:1ec:bdf::70
2a00:1288:80:800::7000
2a00:1288:80:800::7001
2a00:1450:4010:c08::64
2a00:1450:4010:c08::65
2a00:1450:4010:c08::8a
2a00:1450:4010:c08::8b
2a00:1450:4010:c0b::9a
2a00:1450:4010:c0b::9b
2a00:1450:4010:c0b::9c
2a00:1450:4010:c0b::9d
2a01:53c0:ff0f::2e
2a01:53c0:ff0f::34
2a0d:5300:10::2
2a0d:5300:10::3
should support json, csv and pretty output for most commands. If it already does it's not documented in the usage output
Allow users to download a docker image from DockerHub which contains the CLI, and then run a container using that image as a one-off execution.
Seeing Andrew's tweet just inspired an idea https://twitter.com/Andrew___Morris/status/1375516879351992320?s=03
I have this alias in my bash:
$ alias gip
alias gip='grep -Eo "([0-9]{1,3}\.){3}[0-9]{1,3}"'
but andrew is doing filtering of localhost and bogons. It'd be awesome to wrap this all up into a tiny standalone utility, eg:
grepip
Anything else?
This could be a subcommand of the ipinfo command, but it could be something we could release as a standalone tool too.
Eg this should return the details for 1.1.1.1, so default to bulk:
$ echo "8.8.8.8" | ./ipinfo bulk
{
"8.8.8.8": {
"ip": "8.8.8.8",
"hostname": "dns.google",
"anycast": true,
"city": "Mountain View",
"region": "California",
"country": "US",
"country_name": "United States",
"loc": "37.4056,-122.0775",
"org": "",
"postal": "94043",
"timezone": "America/Los_Angeles",
"asn": {
"asn": "AS15169",
"name": "Google LLC",
"domain": "google.com",
"route": "8.8.8.0/24",
"type": "business"
},
"company": {
"name": "Google LLC",
"domain": "google.com",
"type": "business"
}
}
}
As we add more binaries, we should make it easier to discover them from the README, but without sacrificing the spotlight provided to the ipinfo
binary specifically. Right now there's little to no indication that anything besides ipinfo
exists, unless you look at the releases yourself or look at the code.
bigmac:bin michael$ ipinfo myip
Core
- IP 147.**.*.*
- Anycast false
- Hostname *****
- City Santa Clara
- Region California
- Country United States (US)
- Location
- Organization AS396097 Sail Internet, Inc.
- Postal 9***
- Timezone America/Los_Angeles
We can distribute the binary for each platform via Github initially so it can be installed with curl
/wget
/etc, but it'd be even better if developers (the most likely users here) could grab it via their OS distributor's package repo. This could give us auto-completion automatically as well without a separate install step for that.
We can start with making it available via Ubuntu's package repos first, and/or make our own PPA.
I don't use macOS so not sure of the distribution model there (I think most people use Homebrew?), but we can look into that afterwards.
Allow generating only unique random IPs with the --unique, -u
flag.
This requires making a map[u32]struct{}
to store all the IPs we've seen so far and which we can access fast to check for uniqueness on the following generations.
Of course the limitation here is it'll consume a lot of memory for a huge number of desired generations, but that use case should be rare and presumably the host machine that needs to be working on that many random IPs will already have plenty of memory.
Any chance of making Homebrew packages for MacOS users?
==> Upgrading 1 outdated package:
ipinfo-cli 1.1.3 -> 1.1.5
==> Upgrading ipinfo-cli 1.1.3 -> 1.1.5
==> Downloading https://ghcr.io/v2/homebrew/core/ipinfo-cli/manifests/1.1.5
######################################################################## 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/ipinfo-cli/blobs/sha256:215f6613824d7d14ff932d2aa835be7858fe62c046dfe2e22d3bf170f75c0f1c
==> Downloading from https://pkg-containers.githubusercontent.com/ghcr1/blobs/sha256:215f6613824d7d14ff932d2aa835be7858fe62c046dfe2e22d3bf170f75c0f1c?se=2021-
######################################################################## 100.0%
==> Pouring ipinfo-cli--1.1.5.catalina.bottle.tar.gz
🍺 /usr/local/Cellar/ipinfo-cli/1.1.5: 5 files, 7.3MB
Removing: /usr/local/Cellar/ipinfo-cli/1.1.3... (5 files, 7.3MB)
Removing: /Users/bierman/Library/Caches/Homebrew/ipinfo-cli--1.1.3... (3.8MB)
cleaning up brew...
Error: 767: unexpected token at '{
"ipinfo-cli": "homebrew/core"
"grepip": "homebrew/core"
}
'
Please report this issue:
https://docs.brew.sh/Troubleshooting
/usr/local/Homebrew/Library/Homebrew/vendor/portable-ruby/2.6.3_2/lib/ruby/2.6.0/json/common.rb:156:in `parse'
/usr/local/Homebrew/Library/Homebrew/vendor/portable-ruby/2.6.3_2/lib/ruby/2.6.0/json/common.rb:156:in `parse'
/usr/local/Homebrew/Library/Homebrew/tap.rb:605:in `tap_migrations'
/usr/local/Homebrew/Library/Homebrew/formulary.rb:322:in `formula_name_path'
/usr/local/Homebrew/Library/Homebrew/formulary.rb:302:in `initialize'
/usr/local/Homebrew/Library/Homebrew/formulary.rb:508:in `new'
/usr/local/Homebrew/Library/Homebrew/formulary.rb:508:in `loader_for'
/usr/local/Homebrew/Library/Homebrew/formulary.rb:404:in `factory'
/usr/local/Homebrew/Library/Homebrew/formulary.rb:452:in `from_keg'
/usr/local/Homebrew/Library/Homebrew/formulary.rb:425:in `from_rack'
/usr/local/Homebrew/Library/Homebrew/cleanup.rb:85:in `stale_formula?'
/usr/local/Homebrew/Library/Homebrew/cleanup.rb:58:in `stale?'
/usr/local/Homebrew/Library/Homebrew/cleanup.rb:321:in `block in cleanup_cache'
/usr/local/Homebrew/Library/Homebrew/cleanup.rb:304:in `each'
/usr/local/Homebrew/Library/Homebrew/cleanup.rb:304:in `cleanup_cache'
/usr/local/Homebrew/Library/Homebrew/cleanup.rb:192:in `clean!'
/usr/local/Homebrew/Library/Homebrew/cmd/cleanup.rb:58:in `cleanup'
/usr/local/Homebrew/Library/Homebrew/brew.rb:122:in `<main>'
store token inside the ~/.config/ipinfo/config.json
file and allow to configure it using $ ipinfo config token=<tok>
Flags like ipinfo --help
or ipinfo -h
are not getting suggested in auto-completion; only the subcommands are.
This is a bug in the completion fork we made: fix it to ensure it recommends flags along with subcommands in such a context.
is there any option to get ipinfo of a domain name?
suppose ipinfo google.com
would be very much useful with DDNS domains
Right now we don't support looking up ASNs in bulk, but it's a useful feature to have.
In the process, we should actually support mixing together IPs & ASNs in one bulk lookup, by default.
And as a further improvement to the API, we should deprecate the bulk
subcommand and allow automatically looking up things in bulk via e.g. ipinfo 1.1.1.1 8.8.8.8
if the number of inputs is more than 1.
Here's a specific checklist of things to consider:
bulk
subcommand anymore, so write a msg calling it deprecatedipinfo AS1-AS5
, which gives ipinfo AS1 AS2 AS3 AS4 AS5
.I probably assume that you assume all consoles on Windows handles
ANSI-sequences. Mine does, but I've turned that off for various reasons.
And I'm now left with this junk output:
f:\MingW32\src\inet\IP-geo\IPinfo-CLI>ipinfo.exe 8.8.8.8
Core
- ←[36mIP ←[0m ←[32m8.8.8.8←[0m
- ←[36mAnycast ←[0m ←[32mtrue←[0m
- ←[36mHostname ←[0m ←[32mdns.google←[0m
- ←[36mCity ←[0m ←[32mMountain View←[0m
- ←[36mRegion ←[0m ←[32mCalifornia←[0m
- ←[36mCountry ←[0m ←[32mUnited States (US)←[0m
- ←[36mLocation ←[0m ←[32m37.4056,-122.0775←[0m
- ←[36mOrganization←[0m ←[32mAS15169 Google LLC←[0m
- ←[36mPostal ←[0m ←[32m94043←[0m
- ←[36mTimezone ←[0m ←[32mAmerica/Los_Angeles←[0m
Could someone in 2021 please detect that such codes are effective before using them?
AFAIK, a GetConsoleMode()
and test for ENABLE_VIRTUAL_TERMINAL_PROCESSING
should do it.
Ref: https://docs.microsoft.com/en-us/windows/console/getconsolemode
Otherwise this is pretty cool program.
There's a lot to be thought of here, but we can definitely start with something impactful and real use cases we've hit that a CLI could've made easier.
We should do the following, at least:
Look into the greynoise CLI for some motivation: https://github.com/GreyNoise-Intelligence/pygreynoise
What's interesting is they have a "GNQL", a domain-specific query language for their data. I don't know if we want to invent something like that, but it might be possible and provide insane flexibility without having to update the CLI at all for new use cases.
Another thing that catches my eye is that you can check your account details from the CLI. Sounds like an easy add for us since we already have APIs for it. So you could check your usage via the CLI, for example.
In general, I think the main motivation from this is that we want the CLI to allow some pretty tough data manipulation on IPinfo data to become much smoother, powerful and flexible.
Consider a way to make use cases like https://github.com/ipinfo/web/issues/2544#issuecomment-714022130 a lot simpler.
It seems like we'd really want to be able to do a bunch of transforms on a large set of data. I.e., get the result for all these IPs or ASNs, and then do some useful transform for all of them, expressed in a simple way, and give me result X.
See other users' use cases that they've tried to achieve via bash, e.g. https://github.com/niklasberglund/ipinfo.
This one at least looks very simple. I was thinking of a very simple feature to cover this along the lines of: ipinfo fmt <ip> <fmt-string>
, with format flags like %c
for city, %tz
for timezone, etc.
Similar to grepip
, but for domains! Would convert to punycode by default (https://pkg.go.dev/golang.org/x/net/idna), but could be passed -np
to avoid the processing.
Sometime ago, I used the /me EP to validate the token during auth. The /me EP actually returns usefull quota information, but at this point it is not used.
I propose a command that displays the quota information.
$ ipinfo quota
Requests
Day: 0,
Month: 9,
Limit: 50000,
Remaining: 49991
"features": {
"core": {
"daily": 2147483647,
"monthly": 50000
},
"hostio": {
"daily": 2147483647,
"monthly": 1000,
"result_limit": 5
}
}
Or something similar. The design is pending.
panic: runtime error: index out of range [3] with length 0
goroutine 1 [running]:
encoding/binary.bigEndian.Uint32(...)
/usr/lib/go-1.16/src/encoding/binary/binary.go:112
github.com/ipinfo/cli/lib.IPFromStdIP(0x0, 0x0, 0x0, 0x1)
/go/pkg/mod/github.com/ipinfo/[email protected]/lib/ip.go:24 +0x86
github.com/ipinfo/cli/lib.CmdGrepIP.func1(0x5c713d, 0x10, 0x5fc468, 0xc0000b6000)
/go/pkg/mod/github.com/ipinfo/[email protected]/lib/cmd_grepip.go:261 +0xbf5
github.com/ipinfo/cli/lib.CmdGrepIP(0x100010000000101, 0xc000092740, 0x0, 0x1, 0x5d1340, 0x0, 0x5d0309)
/go/pkg/mod/github.com/ipinfo/[email protected]/lib/cmd_grepip.go:324 +0x57b
main.cmd(0x7ffd24fadb1d, 0x6)
/go/pkg/mod/github.com/ipinfo/[email protected]/grepip/main.go:128 +0x3f3
main.main()
/go/pkg/mod/github.com/ipinfo/[email protected]/grepip/main.go:139 +0x85
Error: Process completed with exit code 2.
Currently these tools crash if they encounter ipv6 forms.
Originally tracking this work in #3 but splitting this out as a more specific issue.
Allow users to download and get automatic updates for our binaries via Windows package managers such as:
Hi, please make version for Windows, best regards
What I did.
ipinfo bulk
8.8.8.8
CTRL+D
What did I expect
The results
What happened?
$ ipinfo bulk
** manual input mode **
Enter all IPs, one per line:
8.8.8.8
panic: interface conversion: interface {} is *interface {}, not *ipinfo.Core
goroutine 1 [running]:
github.com/ipinfo/go/v2/ipinfo.(*Client).GetIPStrInfoBatch(0xc0000256c0, 0xc000055ce0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x3, 0xc00001a1b0, ...)
/home/mslm/dev/ipinfo/cli/vendor/github.com/ipinfo/go/v2/ipinfo/batch.go:288 +0x285
github.com/ipinfo/go/v2/ipinfo.(*Client).GetIPInfoBatch(0xc0000256c0, 0xc000180000, 0x1, 0x2710, 0x0, 0x0, 0x0, 0x0, 0x19, 0xc00007e180, ...)
/home/mslm/dev/ipinfo/cli/vendor/github.com/ipinfo/go/v2/ipinfo/batch.go:260 +0x17a
main.cmdBulk(0x7ffe894f0483, 0x4)
/home/mslm/dev/ipinfo/cli/ipinfo/cmd_bulk.go:93 +0x449
main.main()
/home/mslm/dev/ipinfo/cli/ipinfo/main.go:57 +0x398
Before we release v2 with more features, we should refresh some of the README gifs because more subcommands have been added since the first gifs were created, and some subcommands got more features e.g. #22
Tried looking up a private IP and here is the result that I got:
I guess it is expected but I think it will be better to be more explicit that it is a bogon/private IP or else users might wonder why there are IP address results with blank values? We do get a fair amount of people reaching out to support that can't tell or don't know the difference between a valid public IP vs. a bogon/private IP.
For reference, this is what our API returns -> https://ipinfo.io/192.168.1.1/json
It'd be useful as a separate one and costs little to nothing for us to make it so.
Finally had some time to play around with this @UmanShahzad :)
Ok so i decided to follow the path of a casual user and tried it out with your readme. First thing I noted was..
darwin_amd64
dragonfly_amd64
freebsd_amd64
linux_amd64
netbsd_amd64
openbsd_amd64
plan9_amd64
solaris_amd64
windows_amd64
what?? no x86_64
architecture?? hmm.. ok maybe go will just compile to my local arc. lets try just cloning the repository and doing the install. Here is all that I saw:
I have a feeling i am doing something wrong. 🤔
Just wondering if there are plans to support the ARM architecture.
We improved the summary output dramatically in #7 but the pretty output for IP and ASN is still super high contrast, and could be improved:
(oh, actually looks like the ASN output is always raw json)
Those flags currently properly auto-complete for e.g. myip
, bulk
, etc., but we currently aren't able to easily specify that completion must occur for the raw IP / ASN subcommands.
Find a way to make this work and implement that.
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.