summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuval Adam <_@yuv.al>2018-03-18 17:53:22 +0200
committerYuval Adam <_@yuv.al>2018-03-18 21:19:25 +0200
commit4fb3c88a9ff67061e4a38f30ca7b6487712913f0 (patch)
tree77da05c54c0ffb95b8b1bc50518ade355a73c59a
parent6012a0a45c25d1e6ef821bdbf54f463e70dfa41b (diff)
Initial REST support
-rw-r--r--.gitignore2
-rw-r--r--README.md6
-rw-r--r--app.py54
-rw-r--r--requirements.txt23
-rw-r--r--runtime.txt2
5 files changed, 72 insertions, 15 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a295864
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+*.pyc
+__pycache__
diff --git a/README.md b/README.md
index 1aae83f..9724ba9 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,10 @@
# Heroku Python Skeleton
-This repository has all the base files ready for deploying a Heroku application, including a simple database model managed with flask-sqlalchemy.
+This repository has all the base files ready for deploying a Python application on Heroku. It includes the following features:
+
+ - Flask HTTP application
+ - SQLAlchemy model that binds to a Heroku Postgres database
+ - RESTful API based on Flask-RESTful and the Marshmallow serialization framework
## Usage
diff --git a/app.py b/app.py
index 51a1100..14841aa 100644
--- a/app.py
+++ b/app.py
@@ -1,12 +1,19 @@
import os
from flask import Flask
-from flask import render_template
-from flask.ext.sqlalchemy import SQLAlchemy
+from flask import render_template, request
+from flask_sqlalchemy import SQLAlchemy
+from flask_restful import Resource, Api
+from marshmallow_sqlalchemy import ModelSchema
+
app = Flask(__name__)
-app.config['SQLALCHEMY_DATABASE_URI'] = os.environ['DATABASE_URL']
+app.config.update({
+ 'SQLALCHEMY_DATABASE_URI': os.environ['DATABASE_URL'],
+ 'SQLALCHEMY_TRACK_MODIFICATIONS': False
+})
db = SQLAlchemy(app)
+api = Api(app)
class User(db.Model):
@@ -22,6 +29,40 @@ class User(db.Model):
return '<Name %r>' % self.name
+class UserSchema(ModelSchema):
+ class Meta:
+ model = User
+
+
+class UserResource(Resource):
+ def get(self, user_id):
+ user = User.query.get(user_id)
+ return UserSchema().dump(user)
+
+ def put(self, user_id):
+ user = User.query.get(user_id)
+ UserSchema().load(request.form, instance=user, session=db.session)
+ db.session.commit()
+ return 'updated'
+
+ def delete(self, user_id):
+ user = User.query.get(user_id)
+ db.session.delete(user)
+ db.session.commit()
+
+
+class UserListResource(Resource):
+ def get(self):
+ users = User.query.all()
+ return UserSchema(many=True).dump(users)
+
+ def post(self):
+ user = UserSchema().load(request.form, session=db.session).data
+ db.session.add(user)
+ db.session.commit()
+ return 'created'
+
+
@app.route('/')
def home():
return render_template('index.html')
@@ -33,6 +74,9 @@ def robots():
res.mimetype = 'text/plain'
return res
+api.add_resource(UserListResource, '/users/')
+api.add_resource(UserResource, '/users/<user_id>/')
+
+
if __name__ == '__main__':
- port = int(os.environ.get('PORT', 5000))
- app.run(host='0.0.0.0', port=port, debug=True)
+ app.run(host='0.0.0.0', debug=True)
diff --git a/requirements.txt b/requirements.txt
index a75f7bb..a5be6dd 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,9 +1,16 @@
-Flask==0.10.1
-Flask-SQLAlchemy==2.1
-gunicorn==19.4.5
+aniso8601==3.0.0
+click==6.7
+Flask==0.12.2
+Flask-RESTful==0.3.6
+Flask-SQLAlchemy==2.3.2
+gunicorn==19.7.1
itsdangerous==0.24
-Jinja2==2.8
-MarkupSafe==0.23
-psycopg2==2.6.1
-SQLAlchemy==1.0.12
-Werkzeug==0.11.9
+Jinja2==2.10
+MarkupSafe==1.0
+marshmallow==2.15.0
+marshmallow-sqlalchemy==0.13.2
+psycopg2==2.7.4
+pytz==2018.3
+six==1.11.0
+SQLAlchemy==1.2.5
+Werkzeug==0.14.1
diff --git a/runtime.txt b/runtime.txt
index 78082e3..5c45380 100644
--- a/runtime.txt
+++ b/runtime.txt
@@ -1 +1 @@
-python-3.5.1
+python-3.6.4