pyeve / eve Goto Github PK
View Code? Open in Web Editor NEWREST API framework designed for human beings
Home Page: https://python-eve.org
License: Other
REST API framework designed for human beings
Home Page: https://python-eve.org
License: Other
Pinning it here for future reference: Would it be possible to have something like /people/nicola/addresses
?
I get the "working outside of application context' error when trying to use Cerberus Validator to validate docs before inserting into db in a test.
Using self.post is fine.
Any suggestions for hot-wiring Validator to use before db.collection.insert?
Sending repeated GET requests to the same endpoint will occasionally return an Internal Server Error.
Hi,
It seems I can't PATCH an additional lookup url.
My settings.py:
backups = {
# 'title' tag used in item links.
'item_title': 'backup',
#'auth_username_field': 'user',
'resource_methods': ['DELETE', 'GET', 'POST'],
'item_methods': ['PATCH', 'DELETE', 'GET'],
#'user_restricted': False,
# by default the standard item entry point is defined as
# '/people/<ObjectId>/'. We leave it untouched, and we also enable an
# additional read-only entry point. This way consumers can also perform GET
# requests at '/people/<lastname>/'.
'additional_lookup': {
'url': '[\w\.]+',
'field': 'stored_filename'
},
# Schema definition, based on Cerberus grammar. Check the Cerberus project
# (https://github.com/nicolaiarocci/cerberus) for details.
'schema': {
'backend': {
'type': 'string',
'required': True,
},
'backend_hash': {
'type': 'string',
'required': True
},
[...]
When I patch using the standard url:
$ curl -H "If-Match: a09caac09dd2cc6ef9d6cf60931d85a4445d6d5f" -X PATCH -i http://localhost:2404/api/backups/51a90b2f8e3e023199e7c397/ -d 'data={"is_deleted":true}'
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 262
ETag: 427e2f19fb6da5095b8c531a18007fc50fe4088d
Last-Modified: Fri, 31 May 2013 20:45:11 UTC
Server: Eve/0.0.7-dev Werkzeug/0.8.3 Python/2.7.3
Date: Fri, 31 May 2013 20:45:11 GMT
{"data": {"status": "OK", "updated": "Fri, 31 May 2013 20:45:11 UTC", "_id": "51a90b2f8e3e023199e7c397", "_links": {"self": {"href": "localhost:2404/api/backups/51a90b2f8e3e023199e7c397/", "title": "backup"}}, "etag": "427e2f19fb6da5095b8c531a18007fc50fe4088d"}}
When I PATCH with the additional lookup url (it works well on GET)
$ curl -H "If-Match: 427e2f19fb6da5095b8c531a18007fc50fe4088d" -X PATCH -i http://localhost:2404/api/backups/ooomg.20130527134546.tgz/ -d 'data={"is_deleted":true}'
HTTP/1.0 405 METHOD NOT ALLOWED
Content-Type: text/html
Allow: HEAD, OPTIONS, GET
Content-Length: 184
Server: Eve/0.0.7-dev Werkzeug/0.8.3 Python/2.7.3
Date: Fri, 31 May 2013 20:46:17 GMT
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>405 Method Not Allowed</title>
<h1>Method Not Allowed</h1>
<p>The method PATCH is not allowed for the requested URL.</p>
Any thought ?
Thanks!
Curiosity killed the cat
Why do JSON payloads have links as XML-serialized strings?
I submit a record that gets rejected by the validator -- but then, the record is inserted into MongoDB anyway.
gella:~ maksim$ curl -d 'item1={"username":"bobama", "firstname": "barack", "lastname": "2"}' 127.0.0.1:5000/people/
{"item1": {"status": "ERR", "issues": ["min length for field 'username' is 8"]}}
gella:~ maksim$ curl -d 'item1={"username":"bobama", "firstname": "barack", "lastname": "2"}' 127.0.0.1:5000/people/
{"item1": {"status": "ERR", "issues": ["min length for field 'username' is 8", "value 'bobama' for field 'username' not unique"]}}
In both cases, the inserts have failed. However, I list the records and get โฆ.
{
"firstname": "barack",
"_links": {
"self": {
"href": "127.0.0.1:5000/people/518ab5cfe584f144b095c4bf/",
"title": "person"
}
},
"username": "bobama",
"updated": "Thu, 01 Jan 1970 00:00:00 UTC",
"lastname": "2",
"_id": "518ab5cfe584f144b095c4bf",
"created": "Thu, 01 Jan 1970 00:00:00 UTC",
"etag": "493ca13f6a2fbad1f11f321231aa8e0fab6bd0c0"
},
{
"firstname": "barack",
"_links": {
"self": {
"href": "127.0.0.1:5000/people/518ab5e0e584f144b095c4c0/",
"title": "person"
}
},
"username": "bobama",
"updated": "Thu, 01 Jan 1970 00:00:00 UTC",
"lastname": "2",
"_id": "518ab5e0e584f144b095c4c0",
"created": "Thu, 01 Jan 1970 00:00:00 UTC",
"etag": "dbc132dc64baae2bf0b3ff8b12f1d9dcff6ec4dc"
},
{
"firstname": "barack",
"_links": {
"self": {
"href": "127.0.0.1:5000/people/518ab5e9e584f144b8bb5405/",
"title": "person"
}
},
"username": "bobama",
"updated": "Thu, 01 Jan 1970 00:00:00 UTC",
"lastname": "2",
"_id": "518ab5e9e584f144b8bb5405",
"created": "Thu, 01 Jan 1970 00:00:00 UTC",
"etag": "75e0c4b68bc65612ddb591a8dc612191efc44e88"
}
i.e. all 3 inserts have gone through despite failing validators.
Hello,
I have a question about the schema definition. Is it possible to make the schema validation less strict to not need to define all the fields in the schema definition ?
Regards,
Big catch!! :)
Duplicate Lines 314, 315
When an endpoint is hit (either regular, or custom) we should allow people to do something before the endpoint does its things, and after it does its things. Sort of like pre- and post-event.
Minor issue, but could cause developer frustration - if the last-found offending item is used in the exception message string, even if multiple issues are found.
Might be friendlier to collect offending items in a list and insert the list results into the exception message.
application/yourcompany.v1+json would be cool ;)
The & in xml pagination links should be escaped. eg.
...
Here is a example, how it may be handled:
http://docs.rackspace.com/cdns/api/v1.0/cdns-devguide/content/Pagination_Elements_and_Attributes-d1e1754.html
When a query is paginated, there's no way to tell how many pages there will be, nor how many total results there are.
"Would be helpful" if the schema supported referential integrity validation for objectid
types during POST
/PATCH
ops.
For example, in eve-demo:
works = {
'schema': {
# snip
'owner': {
'type': 'objectid',
'required': True,
},
}
There is no (simple) way to ensure that the works.owner
value exists in the people
collection. Currently, one must implement a custom Validator
class in order to enforce basic RI rules.
A simplistic approach would allow schema-based specification of the referenced collection name, and if the value doesn't exist, raise an exception.
A more flexible approach would allow optional specification of a callable validation method, thus providing more sophisticated business rules. A default behavior would be to verify existence in the referenced collection per the 'simplistic' approach.
Hello! This project looks fantastic. Nice work!
I'd like use MongoDB as a File Store, using GridFS. How could this be modeled in Eve? Should it be? (The PyMongo driver already has GridFS support.)
Here's an example of how I'd imagine it working:
<resource href="eve-demo.herokuapp.com/pdfs/515980657ec4430002c22478/" title="PDF">
<link rel="collection" href="eve-demo.herokuapp.com/pdfs/" title="pdfs"/>
<link rel="parent" href="eve-demo.herokuapp.com" title="home"/>
<_id>515980657ec4430002c22478</_id>
...
<mimetype>application/pdf</mimetype>
<file>515980637ec4430002c22473</file>
<creator>515980637ec4430002c22474</creator>
</resource>
So, a resource has an object_id
linking to .read()
able file in gridfs. "Accept: application/pdf" to download? A separate collection? I'd rather not have a 'magic' collection for files only, though that's a bit like how gridFS is handled in Mongo. Hmm...
Should it be possible to create a new 'link' for items in settings.py?
works = {
...
'schema': {
...
}
'additional_links':{
'title':'owner',
'href':owner,
}
}
In settings.py file, allow users to specify additional client domains from which to accept requests.
X_DOMAINS = '*' # list or asterisk (to wildcard for a wide-open API)
Here's a Flask snippet on decorating generic HTTP Headers.
Say I want to extend people schema in settings to lets say users.
So I:
import copy
users = copy.deepcopy(people)
users['schema']['username'] = {
'type': 'string',
'minlength': 1,
'maxlength': 10,
}
That seems to work OK. However,
Suppose I want to send people and users to the same collection, lets say 'contacts'.
Is there a way to designate the name of the collection on a per resource basis? Perhaps:
people['collection'] = 'contacts'
users['collection'] = 'contacts'
After going around several flask/mongodb 'packages', am back again reviewing your project. Your video is great! Thanks to providing a complete functional package along with working examples, it is now possible to expedite building a project on eve.
Thank You :)
It would be useful to transform data retrieved by the upstream datasource (mongoDB fo example). Manipulating that as a dict object and then passing the parsed result along so that Eve can use it to generate the response.data field later on.
something like what I have below is what I am thinking:
# not sure if context is required, but it may be useful to support conditional logic based on knowing the caller URI, users session or some other kind of details.
def people_callback(context,data):
customData = dict()
customData['something'] = _code_to_make_something_
for k,v in data.iteritems():
v['somethingElse'] = _code_to_make_something_else_
customData[k] = v
return customData
`...'
app.on_get_on_read_people += people_callback
please use in function document_etag something like this:
json.dumps(value, sort_keys=True) for dict,
instead of
str(value)
In the second case - order (and hash) will be different when script restart, or between different server instances
Currently (eve 0.0.4) only application/x-www-form-urlencoded is accepted.
Hello!
Would it be a good idea to use an _id
field instead of the AUTH_USERFIELD_NAME
to allow a specific user to access/update only the resources he created?
If a user changes his username, he would have to change every document he own and update their username field.
Things like registration, login, forgotten password and change password would be awesome to have.
The response resulting of a successful POST or PATCH should contain the full content item(s) created or updated, including the etag values (or it could be an optional capability). Currently to get that information it required a GET following the POST or PATCH (or multiple in case of multiple inserts)
Your project requirements specify:
Flask-PyMongo==0.1.3
The latest is 0.2.1
Using the lastest breaks your project for example:
from flask.ext.pymongo import Connection
Any reason for freezing your requirement at: 0.1.3?
I'm trying to use flask-eve with angular resources. The problems is, angular seems to remove the trailing slash from the url.
When eve gets this url, it gives a 301 response, but I don't think angular will follow this :-|
Is it possible to configure eve to serve from a slashless resource without a redirect?
Thanks.
My immediate use case for this are payment notifications (say, paypal), but there are many other cases I can see this would be useful.
max_results is by default config.PAGINATION_DEFAULT, however when I disable pagination for resource I expect to get result without max_results criteria.
It works when I pass some args:
https://github.com/nicolaiarocci/eve/blob/develop/eve/utils.py#L114
but it doesn't work when args is empty
https://github.com/nicolaiarocci/eve/blob/develop/eve/utils.py#L88
I would post patch but I don't know how you want to handle it (change default, or add else for L88)
I really like how the "automatic" mode settings is set up and would love to see authorization implemented in the same manner.
For example:
users = {
'public': {
'base_query': {
{'public': True}
},
'resource_methods': ['GET'],
'item_methods': ['GET'],
},
'private': {
'base_query': {
{
'_id': 'auth.user.id',
}
},
'item_methods': ['PATCH'],
},
'schema': {
'username': {
'type': 'string',
},
'emails': {
'type': 'list',
},
'public': {
'type': 'boolean',
},
'followers': {
'type': 'list'
'actions': ['insert']
}
}
}
Basically I'd add 2 security areas (private/public) where one requires authentication and the other doesn't.
Each area could define a "base" query which will be concatenated with the rest of the queries before execution, thus making sure the user can access only the permitted resources.
Furthermore I'd let the user modify which methods are allowed per resource, thus forcing an authorization flow for each request:
Notice the use of auth.user.id, this of course takes for granted our ability to expose the currently authenticated user (which is a story of it's own)...
Got a server error when make a HEAD call:
curl -I
And server site error log is:
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/Flask-0.9-py2.7.egg/flask/app.py", line 1701, in call
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python2.7/dist-packages/Flask-0.9-py2.7.egg/flask/app.py", line 1689, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/usr/local/lib/python2.7/dist-packages/Flask-0.9-py2.7.egg/flask/app.py", line 1687, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/Flask-0.9-py2.7.egg/flask/app.py", line 1360, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python2.7/dist-packages/Flask-0.9-py2.7.egg/flask/app.py", line 1358, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/Flask-0.9-py2.7.egg/flask/app.py", line 1344, in dispatch_request
return self.view_functionsrule.endpoint
File "/usr/local/lib/python2.7/dist-packages/Eve-0.0.5-py2.7.egg/eve/endpoints.py", line 62, in item_endpoint
return send_response(resource, response)
File "/usr/local/lib/python2.7/dist-packages/Eve-0.0.5-py2.7.egg/eve/render.py", line 48, in send_response
return _prepare_response(resource, _response if response else [None])
File "/usr/local/lib/python2.7/dist-packages/Eve-0.0.5-py2.7.egg/eve/render.py", line 76, in prepare_response
rendered = globals()renderer
TypeError: render_json() argument after * must be a mapping, not NoneType
I guess render.py:L48 might be:
return _prepare_response(resource, *response if response else [{}])
??
Thanks. It is a great package!
Xu Wang
I have a schema where I've defined a list of dictionary objects, however whenever I try to post to the resource with the list defined with a dictionary in it, it returns a status "ERR" and issue ["'field'"].
When I post without the list defined or the list empty, it will post fine, but then when I try to patch the list field with a dict, it gives me a 400 error.
my schema looks something like this...:
'schema': {
'name': {
'type': 'string',
'required': True,
},
'perma_name': {
'type': 'string',
},
'active_list': {
'type': 'list',
'schema': {
'type': 'dict',
'schema': {
'p_id': {
'type': 'objectid',
'required': True,
'data_relation': {
'collection': 'projects'
}
},
'proj_name': {
'type': 'string',
},
'perma_name': {
'type': 'string',
},
'raised': {
'type': 'integer',
},
'goal': {
'type': 'integer',
},
'description': {
'type': 'string',
}
}
}
}
}
I might be biased, but JSON Schema is becoming the defacto validation for JSON*
It would be nice if you could configure a field referencing an objectid
to embed the serialized representation of the document, similar to http://django-rest-framework.org/api-guide/serializers.html#specifying-nested-serialization
For example if you had
DOMAIN = {
'letter': {
'schema': {
author: {'type': 'objectid', 'embed': 'user'}, # FK: User
subject: {'type': 'string'},
body: {'type': 'string'},
}
},
'user': {
'schema': {
# name, email, profile_pic, etc.
}
}
}
The author
field would be rendered as an embedded document in the format of user
due to the 'embed': 'user'
parameter.
If no database settings are available Eve will seamlessly respond with empty resources to GET requests (as long as a database server is running on the system). Raising a ConfigException if no db settings are available would seem more than appropriate ๐
Enable default safe writes
Hi,
It seems that domain configuration is not overriding global settings,
here is a snippet of my settings.py
file:
RESOURCE_METHODS = ['GET']
ITEM_METHODS = []
backups = {
'item_title': 'backup',
'auth_username_field': 'user',
'resource_methods': ['POST'],
'item_methods': [],
'schema': {
'key': {
'type': 'string',
'minlength': 1,
'maxlength': 150,
'required': True,
},
'host': {
'type': 'string',
'required': True
},
'size': {
'type': 'integer',
'required': True,
}
}
}
And when I try to perform a POST request, I get a 405 status code: HTTPError: 405 Client Error: METHOD NOT ALLOWED
,
Any thoughts ?
Thanks!
I'm trying to use SORT parameter, and it fails with 500 error and when I try it in eve-demo it fails too.
The request using CURL is:
curl -i 'http://eve-demo.herokuapp.com/people/?sort={"lastname":1}'
In my case, I enabled debug in Flask and the trace is:
X.X.X.X - - [15/Jul/2013 10:36:07] "GET /v1/contracts/?sort={%22power%22:-1} HTTP/1.1" 500 -
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1701, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1689, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1687, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1360, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1358, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1344, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/usr/local/lib/python2.7/dist-packages/Eve-0.0.8_dev-py2.7.egg/eve/endpoints.py", line 42, in collections_endpoint
response = get(resource)
File "/usr/local/lib/python2.7/dist-packages/Eve-0.0.8_dev-py2.7.egg/eve/methods/common.py", line 187, in rate_limited
return f(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/Eve-0.0.8_dev-py2.7.egg/eve/auth.py", line 42, in decorated
return f(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/Eve-0.0.8_dev-py2.7.egg/eve/methods/get.py", line 57, in get
cursor = app.data.find(resource, req)
File "/usr/local/lib/python2.7/dist-packages/Eve-0.0.8_dev-py2.7.egg/eve/io/mongo/mongo.py", line 116, in find
return self.driver.db[datasource].find(**args)
File "/usr/local/lib/python2.7/dist-packages/pymongo/collection.py", line 717, in find
return Cursor(self, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/pymongo/cursor.py", line 111, in __init__
self.__ordering = sort and helpers._index_document(sort) or None
File "/usr/local/lib/python2.7/dist-packages/pymongo/helpers.py", line 55, in _index_document
"mean %r?" % list(index_list.iteritems()))
TypeError: passing a dict to sort/create_index/hint is not allowed - use a list of tuples instead. did you mean [('power', -1)]?
I don't know what I've done bad. Could you help me.
Thank you.
Oriol Rius
Based on tokens.
Nicola, Just a note to thank you for sharing your project. Rather than use your project as an external package, I am having to literally use your pattern with adaptations. When I first watched your Flask-API video, I appreciated your approach. I have learned and am continuing to learn from your project. Thank you.
Hi guys,
I'm working on a project to auto-generate API docs for Eve. I'm doing it as a blueprint for maintainability. I've been using the settings.py from eve-demo so far, but I'd like to get a more complicated settings file that uses every feature. Can you recommend one?
Thanks!
Charles
"issue about making filtering, sorting & paging optional"
Ref: https://github.com/nicolaiarocci/eve/issues/4#issuecomment-12048339
Hi,
With latest Eve, here is my schema:
incidents = {
'item_title': 'incident',
'auth_username_field': 'user',
'resource_methods': ['GET'],
'item_methods': ['GET'],
'schema': {
'key': {
'type': 'string',
},
'interval': {
'type': 'integer',
},
'interval_human': {
'type': 'string',
},
'last_backup_size': {
'type': 'integer',
},
'last_backup_size_human': {
'type': 'string',
},
'last_backup_date_utc': {
'type': 'string',
},
'last_backup_date_human': {
'type': 'string',
},
'last_backup_host': {
'type': 'string',
},
}
}
And here is what I get on GET:
{
"_items": [
{
"_id": "518a3b908e3e02522dfe98d0",
"_links": {
"self": {
"href": "localhost:2404/api/incidents/518a3b908e3e02522dfe98d0/",
"title": "incident"
}
},
"cal_ts": 1368013712,
"cal_ts_utc": 1368006512,
"call_ts_ago": "2013/05/08 13:48:32",
"created": "Thu, 01 Jan 1970 00:00:00 UTC",
"etag": "17c536402d8b29c766489e6467821c5f2cd8014b",
"interval": 301,
"interval_human": "301s",
"key": "check",
"last_backup_date": "2013/05/08 13:41:54",
"last_backup_date_utc": "Wed, 08 May 2013 11:41:54 UTC",
"last_backup_host": "tomt0m",
"last_backup_size": 9999,
"last_backup_size_human": "10.0 KB",
"login": "thomas",
"updated": "Thu, 01 Jan 1970 00:00:00 UTC"
}
],
"_links": {
"parent": {
"href": "localhost:2404/api",
"title": "home"
},
"self": {
"href": "localhost:2404/api/incidents/",
"title": "incidents"
}
}
}
From what I understand, these keys: "cal_ts": 1368013712,
should be removed from response right ?
"cal_ts_utc": 1368006512,
"call_ts_ago": "2013/05/08 13:48:32",
Any thoughts ?
Not sure how to start on this, but I would definitely be interested in working on it.
Hello,
I was just wondering if you've got any idea when PostgreSQL is going to be supported?
Appreciate the work you're doing!
Cheers!
I am exploring how best to control access to resources. I have spent some time wiring up flask-security with generic PyMongo. @lukateake mentioned a snippet involving the decorating of generic HTTP Headers.
It occurs to me that access control can be wrapped in a similar way. Perhaps domain resource meta details would be ideal for specifying access constraints, etc.
I would enjoy any input regarding best practice for this. Thank You.
It seems that Eve cannot get the items from an existing collection if the documents don't have the "Updated" and "Created" fields.
Documents created through the POST method are fine since they contain those fields.
In methods.py the document expects to have config.LAST_UPDATED but it does not always exist
document[config.LAST_UPDATED] = \
document[config.LAST_UPDATED].replace(tzinfo=None)
Once you hit an endpoint, lower the -Remaining :P
This should be part of headers you receive back I guess.
RateLimit-Limit: 486
RateLimit-Remaining: 485
Eve has got some real potential and can be quite dangerous/useful for me. Great stuff, @nicolaiarocci, thank you for opening it up to the world.
However, I wouldn't say that it is RESTful insofar as other JavaScripters and I have come to think about JSON web services.
The examples below are strictly concerned with use cases where the Accept
header specifically requests JSON to be returned. I haven't used XML it quite sometime, frankly (but would expect the root node to match the endpoint name).
curl -H "Accept:application/json" -i http://eve-demo.herokuapp.com/works/50acfbaa38345b0978fccada/
The JSON response is wrapped with a response
root object and a works
object:
{ "response":
{ "works":
{ "updated": "Wed, 21 Nov 2012 16:04:57 UTC",
"description": "Third description",
"title": "Third Book Title",
"created": "Wed, 21 Nov 2012 16:04:57 UTC",
"owner": "50acfba838345b0978fccad4",
"_id": "50acfbaa38345b0978fccada" }
}
}
I'm a big user of Backbone and it expects the following response at the same endpoint as above:
{ "updated": "Wed, 21 Nov 2012 16:04:57 UTC",
"description": "Third description",
"title": "Third Book Title",
"created": "Wed, 21 Nov 2012 16:04:57 UTC",
"owner": "50acfba838345b0978fccad4",
"_id": "50acfbaa38345b0978fccada" }
Additionally, the /works/
endpoint would be a JavaScript array []
, as such:
curl -H "Accept:application/json" -i http://eve-demo.herokuapp.com/works/
[
{ "updated": "Wed, 21 Nov 2012 16:04:57 UTC",
"description": "Third description",
"title": "Third Book Title",
"created": "Wed, 21 Nov 2012 16:04:57 UTC",
"owner": "50acfba838345b0978fccad4",
"_id": "50acfbaa38345b0978fccada" },
{ "updated": "Wed, 21 Nov 2012 16:04:57 UTC",
"description": "First description",
"title": "First Book Title",
"created": "Wed, 21 Nov 2012 16:04:57 UTC",
"owner": "50acfba838345b0978fccad3",
"_id": "50acfba938345b0978fccad8" }
]
Again, thanks for all your fantastic work. I'm only proposing this change because I feel implementing it would appeal Eve to a large group of potential users, e.g. Backbone et al.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.