Unverified Commit 1ac13070 authored by Dylan Jones's avatar Dylan Jones
Browse files

Actual RESTful apis inbound

parent 511ad440
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"id": 24, "id": 24,
"name": null, "name": null,
"floor": 3, "floor": 3,
"category": "water_fountain", "category": 1,
"parent": 1, "parent": 1,
"lat": 77.374695589, "lat": 77.374695589,
"lon": -44.89345483, "lon": -44.89345483,
......
{ {
"id": 0, "id": 1,
"slug": "water_fountain",
"name": "Water Fountain", "name": "Water Fountain",
"icon": "https://karel.pw/water.png", "icon": "https://karel.pw/water.png",
"attributes": { "attributes": {
"coldness": { "coldness": {
"name": "Coldness", "name": "Coldness",
"type": "rating", "type": "RATING",
"icon": "https://karel.pw/water.png" "slug": "coldness"
}, },
"bottle_filler": { "bottle_filler": {
"type": "bool", "type": "BOOLEAN",
"name": "Has Bottle Filler" "name": "Has Bottle Filler",
"slug": "bottle_filler"
} }
} }
} }
"""empty message
Revision ID: 01aa045b98a6
Revises: 26f2853e67de
Create Date: 2020-02-16 20:19:56.497610
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '01aa045b98a6'
down_revision = '26f2853e67de'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###
"""empty message
Revision ID: 09ab4264e119
Revises: 01aa045b98a6
Create Date: 2020-02-16 20:24:57.916333
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '09ab4264e119'
down_revision = '01aa045b98a6'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###
from flask import Flask from flask import Flask, redirect, jsonify, abort
from where.model import sa
from where.model.field_types import FieldType from where.model.field_types import FieldType
from where.model.sa import Category, Point, Field, session_context
app = Flask(__name__) app = Flask(__name__)
...@@ -21,25 +21,25 @@ def index(): ...@@ -21,25 +21,25 @@ def index():
@app.route('/test_data') @app.route('/test_data')
def test_data(): def test_data():
with sa.session_context() as session: with session_context() as session:
# session = Session() # session = Session()
session.query(sa.Point).delete() session.query(Point).delete()
session.query(sa.Field).delete() session.query(Field).delete()
session.query(sa.Category).delete() session.query(Category).delete()
# Water Fountain, the class. # Water Fountain, the class.
wf = sa.Category() wf = Category()
wf.name = "Water Fountain" wf.name = "Water Fountain"
wf.icon = "https://karel.pw/water.png" wf.icon = "https://karel.pw/water.png"
session.add(wf) session.add(wf)
session.commit() session.commit()
# coldness # coldness
cd = sa.Field() cd = Field()
cd.name = "Coldness" cd.name = "Coldness"
cd.slug = "coldness" cd.slug = "coldness"
cd.type = FieldType.RATING cd.type = FieldType.RATING
cd.category_id = wf.id cd.category_id = wf.id
# filler # filler
fl = sa.Field() fl = Field()
fl.slug = "bottle_filler" fl.slug = "bottle_filler"
fl.name = "Has Bottle Filler" fl.name = "Has Bottle Filler"
fl.type = FieldType.BOOLEAN fl.type = FieldType.BOOLEAN
...@@ -48,7 +48,7 @@ def test_data(): ...@@ -48,7 +48,7 @@ def test_data():
session.add(fl) session.add(fl)
session.commit() session.commit()
# an actual instance! # an actual instance!
fn = sa.Point() fn = Point()
fn.name = None fn.name = None
fn.lat = 38.829791 fn.lat = 38.829791
fn.lon = -77.307043 fn.lon = -77.307043
...@@ -66,7 +66,27 @@ def test_data(): ...@@ -66,7 +66,27 @@ def test_data():
} }
session.add(fn) session.add(fn)
session.commit() session.commit()
return "Success!" return redirect('/')
@app.route('/category/<id>')
def get_category(id):
with session_context() as session:
result = session.query(Category).filter_by(id=id).first()
if result:
return jsonify(result.as_json())
else:
abort(404)
@app.route('/point/<id>')
def get_point(id):
with session_context() as session:
result = session.query(Point).filter_by(id=id).first()
if result:
return jsonify(result.as_json())
else:
abort(404)
if __name__ == '__main__': if __name__ == '__main__':
......
...@@ -24,7 +24,7 @@ def session_context(): ...@@ -24,7 +24,7 @@ def session_context():
@as_declarative() @as_declarative()
class Base(object): class Base(object):
id = Column(Integer, primary_key=True, autoincrement=True) pass
class Point(Base): class Point(Base):
...@@ -32,6 +32,7 @@ class Point(Base): ...@@ -32,6 +32,7 @@ class Point(Base):
Represents actual instances of any and all points on the map. Represents actual instances of any and all points on the map.
""" """
__tablename__ = 'point' __tablename__ = 'point'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String, nullable=True) name = Column(String, nullable=True)
lat = Column(Float, nullable=False) lat = Column(Float, nullable=False)
lon = Column(Float, nullable=False) lon = Column(Float, nullable=False)
...@@ -41,11 +42,11 @@ class Point(Base): ...@@ -41,11 +42,11 @@ class Point(Base):
category_id = Column(Integer, ForeignKey('category.id'), nullable=False) category_id = Column(Integer, ForeignKey('category.id'), nullable=False)
category = relationship('Category') category = relationship('Category')
parent_id = Column(Integer, ForeignKey('point.id'), nullable=True) parent_id = Column(Integer, ForeignKey('point.id'), nullable=True)
parent = relationship('Point') parent = relationship('Point', remote_side=[id])
children = relationship('Point')
@validates('attributes') @validates('attributes')
def validate_data(self, _, data): def validate_data(self, _, data):
# TODO validate
if data is None: if data is None:
return return
fields = self.category.fields fields = self.category.fields
...@@ -59,6 +60,18 @@ class Point(Base): ...@@ -59,6 +60,18 @@ class Point(Base):
field.validate_data(data[key]) field.validate_data(data[key])
return data return data
def as_json(self, children=True):
if children:
children = [child.as_json(children=False) for child in self.children]
return {
"name": self.name,
"lat": self.lat,
"lon": self.lon,
"category": self.category.id,
"attributes": self.attributes,
"children": children
}
class Category(Base): class Category(Base):
""" """
...@@ -66,11 +79,20 @@ class Category(Base): ...@@ -66,11 +79,20 @@ class Category(Base):
""" """
__tablename__ = 'category' __tablename__ = 'category'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String, nullable=False, unique=True) name = Column(String, nullable=False, unique=True)
icon = Column(String, nullable=True) icon = Column(String, nullable=True)
fields = relationship("Field") fields = relationship("Field")
def as_json(self):
return {
"id": self.id,
"name": self.name,
"icon": self.icon,
"attributes": {attr.slug: attr.as_json() for attr in self.fields}
}
class Field(Base): class Field(Base):
""" """
...@@ -78,6 +100,7 @@ class Field(Base): ...@@ -78,6 +100,7 @@ class Field(Base):
""" """
__tablename__ = 'field' __tablename__ = 'field'
id = Column(Integer, primary_key=True, autoincrement=True)
slug = Column(String, nullable=False) slug = Column(String, nullable=False)
name = Column(String, nullable=False) name = Column(String, nullable=False)
type = Column(Enum(FieldType), nullable=False) type = Column(Enum(FieldType), nullable=False)
...@@ -90,3 +113,10 @@ class Field(Base): ...@@ -90,3 +113,10 @@ class Field(Base):
Verify that data is the correct type for this Field. Verify that data is the correct type for this Field.
""" """
self.type.validate(data) self.type.validate(data)
def as_json(self):
return {
"slug": self.slug,
"name": self.name,
"type": self.type.name
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment