Code Monkey home page Code Monkey logo

pook's Introduction

pook PyPI Coverage Status Documentation Status Stability Code Climate Python Versions

Versatile, expressive and hackable utility library for HTTP traffic mocking and expectations made easy in Python. Heavily inspired by gock.

To get started, read the documentation, how it works, FAQ or examples.

Features

  • Simple, expressive and fluent API.
  • Provides both Pythonic and chainable DSL API styles.
  • Full-featured HTTP response definitions and expectations.
  • Matches any HTTP protocol primitive (URL, method, query params, headers, body...).
  • Full regular expressions capable mock expectations matching.
  • Supports most popular HTTP clients via interceptor adapters.
  • Configurable volatile, persistent or TTL limited mocks.
  • Works with unittest and pytest.
  • First-class JSON & XML support matching and responses.
  • Supports JSON Schema body matching.
  • Works in both runtime and testing environments.
  • Can be used as decorator and/or via context managers.
  • Supports real networking mode with optional traffic filtering.
  • Map/filter mocks easily for generic or custom mock expectations.
  • Custom user-defined mock matcher functions.
  • Simulated raised error exceptions.
  • Network delay simulation (only available for aiohttp).
  • Pluggable and hackable API.
  • Customizable HTTP traffic mock interceptor engine.
  • Supports third-party mocking engines, such as mocket.
  • Fits good for painless test doubles.
  • Does not support WebSocket traffic mocking.
  • Works with +3.8 (including PyPy).
  • Dependency-less: just 3 small dependencies for JSONSchema, XML tree comparison, and URL parsing.

Supported HTTP clients

pook can work with multiple mock engines, however it provides a built-in one by default, which currently supports traffic mocking in the following HTTP clients:

More HTTP clients can be supported progressively.

Note: only recent HTTP client package versions were tested.

Installation

Using pip package manager (requires pip 1.8+):

pip install --upgrade pook

Or install the latest sources from Github:

pip install -e git+git://github.com/h2non/pook.git#egg=pook

Getting started

See ReadTheDocs documentation:

Documentation Status

API

See annotated API reference documention.

Examples

See examples documentation for full featured code and use case examples.

Basic mocking:

import pook
import requests

@pook.on
def test_my_api():
    mock = pook.get('http://twitter.com/api/1/foobar', reply=404, response_json={'error': 'not found'})

    resp = requests.get('http://twitter.com/api/1/foobar')
    assert resp.status_code == 404
    assert resp.json() == {"error": "not found"}
    assert mock.calls == 1

Using the chainable API DSL:

import pook
import requests

@pook.on
def test_my_api():
    mock = (pook.get('http://twitter.com/api/1/foobar')
              .reply(404)
              .json({'error': 'not found'}))

    resp = requests.get('http://twitter.com/api/1/foobar')
    assert resp.json() == {"error": "not found"}
    assert mock.calls == 1

Using the decorator:

import pook
import requests

@pook.get('http://httpbin.org/status/500', reply=204)
@pook.get('http://httpbin.org/status/400', reply=200)
def fetch(url):
    return requests.get(url)

res = fetch('http://httpbin.org/status/400')
print('#1 status:', res.status_code)

res = fetch('http://httpbin.org/status/500')
print('#2 status:', res.status_code)

Simple unittest integration:

import pook
import unittest
import requests


class TestUnitTestEngine(unittest.TestCase):

    @pook.on
    def test_request(self):
        pook.get('server.com/foo').reply(204)
        res = requests.get('http://server.com/foo')
        self.assertEqual(res.status_code, 204)

    def test_request_with_context_manager(self):
        with pook.use():
            pook.get('server.com/bar', reply=204)
            res = requests.get('http://server.com/bar')
            self.assertEqual(res.status_code, 204)

Using the context manager for isolated HTTP traffic interception blocks:

import pook
import requests

# Enable HTTP traffic interceptor
with pook.use():
    pook.get('http://httpbin.org/status/500', reply=204)

    res = requests.get('http://httpbin.org/status/500')
    print('#1 status:', res.status_code)

# Interception-free HTTP traffic
res = requests.get('http://httpbin.org/status/200')
print('#2 status:', res.status_code)

Example using mocket Python library as underlying mock engine:

import pook
import requests
from mocket.plugins.pook_mock_engine import MocketEngine

# Use mocket library as underlying mock engine
pook.set_mock_engine(MocketEngine)

# Explicitly enable pook HTTP mocking (optional)
pook.on()

# Target server URL to mock out
url = 'http://twitter.com/api/1/foobar'

# Define your mock
mock = pook.get(url,
                reply=404, times=2,
                headers={'content-type': 'application/json'},
                response_json={'error': 'foo'})

# Run first HTTP request
requests.get(url)
assert mock.calls == 1

# Run second HTTP request
res = requests.get(url)
assert mock.calls == 2

# Assert response data
assert res.status_code == 404
assert res.json() == {'error': 'foo'}

# Explicitly disable pook (optional)
pook.off()

Example using Hy language (Lisp dialect for Python):

(import [pook])
(import [requests])

(defn request [url &optional [status 404]]
  (doto (.mock pook url) (.reply status))
  (let [res (.get requests url)]
    (. res status_code)))

(defn run []
  (with [(.use pook)]
    (print "Status:" (request "http://server.com/foo" :status 204))))

;; Run test program
(defmain [&args] (run))

Development

Clone the repository:

git clone [email protected]:h2non/pook.git

Use [hatch](https://hatch.pypa.io/) to configure the environment by running the test suite:

hatch run test

Install the pre-commit hook:

hatch run lint:install

Lint the code:

hatch run lint:run

Run tests on all supported Python versions and implementations (this requires your host operating system to have each implementation available):

hatch run test:test

To run tests only for a specific version, affix the version designation to the environment name (the left side of the :):

hatch run test.pypy3.10:test

Generate documentation:

hatch run docs:build

License

MIT - Tomas Aparicio

pook's People

Contributors

astagi avatar danigm avatar gradam avatar h2non avatar kvalev avatar kylejameswalker avatar lki avatar mindflayer avatar mitchk1609 avatar odarbelaeze avatar pavdmyt avatar petarmaric avatar qiao-meng-zefr avatar rsheftel avatar sarayourfriend avatar sky-code avatar srusskih avatar wimglenn 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

pook's Issues

Upgrade xmltodict

The version of xmltodict conflicts with wechatpy, please upgrade it to 0.11.0

Pook 1.0.1 Error of JSON module (Py2 only)

Version: Pook==1.0.1
Environment: Python 2.7

Demo code

# demo.py
import pook, requests, json
pook.on()
pook.post('http://x.com', json={"a": "a"}, reply=300)
requests.post('http://x.com', data=json.dumps({"a": "a"}))
pook.off()

Error message:

=> Detailed matching errors:
JSONMatcher: 'module' object has no attribute 'dumps'

Error source code:

image

Debugging

After a bit of debugging at runtime console, I found out that the json module showed above was not actually builtin json but rather a "magic mock":

>>> json
<module 'pook.matchers.json' from '/Users/someone/virtualenv/venv2/lib/python2.7/site-packages/pook/matchers/json.pyc'>
>>> json.dumps
AttributeError: 'module' object has no attribute 'dumps'

>>> import ujson
>>> ujson.dumps({1:1})
'{"1":1}'

aiohttp mocking binary content

I am refactoring one of my project from using requests to aiohttp as http client library and my exists test failing.
I found 2 issues in mockig aiohttp
First is url handling, when i write test for requests library - pook require full url to match

url = 'http://data.alexa.com/data?cli=10&dat=snbamz&url=http%3A%2F%2Ftest.org'

when i replace requests to aiohttp pook stop matching full url and need now url without parameters

url = 'http://data.alexa.com/data'

Second issue with content mocking, when i use requests i mock binary content

    mock_response_content = b'<?xml version="1.0" encoding="UTF-8"?>\r\n\r\n<!-- Need more Alexa data?  Find our APIs here: https://aws.amazon.com/alexa/ -->\r\n<ALEXA VER="0.9" URL="test.org/" HOME="0" AID="=" IDN="test.org/">...</ALEXA>'

this code now throw exception with aiohttp but not throw any exception with requests
here is exception

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
natrix\plugins\alexa_data\alexa_data.py:20: in perform_scan
    async with self.http_session.get(DATA_ALEXA_API_URL, params=alexa_api_params) as resp:
env\lib\site-packages\aiohttp\client.py:529: in __aenter__
    self._resp = yield from self._coro
env\lib\site-packages\pook\interceptors\aiohttp.py:124: in handler
    data=data, headers=headers, **kw)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <pook.interceptors.aiohttp.AIOHTTPInterceptor object at 0x051331D0>
_request = <function ClientSession._request at 0x04578B28>
session = <aiohttp.client.ClientSession object at 0x04E968D0>, method = 'GET'
url = 'http://data.alexa.com/data', data = None, headers = []
kw = {'allow_redirects': True, 'params': {'cli': '10', 'dat': 'snbamz', 'url': 'http://test.org'}}
req = Request(
  method=GET,
  headers=HTTPHeaderDict({}),
  body=None,
  url=http://data.alexa.com/data,
  query={},
)
mock = Mock(
  matches=1,
  times=0,
  persist=False,
  matchers=MatcherEngine([
    MethodMatcher(GET),
    URLMatcher(http:...ARITY URL="test.org/" TEXT="2285614" SOURCE="panel"/><REACH RANK="1897255"/><RANK DELTA="+608439"/></SD></ALEXA>'
  )
)
res = Response(
    headers=HTTPHeaderDict({}),
    status=200,
    body=b'<?xml version="1.0" encoding="UTF-8"?>\r\n\r\n<!-...OPULARITY URL="test.org/" TEXT="2285614" SOURCE="panel"/><REACH RANK="1897255"/><RANK DELTA="+608439"/></SD></ALEXA>'
)
_res = <ClientResponse(http://data.alexa.com/data) [200 OK]>
<CIMultiDictProxy()>


    @asyncio.coroutine
    def _on_request(self, _request, session, method, url,
                    data=None, headers=None, **kw):
        # Create request contract based on incoming params
        req = Request(method)
        req.headers = headers or {}
        req.body = data
    
        # Expose extra variadic arguments
        req.extra = kw
    
        # Compose URL
        req.url = str(url)
    
        # Match the request against the registered mocks in pook
        mock = self.engine.match(req)
    
        # If cannot match any mock, run real HTTP request if networking
        # or silent model are enabled, otherwise this statement won't
        # be reached (an exception will be raised before).
        if not mock:
            return _request(session, method, url,
                            data=data, headers=headers, **kw)
    
        # Simulate network delay
        if mock._delay:
            yield from asyncio.sleep(mock._delay / 1000)  # noqa
    
        # Shortcut to mock response
        res = mock._response
    
        # Aggregate headers as list of tuples for interface compatibility
        headers = []
        for key in res._headers:
            headers.append((key, res._headers[key]))
    
        # Create mock equivalent HTTP response
        _res = HTTPResponse(req.method, self._url(urlunparse(req.url)))
    
        # response status
        _res.version = (1, 1)
        _res.status = res._status
        _res.reason = http_reasons.get(res._status)
        _res._should_close = False
    
        # Add response headers
        _res.raw_headers = tuple(headers)
        _res.headers = multidict.CIMultiDictProxy(
            multidict.CIMultiDict(headers)
        )
    
        # Define `_content` attribute with an empty string to
        # force do not read from stream (which won't exists)
        _res._content = ''
        if res._body:
>           _res._content = res._body.encode('utf-8', errors='replace')
E           AttributeError: 'bytes' object has no attribute 'encode'

env\lib\site-packages\pook\interceptors\aiohttp.py:110: AttributeError

with string content no exception and all working as expected

What about using Mocket as core library?

Hi there, I am the author of mocket and I think our projects are really similar and well connected.
What about joining forces? I think mocket is still a great idea, but currently I am the only one still working on it (we were two friends/colleagues at the time we presented it at EuroPython 2013, and another colleague helped us to fix some issues).
My idea is basically having mocket as pook engine.
What do you think about it?
Thanks in advance,
Giorgio

https://github.com/mocketize/python-mocket

regex url matching doesn't work

Test case

import pook

def test_pook_regex():
    pook.on()
    # from the example docs: http://pook.readthedocs.io/en/latest/examples.html?highlight=regex#regular-expression-matching
    pook.get(pook.regex('h[t]{2}pbin.*'))

Result

    @url.setter
    def url(self, url):
>       if not protoregex.match(url):
E       TypeError: expected string or bytes-like object

../.direnv/python-3.6.2/lib/python3.6/site-packages/pook/request.py:90: TypeError

Use context

with pook('localhost:9200') as mock:
  mock.path('/foo').headers({'foo': 'bar'}).reply(204)
  requests.get('localhost:9200/foo')

Installation fail when your system encoding is cp1251.py

I was trying to install pook on my machine with system preference encoding win-1251 and I have received exception

pip install --upgrade pook
Collecting pook
  Using cached pook-0.1.3.tar.gz
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "C:\Users\sky\AppData\Local\Temp\pip-build-nd_a6pc3\pook\setup.py", line 55, in <module>
        readme = f.read()
      File "C:\Python\Python35-32\lib\encodings\cp1251.py", line 23, in decode
        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
    UnicodeDecodeError: 'charmap' codec can't decode byte 0x98 in position 1842: character maps to <undefined>

Problem in reading file README.rst in symbol
Explicit set encoding when calling read function in setup.py to solve this

Add networking filters

def is_private_host(req):
  return res.url.host == 'foo.com'

pook.network_filter(is_private_host)
pook.flush_network_filters()

error in pook setup command: 'install_requires' must be a string or list

$ pip install pook

Downloading/unpacking pook
  Downloading pook-0.1.2.tar.gz
  Running setup.py (path:/home/me/.virtualenvs/docker/build/pook/setup.py) egg_info for package pook
    error in pook setup command: 'install_requires' must be a string or list of strings containing valid project/version requirement specifiers
    Complete output from command python setup.py egg_info:
    error in pook setup command: 'install_requires' must be a string or list of strings containing valid project/version requirement specifiers

Improve matching error message

pook: cannot match any mock for request:

=> Request
> GET /foo/bar?foo=1
> Host: httpbin.org
> Accept: application/json
> User-Agent: python-requests/2.13.0
> Accept-Encoding: gzip, deflate
> Body:
> {"foo": "bar"}

=> Matching error details
hostname is not valid

Truncate body for large payloads.

Global defaults request/response mock definitions

Persistent mock definition are reused across volatile mock instances via inheritance.

Exposes mock request/response chainable interfaces:

pook.defaults.request.headers({'Client': 'pook/0.1.6'})
pook.defaults.response.headers({'Server': 'pook/0.1.6'})

Testsuite does not work with latest pytest

If you try to run the tests with pytest 5.x series it fails:

[    7s] _________________________ test_base_matcher_exceptions _________________________
[    7s] 
[    7s]     def test_base_matcher_exceptions():
[    7s]         assert _BaseMatcher('foo').match(None) is None
[    7s]     
[    7s] >       with pytest.raises(ValueError,
[    7s]                            message='expectation argument cannot be empty'):
[    7s] E                          TypeError: Unexpected keyword arguments passed to pytest.raises: message
[    7s] E                          Use context-manager form instead?
[    7s] 
[    7s] tests/unit/matchers/base_test.py:35: TypeError

Engine level default base response

Globally defined response object.

pook.base_response(pook.Response(headers={'Content-Type': 'foo'}))
pook.default_response(pook.Response(headers={'Content-Type': 'foo'}))
# Equivalent to:
pook.headers(headers={'Content-Type': 'foo'})

pip install: error in pook setup command

with pip install and an old version of setuptools (19.2) I get:

$ pip install pook
Downloading/unpacking pook
  Downloading pook-0.1.2.tar.gz
  Running setup.py (path:/home/user/repo/venv/build/pook/setup.py) egg_info for package pook
    error in pook setup command: 'install_requires' must be a string or list of strings containing valid project/version requirement specifiers
    Complete output from command python setup.py egg_info:
    error in pook setup command: 'install_requires' must be a string or list of strings containing valid project/version requirement specifiers

pip install --upgrade setuptools solves this

Though the dependencies xmltodict and jsonschema are not installed automatically.

pook.use() context manager is stilll active after use even in follow-up testcases

Hi,
thanks for pook, it's a very handy library that I use in my pytest tests.

However I think I found a bug (using pook v1.0.1, Python 3.8.2, requests 2.21.0, Windows 10):
When using pook.use() as context manager to replace a requests.get() call pook does not seem to remove the patching afterwards. It will also stay active across any follow-up testcases. I can reproduce it using the following pytest:

def test_pookUse_contextManager_isDisabledAfterUse():
    url = 'http://foo.bar'
    with pytest.raises(requests.exceptions.ConnectionError):
        requests.get(url)
    respJson = {"resp": "ok"}
    with pook.use():
        pook.get(url).reply().json(respJson)
        resp = requests.get(url)
        assert resp.json() == respJson
        assert pook.isdone()
    assert not pook.isactive()
    with pytest.raises(requests.exceptions.ConnectionError):
        requests.get(url)

Pytest output:

tests\integration\engines_test.py:14 (test_pookUse_contextManager_isDisabledAfterUse)
def test_pookUse_contextManager_isDisabledAfterUse():
        url = 'http://foo.bar'
        with pytest.raises(requests.exceptions.ConnectionError):
            requests.get(url)
        respJson = {"resp": "ok"}
        with pook.use():
            pook.get(url).reply().json(respJson)
            resp = requests.get(url)
            assert resp.json() == respJson
            assert pook.isdone()
        assert not pook.isactive()
        with pytest.raises(requests.exceptions.ConnectionError):
>           requests.get(url)

tests\integration\engines_test.py:27: 

[...]

            # Raise no matches exception
>           raise PookNoMatches(msg)
E           pook.exceptions.PookNoMatches: pook error!
E           
E           => Cannot match any mock for the following request:
E           ==================================================
E           Method: GET
E           URL: http://foo.bar:80/
E           Headers: HTTPHeaderDict({'User-Agent': 'python-requests/2.21.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'})
E           ==================================================

pook\engine.py:443: PookNoMatches

I put the testcase as the first one that is executed in all modules to avoid any effects from previous testcases (I put it on top in tests/integration/engines_test.py ).
I could not yet figure out what the issue is. Could you have a look if it is reproducible on your side as well? Thank you.

pook can't handle binary headers

If a response header is binary, for example something like ('Content-Type', b'application/pdf'), when pook tries to iterate over the headers, it is expecting a string and throws an error. The problem is in HTTPHeaderDict.itermerged.

Examples

  • unittest example
  • nose example
  • py.test example
  • Raw Python examples
  • Hy examples

Simulate error

# Custom string error
pook.get('foo.com').error('simulated error')
# Custom Exception
pook.get('foo.com').error(RuntimeError('simulated error'))

Add mock mappers and filters

Port feature from gock.

def global_filter(req):
  return req.url.port == 80
pook.filter(global_filter)

def local_filter(req):
    return req.url.port == 80
pook.get('foo.com').filter(local_filter)

Issues using with urllib

When using with urllib an exception is throw as response doesn't have a code attribute. Uncovered this while trying to mock a prometheus push gateway endpoint with prometheus client library. Simplified code snippet below:

Exception raised:

self = <urllib.request.HTTPErrorProcessor object at 0x7f79100e3c18>
request = <urllib.request.Request object at 0x7f79100e3748>
response = <http.client.HTTPResponse object at 0x7f7910608048>

    def http_response(self, request, response):
>       code, msg, hdrs = response.code, response.msg, response.info()
E       AttributeError: 'HTTPResponse' object has no attribute 'code'

Test code snippet:

    @pook.on
    def test_pook(self):
        mock = pook.put('http://prometheus_test', reply=201, response_json={'test': 'test'})

        # resp = requests.put('http://prometheus_test')
        do_request(
            url='http://prometheus_test', method='PUT', timeout=30, data=b'',
        )()

        # assert resp.status_code == 200
        assert mock.calls == 1

def do_request(url, method, timeout, data):
        request = Request(url, data=data)
        request.get_method = lambda: method
        resp = build_opener(HTTPHandler).open(request, timeout=timeout)
        if resp.code >= 400:
            raise IOError("error talking to pushgateway: {0} {1}".format(
                resp.code, resp.msg))

Support pycurl HTTP client

Some "unlucky" people still relies on it. This is purely a nice-to-have feature.

PR are very welcome.

Python 3.7 support

Heya.
After playing a bit with the library (well done!), I've found that, at least on Python 3.7 (which is now officially released), then pook.off() doesn't work.
Moreover, enable_network (with and without hosts) doesn't work. Without host there just seems to be no effect (still raises exception on unmatched requests), and with hosts it yells about incompatibility between a tuple and a list/string.

Would be happy to help fixing these if needed!

API design

class SampleTest(TestCase):
  @pock.on
  def test_sample(self):
     pock.get('google.es', path='/foo', header=('Server', 'nginx'))
     requests.get('google.es/foo')

Decorator mock

@pook.on
def test_request():
  requests.get()

Decorator:

@pook.get('foo.com', reply=404)
def test_request(pook):
  requests.get()

Aiohttp doesn't work

I try example from https://github.com/h2non/pook/blob/master/examples/aiohttp_client.py and it looks that it does't work correctly.

Traceback (most recent call last):
...
  File "/Users/pavel.studenik/Devel/pnl_pricing_app/venv/lib/python3.7/site-packages/pook/interceptors/aiohttp.py", line 92, in _on_request
    _res = HTTPResponse(req.method, self._url(urlunparse(req.url)))
  File "/Users/pavel.studenik/Devel/pnl_pricing_app/venv/lib/python3.7/site-packages/pook/interceptors/aiohttp.py", line 44, in HTTPResponse
    return ClientResponse(*args, **kw)
TypeError: __init__() missing 7 required keyword-only arguments: 'writer', 'continue100', 'timer', 'request_info', 'traces', 'loop', and 'session'

Add custom matcher functions

A possible interface implementation:

def matcher(request, mock):
  return request.url.path == '/v1/foo'

pook.get('api.server.com').match_func(matcher).match_func(matcher)

Overload method for specific matcher function usage:

def json_matcher(body):
  return body == '{"foo": true}'

pook.get('api.server.com').body(json_matcher)

example raises Exception

$ python test_it.py 
Traceback (most recent call last):
  File "test_it.py", line 17, in <module>
    test_my_api()
  File "/home/repo/venv/local/lib/python2.7/site-packages/pook/api.py", line 77, in wrapper
    raise err
pook.exceptions.PookNoMatches: ('Cannot match any mock for request:', Request(
  method=GET,
  headers=HTTPHeaderDict({'Connection': 'keep-alive', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'python-requests/2.11.1'}),
  body=None,
  url=ParseResult(scheme='http', netloc='twitter.com:80', path='/api/1/foobar', params='', query='', fragment=''),
  query={},
))

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.