I'm coming from Java background and now trying my hands on Python. I'm trying to create a RESTful web application for CRUD operations. I've already tried to go through the various links that provide step by step approach in achieving it using Flask RESTplus + SQLAlchemy.
However, I'm more keen on getting this the usual "java-way". Also I would like to avoid using ORM and instead use SQLAlchemy for executing raw SQL and then iterating resultsets to populate my model and then return the model.
I'm taking baby steps and initially I want to see how to populate my Model with dummy data and return it back to the caller. Below is what I'm trying to achieve but not able to move further:
from flask import request
from flask import Flask
from flask import Blueprint
from flask_restplus import Resource, Api, apidoc
from flask_restplus import fields, marshal
from sqlalchemy import create_engine
from sqlalchemy.sql import text
import json
app = Flask(__name__)
blueprint = Blueprint('api', __name__, url_prefix='/edslnk/rest')
api = Api(blueprint, version='1.0', title='EDSLink ResourceSvc API',description='Set of APIs to interactively communicate with Database and HDFS')
app.register_blueprint(blueprint)
ns = api.namespace('eds-workflows', description='Operations related to EDS Workflows')
#engine = create_engine('oracle+cx_oracle://scott:tiger@tnsname')
workFlow = api.model('WorkFlow', {
'workflowName': fields.String,
'workflowScriptLoc': fields.String,
'createUser': fields.String,
'createDate': fields.String,
'lstUpdateUser': fields.String,
'lstUpdateDate': fields.String,
})
@ns.route('/')
class WorkflowsCollection(Resource):
@ns.marshal_list_with(workFlow)
def get(self):
try:
#connection = engine.connect()
#result = connection.execute("select * from EDSOPERATION.EDSLNK_WORKFLOWS")
workFlow_list = []
for x in range(6):
workFlow.workflowName = 'Workflow_Name'+x
workFlow.workflowScriptLoc = 'Workflow_Script_Loc'+x
workFlow.createUser = 'Create_User'+x
workFlow.createDate = 'Create_Date'+x
workFlow.lstUpdateUser = 'Lst_Modified_User'+x
workFlow.lstUpdateDate = 'Lst_Modified_Date'+x
workFlow_list.append(workFlow)
finally:
#connection.close()
print('finally')
#what should I return ? 'workFlow' or 'workFlow_list' ?
@ns.response(201, 'Category successfully created.')
def post(self):
#create_workflow(request.json)
pass
if __name__ == '__main__':
app.run(debug=True)
When I trying to invoke the url curl -X GET "http://127.0.0.1:5000/edslnk/rest/eds-workflows/" -H "accept: application/json" I get server error code 500
My total objective at this stage is to populate my model workFlow with some hardcoded data and then return list of these models as json data back to the caller.
Once I'm able to achieve this, I'll try with actual data from database by iterating the resultset and populating the resultset rows to the model.
Thanks in advance for any help !
********** UPDATE - 1 ***********
I was able to achieve some breakthrough based on below code. I get expected output with below code.
However, I'm now ending up creating two definitions of my Model class viz., one via api.model and other via creating a normal class
The model object workFlow created via api.Model is referred only for marshalling operation (in the @ns.marshal_list_with decorator) while the normal class created model objects workFlow1 and workFlow2 are used to populate the actual data and add them to the workFlow_list
Is it not possible to get different instances of my model object using the api.model and populate them with my data (kind-of using 'setters' as in java) ?
from flask import request
from flask import Flask,jsonify
from flask import Blueprint
from flask_restplus import Resource, Api, apidoc
from flask_restplus import fields, marshal
from sqlalchemy import create_engine
from sqlalchemy.sql import text
import json
app = Flask(__name__)
blueprint = Blueprint('api', __name__, url_prefix='/edslnk/rest')
api = Api(blueprint, version='1.0', title='EDSLink ResourceSvc API',description='Set of APIs to interactively communicate with Database and HDFS')
app.register_blueprint(blueprint)
ns = api.namespace('eds-workflows', description='Operations related to EDS Workflows')
#engine = create_engine('oracle+cx_oracle://scott:tiger@tnsname')
workFlow = api.model('WorkFlow', {
'workflowName': fields.String,
'workflowScriptLoc': fields.String,
'createUser': fields.String,
'createDate': fields.String,
'lstUpdateUser': fields.String,
'lstUpdateDate': fields.String,
})
#workFlow_list = []
class WorkFlow:
def __init__(self, workflowName, workflowScriptLoc, createUser, createDate, lstUpdateUser, lstUpdateDate):
self.workflowName = workflowName
self.workflowScriptLoc = workflowScriptLoc
self.createUser = createUser
self.createDate = createDate
self.lstUpdateUser = lstUpdateUser
self.lstUpdateDate = lstUpdateDate
class MyEncoder(json.JSONEncoder):
def default(self, o):
return o.__dict__
@ns.route('/')
class WorkflowsCollection(Resource):
@ns.marshal_list_with(workFlow)
def get(self):
try:
#connection = engine.connect()
#result = connection.execute("select * from EDSOPERATION.EDSLNK_WORKFLOWS")
workFlow_list = []
#workFlow1 = WorkFlow()
#workFlow1.workflowName='abc'
workFlow1 = WorkFlow('Workflow_Name', 'Workflow_Script_Loc', 'Create_User', 'Create_Date', 'Lst_Modified_User', 'Lst_Modified_Date')
workFlow2 = WorkFlow('Workflow_Name', 'Workflow_Script_Loc', 'Create_User', 'Create_Date', 'Lst_Modified_User', 'Lst_Modified_Date')
workFlow_list.append(workFlow1)
workFlow_list.append(workFlow2)
#responseString = json.dumps(workFlow_list, cls=MyEncoder)
#print('responseString --> ' + responseString)
#response = app.response_class(response=workFlow_list,status=200,mimetype='application/json')
# for x in range(6):
# workFlow.workflowName = 'Workflow_Name'+x
# workFlow.workflowScriptLoc = 'Workflow_Script_Loc'+x
# workFlow.createUser = 'Create_User'+x
# workFlow.createDate = 'Create_Date'+x
# workFlow.lstUpdateUser = 'Lst_Modified_User'+x
# workFlow.lstUpdateDate = 'Lst_Modified_Date'+x
# workFlow_list.append(workFlow)
finally:
#connection.close()
print('finally')
return workFlow_list
@ns.response(201, 'Category successfully created.')
def post(self):
#create_workflow(request.json)
pass
if __name__ == '__main__':
#x = WorkflowsCollection()
#r = x.get()
#print(r)
app.run(debug=True)
workFlowobject as response (with status 200). I then added just this code lineworkFlow.workflowName = 'Workflow_Name'but still get an an emptyworkFlowobject. As I said in my original post, what I'm looking for is a way I can populate a list of my model objectworkFlowwith some hardcoded values and then return that list back to caller as json.