Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

unrest

Package Overview
Dependencies
Maintainers
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

unrest

A troubling rest api library for sqlalchemy models

  • 1.1.0
  • PyPI
  • Socket score

Maintainers
4

UnRest - Simple sqlalchemy rest api generation.

Build Status Coverage Status

from unrest import UnRest
# First, initialize UnRest with your web application
rest = UnRest(app)

# Then declare your endpoint
rest(Person)

This should provide you a /api/person and a /api/person/<login> route accessible in GET only.

To activate data modification, set the methods array like this:

rest(Person, only=['name', 'sex', 'age'], methods=['GET', 'PUT', 'POST', 'DELETE', 'PATCH']) # or simply methods=rest.all

You will get both routes (collection and member) on the five methods. Please see the wikipedia page for their signification.

You can also override the default methods like this:

person = rest(Person)

@person.declare('GET')
def get(payload, login=None):
    # Pre get hook
    if login:
        login = login.upper()
    rv = person.get(payload, login=login)
    # Post get hook
    return {
        'occurences': rv['occurences'],
        'objects': [
            {'login': person['login'].lower()} for person in rv['objects']
        ]
    }

Documentation

Full documentation can be found at kozea.github.io/unrest

Example

Consider this simple web application:

from datetime import timedelta

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.orm import relationship
from sqlalchemy.sql.schema import Column, ForeignKey
from sqlalchemy.types import Integer, Interval, Numeric, String

from unrest import UnRest

# Flask application
app = Flask(__name__)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/unrest.db'

# Model definition
db = SQLAlchemy(app)

class Tree(db.Model):
    id = Column(Integer, primary_key=True)
    name = Column(String)

    @property
    def fruit_colors(self):
        return ', '.join([fruit.color for fruit in self.fruits])

class Fruit(db.Model):
    fruit_id = Column(Integer, primary_key=True)
    color = Column(String(50))
    size = Column(Numeric)
    age = Column(Interval)
    tree_id = Column(Integer, ForeignKey('tree.id'))
    tree = relationship(Tree, backref='fruits')

# Drop everything just in case
db.drop_all()

# Create model
db.create_all()

# Data insertion
pine = Tree(name='pine')
maple = Tree(name='maple')
oak = Tree(name='oak')
db.session.add(pine)
db.session.add(maple)
db.session.add(oak)

db.session.add(Fruit(color='grey', size=12, age=timedelta(days=12, hours=1, minutes=15), tree=pine))
db.session.add(Fruit(color='darkgrey', size=23, age=timedelta(days=49, seconds=230, milliseconds=213), tree=pine))
db.session.add(Fruit(color='brown', size=2.12, age=timedelta(0), tree=pine))
db.session.add(Fruit(color='red', size=.5, age=timedelta(minutes=40), tree=maple))
db.session.add(Fruit(color='orangered', size=100, age=timedelta(hours=2, microseconds=12), tree=maple))

db.session.commit()
db.session.remove()

# Declare rest endpoints
rest = UnRest(app, db.session)

# Authorize every methods
rest(Tree, methods=rest.all, allow_batch=True)
# Don't authorize batch for fruits
rest(Fruit, methods=rest.all)

# Run the app
app.run(debug=True)

You will now have:

GET

With primary keys arguments

$ curl -s http://localhost:5000/api/tree/1

200 OK
{
    "occurences": 1,
    "objects": [
        {
            "id": 1,
            "name": "pine"
        }
    ]
}
$ curl -s http://localhost:5000/api/fruit/1

200 OK
{
    "occurences": 1,
    "objects": [
        {
            "fruit_id": 1,
            "color": "grey",
            "size": 12.0,
            "age": 1041300.0,
            "tree_id": 1
        }
    ]
}

Without argument

$ curl -s http://localhost:5000/api/tree

200 OK
{
    "occurences": 3,
    "objects": [
        {
            "id": 1,
            "name": "pine"
        },
        {
            "id": 2,
            "name": "maple"
        },
        {
            "id": 3,
            "name": "oak"
        }
    ]
}
$ curl -s http://localhost:5000/api/fruit

200 OK
{
    "occurences": 5,
    "objects": [
        {
            "fruit_id": 1,
            "color": "grey",
            "size": 12.0,
            "age": 1041300.0,
            "tree_id": 1
        },
        {
            "fruit_id": 2,
            "color": "darkgrey",
            "size": 23.0,
            "age": 4233830.213,
            "tree_id": 1
        },
        {
            "fruit_id": 3,
            "color": "brown",
            "size": 2.12,
            "age": 0.0,
            "tree_id": 1
        },
        {
            "fruit_id": 4,
            "color": "red",
            "size": 0.5,
            "age": 2400.0,
            "tree_id": 2
        },
        {
            "fruit_id": 5,
            "color": "orangered",
            "size": 100.0,
            "age": 7200.000012,
            "tree_id": 2
        }
    ]
}

PUT

With primary keys arguments

$ curl -s http://localhost:5000/api/tree/1 -X PUT -H "Content-Type: application/json" -d '{
  "name": "cedar"
}'

200 OK
{
    "occurences": 1,
    "objects": [
        {
            "id": 1,
            "name": "cedar"
        }
    ]
}

Get it again to be sure:

$ curl -s http://localhost:5000/api/tree/1

200 OK
{
    "occurences": 1,
    "objects": [
        {
            "id": 1,
            "name": "cedar"
        }
    ]
}

Without argument

$ curl -s http://localhost:5000/api/tree -X PUT -H "Content-Type: application/json" -d '{
  "objects": [{"id": 2, "name": "cedar"}, {"id": 22, "name": "mango"}]
}'

200 OK
{
    "occurences": 2,
    "objects": [
        {
            "id": 2,
            "name": "cedar"
        },
        {
            "id": 22,
            "name": "mango"
        }
    ]
}

Get it again to be sure:

$ curl -s http://localhost:5000/api/tree

200 OK
{
    "occurences": 2,
    "objects": [
        {
            "id": 2,
            "name": "cedar"
        },
        {
            "id": 22,
            "name": "mango"
        }
    ]
}

Check that when allow_batch is not set we can't put all:

$ curl -s http://localhost:5000/api/fruit -X PUT -H "Content-Type: application/json" -d '{
  "objects": [
    {"fruit_id": 2, "color": "red"},
    {"fruit_id": 22, "color": "blue"}
  ]
}'

406 Not Acceptable
{
  "message": "You must set allow_batch to True if you want to use batch methods."
}

POST

With primary keys arguments

$ curl -s http://localhost:5000/api/tree/1 -X POST -H "Content-Type: application/json"

501 Not Implemented
{
  "message": "POST on id corresponds to collection creation. It's not implemented by default. If you want to update an item use the PUT method instead"
}

Without argument

$ curl -s http://localhost:5000/api/fruit -X POST -H "Content-Type: application/json" -d '{
  "color": "forestgreen", "size": 3.14, "age": 1.5926, "tree_id": 3
}'

200 OK
{
    "occurences": 1,
    "objects": [
        {
            "fruit_id": 6,
            "color": "forestgreen",
            "size": 3.14,
            "age": 1.5926,
            "tree_id": 3
        }
    ]
}

Now we should have a total of 6 fruits:

$ curl -s http://localhost:5000/api/fruit

200 OK
{
    "occurences": 6,
    "objects": [
        {
            "fruit_id": 1,
            "color": "grey",
            "size": 12.0,
            "age": 1041300.0,
            "tree_id": 1
        },
        {
            "fruit_id": 2,
            "color": "darkgrey",
            "size": 23.0,
            "age": 4233830.213,
            "tree_id": 1
        },
        {
            "fruit_id": 3,
            "color": "brown",
            "size": 2.12,
            "age": 0.0,
            "tree_id": 1
        },
        {
            "fruit_id": 4,
            "color": "red",
            "size": 0.5,
            "age": 2400.0,
            "tree_id": 2
        },
        {
            "fruit_id": 5,
            "color": "orangered",
            "size": 100.0,
            "age": 7200.000012,
            "tree_id": 2
        },
        {
            "fruit_id": 6,
            "color": "forestgreen",
            "size": 3.14,
            "age": 1.5926,
            "tree_id": 3
        }
    ]
}

DELETE

With primary keys arguments

$ curl -s http://localhost:5000/api/fruit/3 -X DELETE

200 OK
{
    "occurences": 1,
    "objects": [
        {
            "fruit_id": 3,
            "color": "brown",
            "size": 2.12,
            "age": 0.0,
            "tree_id": 1
        }
    ]
}

Now we should have only 5 fruits remaining:

$ curl -s http://localhost:5000/api/fruit

200 OK
{
    "occurences": 5,
    "objects": [
        {
            "fruit_id": 1,
            "color": "grey",
            "size": 12.0,
            "age": 1041300.0,
            "tree_id": 1
        },
        {
            "fruit_id": 2,
            "color": "darkgrey",
            "size": 23.0,
            "age": 4233830.213,
            "tree_id": 1
        },
        {
            "fruit_id": 4,
            "color": "red",
            "size": 0.5,
            "age": 2400.0,
            "tree_id": 2
        },
        {
            "fruit_id": 5,
            "color": "orangered",
            "size": 100.0,
            "age": 7200.000012,
            "tree_id": 2
        },
        {
            "fruit_id": 6,
            "color": "forestgreen",
            "size": 3.14,
            "age": 1.5926,
            "tree_id": 3
        }
    ]
}

Without argument

Batch delete is not allowed on fruit:

$ curl -s http://localhost:5000/api/fruit -X DELETE

501 Not Implemented
{
  "message": "You must set allow_batch to True if you want to use batch methods."
}

But is on tree:

$ curl -s http://localhost:5000/api/tree -X DELETE

200 OK
{
    "occurences": 3,
    "objects": [
        {
            "id": 1,
            "name": "pine"
        },
        {
            "id": 2,
            "name": "maple"
        },
        {
            "id": 3,
            "name": "oak"
        }
    ]
}
$ curl -s http://localhost:5000/api/tree

200 OK
{
    "occurences": 0,
    "objects": []
}

PATCH

With primary keys arguments

$ curl -s http://localhost:5000/api/fruit/1 -X PATCH -H "Content-Type: application/json" -d '{
  "color": "blue"
}'

200 OK
{
    "occurences": 1,
    "objects": [
        {
          "fruit_id": 1,
          "color": "blue",
          "size": 12.0,
          "age": 1041300.0,
          "tree_id": 1
        }
    ]
}

Without argument

$ curl -s http://localhost:5000/api/tree -X PATCH -H "Content-Type: application/json" -d '{
  "objects": [{"id": 2, "name": "cedar"}, {"id": 3, "name": "mango"}]
}'

200 OK
{
    "occurences": 2,
    "objects": [
        {
            "id": 2,
            "name": "cedar"
        },
        {
            "id": 3,
            "name": "mango"
        }
    ]
}

Check that when allow_batch is not set we can't put all:

$ curl -s http://localhost:5000/api/fruit -X PATCH -H "Content-Type: application/json" -d '{
  "objects": [
    {"fruit_id": 1, "color": "blue"},
    {"fruit_id": 3, "age": 1038540.0},
    {"fruit_id": 4, "color": "rainbow", "size": 8},
    {"fruit_id": 5, "size": 10, "tree_id": 1}
  ]
}'

406 Not Acceptable
{
  "message": "You must set allow_batch to True if you want to use batch methods."
}

otherwise all the specified attributes would have been patched.

Keywords

FAQs


Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc