def test_create_api_for_model_collections(self): """Test for read access to model foreign keys """ mary = self.Person(name=u'Mary', age=19, other=19) pc = self.Computer(name=u'PC', vendor=u'Noname') pc.owner.append(mary) laptop = self.Computer(name=u'Lappy', vendor=u'Dell') laptop.owner.append(mary) self.session.add_all([mary, pc, laptop]) self.session.commit() manager = APIManager(self.flaskapp, session=self.Session) manager.create_api(self.Person, methods=['GET']) manager.create_api(self.Computer, methods=['GET']) # test that collection endpoints are present response = self.app.get('/api/person/'+str(mary.id)+'/computers/') self.assertEqual(response.status_code, 200) self.assertEqual(len(loads(response.data)['objects']), 2) # test that not existing collection endpoint returns HTTP 404 response = self.app.get('/api/person/'+str(mary.id)+'/parents/') self.assertEqual(response.status_code, 404) # access is setup for child relations only, master cannot be accessed this way response = self.app.get('/api/computer/'+str(pc.id)+'/owner/') self.assertEqual(response.status_code, 404) # also plain attributes cannot be accessed this way response = self.app.get('/api/person/'+str(mary.id)+'/name/') self.assertEqual(response.status_code, 404) response = self.app.get('/api/computer/'+str(pc.id)+'/owner_id/') self.assertEqual(response.status_code, 404)
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 configure_api(app): manager = APIManager(app, flask_sqlalchemy_db=db) exclude = ['documents', 'orders', 'supplier_contacts'] manager.create_api(Supplier, collection_name='suppliers', exclude_columns=exclude)
def test_universal_preprocessor(self): """Tests universal preprocessor and postprocessor applied to all methods created with the API manager. """ class Counter(object): def __init__(s): s.count = 0 def increment(s): s.count += 1 def __eq__(s, o): return s.count == o.count if isinstance(o, Counter) \ else s.count == o precount = Counter() postcount = Counter() def preget(**kw): precount.increment() def postget(**kw): postcount.increment() manager = APIManager(self.flaskapp, self.session, preprocessors=dict(GET_MANY=[preget]), postprocessors=dict(GET_MANY=[postget])) manager.create_api(self.Person) manager.create_api(self.Computer) self.app.get('/api/person') self.app.get('/api/computer') self.app.get('/api/person') assert precount == postcount == 3
def test_creation_api_without_app_dependency(self): """Tests that api can be added before app will be passed to manager.""" manager = APIManager() manager.create_api(self.Person) manager.init_app(self.flaskapp, self.session) response = self.app.get('/api/person') assert response.status_code == 200
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
def test_multiple_app_delayed_init(self): manager = 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_json_contenttype(testclient2) # First create the API, then initialize the Flask applications after. manager.create_api(self.Person, app=flaskapp1) manager.create_api(self.Computer, app=flaskapp2) manager.init_app(flaskapp1) manager.init_app(flaskapp2) # Tests that only the first Flask application gets requests for # /api/person and only the second gets requests for /api/computer. response = testclient1.get('/api/person') assert response.status_code == 200 response = testclient1.get('/api/computer') assert response.status_code == 404 response = testclient2.get('/api/person') assert response.status_code == 404 response = testclient2.get('/api/computer') assert response.status_code == 200
def load_endpoint(self, Module): r"""Load a single module endpoint. Given a module name, locate the `endpoint.py` file, and instantiate a new Flask Restless compatible endpoint accorindg to the settings contained within the `endpoint.py` file. :param object self: The Application class :param object Module: The of module containing endpoint See the official Flask Restless documentation for more information https://flask-restless.readthedocs.org/en/latest/api.html#\ flask.ext.restless.APIManager.create_api """ manager = APIManager(self.app, flask_sqlalchemy_db=db) if hasattr(Module, 'endpoints'): if hasattr(Module, 'Model'): Seed_ = Module.endpoints.Seed() manager.create_api(Module.Model, **Seed_.__arguments__) logger.info('`%s` module endpoints loaded' % (Module.__name__)) else: logger.error('`%s` module has endpoints, but is missing ' 'Model' % (Module.__name__)) else: logger.info('`%s` module did not contain any endpoints.' % (Module.__name__))
def test_multiple_app_delayed_init(self): manager = 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_json_contenttype(testclient2) # First create the API, then initialize the Flask applications after. manager.create_api(self.Person, app=flaskapp1) manager.create_api(self.Computer, app=flaskapp2) manager.init_app(flaskapp1) manager.init_app(flaskapp2) # Tests that only the first Flask application gets requests for # /api/person and only the second gets requests for /api/computer. response = testclient1.get('/api/person') assert response.status_code == 200 response = testclient1.get('/api/computer') assert response.status_code == 404 response = testclient2.get('/api/person') assert response.status_code == 404 response = testclient2.get('/api/computer') assert response.status_code == 200
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 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
class TestFlaskSqlalchemy(FlaskTestBase): """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() self.db = SQLAlchemy(self.flaskapp) self.session = self.db.session 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 teardown(self): """Drops all tables and unregisters Flask-SQLAlchemy session signals. """ self.db.drop_all() unregister_fsa_session_signals() 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
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'
def test_creation_api_without_app_dependency(self): """Tests that api can be added before app will be passed to manager.""" manager = APIManager() manager.create_api(self.Person) manager.init_app(self.flaskapp, self.session) 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'
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_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_init_app(self): """Tests for initializing the Flask application after instantiating the :class:`flask.ext.restless.APIManager` object. """ manager = APIManager() manager.init_app(self.flaskapp, session=self.session) manager.create_api(self.Person, app=self.flaskapp) response = self.app.get('/api/person') assert response.status_code == 200
def test_init_app(self): """Tests for initializing the Flask application after instantiating the :class:`flask.ext.restless.APIManager` object. """ manager = APIManager() manager.init_app(self.flaskapp, session=self.session) manager.create_api(self.Person, app=self.flaskapp) 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_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 create_api(app): prefix = '/api/v0' api_manager = APIManager(app, flask_sqlalchemy_db=db) api = ((AnalysisTbl, 'analysis', {'methods': ['GET']}), (IrradiationPositionTbl, 'iposition', {'methods': ['GET']}), (IrradiationTbl, 'irradiation', {'methods': ['GET']}), (LevelTbl, 'level', {'methods': ['GET']}), (ProductionTbl, 'production', {'methods': ['GET']})) for table, cname, kw in api: api_manager.create_api(table, collection_name=cname, url_prefix=prefix, **kw)
def create_api(app, db): api_manager = APIManager(app, flask_sqlalchemy_db=db) allowed_methods = ['GET', 'POST', 'PUT', 'DELETE'] for module_name in modules.__all__: module = getattr(modules, module_name) # override existing the default allowed_methods if exists if hasattr(module, 'allowed_methods'): allowed_methods = getattr(modules, 'allowed_methods') api_manager.create_api(module, methods=allowed_methods)
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_url_prefix(self): """Tests for specifying a URL prefix at the manager level but not when creating an API. """ manager = APIManager(self.flaskapp, session=self.session, url_prefix='/foo') manager.create_api(self.Person) response = self.app.get('/foo/person') assert response.status_code == 200 response = self.app.get('/api/person') assert response.status_code == 404
def test_session_class(self): """Test for providing a session class instead of a sesssion instance. """ manager = APIManager(self.flaskapp, session=self.Session) manager.create_api(self.Person, methods=["GET", "POST"]) response = self.app.get("/api/person") self.assertEqual(response.status_code, 200) response = self.app.post("/api/person", data=dumps(dict(name="foo"))) self.assertEqual(response.status_code, 201) response = self.app.get("/api/person/1") self.assertEqual(response.status_code, 200) self.assertEqual(loads(response.data)["id"], 1)
def test_session_class(self): """Test for providing a session class instead of a sesssion instance. """ manager = APIManager(self.flaskapp, session=self.Session) manager.create_api(self.Person, methods=['GET', 'POST']) response = self.app.get('/api/person') self.assertEqual(response.status_code, 200) response = self.app.post('/api/person', data=dumps(dict(name='foo'))) self.assertEqual(response.status_code, 201) response = self.app.get('/api/person/1') self.assertEqual(response.status_code, 200) self.assertEqual(loads(response.data)['id'], 1)
def test_session_class(self): """Test for providing a session class instead of a sesssion instance. """ manager = APIManager(self.flaskapp, session=self.Session) manager.create_api(self.Person, methods=['GET', 'POST']) response = self.app.get('/api/person') self.assertEqual(response.status_code, 200) response = self.app.post('/api/person', data=dumps(dict(name='foo'))) self.assertEqual(response.status_code, 201) response = self.app.get('/api/person/1') self.assertEqual(response.status_code, 200) self.assertEqual(loads(response.data)['id'], 1)
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') response = self.app.get('/bar/person') assert response.status_code == 200 response = self.app.get('/foo/person') assert response.status_code == 404
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') response = self.app.get('/bar/person') assert response.status_code == 200 response = self.app.get('/foo/person') assert response.status_code == 404
def test_url_for(self): manager = APIManager(self.flaskapp, session=self.session) manager.create_api(self.Person, collection_name='people') manager.create_api(self.Computer, collection_name='computers') with self.flaskapp.app_context(): url = url_for(self.Computer) assert url.endswith('/api/computers') assert url_for(self.Person).endswith('/api/people') assert url_for(self.Person, instid=1).endswith('/api/people/1') url = url_for(self.Person, instid=1, relationname='computers') assert url.endswith('/api/people/1/computers') url = url_for(self.Person, instid=1, relationname='computers', relationinstid=2) assert url.endswith('/api/people/1/computers/2')
def setup_api(app, db): manager = APIManager(app, flask_sqlalchemy_db=db) manager.create_api( Score, preprocessors={"DELETE": [score_pre_delete], "PATCH_SINGLE": [score_pre_patch], "POST": [score_pre_post]}, postprocessors={"PATCH_SINGLE": [post_post], "POST": [post_post]}, methods=["DELETE", "GET", "PATCH", "POST", "PUT"], ) manager.create_api( User, methods=["GET"], postprocessors={"GET_MANY": [user_post_get_many], "GET_SINGLE": [filter_user]}, max_results_per_page=None, )
class TestFlaskSqlalchemy(FlaskTestBase): """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) 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 teardown(self): """Drops all tables and unregisters Flask-SQLAlchemy session signals. """ self.db.drop_all() unregister_fsa_session_signals() 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_create_api_before_db_create_all(self): """Tests that we can create APIs before :meth:`flask.ext.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_create_api_before_db_create_all(self): """Tests that we can create APIs before :meth:`flask.ext.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']
class TestFlaskSqlalchemy(FlaskTestBase): """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) 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 teardown(self): """Drops all tables and unregisters Flask-SQLAlchemy session signals. """ self.db.drop_all() unregister_fsa_session_signals() 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 init_webapp(): """Initialize the web application.""" # logging.getLogger('flask_cors').level = logging.DEBUG # app.wsgi_app = LoggingMiddleware(app.wsgi_app) # Note, this url namespace also exists for the Flask-Restless # extension and is where CRUD interfaces live, so be careful not to # collide with model names here. We could change this, but it's nice # to have API live in the same url namespace. app.register_blueprint(api, url_prefix='/api') # Initialize Flask configuration app.config['SQLALCHEMY_DATABASE_URI'] = make_conn_str() app.config['SECRET_KEY'] = 'abc123' app.config['WTF_CSRF_ENABLED'] = False app.config['SECURITY_TOKEN_MAX_AGE'] = 60 app.config['SECURITY_TOKEN_AUTHENTICATION_HEADER'] = 'Auth-Token' # app.config['SECURITY_POST_LOGIN_VIEW'] = 'http://127.0.0.1:4200' # app.config['CORS_HEADERS'] = 'Content-Type' # Initialize Flask-CORS CORS(app, supports_credentials=True) # CORS(app, supports_credentials=True, resources={r"/*": {"origins": "*"}}) # Initialize Flask-Bootstrap Bootstrap(app) # Initialize Flask-Security user_datastore = SQLAlchemyUserDatastore(db, User, Role) security = Security(app, user_datastore) # Initialize Flask-SQLAlchemy db.app = app db.init_app(app) db.create_all() # Initialize Flask-Restless manager = APIManager( app, flask_sqlalchemy_db=db, preprocessors=dict(GET_MANY=[restless_api_auth_func]), ) manager.create_api(Employee, methods=['GET', 'POST', 'OPTIONS']) return app
def init_webapp(): """Initialize the web application.""" # logging.getLogger('flask_cors').level = logging.DEBUG # app.wsgi_app = LoggingMiddleware(app.wsgi_app) # Note, this url namespace also exists for the Flask-Restless # extension and is where CRUD interfaces live, so be careful not to # collide with model names here. We could change this, but it's nice # to have API live in the same url namespace. app.register_blueprint(api, url_prefix='/api') # Initialize Flask configuration app.config['SQLALCHEMY_DATABASE_URI'] = make_conn_str() app.config['SECRET_KEY'] = 'abc123' app.config['WTF_CSRF_ENABLED'] = False app.config['SECURITY_TOKEN_MAX_AGE'] = 60 app.config['SECURITY_TOKEN_AUTHENTICATION_HEADER'] = 'Auth-Token' # app.config['SECURITY_POST_LOGIN_VIEW'] = 'http://127.0.0.1:4200' # app.config['CORS_HEADERS'] = 'Content-Type' # Initialize Flask-CORS CORS(app, supports_credentials=True) # CORS(app, supports_credentials=True, resources={r"/*": {"origins": "*"}}) # Initialize Flask-Bootstrap Bootstrap(app) # Initialize Flask-Security user_datastore = SQLAlchemyUserDatastore(db, User, Role) security = Security(app, user_datastore) # Initialize Flask-SQLAlchemy db.app = app db.init_app(app) db.create_all() # Initialize Flask-Restless manager = APIManager( app, flask_sqlalchemy_db=db, preprocessors=dict(GET_MANY=[restless_api_auth_func]), ) manager.create_api(Employee, methods=['GET', 'POST', 'OPTIONS']) return app
class WebServer(object): """TODO: Add here description """ def __init__(self, hostname, port, app): self.hostname = hostname self.port = port self.app = app self.apimanager = APIManager() def create_blueprints(self, session): # Initialize APIManager with Flask object self.apimanager.init_app(self.app, session=session) # Create API endpoints # SmaliClass self.apimanager.create_api( SmaliClass, app=self.app, methods=['GET', 'POST'] ) # SmaliProperty self.apimanager.create_api( SmaliProperty, app=self.app, methods=['GET', 'POST'] ) # SmaliMethod self.apimanager.create_api( SmaliMethod, app=self.app, methods=['GET', 'POST'] ) # SmaliConstString self.apimanager.create_api( SmaliConstString, app=self.app, methods=['GET', 'POST'] ) # SmaliCall self.apimanager.create_api( SmaliCall, app=self.app, methods=['GET', 'POST'] ) def run(self): """Runs the server""" run_simple(self.hostname, self.port, self.app)
def test_init_multiple(self): manager = APIManager(session=self.session) flaskapp1 = self.flaskapp flaskapp2 = Flask(__name__) testclient1 = self.app testclient2 = flaskapp2.test_client() force_json_contenttype(testclient2) manager.init_app(flaskapp1) manager.init_app(flaskapp2) manager.create_api(self.Person, app=flaskapp1) manager.create_api(self.Computer, app=flaskapp2) response = testclient1.get('/api/person') assert response.status_code == 200 response = testclient1.get('/api/computer') assert response.status_code == 404 response = testclient2.get('/api/person') assert response.status_code == 404 response = testclient2.get('/api/computer') assert response.status_code == 200
def test_init_multiple(self): manager = APIManager(session=self.session) flaskapp1 = self.flaskapp flaskapp2 = Flask(__name__) testclient1 = self.app testclient2 = flaskapp2.test_client() force_json_contenttype(testclient2) manager.init_app(flaskapp1) manager.init_app(flaskapp2) manager.create_api(self.Person, app=flaskapp1) manager.create_api(self.Computer, app=flaskapp2) response = testclient1.get('/api/person') assert response.status_code == 200 response = testclient1.get('/api/computer') assert response.status_code == 404 response = testclient2.get('/api/person') assert response.status_code == 404 response = testclient2.get('/api/computer') assert response.status_code == 200
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 register_api(app, db): db.app = app apimanager = APIManager(app, flask_sqlalchemy_db=db) apimanager.create_api( ModelRun, methods=['GET', 'POST', 'PUT', 'DELETE'], serializer=modelrun_serializer, preprocessors=modelrun_preprocessors, postprocessors={'GET_MANY': [model_run_after_get_many]}, allow_delete_many=False, results_per_page=-1) apimanager.create_api(ModelResource, methods=['GET', 'POST', 'PUT', 'DELETE'], serializer=modelresource_serializer, preprocessors=modelresource_preprocessors, exclude_columns=[], allow_delete_many=False)
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 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 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 test_flask_sqlalchemy(self): """Tests that :class:`flask.ext.restless.APIManager` correctly exposes models defined using Flask-SQLAlchemy. """ manager = APIManager(self.flaskapp, flask_sqlalchemy_db=self.db) # create three different APIs for the same model manager.create_api(self.Person, methods=['GET', 'POST']) manager.create_api(self.Person, methods=['PATCH'], url_prefix='/api2') manager.create_api(self.Person, methods=['GET'], url_prefix='/readonly') # test that specified endpoints exist response = self.app.post('/api/person', data=dumps(dict(name='foo'))) assert response.status_code == 201 assert loads(response.data)['id'] == 1 response = self.app.get('/api/person') assert response.status_code == 200 assert len(loads(response.data)['objects']) == 1 assert loads(response.data)['objects'][0]['id'] == 1 response = self.app.patch('/api2/person/1', data=dumps(dict(name='bar'))) assert response.status_code == 200 assert loads(response.data)['id'] == 1 assert loads(response.data)['name'] == 'bar' # test that the model is the same as before response = self.app.get('/readonly/person') assert response.status_code == 200 assert len(loads(response.data)['objects']) == 1 assert loads(response.data)['objects'][0]['id'] == 1 assert loads(response.data)['objects'][0]['name'] == 'bar'
def test_flask_sqlalchemy(self): """Tests that :class:`flask.ext.restless.APIManager` correctly exposes models defined using Flask-SQLAlchemy. """ manager = APIManager(self.flaskapp, flask_sqlalchemy_db=self.db) # create three different APIs for the same model manager.create_api(self.Person, methods=['GET', 'POST']) manager.create_api(self.Person, methods=['PATCH'], url_prefix='/api2') manager.create_api(self.Person, methods=['GET'], url_prefix='/readonly') # test that specified endpoints exist response = self.app.post('/api/person', data=dumps(dict(name='foo'))) assert response.status_code == 201 assert loads(response.data)['id'] == 1 response = self.app.get('/api/person') assert response.status_code == 200 assert len(loads(response.data)['objects']) == 1 assert loads(response.data)['objects'][0]['id'] == 1 response = self.app.patch('/api2/person/1', data=dumps(dict(name='bar'))) assert response.status_code == 200 assert loads(response.data)['id'] == 1 assert loads(response.data)['name'] == 'bar' # test that the model is the same as before response = self.app.get('/readonly/person') assert response.status_code == 200 assert len(loads(response.data)['objects']) == 1 assert loads(response.data)['objects'][0]['id'] == 1 assert loads(response.data)['objects'][0]['name'] == 'bar'
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 init_manager(app, db): manager = APIManager(app, flask_sqlalchemy_db=db) # Create API endpoints, which will be available at /api/<tablename> by # default. Allowed HTTP methods can be specified as well. manager.create_api( User, methods=['GET', 'POST', 'DELETE'], preprocessors={ 'POST': [pre_post_user], }, ) manager.create_api(Post, methods=['GET', 'POST', 'DELETE']) manager.create_api(Picture, methods=['GET', 'POST', 'DELETE'])
def add_content(): manager = APIManager(app, flask_sqlalchemy_db=db) manager.create_api( User, methods=['GET'], url_prefix='/get', results_per_page=50, include_columns=['id', 'username', 'email', 'messages'], ) manager.create_api(User, methods=['POST'], url_prefix='/add') manager.create_api(Message, methods=['POST'], url_prefix='/add') add_users_messages() myuser_is = None test_followers = (3, 8, 2, 2, 7, 5, 1, 9, 3, 4) # followed users = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) # Add users follow relations i = 1 for j in test_followers: myuser_is = User.query.filter(User.username == 'user%s' % j).one() theuser = User.query.filter(User.username == 'user%s' % i).one() i += 1 u = myuser_is.follow(theuser) if u is None: print dict(message="You can't follow %s" % theuser.username) db.session.add(u) db.session.commit() # test users follow relations from database j = 1 for i in test_followers: flwr = User.query.filter(User.id == i).one() flwd = User.query.filter(User.id == j).one() j += 1 db.session.add(u) db.session.commit()
class FSATest(FlaskTestBase): """Tests which use models defined using Flask-SQLAlchemy instead of pure SQLAlchemy. """ def setUp(self): """Creates the Flask application, the APIManager, the database, and the Flask-SQLAlchemy models. """ super(FSATest, self).setUp() # initialize SQLAlchemy and Flask-Restless self.db = SQLAlchemy(self.flaskapp) self.manager = APIManager(self.flaskapp, flask_sqlalchemy_db=self.db) # for the sake of brevity... db = self.db # declare the models class Computer(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.Unicode, unique=True) vendor = db.Column(db.Unicode) buy_date = db.Column(db.DateTime) owner_id = db.Column(db.Integer, db.ForeignKey('person.id')) owner = db.relationship('Person', backref=db.backref('computers', lazy='dynamic')) class Person(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.Unicode, unique=True) age = db.Column(db.Float) other = db.Column(db.Float) birth_date = db.Column(db.Date) self.Person = Person self.Computer = Computer # create all the tables required for the models self.db.create_all() def tearDown(self): """Drops all tables from the temporary database.""" self.db.drop_all() def test_flask_sqlalchemy(self): """Tests that :class:`flask.ext.restless.APIManager` correctly exposes models defined using Flask-SQLAlchemy. """ # create three different APIs for the same model self.manager.create_api(self.Person, methods=['GET', 'POST']) self.manager.create_api(self.Person, methods=['PATCH'], url_prefix='/api2') self.manager.create_api(self.Person, methods=['GET'], url_prefix='/readonly') # test that specified endpoints exist response = self.app.post('/api/person', data=dumps(dict(name='foo'))) assert response.status_code == 201 assert loads(response.data)['id'] == 1 response = self.app.get('/api/person') assert response.status_code == 200 assert len(loads(response.data)['objects']) == 1 assert loads(response.data)['objects'][0]['id'] == 1 response = self.app.patch('/api2/person/1', data=dumps(dict(name='bar'))) assert response.status_code == 200 assert loads(response.data)['id'] == 1 assert loads(response.data)['name'] == 'bar' # test that the model is the same as before response = self.app.get('/readonly/person') assert response.status_code == 200 assert len(loads(response.data)['objects']) == 1 assert loads(response.data)['objects'][0]['id'] == 1 assert loads(response.data)['objects'][0]['name'] == 'bar'
#coding=utf8 from veterans.main import veteransApp from models import * from flask.ext.restless import APIManager # using restless # init the manager manager = APIManager(veteransApp, flask_sqlalchemy_db=db) # api for drug manager.create_api(drug, methods=['GET', 'POST', 'DELETE', 'PUT'], preprocessors=dict(POST=[drug.post_preprocessor]), postprocessors=dict(GET_MANY=[drug.get_all])) # api for fixedrecipe manager.create_api(fixedrecipe, methods=['GET', 'POST', 'DELETE', 'PUT'], preprocessors=dict(POST=[fixedrecipe.post_preprocessor]), postprocessors=dict(GET_MANY=[fixedrecipe.get_all])) # api for fixedrecipeItem manager.create_api( fixedrecipeItem, methods=['GET', 'POST', 'DELETE', 'PUT'], preprocessors=dict(POST=[fixedrecipeItem.post_preprocessor]), postprocessors=dict(GET_MANY=[fixedrecipeItem.get_all])) # api for chinese_disease manager.create_api(ChineseDisease,
class Person(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.Unicode) #birth_date = db.Column(db.Date) class PersonSchema(Schema): id = fields.Integer() name = fields.String() def make_object(self, data): return Person(**data) person_schema = PersonSchema() def person_serializer(instance): return person_schema.dump(instance).data def person_deserializer(data): return person_schema.load(data).data db.create_all() manager = APIManager(app, flask_sqlalchemy_db=db) manager.create_api(Person, methods=['GET', 'POST'], serializer=person_serializer, deserializer=person_deserializer) app.run()
measurement = db.Column(db.Integer) # FK to Measurement Object name = db.Column(db.Text) description = db.Column(db.Text) class Reading(db.Model): id = db.Column(db.Integer, primary_key=True) sensor = db.Column(db.Integer) # FK to Sensor firefighter = db.Column(db.Integer) # FK to Firefighter measurement_object = db.Column(db.Integer) # FK to Measurement Object value = db.Column(db.Integer) # The value being read timestamp = db.Column(db.Text) # The timestamp of the reading db.create_all() api_manager = APIManager(app, flask_sqlalchemy_db=db) api_manager.create_api(Firefighter, methods=['GET', 'POST', 'DELETE', 'PUT'], results_per_page=-1) api_manager.create_api(Sensor, methods=['GET', 'POST', 'DELETE', 'PUT']) api_manager.create_api(MeasurementObject, methods=['GET', 'POST', 'DELETE', 'PUT']) api_manager.create_api(Type, methods=['GET', 'POST', 'DELETE', 'PUT']) api_manager.create_api(Reading, methods=['GET', 'POST', 'DELETE', 'PUT'], results_per_page=-1) if __name__ == "__main__": app.debug = True app.run(host='0.0.0.0', port=5001, use_reloader=True)