def minimal_app(**config): app = Flask(__name__) app.wsgi_app = ProxyFix(app.wsgi_app) cors = CORS(app) cross_origin() @app.errorhandler(404) def page_not_found(e): # note that we set the 404 status explicitly return render_template('404.html'), 404 configuration.init_app(app, **config) return app
def decorator(fn): cors_fn = flask_cors.cross_origin(automatic_options=False, *args, **kwargs) if inspect.isclass(fn): apply_function_to_members(fn, cors_fn) else: return cors_fn(fn) return fn
def decorator(func): endpoint = ns.endpoint_for(operation) endpoint_path = graph.build_route_path(path, ns.prefix) if enable_cors: func = cross_origin(supports_credentials=True)(func) if enable_basic_auth or ns.enable_basic_auth: func = graph.basic_auth.required(func) if enable_context_logger and ns.controller is not None: func = context_logger( graph.request_context, func, parent=ns.controller, ) # set the opaque component data_func to look at the flask request context func = graph.opaque.initialize(graph.request_context)(func) if graph.route_metrics.enabled: func = graph.route_metrics(endpoint)(func) # keep audit decoration last (before registering the route) so that # errors raised by other decorators are captured in the audit trail if enable_audit: func = graph.audit(func) graph.app.route( endpoint_path, endpoint=endpoint, methods=[operation.value.method], )(func) return func
def main(): parser = argparse.ArgumentParser( description='Meta Reverse Image Search API') parser.add_argument('-p', '--port', type=int, default=5000, help='port number') parser.add_argument('-d', '--debug', action='store_true', help='enable debug mode') parser.add_argument('-c', '--cors', action='store_true', default=False, help="enable cross-origin requests") args = parser.parse_args() if args.debug: app.debug = True if args.cors: CORS(app, resources=r'/search/*') app.config['CORS_HEADERS'] = 'Content-Type' global search search = cross_origin(search) print(" * Running with CORS enabled") port = int(os.environ.get("PORT", 5000)) app.run(host='0.0.0.0', port=port)
class StreamNode(Resource): decorators = [cross_origin(origin='*')] def get(self, id): comp.run_dotbot_node() return Response(comp.read_run_proc(id), mimetype='text/event-stream')
def inner(*args, **kwargs): if not app.config.get('CORS_HOSTS'): return fun(*args, **kwargs) return cross_origin( headers=['Authorization', 'Content-Type'], supports_credentials=True, origins=app.config['CORS_HOSTS'], )(fun)(*args, **kwargs)
class RefreshJwtApi(BaseResource): decorators = [cross_origin(), jwt_refresh_token_required] def post(self): current_user = get_jwt_identity() result = dict( access_token=create_access_token(identity=current_user)) return self.response(result)
class OnlineStatusApi(BaseResource): decorators = [cross_origin(), jwt_required] def get(self): users = User.get_online_users() if users: return self.response(users) result = dict(count=0, results=[]) return self.response(result)
class PrivateAPIEndpoint(MethodView): # make converter run after every request handler method returns decorators = [ json_converter, requires_auth, cross_origin(headers=['Content-Type', 'Authorization']) ] def __init__(self, *args, **kwargs): super(PrivateAPIEndpoint, self).__init__(*args, **kwargs) self.logger = current_app.logger
class RosKill(Resource): decorators = [ cross_origin(origin="*", headers=["content-type", "autorization"]) ] def post(self): json_data = request.get_json(force=True) print("killing Node " + str(json_data["nodeId"])) return jsonify({'response': 'killed ok'})
class GetCoreAddress(Resource): decorators = [ cross_origin(origin="*", headers=["content-type", "autorization"]) ] def post(self): json_data = request.get_json(force=True) print("received core is active on" + json_data["coreAddress"]) return "ok"
def cors(self, func=None, *args, **kwargs): """Helper method for defining CORS on specific endpoints.""" if func is None: return partial(self.cors, *args, **kwargs) methods = sorted({ m.upper() for m in kwargs.pop("methods", ["GET"]) + ["OPTIONS", "HEAD"] }) return cross_origin(methods=methods, *args, **kwargs)(func)
def route_authorization( self, route: str, roles: List[str], methods: List[str] = ['GET'] ): return composed( self.route(route, methods=methods), cross_origin(supports_credentials=True), roles_required(roles=['USER']) )
class HBRProcess(Resource): decorators = [cross_origin(origin="*", headers=["content-type", "autorization"], methods=['GET', 'PUT'])] def post(self): parser = reqparse.RequestParser() parser.add_argument('cmd') args = parser.parse_args() cmd = args['cmd'].split() proc = run_shell.delay(cmd) return 'ok'
class Roscore(Resource): decorators = [ cross_origin(origin="*", headers=["content-type", "autorization"]) ] def get(self): return jsonify({'response': 'get roscore ok'}) def post(self): return jsonify({'response': 'post roscore ok'}) def put(self): return jsonify({'response': 'put roscore ok'})
class Robot(Resource): decorators = [ cross_origin(origin="*", headers=["content-type", "autorization"], methods=['GET', 'PUT']) ] def get(self): return jsonify({ 'name': current_app.config["DOTBOT_NAME"], 'master': current_app.config["ROS_MASTER_URI"], 'ip': current_app.config["ROS_IP"], "macaddress": getMAC('wlan0'), "model": current_app.config["MODEL_HB"] })
class RobotSketch(Resource): decorators = [cross_origin(origin='*')] def put(self): parser = reqparse.RequestParser() parser.add_argument('code') args = parser.parse_args() ''' node_id = 1 file_id = 1 f = File.query.get_or_404(file_id) f.code = args['code'] f.last_edit = datetime.utcnow() db.session.add(f) f.save() db.session.commit() n = Node.query.get_or_404(node_id) comp.run(n) print 'node running' ''' of = open( '/opt/virtualenvs/ros/project/dotbot_ws/src/dotbot_app/dotbot_ros_skeleton/node.py', "w") of.write(args['code']) of.close() return jsonify({'response': 'ok'}) def get(self): print 'getting streaming' node_id = 1 return redirect(url_for("api.stream", id=1)) def options(self): pass def delete(self): print 'delete me' parser = reqparse.RequestParser() parser.add_argument('node') args = parser.parse_args() env = comp.env() env["ROS_NAMESPACE"] = '' killproc = subprocess.Popen(['rosnode', 'kill', args.node], env=env) killproc.wait() return jsonify({'response': 'ok'})
class Rosfile(Resource): decorators = [ cross_origin(origin="*", headers=["content-type", "autorization"]) ] def post(self): json_data = request.get_json(force=True) filecontent = json_data["filecontent"] print(filecontent) filename = json_data["filename"] print(filename) return jsonify({'response': 'ok'}) def put(self): return jsonify({'response': 'ok'})
class Rosnode(Resource): decorators = [ cross_origin(origin="*", headers=["content-type", "autorization"]) ] def post(self): json_data = request.get_json(force=True) node = json_data["node"] files = json_data["files"] print(node) print(files) return jsonify({'response': 'node uploaded ok'}) def put(self): return jsonify({'response': 'ok'})
class ManageRobot(Resource): decorators = [cross_origin(origin='*')] def post(self): parser = reqparse.RequestParser() parser.add_argument('command') args = parser.parse_args() print 'test' if args["command"] == 'poweroff': subprocess.Popen(['poweroff']) return jsonify({'response': "ok"}) elif args["command"] == 'reboot': subprocess.Popen(['reboot']) return jsonify({'response': "ok"}) else: return jsonify({'response': "command not found"})
class DecoratedGraphQLView(GraphQLView): methods = ["GET", "POST", "PUT", "DELETE", "OPTIONS"] decorators = (flask_cors.cross_origin( origins=[ item.strip() for item in os.getenv("ALLOWED_CORS_ORIGINS", "*").split(",") ], expose_headers=["Content-Type"], support_credentials=True, ), ) def dispatch_request(self): request_method = request.method.lower() if request_method == "options": return Response(status=HTTPStatus.NO_CONTENT) return super().dispatch_request()
class DownloadProductApi(BaseResource): decorators = [cross_origin(), jwt_required] def get(self): si = StringIO() cw = csv.writer(si) cw.writerow(['id', 'name', 'description', 'phone', 'email']) users = Product.query.order_by(desc(Product.created_at)).all() for obj in users: cw.writerow( [obj.id, obj.name, obj.description, obj.phone, obj.email]) output = make_response(si.getvalue()) output.headers["Content-Disposition"] = "attachment; " \ "filename={}_{}.csv" \ .format("all_products", datetime.now()) output.headers["Content-type"] = "text/csv" si.close() return output
class StatusApi(BaseResource): decorators = [cross_origin(), jwt_required] def get(self, status_id: int = None): page = request.args.get('page') if status_id: result = Status.get_by_id(status_id) return self.response(**result) statuses = Status.get_all_data(int(page) if page else None) return self.response(statuses) @validate(['name']) def post(self): if not request.is_json: result = dict(message='Content type not json') return self.response(result, 400) status = Status(**request.json) status.create() result = dict(message="Successfully Saved!") return self.response(result, 201) def put(self, status_id=None): status = Status.get_by_id(status_id) if not status: result = dict(message="Id not found") return self.response(result, 404) updated = Status.update(status_id, **request.json) if not updated: result = dict(message="Did not update order status.") return self.response(result, 400) result = dict(message="Successfully Updated!") return self.response(result, 201) def delete(self, status_id=None): status = Status.get_by_id(status_id) if not status: result = dict(message="Id not found") return self.response(result, 404) result = status.delete() if result: result = dict(message="Successfully deleted {}".format(status_id)) return self.response(result) result = dict(message="{} Not deleted".format(status_id)) return self.response(result, 400)
def main(): parser = argparse.ArgumentParser(description='Meta Reverse Image Search API') parser.add_argument('-p', '--port', type=int, default=5000, help='port number') parser.add_argument('-d','--debug', action='store_true', help='enable debug mode') parser.add_argument('-c','--cors', action='store_true', default=False, help="enable cross-origin requests") args = parser.parse_args() if args.debug: app.debug = True if args.cors: CORS(app, resources=r'/search/*') app.config['CORS_HEADERS'] = 'Content-Type' global search search = cross_origin(search) print(" * Running with CORS enabled") app.run(host='0.0.0.0', port=args.port)
def decorator(func): endpoint = ns.endpoint_for(operation) endpoint_path = graph.build_route_path(path, ns.prefix) if enable_cors: func = cross_origin(supports_credentials=True)(func) if enable_basic_auth or ns.enable_basic_auth: func = graph.basic_auth.required(func) if enable_context_logger and ns.controller is not None: func = context_logger( graph.request_context, func, parent=ns.controller, ) # set the opaque component data_func to look at the flask request context func = graph.opaque.initialize(graph.request_context)(func) if enable_metrics or ns.enable_metrics: from microcosm_flask.metrics import StatusCodeClassifier tags = [f"endpoint:{endpoint}", "backend_type:microcosm_flask"] func = graph.metrics_counting( "route", tags=tags, classifier_cls=StatusCodeClassifier, )(func) func = graph.metrics_timing("route", tags=tags)(func) # keep audit decoration last (before registering the route) so that # errors raised by other decorators are captured in the audit trail if enable_audit: func = graph.audit(func) graph.app.route( endpoint_path, endpoint=endpoint, methods=[operation.value.method], )(func) return func
class GenerateJwtApi(BaseResource): decorators = [cross_origin()] schema = AuthSchema() @content_type(['application/json']) @validator(['email', 'password']) def post(self): email = request.json.get('email') password = request.json.get('password') if not request.is_json: result = dict(message="Missing JSON in request") return self.response(result, 400) user = User.get_user_by_email(email) if user: if password_helper.check_password_hash(user.password, password): app.logger.info( "Logged in user with the email {0}".format(email)) access_token = create_access_token( identity=email, expires_delta=False ) refresh_token = create_refresh_token(identity=email) result = dict( access_token=access_token, refresh_token=refresh_token, user=dict( id=user.id, full_name="{} {}".format( user.first_name, user.last_name), email=user.email, roles=[user_role.role.name for user_role in user.roles] ) ) return self.response(result) else: app.logger.warning( "User with the email {0} does not exist".format(email)) result = dict(message="Bad username or password") return self.response(result, 401)
def main(): parser = argparse.ArgumentParser( description='Meta Reverse Image Search API') parser.add_argument('-p', '--port', type=int, default=5000, help='port number') parser.add_argument('-d', '--debug', action='store_true', help='enable debug mode') parser.add_argument('-c', '--cors', action='store_true', default=False, help="enable cross-origin requests") parser.add_argument('-a', '--host', type=str, default='0.0.0.0', help="sets the address to serve on") args = parser.parse_args() if args.debug: app.debug = True if args.cors: CORS(app, resources=r'/shopping/*') CORS(app, resources=r'/food/*') CORS(app, resources=r'/imgcap/*') app.config['CORS_HEADERS'] = 'Content-Type' global search search = cross_origin(search) print(" * Running with CORS enabled") app.run(host=args.host, port=args.port)
class ConfHostname(Resource): decorators = [cross_origin(origin='*')] def get(self): return jsonify({'hostname': current_app.config["DOTBOT_NAME"]}) def put(self): parser = reqparse.RequestParser() parser.add_argument('hostname') args = parser.parse_args() if args["hostname"] is not None and args["hostname"] != "": replace('/opt/virtualenvs/ros/project/config.bash', '^export\sDOTBOT_NAME.*\W', 'export DOTBOT_NAME=%s\n' % args["hostname"]) replace('/etc/avahi/avahi-daemon.conf', '^host-name=.*\W', 'host-name=%s\n' % args["hostname"]) replace( '/opt/virtualenvs/ros/project/config.bash', '^export\sROS_MASTER_URI.*\W', 'export ROS_MASTER_URI=http://%s.local:11311\n' % args["hostname"]) return jsonify({'response': "ok"}) return jsonify({'response': "error"})
class GithubView(MethodView): decorators = [cross_origin()] @cached_property def repo(self): client = github3.login(token=config.github_token) return client.repository('18F', 'fec') @use_kwargs({ 'referer': fields.Url( required=True, validate=validate_referer, location='headers', ), 'action': fields.Str(), 'feedback': fields.Str(), 'about': fields.Str(), 'chart_reaction': fields.Str(), 'chart_location': fields.Str(), 'chart_name': fields.Str(), 'chart_comment': fields.Str() }) def post(self, **kwargs): if not any([kwargs['action'], kwargs['feedback'], kwargs['about'], kwargs['chart_comment']]): return jsonify({ 'message': 'Must provide one of "action", "feedback", or "about".', }), 422 if kwargs['chart_comment']: title = 'Chart reaction on {} page'.format(kwargs['chart_location']) else: title = 'User feedback on {}'.format(kwargs['referer']) body = render_template('feedback.html', headers=request.headers, **kwargs) issue = self.repo.create_issue(title, body=body) return jsonify(issue.to_json()), 201
def cors(cls, fn): """ CORS decorator, to make the endpoint available for CORS Make sure @cors decorator is placed at the top position. All response decorators must be placed below. It's because it requires a response to be available class Index(Assembly): def index(self): return self.render() @request.cors @response.json def json(self): return {} :return: """ if inspect.isclass(fn): raise Error("@cors can only be applied on Assembly methods") else: cors_fn = flask_cors.cross_origin(automatic_options=True) return cors_fn(fn)
class GetEnvironment(Resource): decorators = [ cross_origin(origin="*", headers=["content-type", "autorization"]) ] def get(self): return "ok" import json source1 = app.config["ROS_GLOBAL_SOURCE"] source2 = app.config["ROS_LOCAL_SOURCE"] dump = 'python -c "import os, json;print json.dumps(dict(os.environ))"' pipe = subprocess.Popen( ['/bin/bash', '-c', '%s && %s && %s' % (source1, source2, dump)], stdout=subprocess.PIPE) print pipe env_info = pipe.stdout.read() print env_info _env = json.loads(env_info) if 'LS_COLORS' in _env: del _env['LS_COLORS'] _env["PWD"] = app.config["CATKING_PATH"] return jsonify(_env)
class DownloadUserApi(BaseResource): decorators = [cross_origin(), jwt_required] def get(self): si = StringIO() cw = csv.writer(si) cw.writerow([ 'id', 'first_name', 'last_name', 'phone', 'email', 'roles', 'created_at', 'updated_at' ]) users = User.query.order_by(desc(User.created_at)).all() for obj in users: cw.writerow([ obj.id, obj.first_name, obj.last_name, obj.phone, obj.email, [user_role.role.name for user_role in obj.roles], obj.created_at, obj.updated_at ]) output = make_response(si.getvalue()) output.headers[ "Content-Disposition"] = "attachment; filename={}_{}.csv".format( "all_users", datetime.now()) output.headers["Content-type"] = "text/csv" si.close() return output
DB = ROOT_DIR + '/users.db' SCALE = ScaleController() LOGGER = logging.getLogger(__name__) LOGGER.setLevel(logging.INFO) parser = argparse.ArgumentParser( description='Provide a JSON-RPC proxy for a USB scale.' ) parser.add_argument('-w', '--weight', help='a test weight to return instead of doing a real reading', default=None) parser.add_argument('-p', '--port', help='the port to run on', default="443") args = parser.parse_args() app = Flask(__name__) auth = HTTPBasicAuth() jsonrpc = JSONRPC(app, "/api", decorators=[ cross_origin(methods=['POST', 'OPTIONS'], headers=["accept", "authorization", "content-type"]), json_headers, max_age_headers ]) # Not a route on purpose. # Use an interactive Python shell to add users. def add_user(username, password): '''Adds a new JSON-RPC user to the database.''' salt = str(uuid.uuid4()) db = sqlite3.connect(DB) db.cursor().execute(''' INSERT INTO users(username, pwd_hash, salt) VALUES (?, ?, ?) ''', (username, hashlib.sha256(password + "\x00" + salt).hexdigest(), salt))
# main application serving web content and data from flask_cors import cross_origin import time from flask import Flask, request, jsonify, Response, render_template, url_for from flask.ext.cors import CORS from DatabaseAccess.service.HeadlineSummaryService import HeadlineSummaryService app = Flask(__name__) CORS(app) cross_origin(app) service = HeadlineSummaryService() # API ROUTES # ------------------------------------------------------------------------------------------- @app.route('/api/sample', methods=['GET']) def getSample(): return jsonify(service.getSampleData()) @app.route('/api/headlines', methods=['GET']) def getHeadlines(): date = request.args.get('date') return jsonify(service.findByDate(date))
def _generate_handler_wrapper(api_name, api_spec, endpoint, handler_func, error_callback, global_decorator): """Generate a handler method for the given url method+path and operation""" # Decorate the handler function, if Swagger spec tells us to if endpoint.decorate_server: endpoint_decorator = get_function(endpoint.decorate_server) handler_func = endpoint_decorator(handler_func) @wraps(handler_func) def handler_wrapper(**path_params): log.info("=> INCOMING REQUEST %s %s -> %s" % (endpoint.method, endpoint.path, handler_func.__name__)) # Get caller's klue-call-id or generate one call_id = request.headers.get('KlueCallID', None) if not call_id: call_id = str(uuid.uuid4()) stack.top.call_id = call_id # Append current server to call path, or start one call_path = request.headers.get('KlueCallPath', None) if call_path: call_path = "%s.%s" % (call_path, api_name) else: call_path = api_name stack.top.call_path = call_path if endpoint.param_in_body or endpoint.param_in_query: # Turn the flask request into something bravado-core can process... try: req = FlaskRequestProxy(request, endpoint.param_in_body) except BadRequest: ee = error_callback(ValidationError("Cannot parse json data: have you set 'Content-Type' to 'application/json'?")) return _responsify(api_spec, ee, 400) try: # Note: unmarshall validates parameters but does not fail # if extra unknown parameters are submitted parameters = unmarshal_request(req, endpoint.operation) # Example of parameters: {'body': RegisterCredentials()} except jsonschema.exceptions.ValidationError as e: ee = error_callback(ValidationError(str(e))) return _responsify(api_spec, ee, 400) # Call the endpoint, with proper parameters depending on whether # parameters are in body, query or url args = [] kwargs = {} if endpoint.param_in_path: kwargs = path_params if endpoint.param_in_body: # Remove the parameters already defined in path_params for k in path_params.keys(): del parameters[k] l = list(parameters.values()) assert len(l) == 1 args.append(l[0]) if endpoint.param_in_query: kwargs.update(parameters) result = handler_func(*args, **kwargs) if not result: e = error_callback(KlueException("Have nothing to send in response")) return _responsify(api_spec, e, 500) # Did we get the expected response? if endpoint.produces_html: if type(result) is not tuple: e = error_callback(KlueException("Method %s should return %s but returned %s" % (endpoint.handler_server, endpoint.produces, type(result)))) return _responsify(api_spec, e, 500) # Return an html page return result elif endpoint.produces_json: if not hasattr(result, '__module__') or not hasattr(result, '__class__'): e = error_callback(KlueException("Method %s did not return a class instance but a %s" % (endpoint.handler_server, type(result)))) return _responsify(api_spec, e, 500) # If it's already a flask Response, just pass it through. # Errors in particular may be either passed back as flask Responses, or # raised as exceptions to be caught and formatted by the error_callback result_type = result.__module__ + "." + result.__class__.__name__ if result_type == 'flask.wrappers.Response': return result # Otherwise, assume no error occured and make a flask Response out of # the result. # TODO: check that result is an instance of a model expected as response from this endpoint result_json = api_spec.model_to_json(result) # Send a Flask Response with code 200 and result_json r = jsonify(result_json) r.status_code = 200 return r handler_wrapper = cross_origin(headers=['Content-Type', 'Authorization'])(handler_wrapper) # And encapsulate all in a global decorator, if given one if global_decorator: handler_wrapper = global_decorator(handler_wrapper) return handler_wrapper