Giter Club home page Giter Club logo

sqlrest's Introduction

sqlrest

Automatically generate a REST API for a SQL database. Uses sqlalchemy to talk to databases, bottle to talk to web clients.

Usage

You can initialize sqlrest independently...

# start server on port 8000 mapped to a MySQL instance
$ python -m sqlrest.server \
  --frontend.port 8000 \
  --frontend.host '0.0.0.0' \
  --db.uri "mysql://root:@localhost:3306/kittendb"

...or by attaching it to another app,

import bottle
from configurati import attrs
from sqlrest.server import attach_routes

app = bottle.Bottle()

# attach other routes here
@app.get("/")
def hello_world():
  return "Hello, World!"

# attach sqlrest routes, with URLS prefixed by "/sqlrest". e.g.
# /sqlrest/kittens/columns, /sqlrest/kittens/select, and
# /sqlrest/kittens/aggregate to access table `kittens`
app = attach_routes(attrs({'uri': "mysql://root:@localhost:3306/kittendb"}), app=app, prefix="/sqlrest")

# start serving content
app.run(...)

Querying

Using the wonderful httpie project,

# Get all tables available
$ http get localhost:8000/tables

# Get column names in table `kittens`
$ http get localhost:8000/kittens/columns

# SELECT breed, location, count(*), min(birthday) FROM KITTENS
#   WHERE date(birthday) <= "2009-08-01" AND date(birthday) >= "2009-09-01"
#   GROUP BY breed, location
#   ORDER BY count(*) DESC
#   LIMIT 0, 10;
$ http get localhost:8000/kittens/aggregate <<< '{
    "groupby": ["breed", "location"],
    "filters": {
      "date(birthday)": ["2009-08-01", "2009-09-01"]
    },
    "aggregate": ["count(*)", "min(birthday)"],
    "orderby": ["count(*)", "descending"],
    "page": 0,
    "page_size": 10
  }'

# SELECT name, location FROM kittens
#   WHERE (name = "Mittens") AND
#     (breed = "Calico" OR breed = "Persian") AND
#     (birthday >= "2009-08-01" AND birthday <= "2009-09-01");
#   ORDER BY name
#   LIMIT 50, 60;
$ http get localhost:8000/kittens/select <<< '{
    "filters": {
      "name": "Mittens",
      "breed": ["Calico", "Persian"],
      "birthday": ["2009-08-01", "2009-09-01"]
    },
    "columns": ["name", "location"],
    "orderby": "name"
    "page": 5,
    "page_size": 10
  }'

Filters

Both aggregate and select endpoints can take an argument filters, an object where keys are column names and values are either arrays or single elements.

Let's take the following example,

{
  ...
  'filters': {
     "name": "Mittens",
     "breed": ["Calico", "Persian"],
     "date(birthday)": ["2009-08-01", "2009-09-01"]
  },
  ...
}

In this scenario, only rows where name == "Mittens", breed is one of "Calico" or "Persian", and date(birthday) is after "2009-08-01" but before "2009-09-01" are included. To select one of a finite set of date(birthday)ss, you must simply use a value with more than 2 values, e.g.

{
  ...
  'filters': {
    ...
    "date(birthday)": ["2009-08-01", "2009-09-01", "2009-10-01"]
    ...
  },
  ...
}

Create, Update, Delete

# INSERT INTO kittens
#   (name, breed, birthday)
#   VALUES
#     ("Mittens", "Persian", "2009-08-01"),
#     ( "Tigger",  "Calico", "2009-09-01");
$ http PUT localhost:8000/kittens <<< '{
    "rows": [
      {
        "name": "Mittens",
        "breed": "Persian",
        "birthday": "2009-08-01"
      },
      {
        "name": "Tigger",
        "breed": "Calico",
        "birthday": "2009-09-01"
      }
    ]
  }'

# DELETE FROM kittens
#   WHERE name = "Tigger";
$ http DELETE localhost:8000/kittens <<< '{
    "filters": { "name": "Tigger" }
  }'

# UPDATE kittens
#   SET birthday = "2009-08-01"
#   WHERE name = "Mittens";
$ http PATCH localhost:8000/kittens <<< '{
    "filters" : { "name"     : "Mittens"   },
    "values"  : { "birthday" : "2009-08-01"}
  }'

Caching

sqlrest supports caching via Redis. By default, caching is disabled, but it can be enabled by adding settings caching.enabled = True in your config. For example,

$ redis-server &
$ python -m sqlrest.server                         \
  --db.uri "mysql://root:@localhost:3306/kittendb" \
  --caching.enabled true                           \
  --caching.config.port 6379                       \
  --caching.config.host localhost                  \
  --caching.timeouts '{"select": 300, "aggregate": 900}'

In the event that caching is enabled and sqlrest is unable to reach Redis, it will issue a log warning but will continue serving as if caching were disabled.

Configuration

Configuration in sqlrest is handled by configurati with the following specification,

config.py

frontend = {
  'port'   : optional(type=int, default=8000),
  'host'   : optional(type=str, default='0.0.0.0'),
  'prefix' : optional(type=str, default='')
}

db = {
  'uri': required(type=str)
}

caching = {
  'enabled' : optional(type=bool, default=False),

  # I don't really want to copy/paste all of redis.StrictRedis's
  # arguments, so I'll just leave this as a dict
  'config'  : optional(type=dict, default={}),

  'timeouts' : {
    'tables'    : optional(type=int, default=99999),
    'columns'   : optional(type=int, default=99999),
    'select'    : optional(type=int, default=60 * 5),
    'aggregate' : optional(type=int, default=60 * 60 * 24),
  }
}

# enable create, update, delete endpoints
editing = optional(type=bool, default=False)

A configuration file can be used via the --config command line parameter,

$ python -m sqlrest.server --config config.py

sqlrest's People

Contributors

duckworthd avatar

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.