first commit

This commit is contained in:
Martin
2016-04-18 20:56:24 +02:00
commit ae3a566f68
13 changed files with 195 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
*.pyc
config.py
venv/
+23
View File
@@ -0,0 +1,23 @@
# Photowall API 2
Provides a REST API to Photowall database.
## Installation
`$ pip install -r requirements.txt`
## Configuration
First copy config.sample.py to config.py. This file will be read by the application on startup.
List of available configuration options:
| Name | Description |
| ---- | ----------- |
| `SQLALCHEMY_DATABASE_URI` | Database connection string. e.g: `postgresql://user:password@localhost/photowall`
## Getting started
Starting the application:
`$ python run.py`
+29
View File
@@ -0,0 +1,29 @@
from flask import Flask, jsonify
from flask_sqlalchemy import SQLAlchemy
from api.helpers import JSONEncoder
app = Flask(__name__)
app.config.from_object('config')
# enable this when json encoding works
# app.json_encoder = JSONEncoder
def on_404(e):
return jsonify(dict(error='Not found')), 404
app.errorhandler(404)(on_404)
#SQLAlchemy
db = SQLAlchemy(app)
from api.views import designers
app.register_blueprint(designers.mod)
@app.route("/")
def index():
data = {
"info": {
"api_version": "0.0.1"
}
}
return jsonify(data)
+1
View File
@@ -0,0 +1 @@
from json import JSONEncoder, JsonSerializer
+46
View File
@@ -0,0 +1,46 @@
from flask.json import JSONEncoder as BaseJSONEncoder
class JSONEncoder(BaseJSONEncoder):
"""Custom :class:`JSONEncoder` which respects objects that include the
:class:`JsonSerializer` mixin.
"""
def default(self, obj):
if isinstance(obj, JsonSerializer):
return obj.to_json()
return super(JSONEncoder, self).default(obj)
class JsonSerializer(object):
"""A mixin that can be used to mark a SQLAlchemy model class which
implements a :func:`to_json` method. The :func:`to_json` method is used
in conjuction with the custom :class:`JSONEncoder` class. By default this
mixin will assume all properties of the SQLAlchemy model are to be visible
in the JSON output. Extend this class to customize which properties are
public, hidden or modified before being being passed to the JSON serializer.
"""
__json_public__ = None
__json_hidden__ = None
__json_modifiers__ = None
def get_field_names(self):
for p in self.__mapper__.iterate_properties:
yield p.key
def to_json(self):
field_names = self.get_field_names()
public = self.__json_public__ or field_names
hidden = self.__json_hidden__ or []
modifiers = self.__json_modifiers__ or dict()
rv = dict()
for key in public:
rv[key] = getattr(self, key)
for key, modifier in modifiers.items():
value = getattr(self, key)
rv[key] = modifier(value, self)
for key in hidden:
rv.pop(key, None)
return rv
+1
View File
@@ -0,0 +1 @@
from designer import Designer
+9
View File
@@ -0,0 +1,9 @@
from api import db
from api.helpers import JsonSerializer
class Designer(JsonSerializer, db.Model):
__tablename__ = 'designers'
designerid = db.Column('designerid', db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
path = db.Column(db.String(100), nullable=False)
View File
+41
View File
@@ -0,0 +1,41 @@
from flask import Blueprint, request, jsonify
from api import db
from api.models import Designer
mod = Blueprint('designers', __name__, url_prefix='/designers')
@mod.route("/", methods=["GET"])
def list():
designers = Designer.query.all()
return jsonify(designers=[d.to_json() for d in designers])
@mod.route("/", methods=["POST"])
def create():
data = request.json
designer = Designer(**data)
db.session.add(designer)
db.session.commit()
return jsonify(designer.to_json())
@mod.route("/<int:id>", methods=["GET"])
def show(id):
designer = Designer.query.get_or_404(id)
return jsonify(designer.to_json())
@mod.route("/<id>", methods=["PUT"])
def update(id):
designer = Designer.query.get_or_404(id)
data = request.json
for k, v in data.iteritems():
setattr(designer, k, v)
db.session.add(designer)
db.session.commit()
return jsonify(designer.to_json())
@mod.route("/<id>", methods=["DELETE"])
def delete(id):
designer = Designer.query.get_or_404(id)
db.session.delete(designer)
db.session.commit()
return jsonify({"status": "ok"})
+2
View File
@@ -0,0 +1,2 @@
SQLALCHEMY_DATABASE_URI = 'postgresql://user:password@host/db_name'
SQLALCHEMY_TRACK_MODIFICATIONS = True
+27
View File
@@ -0,0 +1,27 @@
from flask.ext.script import Manager, prompt_bool
from api import app, db
from api.models import Designer
manager = Manager(app)
@manager.command
def initdb():
db.create_all()
print 'All tables created'
@manager.command
def dropdb():
if prompt_bool("Are you sure you want to lose all your data"):
db.drop_all()
print 'All tables dropped'
@manager.command
def seed():
print 'Adding sample data %s' % db.engine.url
designer = Designer(name="Martin", path='/martin', username='martin', password='secret')
db.session.add(designer)
db.session.commit()
if __name__ == '__main__':
manager.run()
+11
View File
@@ -0,0 +1,11 @@
Flask==0.10.1
Flask-SQLAlchemy==2.1
Flask-Script==2.0.5
Jinja2==2.8
MarkupSafe==0.23
SQLAlchemy==1.0.12
Werkzeug==0.11.8
argparse==1.2.1
itsdangerous==0.24
psycopg2==2.6.1
wsgiref==0.1.2
+2
View File
@@ -0,0 +1,2 @@
from api import app
app.run(debug=True)