def test_init_app(self): self.db.create_all() manager = APIManager(flask_sqlalchemy_db=self.db) manager.create_api(self.Person) manager.init_app(self.flaskapp) response = self.app.get('/api/person') assert response.status_code == 200
class TestFlaskSQLAlchemy(FlaskSQLAlchemyTestBase): """Tests for creating resources defined as Flask-SQLAlchemy models instead of pure SQLAlchemy models. """ def setUp(self): """Creates the Flask-SQLAlchemy database and models.""" super(TestFlaskSQLAlchemy, self).setUp() class Person(self.db.Model): id = self.db.Column(self.db.Integer, primary_key=True) self.Person = Person self.db.create_all() self.manager = APIManager(self.flaskapp, flask_sqlalchemy_db=self.db) self.manager.create_api(self.Person, methods=['POST']) def test_create(self): """Tests for creating a resource.""" data = dict(data=dict(type='person')) response = self.app.post('/api/person', data=dumps(data)) assert response.status_code == 201 document = loads(response.data) person = document['data'] # TODO To make this test more robust, should query for person objects. assert person['id'] == '1' assert person['type'] == 'person'
class TestFlaskSQLAlchemy(FlaskSQLAlchemyTestBase): """Tests for deleting resources defined as Flask-SQLAlchemy models instead of pure SQLAlchemy models. """ def setUp(self): """Creates the Flask-SQLAlchemy database and models.""" super(TestFlaskSQLAlchemy, self).setUp() class Person(self.db.Model): id = self.db.Column(self.db.Integer, primary_key=True) self.Person = Person self.db.create_all() self.manager = APIManager(self.flaskapp, flask_sqlalchemy_db=self.db) self.manager.create_api(self.Person, methods=['DELETE']) def test_delete(self): """Tests for deleting a resource.""" person = self.Person(id=1) self.session.add(person) self.session.commit() response = self.app.delete('/api/person/1') assert response.status_code == 204 assert self.Person.query.count() == 0
def test_multiple_managers_init_multiple_apps(self): """Tests for calling :meth:`~APIManager.init_app` on multiple :class:`~flask.Flask` applications after calling :meth:`~APIManager.create_api` on multiple instances of :class:`APIManager`. """ manager1 = APIManager(session=self.session) manager2 = APIManager(session=self.session) # Create the Flask applications and the test clients. flaskapp1 = self.flaskapp flaskapp2 = Flask(__name__) testclient1 = self.app testclient2 = flaskapp2.test_client() force_content_type_jsonapi(testclient2) # First create the API, then initialize the Flask applications after. manager1.create_api(self.Person) manager2.create_api(self.Article) manager1.init_app(flaskapp1) manager2.init_app(flaskapp2) # Tests that only the first Flask application gets requests for # /api/person and only the second gets requests for /api/article. response = testclient1.get('/api/person') assert response.status_code == 200 response = testclient1.get('/api/article') assert response.status_code == 404 response = testclient2.get('/api/person') assert response.status_code == 404 response = testclient2.get('/api/article') assert response.status_code == 200
def test_constructor_app(self): """Tests for providing a :class:`~flask.Flask` application in the constructor. """ manager = APIManager(app=self.flaskapp, session=self.session) manager.create_api(self.Person) response = self.app.get('/api/person') assert response.status_code == 200
def test_single_manager_init_single_app(self): """Tests for calling :meth:`~APIManager.init_app` with a single :class:`~flask.Flask` application after calling :meth:`~APIManager.create_api`. """ manager = APIManager(session=self.session) manager.create_api(self.Person) manager.init_app(self.flaskapp) response = self.app.get('/api/person') assert response.status_code == 200
def test_schema_app_in_constructor(self): manager = APIManager(self.flaskapp, session=self.session) manager.create_api(self.Article) manager.create_api(self.Person) response = self.app.get('/api') self.assertEqual(response.status_code, 200) document = loads(response.data) info = document['meta']['modelinfo'] self.assertEqual(sorted(info), ['article', 'person']) self.assertTrue(info['article']['url'].endswith('/api/article')) self.assertTrue(info['person']['url'].endswith('/api/person'))
def test_empty_url_prefix(self): """Tests for specifying an empty string as URL prefix at the manager level but not when creating an API. """ manager = APIManager(self.flaskapp, session=self.session, url_prefix='') manager.create_api(self.Person) response = self.app.get('/person') assert response.status_code == 200 response = self.app.get('/api/person') assert response.status_code == 404
def test_create_api_before_db_create_all(self): """Tests that we can create APIs before :meth:`flask_sqlalchemy.SQLAlchemy.create_all` is called. """ manager = APIManager(self.flaskapp, flask_sqlalchemy_db=self.db) manager.create_api(self.Person) self.db.create_all() person = self.Person(id=1) self.db.session.add(person) self.db.session.commit() response = self.app.get('/api/person/1') assert response.status_code == 200 document = loads(response.data) person = document['data'] assert '1' == person['id']
def test_missing_session(self): """Tests that setting neither a session nor a Flask-SQLAlchemy object yields an error. """ with self.assertRaises(ValueError): APIManager(app=self.flaskapp)
def setUp(self): """Initializes an instance of :class:`~flask_restless.APIManager` with a SQLAlchemy session. """ super(ManagerTestBase, self).setUp() self.manager = APIManager(self.flaskapp, session=self.session)
def setup(self): manager = APIManager(self.app, session=self.session) manager.create_api(Article) manager.create_api(Person) manager.create_api(Comment) self.manager = manager Base.metadata.create_all(bind=self.engine) yield Base.metadata.drop_all(bind=self.engine)
def setup(self): manager = APIManager(self.app, session=self.session, include_links=True) manager.create_api(Article) manager.create_api(Person, methods=['GET', 'POST']) manager.create_api(Comment) Base.metadata.create_all(bind=self.engine) yield Base.metadata.drop_all(bind=self.engine)
class TestFlaskSQLAlchemy(FlaskSQLAlchemyTestBase): """Tests for updating resources defined as Flask-SQLAlchemy models instead of pure SQLAlchemy models. """ def setUp(self): """Creates the Flask-SQLAlchemy database and models.""" super(TestFlaskSQLAlchemy, self).setUp() if not has_flask_sqlalchemy: self.skipTest('Flask-SQLAlchemy not found.') # HACK During testing, we don't want the session to expire, so that we # can access attributes of model instances *after* a request has been # made (that is, after Flask-Restless does its work and commits the # session). session_options = dict(expire_on_commit=False) # Overwrite the `db` and `session` attributes from the superclass. self.db = SQLAlchemy(self.flaskapp, session_options=session_options) self.session = self.db.session class Person(self.db.Model): id = self.db.Column(self.db.Integer, primary_key=True) name = self.db.Column(self.db.Unicode) self.Person = Person self.db.create_all() self.manager = APIManager(self.flaskapp, flask_sqlalchemy_db=self.db) self.manager.create_api(self.Person, methods=['PATCH']) def test_create(self): """Tests for creating a resource.""" person = self.Person(id=1, name=u'foo') self.session.add(person) self.session.commit() data = { 'data': { 'id': '1', 'type': 'person', 'attributes': { 'name': u'bar' } } } response = self.app.patch('/api/person/1', data=dumps(data)) assert response.status_code == 204 assert person.name == 'bar'
def test_override_url_prefix(self): """Tests that a call to :meth:`APIManager.create_api` can override the URL prefix provided in the constructor to the manager class, if the new URL starts with a slash. """ manager = APIManager(self.flaskapp, session=self.session, url_prefix='/foo') manager.create_api(self.Person, url_prefix='/bar') manager.create_api(self.Article, url_prefix='') response = self.app.get('/bar/person') assert response.status_code == 200 response = self.app.get('/article') assert response.status_code == 200 response = self.app.get('/foo/person') assert response.status_code == 404 response = self.app.get('/foo/article') assert response.status_code == 404
def init_app(self, app, **kwargs): self.app = app self.manager = APIManager(self.app, **kwargs) swagger = Blueprint('swagger', __name__, static_folder='static', static_url_path=self.app.static_url_path + '/swagger', ) @swagger.route('/swagger') def swagger_ui(): return redirect('/static/swagger/swagger-ui/index.html') @swagger.route('/swagger.json') def swagger_json(): # I can only get this from a request context self.swagger['host'] = urlparse.urlparse(request.url_root).netloc return jsonify(self.swagger) app.register_blueprint(swagger)
def setup_api(app): # Setup CORS CORS(app.flask_app) # Initialize the login manager login_manager = LoginManager() login_manager.init_app(app.flask_app) # Setup the user and request loading @login_manager.user_loader def user_loader(user_id): return User.find_one(id=user_id) @login_manager.request_loader def request_loader(request): session_token = request.headers.get('X-Session-Token') return User.from_token(session_token) # Add the auth endpoint app.api.add_resource(AuthResource, '/api/auth') # Add the answer endpoint app.api.add_resource(AnswerResource, '/api/question/<int:question_id>/answer') # Add the object endpoints manager = APIManager(app.flask_app, flask_sqlalchemy_db=app.db) manager.create_api( Question, methods=['GET', 'POST', 'PUT', 'DELETE'], preprocessors={ 'POST': [authenticate], 'PUT_SINGLE': [authenticate], 'PUT_MANY': [authenticate], 'DELETE_SINGLE': [authenticate], 'DELETE_MANY': [authenticate], }, postprocessors={'POST': [weight_postprocessor(Question)]}) manager.create_api( Category, methods=['GET', 'POST', 'PUT', 'DELETE'], preprocessors={ 'POST': [authenticate], 'PUT_SINGLE': [authenticate], 'PUT_MANY': [authenticate], 'DELETE_SINGLE': [authenticate], 'DELETE_MANY': [authenticate], }, postprocessors={'POST': [weight_postprocessor(Category)]}) manager.create_api( QuestionWeight, methods=['PUT'], preprocessors={'PUT': [authenticate]}, )
class TestFlaskSQLAlchemy(FlaskSQLAlchemyTestBase): """Tests for updating resources defined as Flask-SQLAlchemy models instead of pure SQLAlchemy models. """ def setUp(self): """Creates the Flask-SQLAlchemy database and models.""" super(TestFlaskSQLAlchemy, self).setUp() # HACK During testing, we don't want the session to expire, so that we # can access attributes of model instances *after* a request has been # made (that is, after Flask-Restless does its work and commits the # session). session_options = dict(expire_on_commit=False) # Overwrite the `db` and `session` attributes from the superclass. self.db = SQLAlchemy(self.flaskapp, session_options=session_options) self.session = self.db.session class Person(self.db.Model): id = self.db.Column(self.db.Integer, primary_key=True) name = self.db.Column(self.db.Unicode) self.Person = Person self.db.create_all() self.manager = APIManager(self.flaskapp, flask_sqlalchemy_db=self.db) self.manager.create_api(self.Person, methods=['PATCH']) def test_create(self): """Tests for creating a resource.""" person = self.Person(id=1, name=u'foo') self.session.add(person) self.session.commit() data = { 'data': { 'id': '1', 'type': 'person', 'attributes': { 'name': u'bar' } } } response = self.app.patch('/api/person/1', data=dumps(data)) assert response.status_code == 204 assert person.name == 'bar'
def test_schema_init_app(self): manager = APIManager(session=self.session) manager.create_api(self.Article) manager.create_api(self.Person) manager.init_app(self.flaskapp) response = self.app.get('/api') self.assertEqual(response.status_code, 200) document = loads(response.data) info = document['meta']['modelinfo'] self.assertEqual(sorted(info), ['article', 'person']) self.assertTrue(info['article']['url'].endswith('/api/article')) self.assertTrue(info['person']['url'].endswith('/api/person'))
def test_single_manager_init_multiple_apps(self): """Tests for calling :meth:`~APIManager.init_app` on multiple :class:`~flask.Flask` applications after calling :meth:`~APIManager.create_api`. """ manager = APIManager(session=self.session) flaskapp1 = self.flaskapp flaskapp2 = Flask(__name__) testclient1 = self.app testclient2 = flaskapp2.test_client() force_content_type_jsonapi(testclient2) manager.create_api(self.Person) manager.init_app(flaskapp1) manager.init_app(flaskapp2) response = testclient1.get('/api/person') assert response.status_code == 200 response = testclient2.get('/api/person') assert response.status_code == 200
def setup(self): manager = APIManager(self.app, session=self.session) manager.create_api(Article, methods=['PATCH']) manager.create_api(Person, methods=['PATCH']) manager.create_api(Person, methods=['PATCH'], url_prefix='/api2', allow_to_many_replacement=True, allow_delete_from_to_many_relationships=True) Base.metadata.create_all(bind=self.engine) yield Base.metadata.drop_all(bind=self.engine)
def setUp(self): """Creates the Flask-SQLAlchemy database and models.""" super(TestFlaskSQLAlchemy, self).setUp() # HACK During testing, we don't want the session to expire, so that we # can access attributes of model instances *after* a request has been # made (that is, after Flask-Restless does its work and commits the # session). session_options = dict(expire_on_commit=False) # Overwrite the `db` and `session` attributes from the superclass. self.db = SQLAlchemy(self.flaskapp, session_options=session_options) self.session = self.db.session class Person(self.db.Model): id = self.db.Column(self.db.Integer, primary_key=True) name = self.db.Column(self.db.Unicode) self.Person = Person self.db.create_all() self.manager = APIManager(self.flaskapp, flask_sqlalchemy_db=self.db) self.manager.create_api(self.Person, methods=['PATCH'])
def setUp(self): """Creates the Flask-SQLAlchemy database and models.""" super(TestFlaskSQLAlchemy, self).setUp() class Person(self.db.Model): id = self.db.Column(self.db.Integer, primary_key=True) self.Person = Person self.db.create_all() self.manager = APIManager(self.flaskapp, flask_sqlalchemy_db=self.db) self.manager.create_api(self.Person, methods=['POST'])
def initialize_resources(app): from server.api.health_check import HealthCheckAPI from server.api.race_resource import RaceAPI, race_deserializer, race_serializer from server.models.race import Race, RaceFollow from server.models.user import User from server.models.route import Route api = Api(app, default_mediatype='application/json', prefix='/api/v1') api_manager = APIManager(app, flask_sqlalchemy_db=db) api_manager.create_api( Race, methods=['GET', 'PUT'], url_prefix='/api/v2', exclude_columns=['race_follows', 'routes', 'user_id'], serializer=race_serializer, deserializer=race_deserializer) api_manager.create_api(User, methods=['GET']) api_manager.create_api(Route, methods=['GET']) api_manager.create_api(RaceFollow, methods=['GET']) api.add_resource(HealthCheckAPI, '/health-check/') api.add_resource(RaceAPI, '/races/')
def get_app(config): app = Flask(__name__) app.config.from_object('mpeb.web.config') app.config['SQLALCHEMY_DATABASE_URI'] = config.get_sqlalchemy_url() app.config['DEBUG'] = config.get_debug() db = SQLAlchemy(app) manager = APIManager(app, flask_sqlalchemy_db=db) class Config(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String) # Create API endpoints, which will be available at /api/<tablename> by # default. Allowed HTTP methods can be specified as well. manager.create_api(Config, methods=['GET', 'POST', 'DELETE']) db.create_all() return app
def test_multiple_managers_init_single_app(self): """Tests for calling :meth:`~APIManager.init_app` on a single :class:`~flask.Flask` application after calling :meth:`~APIManager.create_api` on multiple instances of :class:`APIManager`. """ manager1 = APIManager(session=self.session) manager2 = APIManager(session=self.session) # First create the API, then initialize the Flask applications after. manager1.create_api(self.Person) manager2.create_api(self.Article) manager1.init_app(self.flaskapp) manager2.init_app(self.flaskapp) # Tests that both endpoints are accessible on the Flask application. response = self.app.get('/api/person') assert response.status_code == 200 response = self.app.get('/api/article') assert response.status_code == 200
def create_app(config_filename): # import flask.ext.restless app = UserlessApp(__name__) app.config.from_pyfile(config_filename) from userless.models import ( db, User, Group, ) from userless.bootstrap import check if not check(): raise OSError('✘ Pre-Flight Check Failed; Check console for output.') db.init_app(app) celery.init_app(app) manager = APIManager(app, flask_sqlalchemy_db=db) with app.app_context(): db.create_all() manager.create_api(User, methods=['GET', 'PUT', 'POST', 'DELETE']) manager.create_api(Group, methods=['GET', 'PUT', 'POST', 'DELETE']) app.db = db app.api_manager = manager return app
def setupRestApi(): if importSuccess: app = Flask(__name__) app.config.update( DEBUG=True, SQLALCHEMY_DATABASE_URI="sqlite:///dmb.db", SQLALCHEMY_TRACK_MODIFICATIONS=False, ) db = SQLAlchemy(app) class MenuItem(db.Model): id = db.Column(db.Integer, primary_key=True) menuItemName = db.Column(db.Text) price = db.Column(db.Float) class ItemAddOn(db.Model): id = db.Column(db.Integer, primary_key=True) menuItemId = db.Column(db.Integer, db.ForeignKey("menu_item.id")) addOnName = db.Column(db.Text) price = db.Column(db.Integer) db.create_all() manager = APIManager(app, flask_sqlalchemy_db=db) methods = ["GET", "POST", "DELETE", "PATCH"] url_prefix = "/dmb" manager.create_api(MenuItem, methods=methods, url_prefix=url_prefix) manager.create_api(ItemAddOn, methods=methods, url_prefix=url_prefix) app.run() else: print( "Could not find flask; try `pip install flask` to troubleshoot API." )
def create_app(config_name): app = Flask(__name__, instance_relative_config=True) app.config.from_object(app_config[config_name]) app.config.from_pyfile('config.py') db.init_app(app) app.app_context().push() migrate = Migrate(app, db) from app import models # temporary route @app.route('/') def home(): return 'PWX App!' # admin initialization admin = Admin(app) admin.add_view(ModelView(models.Category, db.session)) admin.add_view(ModelView(models.Product, db.session)) #api initialization manager = APIManager(app, flask_sqlalchemy_db=db) includes_cat = ['id', 'name', 'is_active', 'products', 'products.name'] manager.create_api(models.Category, include_columns=includes_cat, methods=['GET', 'POST', 'PUT', 'DELETE']) includes_prod = ['id', 'name', 'price', 'category', 'category.name'] manager.create_api(models.Product, include_columns=includes_prod, methods=['GET', 'POST', 'PUT', 'DELETE']) return app
def setUp(self): """Creates the Flask-SQLAlchemy database and models.""" super(TestFlaskSQLAlchemy, self).setUp() if not has_flask_sqlalchemy: self.skipTest('Flask-SQLAlchemy not found.') # HACK During testing, we don't want the session to expire, so that we # can access attributes of model instances *after* a request has been # made (that is, after Flask-Restless does its work and commits the # session). session_options = dict(expire_on_commit=False) # Overwrite the `db` and `session` attributes from the superclass. self.db = SQLAlchemy(self.flaskapp, session_options=session_options) self.session = self.db.session class Person(self.db.Model): id = self.db.Column(self.db.Integer, primary_key=True) name = self.db.Column(self.db.Unicode) class Parent(self.db.Model): id = Column(Integer, primary_key=True) children = relationship( 'Child', primaryjoin= 'and_(Parent.id==Child.parent_id,Child.invisible==0)') class Child(self.db.Model): id = Column(Integer, primary_key=True) parent_id = self.db.Column(self.db.Integer, ForeignKey('parent.id')) invisible = self.db.Column(self.db.Boolean) self.Person = Person self.Parent = Parent self.Child = Child self.db.create_all() self.manager = APIManager(self.flaskapp, session=self.db.session) self.manager.create_api(self.Person, methods=['PATCH']) self.manager.create_api(self.Parent) self.manager.create_api(self.Child)
class TestFlaskSQLAlchemy(FlaskSQLAlchemyTestBase): """Tests for fetching resources defined as Flask-SQLAlchemy models instead of pure SQLAlchemy models. """ def setUp(self): """Creates the Flask-SQLAlchemy database and models.""" super(TestFlaskSQLAlchemy, self).setUp() class Person(self.db.Model): id = self.db.Column(self.db.Integer, primary_key=True) self.Person = Person self.db.create_all() self.manager = APIManager(self.flaskapp, session=self.db.session) self.manager.create_api(self.Person) def test_fetch_resource(self): """Test for fetching a resource.""" person = self.Person(id=1) self.session.add(person) self.session.commit() response = self.app.get('/api/person/1') document = response.json person = document['data'] assert person['id'] == '1' assert person['type'] == 'person' def test_fetch_collection(self): """Test for fetching a collection of resource.""" person1 = self.Person(id=1) person2 = self.Person(id=2) self.session.add_all([person1, person2]) self.session.commit() response = self.app.get('/api/person') document = response.json people = document['data'] assert ['1', '2'] == sorted(person['id'] for person in people)
def initApiServer(conf): # load config app.config.from_object(conf) # init flask sqlalchemy db.app = app db.init_app(app) db.create_all() # init API endpoints manager = APIManager(app, flask_sqlalchemy_db=db) createApi(manager) return app
def __init__(self, db_manager, download_manager, putio_client, synchronizer, launch_browser=False, host="0.0.0.0", port=7001): self.app = flask.Flask(__name__) self.synchronizer = synchronizer self.db_manager = db_manager self.api_manager = APIManager(self.app, session=self.db_manager.get_db_session()) self.download_manager = download_manager self.putio_client = putio_client self.transmission_rpc_server = TransmissionRPCServer(putio_client, self.synchronizer) self.launch_browser = launch_browser self._host = host self._port = port self._rate_tracker = DownloadRateTracker() self.app.logger.setLevel(logging.WARNING) def include_datetime(result): print(result) self.download_record_blueprint = self.api_manager.create_api( DownloadRecord, methods=['GET'], postprocessors={ "GET_MANY": [include_datetime] }) # filters self.app.jinja_env.filters["prettysize"] = self._pretty_size # urls self.app.add_url_rule("/", view_func=self._view_active) self.app.add_url_rule("/active", view_func=self._view_active) self.app.add_url_rule("/history", view_func=self._view_history) self.app.add_url_rule("/download_queue", view_func=self._view_download_queue) self.app.add_url_rule("/history/page/<int:page>", view_func=self._view_history) self.app.add_url_rule("/transmission/rpc", methods=['POST', 'GET', ], view_func=self.transmission_rpc_server.handle_request)
def test_universal_preprocessor(self): """Tests universal preprocessor and postprocessor applied to all methods created with the API manager. """ class Counter: """An object that increments a counter on each invocation.""" def __init__(self): self._counter = 0 def __call__(self, *args, **kw): self._counter += 1 def __eq__(self, other): if isinstance(other, Counter): return self._counter == other._counter if isinstance(other, int): return self._counter == other return False increment1 = Counter() increment2 = Counter() preprocessors = dict(GET_COLLECTION=[increment1]) postprocessors = dict(GET_COLLECTION=[increment2]) manager = APIManager(self.flaskapp, session=self.session, preprocessors=preprocessors, postprocessors=postprocessors) manager.create_api(self.Person) manager.create_api(self.Article) # After each request, regardless of API endpoint, both counters should # be incremented. self.app.get('/api/person') self.app.get('/api/article') self.app.get('/api/person') assert increment1 == increment2 == 3
def create_app(config_class=Config): app = Flask(__name__) app.config.from_object(config_class) db.init_app(app) migrate.init_app(app, db) app.elasticsearch = Elasticsearch([app.config['ELASTICSEARCH_URL']]) \ if app.config['ELASTICSEARCH_URL'] else None api_manager = APIManager(app, flask_sqlalchemy_db=db) api_manager.create_api(models.Item, methods=['GET'], url_prefix='', results_per_page=-1) api_manager.create_api(models.Skill, methods=['GET'], url_prefix='', results_per_page=-1) api_manager.create_api(models.Video, methods=['GET'], url_prefix='', results_per_page=-1) api_manager.create_api(models.Reddit, methods=['GET'], url_prefix='', results_per_page=-1) from app.errors import bp as errors_bp app.register_blueprint(errors_bp) from app.api import bp as main_bp app.register_blueprint(main_bp) CORS(app) return app
def init_app(self, app, **kwargs): self.app = app self.manager = APIManager(self.app, **kwargs) swagger = Blueprint('swagger', __name__, static_folder='static/swagger-ui', static_url_path=self.app.static_url_path + '/swagger', ) swaggerui_folder = os.path.join( os.path.dirname(os.path.abspath(__file__)), 'static/swagger-ui') print(swaggerui_folder) self.app.jinja_loader.searchpath.append(swaggerui_folder) @swagger.route('/swagger') def swagger_ui(): return render_template('index.html') # return redirect('/static/swagger/swagger-ui/index.html') @swagger.route('/swagger.json') def swagger_json(): # I can only get this from a request context self.swagger['host'] = urlparse.urlparse(request.url_root).netloc return jsonify(self.swagger) app.register_blueprint(swagger)
def create_app(mode): app = Flask(__name__) config = Config('conf.json') config['current_mod'] = mode config['init'] = True app.service_config = config # mode配置需要在db_engine产生前完成 from DataService.models import engine, get_session from DataService.api_manager import api_manager from DataService.table_manager import table_manager # 切换工作目录 os.chdir(config['working_dir']) # 设置全局db_session app.db_session = get_session() # 设置全局table_manager app.table_manager = table_manager() # flask-restless Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) mysession = scoped_session(Session) restless_manager = APIManager( app, session=mysession) # 全局preprocessors postprocessors无效 原因不明 app.restless_manager = restless_manager api_manager.init_api_from_db(restless_manager) # url屏蔽 @app.before_request def intercept(): if request.path in app.service_config['api']['intercept_urls']: return general_error(403, 'request url is intercepted') from DataService.app.api import api app.register_blueprint(api, url_prefix='/api') # 设置全局api_manager sys_api_manager = api_manager(app) app.api_manager = sys_api_manager from DataService.app.manager import manager app.register_blueprint(manager, url_prefix='/manager') return app
def test_schema_app_in_constructor(self): manager = APIManager(self.flaskapp, session=self.session) manager.create_api(self.Article) manager.create_api(self.Person) response = self.app.get('/api') self.assertEqual(response.status_code, 200) document = loads(response.data) urls = document['meta']['urls'] self.assertEqual(sorted(urls), ['article', 'person']) self.assertTrue(urls['article'].endswith('/api/article')) self.assertTrue(urls['person'].endswith('/api/person'))
def create_app(): app = Flask(__name__) # 第一个参数是模块或者包的名字,参数是必须的 print os.environ.get('MODE') if os.environ.get('MODE') == 'TEST_SQLITE': app.config.from_object(config['development_sqlite_disk']) #config是一个字典 else: app.config.from_object(config['development_mysql']) db.app = app db.init_app(app) # flask-restless restless_api_manager = APIManager(app, flask_sqlalchemy_db=db) create_company_blueprint(restless_api_manager) create_owner_blueprint(restless_api_manager) create_warehouse_blueprint(restless_api_manager) return app
class TestProcessors(BaseTestClass): """Tests for pre- and post-processors.""" @pytest.fixture(autouse=True) def setup(self): self.manager = APIManager(self.app, session=self.session) Base.metadata.create_all(bind=self.engine) yield Base.metadata.drop_all(bind=self.engine) def test_preprocessor(self): """Tests :http:method:`post` requests with a preprocessor function.""" def set_name(data=None, **__): """Sets the name attribute of the incoming data object, regardless of the value requested by the client. """ if data is not None: data['data']['attributes']['name'] = u'bar' preprocessors = dict(POST_RESOURCE=[set_name]) self.manager.create_api(Person, methods=['POST'], preprocessors=preprocessors) post_data = dict(data=dict(type='person', attributes=dict(name=u'foo'))) document = self.post_and_validate('/api/person', json=post_data) assert document['data']['attributes']['name'] == 'bar' def test_postprocessor(self): """Tests that a postprocessor is invoked when creating a resource.""" def modify_result(result=None, **__): result['foo'] = 'bar' postprocessors = dict(POST_RESOURCE=[modify_result]) self.manager.create_api(Person, methods=['POST'], postprocessors=postprocessors) data = dict(data=dict(type='person')) response = self.client.post('/api/person', json=data) assert response.status_code == 201 document = response.json assert document['foo'] == 'bar' def test_postprocessor_can_rollback_transaction(self): """Tests that a postprocessor can rollback the transaction.""" def rollback_transaction(**__): self.session.rollback() postprocessors = dict(POST_RESOURCE=[rollback_transaction]) self.manager.create_api(Person, methods=['POST'], postprocessors=postprocessors) data = dict(data=dict(type='person')) self.post_and_validate('/api/person', json=data) assert self.session.query(Person).count() == 0
def __init__(self): """ Initialize the application, its context, and the API manager """ self.app.config.from_object(config) # init the logging and context self.setup_logging(); self.app.test_request_context().push() # grab the database from the model, init the service db.init_app(self.app) # Create the Flask-Restless API manager. self.manager = APIManager(self.app, flask_sqlalchemy_db=db) # define the blueprint self.myplaceServiceBlueprint = self.manager.create_api_blueprint( MyPlace, # if a custom URL prefix is desired: url_prefix='/api/', methods=['GET', 'POST', 'PUT', 'DELETE'], preprocessors=dict(GET_MANY=[self.preprocessor])) self.app.logger.info('MyService blueprint created')
def init_app(app): manager = APIManager(app, flask_sqlalchemy_db=db, url_prefix='/models') manager.create_api(User, preprocessors=admin_only_preprocessors, url_prefix='', methods=all_methods, max_page_size=100, exclude=('password',)) manager.create_api(Role, preprocessors=admin_only_preprocessors, url_prefix='', methods=all_methods, max_page_size=100) app.logger.addFilter(ProcessingExceptionFilter())
def setup_endpoints(application): with application.app_context(): manager = APIManager(application, flask_sqlalchemy_db=db) manager.create_api( Company, methods=['GET', 'POST', 'OPTIONS'], include_columns=['id', 'name', 'tags'], include_methods=['name', 'lang_code'], ) manager.create_api( Tag, methods=['GET', 'OPTIONS'], exclude_columns=['names', 'companies.tags'], include_methods=['name', 'lang_code'], )
# Step 0: the database in this example is at './test.sqlite'. DATABASE = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'test.sqlite') if os.path.exists(DATABASE): os.unlink(DATABASE) # Step 1: setup the Flask application. app = Flask(__name__) app.config['DEBUG'] = True app.config['TESTING'] = True app.config['SECRET_KEY'] = os.urandom(24) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///%s' % DATABASE # Step 2: initialize extensions. db = SQLAlchemy(app) api_manager = APIManager(app, flask_sqlalchemy_db=db) login_manager = LoginManager() login_manager.setup_app(app) # Step 3: create the user database model. class User(db.Model, UserMixin): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.Unicode) password = db.Column(db.Unicode) # Step 4: create the database and add a test user. db.create_all() user1 = User(username=u'example', password=u'example') db.session.add(user1)
class MyPlaceService(): """ A RESTful service, exposing the MyPlace model, interacting with a persistence tier (using SQLAlchemy for persistence). C Currently delegates some validations to the model and can further implement auth/authz Handles exceptions Handles some pagination Exposes a blueprint that can be used for embedding this service in different apps """ # define the application as a class obj app = flask.Flask("mypoiservice") def __init__(self): """ Initialize the application, its context, and the API manager """ self.app.config.from_object(config) # init the logging and context self.setup_logging(); self.app.test_request_context().push() # grab the database from the model, init the service db.init_app(self.app) # Create the Flask-Restless API manager. self.manager = APIManager(self.app, flask_sqlalchemy_db=db) # define the blueprint self.myplaceServiceBlueprint = self.manager.create_api_blueprint( MyPlace, # if a custom URL prefix is desired: url_prefix='/api/', methods=['GET', 'POST', 'PUT', 'DELETE'], preprocessors=dict(GET_MANY=[self.preprocessor])) self.app.logger.info('MyService blueprint created') def setup_logging(self): """ Set up some rudimentary logging for production *and* for hosting situations It might be better to move this to the tools package, as it can be reused, but will need more configuration for usage by different services (TODO) """ #if not config.DEBUG: # file_handler = RotatingFileHandler('logs/myservice.log', 'a', 1 * 1024 * 1024, 10) # file_handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]')) # self.app.logger.setLevel(logging.INFO) # file_handler.setLevel(logging.INFO) # self.app.logger.addHandler(file_handler) # self.app.logger.info("App hosting logging started...") if config.HOSTING is not None: stream_handler = logging.StreamHandler() self.app.logger.addHandler(stream_handler) self.app.logger.setLevel(logging.INFO) self.app.logger.info("App hosting logging started...") def get_blueprint(self): """ Return the service blueprint for inclusion in apps """ return self.myplaceServiceBlueprint; def preprocessor(self, search_params=None, **kw): """ Preprocessor can be used for auth if needed for now, let it remain unused """ return def run_standalone(self): """ For when the library needs to be up and running on its own """ self.app.register_blueprint(self.myplaceServiceBlueprint) self.app.run(config.API_SERVICE_HOST, config.API_SERVICE_PORT) def shutdown_server(self): """ In case we want to shut down the standalone service (a hook can be implemented to trigger this) """ func = request.environ.get('werkzeug.server.shutdown') if func is None: raise RuntimeError('Not running with the Werkzeug Server') func() return
def initRestlessApi(app): manager = APIManager(app, flask_sqlalchemy_db=DBManager.db) manager.create_api(User, methods=['POST']) manager.create_api(User, methods=['GET'], include_columns=['sid', 'username', 'email']) # manager.create_api(Gcm, methods=['POST']) manager.create_api(Allergy, methods=['GET', 'POST', 'DELETE']) manager.create_api(Provider, methods=['GET', 'POST', 'DELETE']) manager.create_api(ProviderInfo, methods=['GET']) manager.create_api(Neis, methods=['GET']) manager.create_api(Article, methods=['GET']) manager.create_api(Rate, methods=['POST'])
int(self.students/100*self.val4), int(self.students/100*self.val5), int(self.students/100*self.val6), int(self.students/100*self.val7), int(self.students/100*self.val8), int(self.students/100*self.val9)] @app.route('/') def index(): return redirect('/api/simple/results?q={"filters":[{"name":"school","op":"has","val":{"name":"area","op":"ilike","val":"%район%"}}]}') if __name__ == '__main__': mr_manager = APIManager(app, flask_sqlalchemy_db=db) simple_methods = ['abs_scores', 'scores', 'school.location', 'school.extra'] simple_columns = ['year', 'subject', 'students', 'school', 'school.name', 'school.type', 'school_id'] mr_manager.create_api(Result, url_prefix='/api/all', collection_name='results', methods=['GET'], # include_methods=simple_methods, # include_columns=simple_columns, #exclude_columns=['school'], results_per_page=10000, max_results_per_page=10000, # exclude_columns=['id', 'school.id', 'school_id'], # preprocessors={'GET_MANY':[]}, # postprocessors={'GET_MANY':[]} )
from functools import wraps from flask_admin import Admin from flask_admin.contrib.sqla import ModelView from flask_restless import APIManager from database import db from models import Train app = Flask(__name__) app.config.from_object("config.DevelopmentConfig") db.init_app(app) #this changes the app with app.app_context(): api_manager = APIManager(app, flask_sqlalchemy_db=db) # api_manager.init_app(app) #this cannot work #api_manager.create_api(Train, methods=["GET", 'POST', 'DELETE']) api_manager.create_api(Train, include_columns =["id", "fromCity", "toCity"], methods=["GET", 'POST', 'PUT', 'DELETE']) #def get_trains(): def create_admin(): admin = Admin(app, name="TrainsBooking") admin.add_view(ModelView(Train, db.session)) def login_required(f): @wraps(f) def wrap(*args, **kwargs): if "logged_in" in session:
username = Column(Text, unique=True) password = Column(Text, unique=False) user_preference = Column(Text, unique=False) def __init__(self, username, password, user_preference): self.username = username self.password = password self.user_preference = user_preference def __repr__(self): return '<User %r>' % self.username db.create_all() api_manager = APIManager(app, flask_sqlalchemy_db=db) api_manager.create_api(User, methods=['GET', 'POST', 'DELETE', 'PUT']) @app.route('/') def index(): return render_template('index.html') @app.route('/signup', methods=['GET', 'POST']) def signup(): error = None if request.method == 'POST': _username = request.form['username'] _password = request.form['password'] if db.session.query(User).filter(User.username == _username).scalar() is None:
# Step 0: the database in this example is at './test.sqlite'. DATABASE = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'test.sqlite') if os.path.exists(DATABASE): os.unlink(DATABASE) # Step 1: setup the Flask application. app = Flask(__name__) app.config['DEBUG'] = True app.config['TESTING'] = True app.config['SECRET_KEY'] = os.urandom(24) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///%s' % DATABASE # Step 2: initialize extensions. db = SQLAlchemy(app) api_manager = APIManager(app, flask_sqlalchemy_db=db) # Step 3: create the database model. class Person(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.Unicode) # Step 4: create the database and add some test people. db.create_all() for i in range(1, 10): name = u'person{0}'.format(i) person = Person(name=name) db.session.add(person) db.session.commit()
# -*- coding: utf-8 -*- from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask_restless import APIManager app = Flask(__name__) app.config[ 'SQLALCHEMY_DATABASE_URI'] = 'mysql+mysqlconnector://root:root@localhost:3306/test1' db = SQLAlchemy(app) restless = APIManager(app, flask_sqlalchemy_db=db) class User(db.Model): """ user """ id = db.Column(db.Integer, primary_key=True, autoincrement=True) username = db.Column(db.String(255), unique=True, nullable=False) password = db.Column(db.String(255), nullable=False) content = db.Column(db.String(255), nullable=False) restless.create_api( User, methods=['GET', 'POST', 'DELETE', 'PATCH', 'PUT'], results_per_page=100) db.create_all()
def load_user(payload): user = user_datastore.find_user(id=payload['identity']) return user jwt = JWT(app, authenticate, load_user) # Flask-Restless API ========================================================= @jwt_required() def auth_func(**kw): pass apimanager = APIManager(app, flask_sqlalchemy_db=db) apimanager.create_api(SomeStuff, methods=['GET', 'POST', 'DELETE', 'PUT'], url_prefix='/api/v1', collection_name='free_stuff', include_columns=['id', 'data1', 'data2', 'user_id']) apimanager.create_api(SomeStuff, methods=['GET', 'POST', 'DELETE', 'PUT'], url_prefix='/api/v1', preprocessors=dict(GET_SINGLE=[auth_func], GET_MANY=[auth_func]), collection_name='protected_stuff', include_columns=['id', 'data1', 'data2', 'user_id']) # Setup Admin ================================================================ init_admin()
__author__ = 'rebecca' from flask import Flask from flask_bootstrap import Bootstrap from flask_login import LoginManager from flask_restless import APIManager from models import db, User app = Flask(__name__) Bootstrap(app) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db' db.init_app(app) with app.test_request_context(): db.create_all() manager = APIManager(app, flask_sqlalchemy_db=db) user_blueprint = manager.create_api(User, methods=['GET', 'POST']) login_manager = LoginManager() login_manager.init_app(app) import apptrack.views
app = Flask(__name__) app.secret_key = config.get('secrets', 'SECRET') #app.config['SERVER_NAME'] = 'localhost:5000' login_manager = LoginManager() login_manager.init_app(app) login_manager.session_protection = 'strong' # or 'basic' @login_manager.user_loader def load_user(user_id): return db_session.query(User).get(int(user_id)) # Flask-Restless API endpoints manager = APIManager(app, session=db_session, preprocessors=dict(DELETE=[authn_func], GET_SINGLE=[authn_func], GET_MANY=[authn_func], PATCH=[authn_func])) opportunity_blueprint = manager.create_api(Opportunity, methods=['GET', 'DELETE', 'PATCH', 'POST'], collection_name='opportunity', url_prefix='/v1', max_results_per_page=300, preprocessors=dict(POST=[authn_func])) provider_blueprint = manager.create_api(Provider, methods=['GET', 'DELETE', 'PATCH', 'POST'], collection_name='provider', url_prefix='/v1', max_results_per_page=300, preprocessors=dict(POST=[authn_func])) session_blueprint = manager.create_api(Session, methods=['POST'], collection_name='session',