oasis-open / cti-taxii-client Goto Github PK
View Code? Open in Web Editor NEWOASIS TC Open Repository: TAXII 2 Client Library Written in Python
Home Page: https://taxii2client.readthedocs.io/
License: BSD 3-Clause "New" or "Revised" License
OASIS TC Open Repository: TAXII 2 Client Library Written in Python
Home Page: https://taxii2client.readthedocs.io/
License: BSD 3-Clause "New" or "Revised" License
...and/or use a default that is specific to the taxii client.
Seems to be contradictory info:
"Installation
The easiest way to install the TAXII client is with pip:
$ pip install taxii2_client
The cti-taxii-client is not currently available on pip."
pip install taxii2_client
Collecting taxii2_client
Could not find a version that satisfies the requirement taxii2_client (from versions: )
No matching distribution found for taxii2_client
We can still get reports about them, but we don't want them to mark the build as failing. If that doesn't work, we can just remove that.
Hello,
I am trying to add individual stix domain objects to a server, not a bundle, using this:
from taxii2client.v20 import Collection
from stix2 import *
coll = Collection('http://127.0.0.1:5000/trustgroup1/collections/365fed99-08fa-fdcd-a1b3-fb247eb41d01',
user='admin',
password='Password0')
indicator = Indicator(name="File hash for malware variant",
labels=["malicious-activity"],
pattern="[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']")
print(indicator)
coll.add_objects(indicator)
But I am getting an error as the client does not know how to handle objects that are not bundles. Is there a way I can do that or it's not possible at this time?
Thank you.
Can you add an option to set verification of ssl certificate to true or false?
requests.get(url, verify=False)
In the spirit of helping users debug the case when they are using an incorrect TAXII Protocol Version to communicate with a server.
api_root = server.api_roots
returns
ConnectionError: HTTPSConnectionPool(host='*****', port=443): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x7f9e8c142c18>: Failed to establish a new connection: [Errno 111] Connection refused'))
Hi,
I want to connect to TAXII server through a proxy so I use this:
http_conn = _HTTPConnection(proxies=proxies)
But it returns a warning "Unexpected argument proxies".
I checked out its code and the init function is:
def __init__(self, user=None, password=None, verify=True):
No proxies.
So how can I use this through a proxy please?
Thankx
Can we get responses based off a particular time? For ex, can we make a request to get data after 7th jan 2021?
I am new here, and confused about polling from taxii servers
I can't find any relevant documentation for polling from a remote server
Please guide me further and thanks
Hi,
I see there are two ways of getting objects in TAXII. One is by passing added_after on, another is by adding Range to header like this: curl -k -H "Range: items 100-150" --user <user:pass> <domain>/api/v1/taxii2/ti/collections/<collection-id>/objects/?added_after=2019-01-01T00:29:09.002Z
My question is how can I use this library to get objects by Range? Thanks!
My company server connects to internet through http proxy: 192.168.5.8:3128
I'm trying to feed data from limo
When I try it with curl command, it works:
curl -x http://192.168.5.8:3128 --user guest:guest -k https://limo.anomali.com/api/v1/taxii2/taxii/
{"api_roots": ["https://limo.anomali.com/api/v1/taxii2/feeds/", "https://limo.anomali.com/api/v1/taxii2/trusted_circles/", "https://limo.anomali.com/api/v1/taxii2/search_filters/"], "contact": "[email protected]", "default": "https://limo.anomali.com/api/v1/taxii2/feeds/", "description": "TAXII 2.0 Server (guest)", "title": "ThreatStream Taxii 2.0 Server"}
But when I use cti-taxii-client, it doesn't return anything.
api_user = "guest"
api_password = "guest"
taxii_domain = "https://limo.anomali.com/api/v1/taxii2/taxii"
proxy = "192.168.5.8:3128"
proxies = {
'http': proxy
}
http_conn = _HTTPConnection(proxies=proxies, user=api_user, password=api_password, verify=False)
server_discovery = Server(url=taxii_domain, conn=http_conn)
What am I doing wrong here? Please help. Thank you!
Building on #10, we should make the content-type matching more robust than just a string's .startwith()
.
This occurs in 2 places:
taxii2client._HTTPConnection.post()
should use requests.post(data=X)
rather than requests.post(json=X). This function is called from taxii2client.Collection.add_objects()
. X should be a UTF-8 encoded byte string.
json.dumps()
, which is OK but means we can’t pass dicts containing datetime objects or anything else that isn’t JSON-serializeable (such as _STIXBase objects).taxii2client.Collection.add_objects(X)
should prefer to accept a Unicode string, which it encodes as UTF-8 before passing to requests (urllib3, which requests uses internally, wants a bytes-like object).
json.dumps()
, which returns a Unicode string, that we then encode as UTF-8. isoformat()
, butHi,
I am using taxii2_client-2.2.2.dist-info and find that verify=False does not work. I am using self-sign certificate on https://192.168.129.141/taxii/:
from taxii2client.v20 import Server server_dst = Server('https://192.168.129.141/taxii/', user='username', password='password', verify=False)
It looks like it is because in sessions.py:request (line 463), it uses another verify rather than self.verify. As a result, verify=None and the verify=False passed does not take effect.
I can resolve the issue if add "verify=False" in line 543 of sessions.py:
def get(self, url, **kwargs): r"""Sends a GET request. Returns :class:
Response` object.
:param url: URL for the new :class:`Request` object.
:param \*\*kwargs: Optional arguments that ``request`` takes.
:rtype: requests.Response
"""
kwargs.setdefault('allow_redirects', True)
return self.request('GET', url, verify=False, **kwargs)`
I'm trying to pass the "added_after" to collection.get_objects
but I keep getting this error:
TypeError: get_objects() takes 1 positional argument but 2 were given
code:
objects = collection.get_objects({"added_after": lastUpdate})
For example: If the server's API root is without description, the client will throw an exception.
But the description is optional according to the spec, I expected there is no error here.
We need to discuss whether or not this should be in scope for this library.
Hopefully we can support all versions simultaneously, but we could also support different versions of the spec in different versions of the client. This may mean sending multiple media types in the accept header.
server = Server(url, user=self.conf_api["user"], password=self.conf_api["password"], verify=False)
api_root = server.api_roots[0]
collections = api_root.collections
These code lines return this exceptions:
ERROR - _populate_fields() got an unexpected keyword argument 'type'
When I use curl, server returns like this:
{"collections": [{"can_read": true, "can_write": false, "description": "This data collection is for collecting malicious domains", "id": "861ecee6-09af-4cc9-8f80-8c6eac8bb5a4", "media_types": ["application/vnd.oasis.stix+json; version=2.0"], "title": "Indicator Domain Collection", "type": "domain"}]}
This error happens when we add a new field to collection "type": "domain"
. But STIX standards allow us to custom collection fields.
Can you fix this? Thank you so much!
Hello,
i am using your library to connect successfully to one of our CTI providers using username+password.
Sadly, the second one is using username+password and required additionally a certificate (.crt and .key file).
Is it possible to use this authentication methods using taxii2client? I get the following error message:
taxii2client.exceptions.InvalidArgumentsError: Only one of a connection, username/password, or auth object may be provided._
I looked into your source and could verify that you check that not both methods are provided at the same time. Is there a way around that other than editing the library? Will this feature be added in the future?
Thank you very much in advance.
The TAXII server response is now "application/vnd.oasis.stix+json; version=2.1". Client library code is looking for "application/vnd.oasis.stix+json; version=2.0".
I didn't find any implementation for Pagination.
Do I have to implement the code for pagination or is there any other way?
As we keep adding specific parameters that are used when building an HTTP connection, the conn
parameter keeps getting pushed back, which caused some problems with the recent verify
addition.
I see the following traceback while invoking paged fetch:
for bundle in as_pages(collection.get_objects, per_request=50):
File "/usr/local/lib/python2.7/dist-packages/taxii2client/v20/__init__.py", line 47, in as_pages
total_in_request, total_available = _grab_total_items(resp)
File "/usr/local/lib/python2.7/dist-packages/taxii2client/common.py", line 132, in _grab_total_items
results = re.match(r"^items (\d+)-(\d+)/(\d+)$", resp.headers["Content-Range"])
File "/usr/local/lib/python2.7/dist-packages/requests/structures.py", line 54, in __getitem__
return self._store[key.lower()][1]
KeyError: 'content-range'
To fix:
if not resp.headers.get("Content-Range"):
return 0, 0
Hi,
I using the cti-taxii-client for the first time inorder to subscribe to a taxii 2.x version of feed . I have the cti-taxii-client installed on my linux and used the following python script to connect to the https://cti-taxii.mitre.org/taxii/ feed - as described in one of the blogs.. https://www.mitre.org/capabilities/cybersecurity/overview/cybersecurity-blog/attck%E2%84%A2-content-available-in-stix%E2%84%A2-20-via
server = Server("https://cti-taxii.mitre.org/taxii/")
api_root = server.api_roots[0]
But while trying to connect i am getting :
File "/usr/lib/python2.7/site-packages/requests/models.py", line 941, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 406 Client Error: Not Acceptable for url: https://cti-taxii.mitre.org/taxii/
But this URL seems to be working fine.. Would like to get some help with the taxii client onhow to connect tothe taxii2 feeds
Appreciate your time
There are almost certainly going to be use cases where we need to disable TLS certificate verification or supply our own CA certificate.
When checking the content type of packets the client receives, it checks if it is an exact match (https://github.com/oasis-open/cti-taxii-client/blob/master/taxii2client/__init__.py#L481). This fails if for example "; charset=utf-8" is appended to the content type.
When I run the code below I am getting an SSLError the certificate that i am using is self signed:
from taxii2client import Server
server = Server('https://192.168.56.100/taxii/', 'admin', 'letmein')
print(server.title)
Stack Trace:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/connectionpool.py", line 601, in urlopen
chunked=chunked)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/connectionpool.py", line 346, in _make_request
self._validate_conn(conn)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/connectionpool.py", line 850, in _validate_conn
conn.connect()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/connection.py", line 326, in connect
ssl_context=context)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/util/ssl_.py", line 329, in ssl_wrap_socket
return context.wrap_socket(sock, server_hostname=server_hostname)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 407, in wrap_socket
_context=self, _session=session)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 814, in __init__
self.do_handshake()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 1068, in do_handshake
self._sslobj.do_handshake()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 689, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:777)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/adapters.py", line 440, in send
timeout=timeout
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/connectionpool.py", line 639, in urlopen
_stacktrace=sys.exc_info()[2])
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/util/retry.py", line 388, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='192.168.56.100', port=443): Max retries exceeded with url: /taxii/ (Caused by SSLError(SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:777)'),))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "stix2Taxii.py", line 8, in <module>
print(server.title)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/taxii2client/__init__.py", line 497, in title
self._ensure_loaded()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/taxii2client/__init__.py", line 522, in _ensure_loaded
self.refresh()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/taxii2client/__init__.py", line 525, in refresh
response = self._conn.get(self.url, accept=MEDIA_TYPE_TAXII_V20)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/taxii2client/__init__.py", line 571, in get
resp = self.session.get(url, headers=headers, params=params)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/sessions.py", line 521, in get
return self.request('GET', url, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/sessions.py", line 508, in request
resp = self.send(prep, **send_kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/sessions.py", line 618, in send
r = adapter.send(request, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/adapters.py", line 506, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='192.168.56.100', port=443): Max retries exceeded with url: /taxii/ (Caused by SSLError(SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:777)'),))
I first started noticing this while working on the user-agent changes (#45), but this isn't directly related to those changes, so I am making a separate issue for this.
One of the things I added (and forgot to mention in the commit message, oops) was to add parameter documentation to _HTTPConnection.post(), which for some reason had been missing. For the "data" parameter, I just copied text from the Requests documentation, since it's passed directly into Session.post(). Notice that JSON content is not listed as a legal value. That was odd, because aren't the TAXII services all JSON-based? Note also that there is a "json" parameter you can use specifically for JSON. Wouldn't it have made more sense to use that? This got me looking at the JSON handling.
The usage of the "data" parameter within taxii2-client is via the Collection.add_objects() method; the actual value is obtained here:
if isinstance(bundle, dict):
if six.PY2:
bundle = json.dumps(bundle, encoding="utf-8")
else:
bundle = json.dumps(bundle)
(I just picked master branch head commit as of this writing, to refer to; the aforementioned PR hasn't changed this part.) This code snip creates JSON which is subsequently passed via "data" parameter, instead of using the "json" parameter and letting Requests take care of the conversion. There may be some reinvention of the wheel here. What of that "encoding" parameter though? Why is it hard-coded, and why make encoding decisions in the Collection endpoint class anyway?
To start with, here's what I think the encoding kwarg actually does: in case there are any binary values in the passed dict, they must be decoded to strings before being encoded as JSON (JSON is a textual format, after all). The encoding argument describes how to do that. I.e. the encoding argument is actually about decoding.
What may have happened is a misunderstanding: that a decision needed to be made here about what to do with high-value codepoints, and the decision was to encode as utf-8. Lending credence to this idea is that the TAXII 2.0 spec actually defines the string type as The string data type represents a finite-length string of valid characters from the Unicode coded character set [ISO10646] that are encoded in UTF-8.
So the spec actually mentions utf-8. Perhaps the idea was that a json.dumps() call could do double-duty, as a JSON-encode operation followed by a string encode operation. On the other hand, this code is written to behave differently depending on python version, and there is no usage of encoding on python3. If encoding needed to happen for python2, why not python3? On python3 the API changed: there actually is no "encoding" parameter in json.dumps(). Under this misunderstanding, that would mean that the result must remain text, and text is passed to _HTTPConnection.post(), then to Session.post(), which is invalid according to the documentation. So even if the misunderstanding were true, the code is incorrect.
Also, the "ensure_ascii" param was left at default (True), which means there can be no high-value codepoints in the resulting JSON anyway. They will all be escaped using the format "\u1234". JSON specs I looked at do seem to recognize this as an escape syntax, but do we need to do that? Why not let them pass?
Here's how I think it should work:
This can probably be behind some sort of "private" interface (like _raw
), but it would be helpful to have access to the raw JSON bodies on returned responses.
Hi,
Thanks for such great tool.
I use this tool to connect to a TAXII server.
I can get root_api and collections succesfully.
But when I use get_objects() to get objects, after about 30 second, it closes connection.
I try to curl
the get objects API and it does response after quite a long time.
So how can set timeout for cti-taxii-client when get objects so I can wait for a longer time?
Thanks so much.
I'm interested in using cti-taxii-client. Is it possible to estimate when the majority of the implementation will be completed?
Thanks!
I apparently took this out at some point and never added it back.
Hello,
I am running these lines of code from this file:
from taxii2client import Collection
(Line 4)
collection = Collection("<url>")
(Line 41)
In Python 3.7, this works!
Unfortunately with Python 3.9, it errors. Using the guidance of the error message, I tweaked the import statement and
from taxii2client.v21 import Collection
still error'ed
from taxii2client.v20 import Collection
worked!
I initially thought it would be .v21 because by debugging the if-statement here, I saw my self.version
was 2.1
.
My question is therefore how can I tell which server I am using (to ultimately decide which import statement I should use)? Is this mainly down to server config in code I am using? Or does it default to 2.0?
Why did the upgrade in Python 3 break the original lines of code? (I assume because of later releases of taxii-client but I'm asking in case there's something I should be mindful of here)
Apologies if there are basics on requests I am missing, thanks!
HELLO
Please, i wrote this python code to collect data from TAXII server :
from taxii2client import Collection
collection = Collection('https://otx.alienvault.com/api1/collections/91a7b528-80eb-42ed-a74d-c6fbd5a26116')
collection.get_object('indicator--252c7c11-daf2-42bd-843b-be65edca9f61')
when I execute the code, I get this error "taxii2client.TAXIIServiceException: Unexpected Response. Got Content-Type: 'text/html; charset=utf-8' for Accept: 'application/vnd.oasis.taxii+json; version=2.0'"
Can you help me please.
I know of a few taxii servers requiring auth using api keys.
Is there any plan to implement auth using this?
e.g: self.my_taxii = Server(url=self.url, verify=self.verify, proxies=self.proxies, token=self.api_key)
>>> collection = Collection('http://localhost:5000/trustgroup1/collections/91a7b528-80eb-42ed-a74d-c6fbd5a26116', user='user1', password='Password1')
>>> collection.get_object('indicator--252c7c11-daf2-42bd-843b-be65edca9f61')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/lu/Projects/cti-taxii-client/taxii2client/__init__.py", line 483, in get_object
params=query_params)
File "/home/lu/Projects/cti-taxii-client/taxii2client/__init__.py", line 876, in get
resp.raise_for_status()
File "/home/lu/.virtualenvs/cti-taxii-client/lib/python3.6/site-packages/requests/models.py", line 939, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 404 Client Error: NOT FOUND for url: http://localhost:5000/trustgroup1/collections/91a7b528-80eb-42ed-a74d-c6fbd5a26116objects/indicator--252c7c11-daf2-42bd-843b-be65edca9f61/
If I set up the collection with a /
at the end of the url, it works fine because it's not trying to find a collection called 91a7b528-80eb-42ed-a74d-c6fbd5a26116objects
.
Due to the addition of the auth with api_key,
@emmanvg When are you planning to release the next version?
I'm not sure I understand how "closing" an object (or the underlying requests.Session
) works.
I added a test that I expected to fail. If the session is closed, I thought subsequent web requests could not be sent. I don't fully understand the requests
internals, but is it possibly opening new connections, and close
just shuts all existing, open connections?
@responses.activate
def test_cannot_use_closed_connection(collection):
set_collection_response()
collection.close()
collection.refresh()
This has caused a lot of confusion and problems. See my comment for more information.
@johnwunder asked me to test the TAXII2 server MITRE is launching to host ATT&CK and CAPEC content. Since this is currently using a certificate issued by MITRE's internal CA, certificate validation needs to be disabled.
Cf. the closed issues #17 and #24, the verify
parameter doesn't get processed correctly. When I try:
collection = Collection("https://obfuscated.mitre.org/taxii", verify=False)
I get:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "~/cti-python-stix2/venv/lib/python3.5/site-packages/taxii2client/__init__.py", line 223, in __init__
self._populate_fields(**kwargs)
TypeError: _populate_fields() got an unexpected keyword argument 'verify'
I can (of course) monkey-patch cti-taxii-client as an immediate workaround but this should be fixed.
If a server (incorrectly) returns malformed data, we should at least catch the error and ensure it doesn't produce a traceback. See mitre/cti#16
Create Coverage and Version badges.
Hi,
My corporate environment uses an HTTP proxy for all external requests. How do I configure the API to support this? I tried the following snippet:
proxies = {'https': .....}
httpConn = _HTTPConnection(proxies=proxies)
server = Server("https://cti-taxii.mitre.org/taxii/", conn=httpConn)
But it appears the version of the api that is installed via pip install taxii2-client
(0.3.1) is an outdated version of the API that doesn't include support for proxies. I also tried setting up the environment variables http_proxy and https_proxy as stated in the documentation for the requests module but that also doesn't seem to work.
Any advice?
Also how do I get the latest version of the API?
Thanks!
Hello!
I am trying to pull data from the ATT&CK TAXII server, and I'm following the recipe code from their github:
https://github.com/mitre/cti/blob/master/USAGE.md#access-from-the-attck-taxii-server
This is the code I'm running:
from stix2 import TAXIICollectionSource
from taxii2client.v20 import Collection # only specify v20 if your installed version is >= 2.0.0
collections = {
"enterprise_attack": "95ecc380-afe9-11e4-9b6c-751b66dd541e",
"pre_attack": "062767bd-02d2-4b72-84ba-56caef0f8658",
"mobile_attack": "2f669986-b40b-4423-b720-4396ca6a462b"
}
collection = Collection(f"https://cti-taxii.mitre.org/stix/collections/{collections['enterprise_attack']}/")
src = TAXIICollectionSource(collection)
src.get('x-mitre-tactic--ffd5bcee-6e16-4dd2-8eca-7b3beedf33ca')
But I'm getting this error:
File "C:\Users\MY_USERNAME\AppData\Local\Programs\Python\Python39\lib\site-packages\stix2\datastore\taxii.py", line 213, in get
if stix_obj.id != stix_id:
AttributeError: 'dict' object has no attribute 'id'
When I'm trying to use a local filesystem, it works fine. IE:
import stix2
src = stix2.FileSystemSource(r"C:\Git\cti\enterprise-attack")
src.get('x-mitre-tactic--ffd5bcee-6e16-4dd2-8eca-7b3beedf33ca')
Is this a bug or am I missing something?
Thanks :)
Hi!
I'm trying to access ATT&CK data through the stix2 and taxiiclient package. However I'm getting the following error:
"406 Client Error: Not Acceptable for url: https://cti-taxii.mitre.org/stix/collections/95ecc380-afe9-11e4-9b6c-751b66dd541e/"
I'm trying to run this snippet:
from stix2 import TAXIICollectionSource
from taxii2client import Server
server = Server("https://cti-taxii.mitre.org/taxii/")
api_root = server.api_roots[0]
What am I missing? Do I need to set something up first?
Thanks in advance!
When trying to connect to a public taxi server, using'Server' class of taxi2client, it gives 406 error (requests.exceptions.HTTPError: 406 Client Error: Not Acceptable for URL: https://cti-taxii.mitre.org/taxii/). Which I found out to be related to the header.
And when I used postman to connect to the same server attaching the header {'Accept': 'application/vnd.oasis.taxii+json'}... there is no problem in postman, it works.
But how do I attach the header while using taxi2client so that I can get the desired output?
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.