py-dataql
py-dataql copied to clipboard
Python backend for "Data Query Languages" (like GraphQL and others)
py-dataql
Python backend for "Data Query Languages" (like GraphQL and others)
What is it?
dataql
is for "Data Query Language". It allows to query data in a simple way.
It is heavily inspired by GraphQL, from Facebook
I didn't want to force people to think "graph", and I chose a language that is different in some ways. But this library is written with a base, and we provide a generic parser, but other parsers could easily be written!
But I have an implementation of a GraphQL server in python,
using dataql
. The main difference is that it's strongly typed compared to dataql
.
How it works?
For example, the default generic parser included, DataQLParser
, allows to ask for data
with this example query:
User.get('Elon Musk') {
name,
birthday.strftime('%x'),
companies[{
name,
year:created_year,
}],
company_names: companies[name],
first_company:companies.0.name,
}
And to get data like that:
{
'name': 'Elon Musk',
'birthday': '06/28/71',
'companies': [
{
'name': 'Paypal',
'year': 1999
},
{
'name': 'Space X',
'year': 2002
}
],
'company_names': ['Paypal', 'Space X'],
'first_company': 'Paypal',
}
The main use is for an API, letting the client asking what it really needs, in only one http query, without having to update the API endpoints.
The only thing to do on the server side is to define, via a registry, what objects and attributes are allowed.
Full example
This repository provides a full, but simple, example
Installing
This library is available on pypi, but still in alpha version.
pip install dataql
Documentation
No external documentation yet, but the code is heavily documented using "Numpydoc":
---------------------------------------------------------------------------
File blank comment code
---------------------------------------------------------------------------
./__init__.py 2 1 6
./exceptions.py 5 5 3
./parsers/__init__.py 4 4 1
./parsers/base.py 142 383 120
./parsers/exceptions.py 13 13 15
./parsers/generic.py 150 477 86
./parsers/mixins.py 275 794 113
./resources.py 149 261 161
./solvers/exceptions.py 91 112 140
./solvers/filters.py 62 146 30
./solvers/registry.py 259 914 214
./solvers/resources.py 112 339 58
./utils.py 6 20 5
---------------------------------------------------------------------------
SUM: 1270 3469 952
---------------------------------------------------------------------------
You may refer to the example.py file for usage.
TODO
This prototype is working as expected, but there is a lot of things to do:
- ~~create subclasses for exceptions~~
- ~~allow the use of filters that are not attributes of instances, but simple functions~~
- ~~allow the retrieval of list entries or dict entries, not only instance attributes~~
- ~~allow returning lists of values, not only objects~~
- write documentation about how to use
dataql
to get data from a query - write documentation about how to create its own parser
- ~~test on the the Django ORM~~ (works)
- create an advanced solver for Django (using
select_related
andprefetch_related
) - tell me
Tests
There are no external tests for now but there are a lot of examples in the classes and method docstrings that are valid (and passing!) doctests.
You can launch all these doctests this way (at the root of the repository) :
./run_tests.sh
Ran 110 tests in 0.207s
OK
Python version
It's 2015. So dataql
is written with python 3.4 in mind. No plan to port it to python 2.
License
The dataql
library is under the BSD License. See LICENSE file
Contributing
I created the base for a tool that could be really useful. I may have chose the wrong way for some things, or maybe the whole project. Tell me. Add issues, create pull requests, define new languages, or simply enhance the parser.... Feel free to contribute!
Internals
This library is split in two main parts:
parsers
dataql.parsers
include everything that is needed to create a parser to parse a query into what
I named "resources" (for example a field, a list, an object, with filter, arguments...)
Each parser (only one for now) returns the same kind of resources. So there is no need to write a new solver for a new parser
solvers
dataql.solvers
is the place where, with a base value and a resource, we can have a result
matching the query.
Etc
More to come, folks!