Code Monkey home page Code Monkey logo

python-json-pointer's People

Contributors

alexdutton avatar benkehoe avatar cunla avatar hugovk avatar jdanford avatar kislyuk avatar kxepal avatar marble avatar peterlitszo avatar rossburton avatar stefankoegl avatar thekafkaf 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

python-json-pointer's Issues

Parsing of command-line arguments is broken

The jsonpointer ver ~ 2 has the following issues parsing command line arguments:

  1. It is not compatible with the jsonpointer ver ~ 1
  2. It does not parse correctly the -f argument, so it is not possible to provide the pointer in a file (as it was possible in jsonpointer ver ~ 1)
  3. The help text from jsonpointer --help allows ambiguous explanation of the command line parameters
  4. The documentation The jsonpointer commandline utility follows the jsonpointer ver ~ 1 syntax.

Here are more details:
ad 1 and 4) The example from The jsonpointer commandline utility works fine with the jsonpointer ver ~ 1
Unfortunately with the jsonpointer ver ~ 2 the example generates the following error:

$ jsonpointer ./ptr.json ./a.json ./b.json
Could not resolve pointer: location must starts with /
Could not resolve pointer: location must starts with /

This is because the jsonpointer ver ~ 2 expects the pointer as the first argument, instead of a file with the pointer.

ad 2) When I try to use the -f argument to provide the pointer in a file, then the argument of the first json file (a.json) is parsed in a wrong way and jsonpointer does not understand it, as it considers the file name as a pointer expression:

$ jsonpointer -f ./ptr.json ./a.json ./b.json
usage: jsonpointer [-h] [-f [POINTER_FILE]] [--indent INDENT] [-v] [POINTER] FILE [FILE ...]
jsonpointer: error: argument POINTER: not allowed with argument -f/--pointer-file

ad 3) Let's assume the -f works, then the help text

$ jsonpointer --help
usage: jsonpointer [-h] [-f [POINTER_FILE]] [--indent INDENT] [-v] [POINTER] FILE [FILE ...]

has ambiguous explanation because POINTER_FILE is in square brackets. It can been understood as the POINTER_FILE is not mandatory when using the -f argument and then the -f can be used even with the POINTER.

I can write a patch to fix this issues, however before I do so, I need to understand what was the intention behind the change of the command-line syntax in ver ~ 2 and how it is expected those command-line parameters will work.

IMO the best way will be to keep the command-line syntax compatible with ver ~ 1. If there is a need to have a pointer expressed directly on command-line, then a new parameter (i.e. -e|--expression or -p|--ptr|--pointer) should be introduced. However as the ver ~ 2 is already in place for some time, this will introduce a regression to the current syntax in ver ~ 2.

Adding elemente to array

Add operations with - at the of the path intending to insert a new value in a array is implemented?

from: http://jsonpatch.com/

Add
{ "op": "add", "path": "/biscuits/1", "value": { "name": "Ginger Nut" } }
Adds a value to an object or inserts it into an array. In the case of an array, the value is inserted before the given index. The - character can be used instead of an index to insert at the end of an array.

When trying to do so "path": "/biscuits/-", ex:

 [
 {
    "op": "add",
    "path": "/biscuits/-",
    "value": "bono"
  }
]

I get:

list indices must be integers or slices, not str

Am I doing something wrong or the feature is not implemented?

Could set_pointer create structures if it can't find any?

>>> data = {}
>>> set_pointer(data, "/cat/name", "whiskers")
Traceback (most recent call last):
  File "......./jsonpointer.py", line 276, in walk
    return doc[part]
KeyError: 'cat'

During handling of the above exception, another exception occurred:

..........
    raise JsonPointerException("member '%s' not found in %s" % (part, doc))
jsonpointer.JsonPointerException: member 'cat' not found in {}

Could there be an option (off by default) to create dicts/lists as it tries to set things? So instead you'd get:

>>> data = {}
>>> set_pointer(data, "/cat/name", "whiskers", option=True)
{'cat': {'name': 'whiskers'}}

I started hacking on something at https://github.com/stefankoegl/python-json-pointer/compare/master...odscjames:set-create-structures?expand=1

More needs to be done on that, but if I can get something to work is this something your interested in?

I can see there might always be some edge cases around things like creating lists, and I don't think that could be fixed but it might still be useful?

Exception occured in Jsonpointer

I am trying to document schema files using sphinx.
Once I add the file path it throws this error

  File "/Users/eyshika.agarwal/.virtualenvs/gui-intrinsic/lib/python3.7/site-packages/jsonpointer.py", line 279, in walk
    raise JsonPointerException("member '%s' not found in %s" % (part, doc))
jsonpointer.JsonPointerException: member 'src' not found in OrderedDict([('$schema', 'http://json-schema.org/draft-07/schema#'), ('$id', '/sports_field'), ('title', 'Field'), ('description', 'A sports field description.'), ('type', 'object'), ('properties', OrderedDict([('description', OrderedDict([('description', 'Field description'), ('type', 'string')])), ('units', OrderedDict([('description', 'length units in which the calibration points are defined.'), ('$ref', '/units_length')])), ('calibration_points', OrderedDict([('description', "list of XYZ corner points of the filed lines. Length units defined by 'units' property."), ('type', 'array'), ('items', OrderedDict([('type', 'array'), ('maxItems', 3), ('minItems', 3), ('items', OrderedDict([('anyOf', [OrderedDict([('type', 'number')]), OrderedDict([('type', 'string'), ('description', 'An arithmetic expression to be evaluated along with the parameters provided.'), ('examples', ['(0.5 * width) + 10.0'])])])]))])), ('uniqueItems', True)])), ('parameters', OrderedDict([('description', 'parameter list used for generating the calibration points'), ('type', 'array'), ('items', OrderedDict([('type', 'object'), ('properties', OrderedDict([('name', OrderedDict([('type', 'string'), ('description', 'parameter name')])), ('description', OrderedDict([('type', 'string'), ('description', 'parameter description')])), ('default', OrderedDict([('type', 'number'), ('description', 'parameter default value')]))])), ('required', ['name', 'description', 'default'])]))]))])), ('required', ['units', 'calibration_points'])])```

Relative JSON Pointers

Hi!

Was wondering what you think about @handrews' Relative JSON Pointer specification.

Do you feel it has a place within this library, or would you rather it be separate?

(I ask of course because as in #20, I'm about to add support for validating relative JSON pointers to jsonschema).

Cheers,
-J

unicode issue using Python 2.7.2

I am using Python 2.7.2 and did a pip install jsonpatch

I am seeing the following error when trying to apply a patch to my json doc.

patch = jsonpatch.apply_patch(data['request_body'], myPatch)
File "/Users/test/projects/venv/lib/python2.7/site-packages/jsonpatch.py", line 102, in apply_patch
return patch.apply(doc, in_place)
File "/Users/test/projects/venv/lib/python2.7/site-packages/jsonpatch.py", line 301, in apply
obj = operation.apply(obj)
File "/Users/test/projects/venv/lib/python2.7/site-packages/jsonpatch.py", line 393, in apply
subobj, part = self.pointer.to_last(obj)
File "/Users/test/projects/venv/lib/python2.7/site-packages/jsonpointer.py", line 129, in to_last
return doc, self.get_part(doc, self.parts[-1])
File "/Users/test/projects/venv/lib/python2.7/site-packages/jsonpointer.py", line 168, in get_part
raise JsonPointerException("Unknown document type '%s'" % (doc.class,))
JsonPointerException: Unknown document type '<type 'unicode'>'

Please add license

This library looks like exactly what I'm looking for, but I can't use it without a license. Could you add a license please? BSD, MIT or Apache preferred.

Curious about modified BSD license?

Hello there, and thanks for the awesome library!

While taking a look at the source today I noticed that it was listed as having a "modified BSD" license. I was curious to see what was modified and if I should be aware when using it, so I generated a quick diff between the usual BSD license and the one for the project:

-Copyright <YEAR> <COPYRIGHT HOLDER>
+Copyright (c) 2011 Stefan Kögl <[email protected]>
+All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
@@ -9,13 +10,13 @@
 2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
-3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products
+3. The name of the author may not be used to endorse or promote products
    derived from this software without specific prior written permission.
 
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY

The change seems rather harmless as far as use goes; for contribution I wonder if changing "the copyright holders and contributors" to "the author" would mean that other contributors would not be exempted in some of the clauses...?

My question is: I'm curious what the motivation behind the modified license is, and have you considered going back to the usual wording?

Thanks 🙏

resolve_pointer() won't always return the default.

I noticed the behavior in to cases:

  1. The path that was given was longer the the dicts depth and the last object resolved was a string.
  2. The 'doc' obj to be resolved against was not a dict nor a list and the path was'nt defined.

Both this cases are the product of the handling of getitem in the function walk(), in case the doc is not a list nor a dict, getitem is called without an except.
Is there a reason for that? If not, I'd would be more than happy to open a pull request with new tests and a fix.

Publish new version with JsonPointerException typo fix

Thanks for the library - it works well with jsonpatch :-)

I noticed that, when a JsonPointerException is raised due to an invalid location, the error message says "location must starts with /". The plural "starts" is a typo. This appears to have been fixed in master. I was wondering if the corrected version could be pushed out as a bugfix? Right now, I'm catching and correcting it before re-raising.

$ python3
Python 3.7.6 (default, Jan 11 2020, 15:56:36)
[Clang 11.0.0 (clang-1100.0.33.16)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import jsonpointer
>>> jsonpointer.JsonPointer("/field")
<jsonpointer.JsonPointer object at 0x10a80afd0>
>>> jsonpointer.JsonPointer("field")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/aru/.virtualenvs/venv/lib/python3.7/site-packages/jsonpointer.py", line 182, in __init__
    raise JsonPointerException('location must starts with /')
jsonpointer.JsonPointerException: location must starts with /
>>> jsonpointer.__version__
'2.0'

setup.py ascii decode error in python3 when using "C" system locale.

Hi, I'm seeing the following error:

$ LC_ALL=C python3.4 -B setup.py config
Traceback (most recent call last):
  File "setup.py", line 9, in <module>
    src = open(filename).read()
  File "/usr/lib64/python3.4/encodings/ascii.py", line 26, in decode
    return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 179: ordinal not in range(128)

This is causing issues during linux distribution software packaging, where you often can't rely on having a unicode locale set.

The issue appears to be that in the 'C' locale, python is defaulting to ASCII decoding rather than UTF-8. You should explicitly state the encoding of the file being opened to solve this issue; the syntax io.open(filename, encoding="utf-8") should work in python2.6 and newer (including python3).

Optimizations from #16 reverted

I had to revert the optimizations from #16, because the tests of jsonpatch failed with

$ ./tests.py 
........E.......E...................................................................
======================================================================
ERROR: test_append (__main__.ApplyPatchTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "./tests.py", line 218, in test_append
    {'op': 'add', 'path': '/foo/-', 'value': 4},
  File "/home/stefan/python-json-patch/jsonpatch.py", line 154, in apply_patch
    return patch.apply(doc, in_place)
  File "/home/stefan/python-json-patch/jsonpatch.py", line 364, in apply
    obj = operation.apply(obj)
  File "/home/stefan/python-json-patch/jsonpatch.py", line 438, in apply
    elif part > len(subobj) or part < 0:
TypeError: unorderable types: EndOfList() > int()

======================================================================
ERROR: test_js_file (__main__.ApplyPatchTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "./tests.py", line 23, in test_js_file
    result = jsonpatch.apply_patch(test['doc'], test['patch'])
  File "/home/stefan/python-json-patch/jsonpatch.py", line 154, in apply_patch
    return patch.apply(doc, in_place)
  File "/home/stefan/python-json-patch/jsonpatch.py", line 364, in apply
    obj = operation.apply(obj)
  File "/home/stefan/python-json-patch/jsonpatch.py", line 438, in apply
    elif part > len(subobj) or part < 0:
TypeError: unorderable types: EndOfList() > int()

----------------------------------------------------------------------
Ran 84 tests in 0.019s

FAILED (errors=2)

Drop Python 2.7 support

In #47 the question has come up whether to drop support for Python 2.7.

I don't have any opinion on that yet, but I'd like to open the discussion.

A related issue is open for jsonpatch at stefankoegl/python-json-patch#140.

Input

The charts on https://pypistats.org/packages/jsonpointer show download stats based on Python versions.

Sunset date for the Python project itself was Jan 1, 2020: https://www.python.org/doc/sunset-python-2/

See https://python3statement.org/ for projects that have dropped support for Python 2 by/before the sunset date.

jsonpointer.EndOfList class compain about indexing a list

I am trying to index a list of dict object via resolve_pointer() and came across the following error. This happens with both version 1.1 and 1.7. The output is as below:

bliang@latite:~/lumberjack/python-json-pointer$ python
Python 2.6.6 (r266:84292, Jun 18 2012, 09:57:52)
[GCC 4.4.6 20110731 (Red Hat 4.4.6-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.

from jsonpointer import resolve_pointer
ranges = {'items': [{'start': 7, 'end': 7}, {'start': 23, 'end': 23}, {'start': 37, 'end': 37}, {'start': 107, 'end': 107}, {'start': 179, 'end': 179}, {'start': 513, 'end': 514}, {'start': 1494, 'end': 1494}, {'start': 1718, 'end': 1720}, {'start': 2000, 'end': 2003}, {'start': 2427, 'end': 2427}, {'start': 2598, 'end': 2598}, {'start': 2727, 'end': 2727}, {'start': 3389, 'end': 3389}, {'start': 5060, 'end': 5060}, {'start': 5631, 'end': 5631}, {'start': 5900, 'end': 5903}, {'start': 6000, 'end': 6000}], 'label': u'Interactive'}
resolve_pointer(ranges, '/items/-')
EndOfList([{'start': 7, 'end': 7}, {'start': 23, 'end': 23}, {'start': 37, 'end': 37}, {'start': 107, 'end': 107}, {'start': 179, 'end': 179}, {'start': 513, 'end': 514}, {'start': 1494, 'end': 1494}, {'start': 1718, 'end': 1720}, {'start': 2000, 'end': 2003}, {'start': 2427, 'end': 2427}, {'start': 2598, 'end': 2598}, {'start': 2727, 'end': 2727}, {'start': 3389, 'end': 3389}, {'start': 5060, 'end': 5060}, {'start': 5631, 'end': 5631}, {'start': 5900, 'end': 5903}, {'start': 6000, 'end': 6000}])
resolve_pointer(ranges, '/items/-/start')
Traceback (most recent call last):
File "", line 1, in
File "jsonpointer.py", line 111, in resolve_pointer
return pointer.resolve(doc, default)
File "jsonpointer.py", line 168, in resolve
doc = self.walk(doc, part)
File "jsonpointer.py", line 224, in walk
part = self.get_part(doc, part)
File "jsonpointer.py", line 218, in get_part
"must be dict/list or support getitem" % type(doc))
jsonpointer.JsonPointerException: Document '<class 'jsonpointer.EndOfList'>' does not support indexing, must be dict/list or support getitem

jsonpointer will not work with unicode keys in python 2.7

It looks like jsonpointer will not work with unicode keys, both of the following code snippets fail:

data = {u'\xee': u'\xee'}
jsonpatch.make_patch({}, data)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/sendhub/scratch/contacts_v2_scratch/venv/local/lib/python2.7/site-packages/jsonpatch.py", line 171, in make_patch
    return JsonPatch.from_diff(src, dst)
  File "/opt/sendhub/scratch/contacts_v2_scratch/venv/local/lib/python2.7/site-packages/jsonpatch.py", line 322, in from_diff
    return cls(list(compare_values([], src, dst)))
  File "/opt/sendhub/scratch/contacts_v2_scratch/venv/local/lib/python2.7/site-packages/jsonpatch.py", line 293, in compare_values
    for operation in compare_dicts(path, value, other):
  File "/opt/sendhub/scratch/contacts_v2_scratch/venv/local/lib/python2.7/site-packages/jsonpatch.py", line 314, in compare_dicts
    ptr = JsonPointer.from_parts(path + [key])
  File "/opt/sendhub/scratch/contacts_v2_scratch/venv/local/lib/python2.7/site-packages/jsonpointer.py", line 291, in from_parts
    parts = [str(part) for part in parts]
UnicodeEncodeError: 'ascii' codec can't encode character u'\xee' in position 0: ordinal not in range(128)
data2 = {u'\xee'.encode('utf-8'): u'\xee'.encode('utf-8')}
jsonpatch.make_patch({}, data2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/sendhub/scratch/contacts_v2_scratch/venv/local/lib/python2.7/site-packages/jsonpatch.py", line 171, in make_patch
    return JsonPatch.from_diff(src, dst)
  File "/opt/sendhub/scratch/contacts_v2_scratch/venv/local/lib/python2.7/site-packages/jsonpatch.py", line 322, in from_diff
    return cls(list(compare_values([], src, dst)))
  File "/opt/sendhub/scratch/contacts_v2_scratch/venv/local/lib/python2.7/site-packages/jsonpatch.py", line 293, in compare_values
    for operation in compare_dicts(path, value, other):
  File "/opt/sendhub/scratch/contacts_v2_scratch/venv/local/lib/python2.7/site-packages/jsonpatch.py", line 314, in compare_dicts
    ptr = JsonPointer.from_parts(path + [key])
  File "/opt/sendhub/scratch/contacts_v2_scratch/venv/local/lib/python2.7/site-packages/jsonpointer.py", line 292, in from_parts
    parts = [part.replace('~', '~0') for part in parts]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)

Ability to control how verbose the JsonPointerException is

Hi,
Love this library.

I'm using it for JsonPointing to an element inside a JSON schema. My schema files could be ~10k lines.
When a member is not found, this line formats (and dumps) the entire doc inside the message via this line:

raise JsonPointerException("member '%s' not found in %s" % (part, doc))

It would be wonderful to control the dumping of the doc to the exception message (e.g. Enabled by default, Disabled otherwise - in this case just the member is formatted).

Thanks

Add `get_parts`

get_parts function looks useful because use variable parts looks not good...

Maybe you want to know that why I want to use parts - because I want to check if the path is right for me. I do not want to agree a patch that I do not want to agree. So I need to check the path before change my data struct and database.

DeprecationWarning in tests

i know the project doesnt officially use pytest but it seems to support the existing tests as is which is nice, and it gives a bit more information in the output.

when testing with pytest the following warning is emitted due to deprecated syntax.
i was going to do a pr to fix it, but wasnt sure if this is relevant when working with json pointers or is something that can be resolved.

===>  Regression tests for py3-jsonpointer-2.2
============================= test session starts ==============================
platform xxxxx -- Python 3.9.10, pytest-7.1.0, pluggy-1.0.0
rootdir: /usr/ports/pobj/py-jsonpointer-2.2-python3/jsonpointer-2.2
collected 19 items

tests.py ...................                                             [100%]

=============================== warnings summary ===============================
tests.py:88
  /usr/ports/pobj/py-jsonpointer-2.2-python3/jsonpointer-2.2/tests.py:88: DeprecationWarning: invalid escape sequence \j
    ("/i\\j", ['i\j']),

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
======================== 19 passed, 1 warning in 0.11s =========================

Provide an API for detecting invalid JSON Pointers

Hi!

Would you consider an API to validate whether a particular input was valid under RFC 6901 (or does such a thing exist already and I've missed it)?

E.g., /foo/bar~ is not a valid JSON Pointer seemingly (the ~ is not escaped), but I cannot see an API that complains about that -- jsonpointer.JsonPointer will happily accept it as another pointer part.

(Even having jsonpointer.JsonPointer do enough validation of its inputs would also work).

Full context: JSON Schema Draft 6 adds a jsonpointer format. I'd love to use python-json-pointer to implement it in jsonschema.

bad interpreter: No such file or directory

After installing from pip
$ sudo pip install jsonpointer

Running jsonpointer gives me this error.
-bash: /usr/local/bin/jsonpointer: /home/stefan/work/python-json-patch/venv/bin/python: bad interpreter: No such file or directory

jsonpointer should not expect pointers to be urlencoded

As pointed out by @mithrandi in stefankoegl/python-json-patch#63:

The first problem is that jsonpointer expects pointers to be urlencoded, which I don't think is correct
(my reading of the RFC is that urlencoding should only be used when the pointer is part of a URL, so
nothing special to JSON pointer itself).

My response within the referenced issue

[...] the failing example should be

>>> import jsonpointer
>>> obj = {'a b': 1}
>>> jsonpointer.resolve_pointer(obj, '/a%20b')
1

Instead this should give an error because there is no member a%20b.

It seems that I added the unquoting (currently
line 145) already in the very first commit.
Initially the [RFC draft|https://tools.ietf.org/html/draft-pbryan-zyp-json-pointer-00] did contain

Property names SHOULD be URI encoded per [RFC2396]. In particular,
any "/" character in a property name MUST be encoded as "%2F" to
avoid being interpreted as a property reference token separator.

but this was removed before the final RFC, and is thus no longer correct.

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.