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 setUp(self): app = Flask(__name__) self.engine = create_engine('sqlite://', echo=False) session = scoped_session( sessionmaker(autocommit=False, autoflush=False, bind=self.engine))() Base.metadata.create_all(bind=self.engine) session.bulk_save_objects( [Person(id=i, name=f'Person {i}') for i in range(1, 10001)]) session.bulk_save_objects([ Article(id=i, title=f'Title {i}', author_id=i % 3) for i in range(1, 101) ]) session.bulk_save_objects( [Comment(id=i, author_id=i, article_id=i) for i in range(1, 11)]) self.test_client = app.test_client() api_manager = APIManager(app=app, session=session, url_prefix='/api', include_links=False) api_manager.create_api(Person, collection_name='people', page_size=0) api_manager.create_api(Article, collection_name='articles', page_size=0) api_manager.create_api(Comment, collection_name='comments', page_size=0) self.profile = cProfile.Profile()
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 setup(self): manager = APIManager(self.app, session=self.session) manager.create_api(Article) manager.create_api(Person) Base.metadata.create_all(bind=self.engine) yield Base.metadata.drop_all(bind=self.engine)
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 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 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 if not self.swagger['host']: self.swagger['host'] = urlparse.urlparse( request.url_root).netloc return jsonify(self.swagger) @swagger.route('/swagger.yaml') def swagger_yaml(): # I can only get this from a request context if not self.swagger['host']: self.swagger['host'] = urlparse.urlparse( request.url_root).netloc return self.to_yaml() app.register_blueprint(swagger)
def create_app(): from .model import Data app = Flask(__name__) app.config.from_mapping(config) db.init_app(app) db.app = app db.create_all() cache.init_app(app) admin = Admin(app, name='covid19', template_mode='bootstrap3') admin.add_view(ModelView(Data, db.session)) def add_cors_headers(response): response.headers['Access-Control-Allow-Origin'] = '*' return response manager = APIManager(app, flask_sqlalchemy_db=db) blueprint = manager.create_api_blueprint( Data, app=app, results_per_page=-1, max_results_per_page=-1, postprocessors={'GET_MANY': [cache_postprocessor]}) blueprint.after_request(add_cors_headers) toolbar = DebugToolbarExtension(app) @app.before_request def preprocess_request(): return cache.get(get_cache_key()) return app
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 setup_app(config_name, app, database): """ Creates a JSON:API compliant REST application. :param config_name str: String name of the config. :param app: The application. :param database: SQLAlchemy database. """ # 0) Import models. SQLAlchemy requires this during app initialization. import models # 1) Set up appropriate app configs. app.config.from_object(config[config_name]) # 2) Set up CORS. CORS(app) # 3) Get JSON:API compliant endpoints, based on models. apimanager = APIManager(app, flask_sqlalchemy_db=database, preprocessors=dict(GET_MANY=[auth_func], GET_SINGLE=[auth_func], POST=[auth_func], DELETE=[auth_func])) apimanager.create_api(models.Item, methods=['GET', 'POST', 'DELETE']) apimanager.create_api(models.Group, methods=['GET', 'POST', 'DELETE']) apimanager.create_api(models.ItemImage, methods=['GET', 'POST', 'DELETE']) return apimanager
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_restless.APIManager.create_api """ manager = APIManager(self.app, flask_sqlalchemy_db=db) if hasattr(Module, 'endpoints'): if hasattr(Module, 'Model'): Seed_ = Module.endpoints.Seed() with self.app.app_context(): 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 setup(self): self.manager = APIManager(self.app, session=self.session) Base.metadata.create_all(bind=self.engine) self.session.add(Person(pk=1)) self.session.commit() yield Base.metadata.drop_all(bind=self.engine)
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 init_app(self, app, **kwargs): self.app = app self.manager = APIManager(self.app, **kwargs) if app and app.debug: host = app.config['HOST'] if host == '0.0.0.0': host = '127.0.0.1' self.swagger['servers'][0]['url'] = 'http://{}:{}/'.format( host, app.config['PORT']) if app.config['ESHOST']: self.swagger['servers'][0]['url'] = 'http://{}:{}/'.format( app.config['ESHOST'], app.config['PORT']) # self.swagger['servers'].append({ # 'url': 'http://127.0.0.1:5000/' # }) swaggerbp = Blueprint('swagger', __name__, static_folder='swagger_ui') @swaggerbp.route('/swagger') def swagger_ui(): return redirect('/swagger_ui/index.html') @swaggerbp.route('/swagger.json') def swagger_json(): # I can only get this from a request context return jsonify(self.swagger) app.register_blueprint(swaggerbp)
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 api(): with app.app_context(): api_manager = APIManager(app=app, session=db.session, url_prefix='', include_links=False) api_manager.create_api(Client, collection_name='clients', page_size=0) api_manager.create_api(Order, collection_name='orders', page_size=0) api_manager.create_api(Report, collection_name='reports', page_size=0) api_manager.create_api(Device, collection_name='devices', page_size=0) api_manager.create_api(Sheet, collection_name='sheets', page_size=0) db.drop_all() db.create_all() client = Client(id=1, name='Client') client.starred_orders.append(Order(id=1, client_id=1)) db.session.add(client) db.session.commit() db.session.bulk_save_objects( [Order(id=i, client_id=1) for i in range(2, 6)]) db.session.bulk_save_objects( [Order(id=i, client_id=1, archived=True) for i in range(6, 11)]) db.session.commit() yield app.test_client()
def register(self, db_clazz, db_session, plugin, methods=None, collection_name=None): """ Adds a new class-based view to the flask-admin instance. :param plugin: plugin which has registered the api :param methods: supported HTTP methods :param collection_name: :param db_clazz: SQLAlchemy class object :param db_session: session object :return: Name of the endpoint, which can be used to generate urls for it. """ # We must initialise the Flask-restless class. # This can not be done during pattern initialisation, because Flask gets loaded and configured during # activation phase. So during initialisation it is not available. if self.flask_restless is None: self.flask_restless = APIManager(self.app.web.flask, session=db_session) if methods is None: methods = ["GET", "POST", "DELETE", "PATCH", "PUT"] if collection_name is None: collection_name = db_clazz.__name__.lower() self.flask_restless.create_api(db_clazz, methods=methods, collection_name=collection_name) blueprint = self.app.web.flask.blueprints[collection_name + 'api0'] context = self.app.web.contexts.get('api', None) if blueprint is not None and context is None: context = self.app.web.contexts.register( name='api', template_folder=blueprint.template_folder, static_folder=blueprint.static_folder, url_prefix=blueprint.url_prefix, description='api panel context', plugin=plugin, blueprint=blueprint) routes = get_routes(self.app.web.flask, collection_name, context) for route in routes: reg_route = self.app.web.routes.register(route['url'], plugin, methods=route['methods'], name=route['name'], context=route['context']) for key, method in reg_route.methods.items(): for key, param in route['parameters'].items(): method.add_parameter(name=param['name'], data_type=param['type'], description=param['description'], path_type='path')
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 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 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) manager.create_api(Tag, methods=['GET', 'PATCH']) Base.metadata.create_all(bind=self.engine) yield Base.metadata.drop_all(bind=self.engine)
def create_api(app, db, endpoints): # Create the Flask-Restless API Manager manager = APIManager(app, flask_sqlalchemy_db=db) # Create API endpoints, available at /api/<tablename> by default. for endpoint in endpoints: manager.create_api(**endpoint) return manager
def create_app(config_mode=None, config_file=None): app = Flask(__name__) # app.register_blueprint(blueprint) CORS(app, resources=r'/*', allow_headers='Content-Type') compress.init_app(app) cache_config = {} if config_mode: app.config.from_object(getattr(config, config_mode)) elif config_file: app.config.from_pyfile(config_file) else: app.config.from_envvar('APP_SETTINGS', silent=True) db.init_app(app) if app.config.get('SERVER_NAME'): SSLify(app) if app.config['HEROKU']: cache_config['CACHE_TYPE'] = 'saslmemcached' cache_config['CACHE_MEMCACHED_SERVERS'] = [getenv('MEMCACHIER_SERVERS')] cache_config['CACHE_MEMCACHED_USERNAME'] = getenv('MEMCACHIER_USERNAME') cache_config['CACHE_MEMCACHED_PASSWORD'] = getenv('MEMCACHIER_PASSWORD') elif app.config['DEBUG_MEMCACHE']: cache_config['CACHE_TYPE'] = 'memcached' cache_config['CACHE_MEMCACHED_SERVERS'] = [getenv('MEMCACHE_SERVERS')] else: cache_config['CACHE_TYPE'] = 'simple' cache.init_app(app, config=cache_config) @app.route('/', methods=['GET']) def home(): return 'Welcome to the TodoMVC API!' @app.route('/reset/') def reset(): db.drop_all() db.create_all() return jsonify({'message': 'Database reset!'}) mgr = APIManager(app, flask_sqlalchemy_db=db) kwargs = { 'methods': app.config['API_METHODS'], 'validation_exceptions': API_EXCEPTIONS, 'allow_functions': app.config['API_ALLOW_FUNCTIONS'], 'allow_patch_many': app.config['API_ALLOW_PATCH_MANY'], 'allow_delete_many': app.config['ALLOW_DELETE_MANY'], 'max_results_per_page': app.config['API_MAX_RESULTS_PER_PAGE'], 'url_prefix': ''} with app.app_context(): mgr.create_api(Todo, **kwargs) return app
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)
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]}, )
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 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, methods=['POST', 'DELETE'])
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 init_api(): api_mgr = APIManager(app, flask_sqlalchemy_db=db) api_mgr.create_api(Device, methods=['GET', 'POST', 'PUT'], url_prefix='/api/v1', preprocessors=dict(GET_SINGLE=[protected], GET_MANY=[protected]), include_columns=[ 'id', 'sn', 'brand', 'model', 'latitude', 'longitude' ], primary_key='sn')
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_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) urls = document['meta']['urls'] self.assertEqual(sorted(urls), ['article', 'person']) self.assertTrue(urls['article'].endswith('/api/article')) self.assertTrue(urls['person'].endswith('/api/person'))