Coder Social home page Coder Social logo

taxiiproject / libtaxii Goto Github PK

View Code? Open in Web Editor NEW
70.0 70.0 43.0 2.26 MB

A Python library for handling TAXII Messages invoking TAXII Services.

Home Page: http://libtaxii.readthedocs.org/

License: BSD 3-Clause "New" or "Revised" License

Python 100.00%

libtaxii's People

Contributors

brlogan avatar clenk avatar danielsamuels avatar daybarr avatar emmanvg avatar gtback avatar guidovranken avatar ics avatar imjonsnooow avatar jasenj1 avatar kralca avatar marcelslotema avatar markdavidson avatar mbekavac avatar mgoffin avatar motok avatar nschwane avatar orsinium avatar rroberge avatar sddj avatar stkyle avatar traut avatar wbolster 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

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

libtaxii's Issues

Explore adding __str__ and-or __repr__

It would be nice if calling print taxii_message printed the XML instead of the usual object print statement; e.g., <SomeObject at #9840329840938203>.

Adding support for automatically printing the XML representation should be explored.

EDIT: Formatting

libtaxii.ContentBlock.content doesn't properly handle non-XML strings that look like XML

Yes, confusing title. The best way to describe the problem is with an example:

  1. a Content Block object is created from this XML:
<taxii:Content_Block>
      ...
      <taxii:Content>&lt;Hello/&gt;</taxii:Content>
      ...
</taxii:Content_Block>

The Content element contains a string (&lt;Hello/&gt;) that, when unescaped (<Hello/>), looks like XML.

  1. When serializing the Content Block (e.g., to_xml()), the following is produced:
<taxii:Content_Block>
      ...
      <taxii:Content><Hello/></taxii:Content>
      ...
</taxii:Content_Block>

This is incorrect, as it does not match the source XML document.

In the Python object, after deserialization, ContentBlock.content appears as <Hello/> (e.g., the unescaped string). During serialization, libtaxii inspects the first character of ContentBlock.content to see if it is a beginning bracket <. If the first character is a beginning bracket, libtaxii tries to process ContentBlock.content as XML. The test that libtaxii uses is not correct, as strings that look like XML will be treated as XML.

I'm thinking a boolean flag should be added to keep track of whether the content is XML or not.

Proxy arguments are not intuitive

Currently, you can set proxy information in 3 ways in libtaxii:

client.setProxy('http://proxy.example.com:80', tc.PROXY_HTTP)#Tells libtaxii to use a proxy
client.setProxy(None)#Tells libtaxii to use the system proxy
client.setProxy('noproxy')#Tells libtaxii to not use any proxy (including the system proxy)

'noproxy' and None are not obviously different. Consider adding another option called something like use_system_proxy which would be more clear. The additional argument would be in addition to None so as to not break backward compatibility.

libtaxii follows redirects

It seems that libtaxii follows HTTP-300 redirects by default, and I don't think there's a way (short of some hackery) that a user can turn this "feature" off. libtaxii should not follow redirects by default, but should give the user an option to enable the following of redirects.

add package layout information to readme

Provide information regarding the general layout of the libtaxii package. Explain the directory structure at a high level. This documentation will exist in the README.

ContentBlock.content

When parsing a ContentBlock from XML that contains XML content, e.g., (pseudo-xml):

<Content_Block>
   <ContentBinding>...</ContentBinding>
   <Content>
           <STIX_Package/>
   </Content>
</Content_Block>

The contentblock.content object will be an etree. This is a result of the change to not make an extra parse. Now, the Content Block keeps the content around as an etree if it is in fact XML.

However, before the previous change, the content was always a string, even if it was XML.This is a change in behavior and should somehow be fixed without re-introducing the extra parse that was previously happening.

Content Block parsing of XML is inefficient

Currently, passing XML content into a Content Block (probably the most common case) can end up with a double parse of the XML content.

For example:

#This is pseudocode
data = StringIO.StringIO('/usr/SuperBigData')
msg = tm11.InboxMessage(id='1')
content_block = tm11.ContentBlock(binding_id='urn:stix.mitre.org:xml:1.1', content=data) #Parse / read into memory happens here
msg.content_blocks.append(content_block)
callTaxiiService2(…, msg.to_xml(), …)#an etree gets created (requiring a parse) then serialized

One solution might be to keep around the etree that's created in _stringify_content() for later if the content is truly XML.

Use PEP 8 docstring conventions

Many methods and classes in libtaxii have comments above their definition. For example:

messages.py

62   #validate XML with the TAXII XML Schema 1.0
63   def validate_xml(xml_string):

This type of documentation should probably be converted to a docstring

62    def validate_xml(xml_string):
63        """Validate XML with the TAXII XML Schema 1.0."""

Doing so allows you to call help() on a method/class/module from the python interpreter and get the documentation for that python code. Also, some documentation generation utilities will better recognize docstrings as the documentation for that piece of code.

ContentBlocks handle file-like Content poorly

When creating a content block as such:

cb2 = tm10.ContentBlock(content_binding=t.CB_STIX_XML_10,
          content=StringIO.StringIO('<stix:STIX_Package xmlns:stix="http://stix.mitre.org/stix-1"/>'))

to_xml() incorrectly returns:

<taxii:Content_Block xmlns:taxii="http://taxii.mitre.org/messages/taxii_xml_binding-1"><taxii:Content_Binding>urn:stix.mitre.org:x
ml:1.0</taxii:Content_Binding><taxii:Content>&lt;StringIO.StringIO instance at 0x02B6FD00&gt;</taxii:Content></taxii:Content_Block>

This error is in both TAXII 1.0 and TAXII 1.1 messages code.

Add CLI

Libtaxii could benefit from a CLI for calling TAXII Services. Kind of like what we've got going on with YETI but built into libtaxii (and not defaulted to hit YETI).

Input Validation

Currently, libtaxii doesn't offer much input validation. In general, inputs should be validated so that libtaxii users can be notified of bad inputs sooner rather than later.

Installation Trouble Spots

A couple of trouble spots identified during installation that should be looked at. This install was on an Ubuntu 12.04 system. Here are the trouble spots:

libxml2-dev and libxslt-dev had to be manually installed. The install error was ERROR:/bin/sh 1: xslt-config: not found and the install correctly identified the problem: "** make sure the development packages of libxml2 and libxslt are installed **".

And

The libtaxii dependencies list lxml, libxml2, python-dateutil. I did not install any of these dependencies, just ran "pip install django libtaxii pyOpenSSL" as described in the YETI installation notes. The result was that lxml and python-dateutil were installed during this process, libxml2 was not. Looking at the log file, I determined it also needed libxslt, so installed libxml2-dev and libxslt-dev manually, and re-ran pip.

The installer was, ultimately, able to fully install libtaxii & YETI, but we should try and smooth out the process as much as possible.

Various (de)serialization errors

These were all discovered after correcting the eq method

There's a few problems here:

  • Single value items deserializing to a list of values
  • boolean values not deserializing correctly (e.g., always deserializing to True)
  • Supported content detail not deserializing correctly
  • ServiceInstance not deserializing correctly (the available attribute, specifically)
  • CollectionInformation / Receiving Inbox Service not deserializing correctly
  • CollectionInformation not serializing correctly
  • PollInstance not serializing correctly
  • PollInstance not deserializing correctly
  • PollResponse not serializing correctly
  • PollResponse not deserializing correctly.

In most cases, each of these was a single property not being done 100% correct.

Support for older dependencies

In the "I need to support RHEL6" category, the libtaxii dependencies use newer versions than what is available in the RHEL6 repos. Are there any hard reasons to use lxml 2.3 and python-dateutil 1.5 (i.e. features only available in the newer versions)? RHEL6 has 2.2 and 1.4, respectively. Is it possible to support those older versions?

This issue generally applies to libtaxii, python-stix, and cybox, but I'll just open up this particular issue for now.

Add args to client.HttpClient__init__

Currently, init does not take any arguments. It should be updated to take authType and other arguments. That way, instead of looking like this:

c = client.HttpClient()
c.setAuthType(HttpClient.AUTH_CERT, { ... })

You could write code that looks like this:

c = client.HttpClient(auth_type=HttpClient.AUTH_CERT, auth_credentials={...})

Maybe add pretty_print option to to_xml()

It might be nice if all the to_xml() functions had a pretty_print=True/False parameter that could be specified. Should default to False in order to preserve existing functionality when not specified.

PollResponse - empty messages

I wrote a simple test_client just like the example you provide in the script directory using libtaxii11.

When I run this client without time filters, I can see events returned and that's great. However, when I filter to have no events returned, I still have a PollResponse Message with no events in it but having the stix headers.

How can I identify this behavior (a response only containing headers) ?

<taxii_11:Poll_Response xmlns:taxii_11="http://taxii.mitre.org/messages/taxii_xml_binding-1.1" message_id="32288" in_response_to="60368" collection_name="XXXXXX" more="false">
  <taxii_11:Inclusive_End_Timestamp>2014-07-24T18:53:44.071702+00:00</taxii_11:Inclusive_End_Timestamp>
  <taxii_11:Content_Block>
    <taxii_11:Content_Binding binding_id="urn:stix.mitre.org:xml:1.0"/>
    <taxii_11:Content>
      <stix:STIX_Package xmlns:CodeObj="http://cybox.mitre.org/objects#CodeObject-2" xmlns:ioc-tr="http://schemas.mandiant.com/2010/ioc/TR/" xmlns:GUIObj="http://cybox.mitre.org/objects#GUIObject-2" xmlns:ioc="http://schemas.mandiant.com/2010/ioc" xmlns:coa="http://stix.mitre.org/CourseOfAction-1" xmlns:WinDriverObj="http://cybox.mitre.org/objects#WinDriverObject-2" xmlns:ProcessObj="http://cybox.mitre.org/objects#ProcessObject-2" xmlns:PDFFileObj="http://cybox.mitre.org/objects#PDFFileObject-1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:DiskObj="http://cybox.mitre.org/objects#DiskObject-2" xmlns:UserAccountObj="http://cybox.mitre.org/objects#UserAccountObject-2" xmlns:CustomObj="http://cybox.mitre.org/objects#CustomObject-1" xmlns:ARPCacheObj="http://cybox.mitre.org/objects#ARPCacheObject-1" xmlns:WinNetworkRouteEntryObj="http://cybox.mitre.org/objects#WinNetworkRouteEntryObject-2" xmlns:AddressObj="http://cybox.mitre.org/objects#AddressObject-2" xmlns:UserSessionObj="http://cybox.mitre.org/objects#UserSessionObject-2" xmlns:cvrf="http://www.icasi.org/CVRF/schema/cvrf/1.1" xmlns:WinPipeObj="http://cybox.mitre.org/objects#WinPipeObject-2" xmlns:ArtifactObj="http://cybox.mitre.org/objects#ArtifactObject-2" xmlns:PacketObj="http://cybox.mitre.org/objects#PacketObject-2" xmlns:incident="http://stix.mitre.org/Incident-1" xmlns:HTTPSessionObj="http://cybox.mitre.org/objects#HTTPSessionObject-2" xmlns:WinCriticalSectionObj="http://cybox.mitre.org/objects#WinCriticalSectionObject-2" xmlns:DeviceObj="http://cybox.mitre.org/objects#DeviceObject-2" xmlns:WinVolumeObj="http://cybox.mitre.org/objects#WinVolumeObject-2" xmlns:MutexObj="http://cybox.mitre.org/objects#MutexObject-2" xmlns:scap-core="http://scap.nist.gov/schema/scap-core/1.0" xmlns:WinSystemRestoreObj="http://cybox.mitre.org/objects#WinSystemRestoreObject-2" xmlns:WinMailslotObj="http://cybox.mitre.org/objects#WinMailslotObject-2" xmlns:WinFileObj="http://cybox.mitre.org/objects#WinFileObject-2" xmlns:DiskPartitionObj="http://cybox.mitre.org/objects#DiskPartitionObject-2" xmlns:ciq="urn:oasis:names:tc:ciq:xpil:3" xmlns:WinSystemObj="http://cybox.mitre.org/objects#WinSystemObject-2" xmlns:PipeObj="http://cybox.mitre.org/objects#PipeObject-2" xmlns:ttp="http://stix.mitre.org/TTP-1" xmlns:URLHistoryObj="http://cybox.mitre.org/objects#URLHistoryObject-1" xmlns:capecInstance="http://stix.mitre.org/extensions/AP#CAPEC2.5-1" xmlns:UnixUserAccountObj="http://cybox.mitre.org/objects#UnixUserAccountObject-2" xmlns:WinMemoryPageRegionObj="http://cybox.mitre.org/objects#WinMemoryPageRegionObject-2" xmlns:NetworkSubnetObj="http://cybox.mitre.org/objects#NetworkSubnetObject-2" xmlns:indicator="http://stix.mitre.org/Indicator-2" xmlns:UnixPipeObj="http://cybox.mitre.org/objects#UnixPipeObject-2" xmlns:WinProcessObj="http://cybox.mitre.org/objects#WinProcessObject-2" xmlns:ciqAddress="http://stix.mitre.org/extensions/Address#CIQAddress3.0-1" xmlns:SemaphoreObj="http://cybox.mitre.org/objects#SemaphoreObject-2" xmlns:cvrfVuln="http://stix.mitre.org/extensions/Vulnerability#CVRF-1" xmlns:WinEventObj="http://cybox.mitre.org/objects#WinEventObject-2" xmlns:EmailMessageObj="http://cybox.mitre.org/objects#EmailMessageObject-2" xmlns:WinWaitableTimerObj="http://cybox.mitre.org/objects#WinWaitableTimerObject-2" xmlns:WhoisObj="http://cybox.mitre.org/objects#WhoisObject-2" xmlns:WinEventLogObj="http://cybox.mitre.org/objects#WinEventLogObject-2" xmlns:capec="http://capec.mitre.org/capec-2" xmlns:UnixProcessObj="http://cybox.mitre.org/objects#UnixProcessObject-2" xmlns:genericTM="http://stix.mitre.org/extensions/TestMechanism#Generic-1" xmlns:oval="http://oval.mitre.org/XMLSchema/oval-common-5" xmlns:WinSemaphoreObj="http://cybox.mitre.org/objects#WinSemaphoreObject-2" xmlns:NetworkRouteEntryObj="http://cybox.mitre.org/objects#NetworkRouteEntryObject-2" xmlns:stixVocabs="http://stix.mitre.org/default_vocabularies-1" xmlns:CISCP="http://www.us-cert.gov/ciscp" xmlns:VolumeObj="http://cybox.mitre.org/objects#VolumeObject-2" xmlns:DNSQueryObj="http://cybox.mitre.org/objects#DNSQueryObject-2" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:WinUserAccountObj="http://cybox.mitre.org/objects#WinUserAccountObject-2" xmlns:campaign="http://stix.mitre.org/Campaign-1" xmlns:snortTM="http://stix.mitre.org/extensions/TestMechanism#Snort-1" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:PortObj="http://cybox.mitre.org/objects#PortObject-2" xmlns:UnixVolumeObj="http://cybox.mitre.org/objects#UnixVolumeObject-2" xmlns:SMSMessageObj="http://cybox.mitre.org/objects#SMSMessageObject-1" xmlns:maec="http://maec.mitre.org/XMLSchema/maec-package-2" xmlns:NetworkSocketObj="http://cybox.mitre.org/objects#NetworkSocketObject-2" xmlns:GUIDialogBoxObj="http://cybox.mitre.org/objects#GUIDialogboxObject-2" xmlns:LibraryObj="http://cybox.mitre.org/objects#LibraryObject-2" xmlns:WinThreadObj="http://cybox.mitre.org/objects#WinThreadObject-2" xmlns:cvrf-common="http://www.icasi.org/CVRF/schema/common/1.1" xmlns:NetworkConnectionObj="http://cybox.mitre.org/objects#NetworkConnectionObject-2" xmlns:ovalTM="http://stix.mitre.org/extensions/TestMechanism#OVAL5.10-1" xmlns:tlpMarking="http://data-marking.mitre.org/extensions/MarkingStructure#TLP-1" xmlns:WinKernelHookObj="http://cybox.mitre.org/objects#WinKernelHookObject-2" xmlns:WinComputerAccountObj="http://cybox.mitre.org/objects#WinComputerAccountObject-2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:LinuxPackageObj="http://cybox.mitre.org/objects#LinuxPackageObject-2" xmlns:sch="http://purl.oclc.org/dsdl/schematron" xmlns:yaraTM="http://stix.mitre.org/extensions/TestMechanism#YARA-1" xmlns:prod="http://www.icasi.org/CVRF/schema/prod/1.1" xmlns:DNSCacheObj="http://cybox.mitre.org/objects#DNSCacheObject-2" xmlns:UnixFileObj="http://cybox.mitre.org/objects#UnixFileObject-2" xmlns:NetFlowObj="http://cybox.mitre.org/objects#NetworkFlowObject-2" xmlns:cyboxVocabs="http://cybox.mitre.org/default_vocabularies-2" xmlns:openiocTM="http://stix.mitre.org/extensions/TestMechanism#OpenIOC2010-1" xmlns:WinRegistryKeyObj="http://cybox.mitre.org/objects#WinRegistryKeyObject-2" xmlns:ProductObj="http://cybox.mitre.org/objects#ProductObject-2" xmlns:WinHandleObj="http://cybox.mitre.org/objects#WinHandleObject-2" xmlns:oval-var="http://oval.mitre.org/XMLSchema/oval-variables-5" xmlns:HostnameObj="http://cybox.mitre.org/objects#HostnameObject-1" xmlns:a="urn:oasis:names:tc:ciq:xal:3" xmlns:cvssv2="http://scap.nist.gov/schema/cvss-v2/1.0" xmlns:DomainObj="http://cybox.mitre.org/objects#DomainObject-1" xmlns:vuln="http://www.icasi.org/CVRF/schema/vuln/1.1" xmlns:simpleMarking="http://data-marking.mitre.org/extensions/MarkingStructure#Simple-1" xmlns:APIObj="http://cybox.mitre.org/objects#APIObject-2" xmlns:DomainNameObj="http://cybox.mitre.org/objects#DomainNameObject-1" xmlns:genericStructuredCOA="http://stix.mitre.org/extensions/StructuredCOA#Generic-1" xmlns:ct="urn:oasis:names:tc:ciq:ct:3" xmlns:SystemObj="http://cybox.mitre.org/objects#SystemObject-2" xmlns:DNSRecordObj="http://cybox.mitre.org/objects#DNSRecordObject-2" xmlns:stixCommon="http://stix.mitre.org/common-1" xmlns:WinServiceObj="http://cybox.mitre.org/objects#WinServiceObject-2" xmlns:cyboxCommon="http://cybox.mitre.org/common-2" xmlns:cpe="http://cpe.mitre.org/language/2.0" xmlns:FileObj="http://cybox.mitre.org/objects#FileObject-2" xmlns:GUIWindowObj="http://cybox.mitre.org/objects#GUIWindowObject-2" xmlns:WinPrefetchObj="http://cybox.mitre.org/objects#WinPrefetchObject-2" xmlns:WinKernelObj="http://cybox.mitre.org/objects#WinKernelObject-2" xmlns:stix="http://stix.mitre.org/stix-1" xmlns:cybox="http://cybox.mitre.org/cybox-2" xmlns:WinFilemappingObj="http://cybox.mitre.org/objects#WinFilemappingObject-2" xmlns:marking="http://data-marking.mitre.org/Marking-1" xmlns:URIObj="http://cybox.mitre.org/objects#URIObject-2" xmlns:ta="http://stix.mitre.org/ThreatActor-1" xmlns:MemoryObj="http://cybox.mitre.org/objects#MemoryObject-2" xmlns:WinTaskObj="http://cybox.mitre.org/objects#WinTaskObject-2" xmlns:SocketAddressObj="http://cybox.mitre.org/objects#SocketAddressObject-1" xmlns:WinMutexObj="http://cybox.mitre.org/objects#WinMutexObject-2" xmlns:ASObj="http://cybox.mitre.org/objects#ASObject-1" xmlns:et="http://stix.mitre.org/ExploitTarget-1" xmlns:WinExecutableFileObj="http://cybox.mitre.org/objects#WinExecutableFileObject-2" xmlns:WinNetworkShareObj="http://cybox.mitre.org/objects#WinNetworkShareObject-2" xmlns:LinkObj="http://cybox.mitre.org/objects#LinkObject-1" xmlns:NetworkRouteObj="http://cybox.mitre.org/objects#NetworkRouteObject-2" xmlns:NetworkPacketObj="http://cybox.mitre.org/objects#NetworkPacketObject-2" xmlns:xnl="urn:oasis:names:tc:ciq:xnl:3" xmlns:X509CertificateObj="http://cybox.mitre.org/objects#X509CertificateObject-2" xmlns:maecInstance="http://stix.mitre.org/extensions/Malware#MAEC4.0-1" xmlns:UnixNetworkRouteEntryObj="http://cybox.mitre.org/objects#UnixNetworkRouteEntryObject-2" xmlns:oval-def="http://oval.mitre.org/XMLSchema/oval-definitions-5" xmlns:ciqIdentity="http://stix.mitre.org/extensions/Identity#CIQIdentity3.0-1" xmlns:AccountObj="http://cybox.mitre.org/objects#AccountObject-2" xmlns:xlink="http://www.w3.org/1999/xlink" id="repository:XXXXXXXXXXXXX" version="1.0"/>
    </taxii_11:Content>
    <taxii_11:Timestamp_Label>2014-07-24T18:53:44.075505+00:00</taxii_11:Timestamp_Label>
  </taxii_11:Content_Block>
</taxii_11:Poll_Response>

Add better proxy support in libtaxii

Libtaxii doesn't currently support connect method through proxies. This should be added to clients.py.

this can be confirmed by running tcpdump/wireshark when attempting to connect - you will see raw SSL traffic rather than a connect method followed by SSL traffic. Some proxies are configured to only allow connects, and libtaxii does not currently work with those proxies.

libtaxii doesn't permit custom Status Types

Currently, the setter for StatusMessage.status_type doesn't permit custom status types (e.g., those defined by TAXII Default Query), while the spec permits Status Messages to contain custom Status Types. The code should be updated to align with the spec.

Explore adding GUI

Following on the CLI (#57), possibly explore adding a GUI that provides the same functionality.

Support multiple forms of authentication

Currently, libtaxii.clients supports TLS Certificate Auth OR HTTP Basic Auth OR No authentication. Some use cases require multiple forms of authentication (HTTP Basic AND TLS Certificate Auth, for example), which libtaxii does not currently support.

This issue is specifically for HTTP Basic and TLS Certificate Auth.

taxii_default_query.py #644 ALWAYS fails

the line in question contains cm_info[self.capability_id][self.relationship].keys(), and cm_info isn't defined, so if this line of code is reached an error will always occur.

Ensure 100% script coverage

Currently, the scripts do not have 100% coverage across all possible TAXII 1.1 and TAXII 1.0 message exchanges. The coverage should be expanded to be 100%.

Everywhere ContentBinding is used, permit a string

Currently, the various structures require a ContentBinding object for the content_binding argument. In constructors, content_binding=tm11.ContentBinding('Foo') and content_binding='Foo' should be equivalent. If users want to specify a subtype, they'll still have to use the ContentBinding object.

Having to type in tm11.ContentBinding every time is a little cumbersome and I think that this improvement will make libtaxii user's lives easier.

Deprecate 1.0 Draft code

The current libtaxii code has code that conforms with TAXII 1.0 Draft, but not TAXII 1.0. To ease the transition from TAXII 1.0 Draft to TAXII 1.0, code not conformant with TAXII 1.0 will be deprecated before it is removed.

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.