A RESTFul with Openshft, Python + Flask and AeroGear
As a new year's resolution I have started to learn Python. So I have read an introduction to this programming language. Then as next step I have created a RESTful API app. I have found tons of documents but, however, it take a lot of time and effort...
This is the required library, in my setup.py:
At line 4 i get the json from a curl rerquest :
Then if the json is valid, it's stored into the database. My app manages geographic data, so to use these it's necessary to modify the json, and put latitude and longitude in a loc variable. In order to use it in geographical operation enable it with db.points.create_index([('loc', GEO2D)]).
The last step is send notification to Aerogear. It's mandatory put the data into json.dumps() to avoid trouble to encoding. theAeroGearID and AeroGearAuth are available in the AeroGear dashboard into application. In the last line I have put the whole signature identifier for HTTPBasicAuth because Flask has it's own HTTPBasicAuth.
The aim
Build a RESTFul API to store and retrive data. It use MongoDB and AeroGear to send a notification (when new object is stored).
Tools
- openshift, as hosting platform.
- Python + Flask, to build the RESTFul API.
- AeroGear used to push notification.
Notification
The notifications are send with AeroGear. So I have used one of the openshift gears to hosting this service. I also have built an Android App to receive the notification (using Android SDK, AeroGear library for Android and the Google Api to manage push notifications).
RESTFull API
To build the Flask app I have followed this tutorial and add some code.
This is the required library, in my setup.py:
install_requires=['Flask==0.10.1', 'MarkupSafe' , 'Flask-SQLAlchemy==0.16','Flask-HTTPAuth==2.2.0', 'jsonschema>= 2.3.0','requests'],Then, as simple auth method (the same in the tutorial):
@auth.get_password def get_password(username): if username == "myUserName": return "myPwd" return None @auth.error_handler def unauthorized(): return make_response(jsonify({"error": "Unauthorized access"}), 401)To initialize MongoDB it's necessary to use the environment variables (OPENSHIFT_MONGODB_DB_URL,OPENSHIFT_APP_NAME), as in the getData method:
@app.route("/api/getMyData/", methods=['GET']) def getData(): conn = pymongo.Connection(os.environ['OPENSHIFT_MONGODB_DB_URL']) db = conn[os.environ['OPENSHIFT_APP_NAME']] result = db.mydata.find() return str(json.dumps({'results':list(result)},default=json_util.default))The last, and more complicated method is:
@app.route("/api/setMyData/", methods=['POST']) @auth.login_required def createData(): myJson = request.json with open(os.path.join(os.path.dirname(__file__),"myData.json"),'r') as f: schema = f.read() try: jsonschema.validate(myJson, json.loads(schema)) except jsonschema.ValidationError as e: return "problem with json schema" conn = pymongo.Connection(os.environ['OPENSHIFT_MONGODB_DB_URL']) db = conn[os.environ['OPENSHIFT_APP_NAME']] mydata = db['mydata'] mydata.insert(myJson) headers={"Accept":u"application/json", "Content-type": u"application/json"} url="https://myOpenshift/ag-push/rest/sender/" resp = requests.post(url, data=json.dumps({ "message": { "alert": "My first notification!", "action-category": "cat1", "sound": "default", "badge": 2, "content-available": true, "user-data": { "key": "value", "key2": "other value" }, "simple-push": "version=1.2" }, "config": { "ttl": 3600 }}), auth=requests.auth.HTTPBasicAuth("theAeroGearID", "AeroGearAuth"),headers=headers) return str(resp)This method required some extra imports: jsonschema, requests, json.
At line 4 i get the json from a curl rerquest :
curl -i -H "Content-Type: application/json" -X POST --data '{"idStation": 2,"name": "test","lat": 43, "lng": 11,"z": 200,"stationOwner": "daniele","lastUpdate": "today"}' http://myopenschifturl/api/setMyData -u myUserName:myPwdFrom line 5 to 8, my json schema is read (from myData.json file) and is verified if actual json has this schema. To read the file it's necessary to use the variable os.path.dirname(__file__) as the root.
Then if the json is valid, it's stored into the database. My app manages geographic data, so to use these it's necessary to modify the json, and put latitude and longitude in a loc variable. In order to use it in geographical operation enable it with db.points.create_index([('loc', GEO2D)]).
The last step is send notification to Aerogear. It's mandatory put the data into json.dumps() to avoid trouble to encoding. theAeroGearID and AeroGearAuth are available in the AeroGear dashboard into application. In the last line I have put the whole signature identifier for HTTPBasicAuth because Flask has it's own HTTPBasicAuth.
Comments
Post a Comment