{"id":1985,"date":"2024-06-26T18:18:07","date_gmt":"2024-06-26T18:18:07","guid":{"rendered":"https:\/\/www.w3computing.com\/articles\/?p=1985"},"modified":"2024-06-26T18:27:01","modified_gmt":"2024-06-26T18:27:01","slug":"building-scalable-web-apis-with-flask-and-sqlalchemy","status":"publish","type":"post","link":"https:\/\/www.w3computing.com\/articles\/building-scalable-web-apis-with-flask-and-sqlalchemy\/","title":{"rendered":"Building Scalable Web APIs with Flask and SQLAlchemy"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Building scalable web APIs is a critical skill in modern software development. Flask, a micro web framework for Python, and SQLAlchemy, a SQL toolkit and Object-Relational Mapping (ORM) library, are two powerful tools that can help you achieve this. This tutorial will guide you through creating a scalable web API using Flask and SQLAlchemy, focusing on best practices and advanced techniques suitable for non-beginners.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Prerequisites<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Before we begin, ensure you have the following prerequisites:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Python 3.6+ installed<\/li>\n\n\n\n<li>Basic understanding of Flask and SQLAlchemy<\/li>\n\n\n\n<li>Familiarity with RESTful APIs<\/li>\n\n\n\n<li>Basic knowledge of Docker (optional but recommended)<\/li>\n\n\n\n<li>Basic understanding of Git<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">1. Setting Up the Environment<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Installing Required Packages<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">First, let&#8217;s set up a virtual environment and install the required packages. Open your terminal and run the following commands:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"Arduino\" data-shcb-language-slug=\"arduino\"><span><code class=\"hljs language-arduino\"># Create a <span class=\"hljs-keyword\">virtual<\/span> environment\npython3 -m venv venv\n\n# Activate the <span class=\"hljs-keyword\">virtual<\/span> environment\n# On Windows\nvenv\\Scripts\\activate\n# On macOS\/Linux\nsource venv\/bin\/activate\n\n# Install Flask <span class=\"hljs-keyword\">and<\/span> SQLAlchemy\npip install Flask SQLAlchemy Flask-Migrate Flask-JWT-Extended<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Arduino<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">arduino<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Setting Up the Database<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">For this tutorial, we will use PostgreSQL as our database. Make sure you have PostgreSQL installed and running on your machine. Create a new database:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\"><span class=\"hljs-comment\"># Replace 'your_db_user' and 'your_db_password' with your PostgreSQL credentials<\/span>\ncreatedb flask_api_db<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">2. Project Structure<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A well-structured project is crucial for scalability. Here&#8217;s a recommended project structure:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Markdown\" data-shcb-language-slug=\"markdown\"><span><code class=\"hljs language-markdown\">flask_api\/\n\u251c\u2500\u2500 app\/\n\u2502   \u251c\u2500\u2500 <span class=\"hljs-strong\">__init__<\/span>.py\n\u2502   \u251c\u2500\u2500 config.py\n\u2502   \u251c\u2500\u2500 models.py\n\u2502   \u251c\u2500\u2500 routes\/\n\u2502   \u2502   \u251c\u2500\u2500 <span class=\"hljs-strong\">__init__<\/span>.py\n\u2502   \u2502   \u251c\u2500\u2500 user_routes.py\n\u2502   \u2502   \u2514\u2500\u2500 item_routes.py\n\u2502   \u251c\u2500\u2500 services\/\n\u2502   \u2502   \u251c\u2500\u2500 <span class=\"hljs-strong\">__init__<\/span>.py\n\u2502   \u2502   \u251c\u2500\u2500 user_service.py\n\u2502   \u2502   \u2514\u2500\u2500 item_service.py\n\u2502   \u251c\u2500\u2500 utils\/\n\u2502   \u2502   \u251c\u2500\u2500 <span class=\"hljs-strong\">__init__<\/span>.py\n\u2502   \u2502   \u251c\u2500\u2500 pagination.py\n\u2502   \u2502   \u2514\u2500\u2500 error_handlers.py\n\u251c\u2500\u2500 migrations\/\n\u251c\u2500\u2500 tests\/\n\u2502   \u251c\u2500\u2500 <span class=\"hljs-strong\">__init__<\/span>.py\n\u2502   \u251c\u2500\u2500 test_user.py\n\u2502   \u2514\u2500\u2500 test_item.py\n\u251c\u2500\u2500 Dockerfile\n\u251c\u2500\u2500 requirements.txt\n\u251c\u2500\u2500 run.py<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Markdown<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">markdown<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">3. Initializing Flask and SQLAlchemy<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Creating the Application Factory<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In <code>app\/__init__.py<\/code>, create an application factory function:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> flask <span class=\"hljs-keyword\">import<\/span> Flask\n<span class=\"hljs-keyword\">from<\/span> flask_sqlalchemy <span class=\"hljs-keyword\">import<\/span> SQLAlchemy\n<span class=\"hljs-keyword\">from<\/span> flask_migrate <span class=\"hljs-keyword\">import<\/span> Migrate\n<span class=\"hljs-keyword\">from<\/span> flask_jwt_extended <span class=\"hljs-keyword\">import<\/span> JWTManager\n<span class=\"hljs-keyword\">from<\/span> .config <span class=\"hljs-keyword\">import<\/span> Config\n\ndb = SQLAlchemy()\nmigrate = Migrate()\njwt = JWTManager()\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">create_app<\/span><span class=\"hljs-params\">(config_class=Config)<\/span>:<\/span>\n    app = Flask(__name__)\n    app.config.from_object(config_class)\n\n    db.init_app(app)\n    migrate.init_app(app, db)\n    jwt.init_app(app)\n\n    <span class=\"hljs-keyword\">from<\/span> .routes <span class=\"hljs-keyword\">import<\/span> user_routes, item_routes\n    app.register_blueprint(user_routes.bp)\n    app.register_blueprint(item_routes.bp)\n\n    <span class=\"hljs-keyword\">from<\/span> .utils.error_handlers <span class=\"hljs-keyword\">import<\/span> register_error_handlers\n    register_error_handlers(app)\n\n    <span class=\"hljs-keyword\">return<\/span> app<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Configuration<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Create a <code>config.py<\/code> file in the <code>app<\/code> directory to store the configuration:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">import<\/span> os\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Config<\/span>:<\/span>\n    SECRET_KEY = os.environ.get(<span class=\"hljs-string\">'SECRET_KEY'<\/span>) <span class=\"hljs-keyword\">or<\/span> <span class=\"hljs-string\">'you-will-never-guess'<\/span>\n    SQLALCHEMY_DATABASE_URI = os.environ.get(<span class=\"hljs-string\">'DATABASE_URL'<\/span>) <span class=\"hljs-keyword\">or<\/span> <span class=\"hljs-string\">'postgresql:\/\/your_db_user:your_db_password@localhost\/flask_api_db'<\/span>\n    SQLALCHEMY_TRACK_MODIFICATIONS = <span class=\"hljs-literal\">False<\/span>\n    JWT_SECRET_KEY = os.environ.get(<span class=\"hljs-string\">'JWT_SECRET_KEY'<\/span>) <span class=\"hljs-keyword\">or<\/span> <span class=\"hljs-string\">'super-secret'<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Entry Point<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Create a <code>run.py<\/code> file at the root of your project:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> app <span class=\"hljs-keyword\">import<\/span> create_app\n\napp = create_app()\n\n<span class=\"hljs-keyword\">if<\/span> __name__ == <span class=\"hljs-string\">'__main__'<\/span>:\n    app.run()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">4. Creating Models<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In <code>app\/models.py<\/code>, define your database models. For this example, we will create <code>User<\/code> and <code>Item<\/code> models:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> datetime <span class=\"hljs-keyword\">import<\/span> datetime\n<span class=\"hljs-keyword\">from<\/span> werkzeug.security <span class=\"hljs-keyword\">import<\/span> generate_password_hash, check_password_hash\n<span class=\"hljs-keyword\">from<\/span> flask_sqlalchemy <span class=\"hljs-keyword\">import<\/span> SQLAlchemy\n\ndb = SQLAlchemy()\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">User<\/span><span class=\"hljs-params\">(db.Model)<\/span>:<\/span>\n    id = db.Column(db.Integer, primary_key=<span class=\"hljs-literal\">True<\/span>)\n    username = db.Column(db.String(<span class=\"hljs-number\">64<\/span>), index=<span class=\"hljs-literal\">True<\/span>, unique=<span class=\"hljs-literal\">True<\/span>, nullable=<span class=\"hljs-literal\">False<\/span>)\n    email = db.Column(db.String(<span class=\"hljs-number\">120<\/span>), index=<span class=\"hljs-literal\">True<\/span>, unique=<span class=\"hljs-literal\">True<\/span>, nullable=<span class=\"hljs-literal\">False<\/span>)\n    password_hash = db.Column(db.String(<span class=\"hljs-number\">128<\/span>), nullable=<span class=\"hljs-literal\">False<\/span>)\n    created_at = db.Column(db.DateTime, default=datetime.utcnow)\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">set_password<\/span><span class=\"hljs-params\">(self, password)<\/span>:<\/span>\n        self.password_hash = generate_password_hash(password)\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">check_password<\/span><span class=\"hljs-params\">(self, password)<\/span>:<\/span>\n        <span class=\"hljs-keyword\">return<\/span> check_password_hash(self.password_hash, password)\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Item<\/span><span class=\"hljs-params\">(db.Model)<\/span>:<\/span>\n    id = db.Column(db.Integer, primary_key=<span class=\"hljs-literal\">True<\/span>)\n    name = db.Column(db.String(<span class=\"hljs-number\">128<\/span>), nullable=<span class=\"hljs-literal\">False<\/span>)\n    description = db.Column(db.String(<span class=\"hljs-number\">256<\/span>))\n    user_id = db.Column(db.Integer, db.ForeignKey(<span class=\"hljs-string\">'user.id'<\/span>), nullable=<span class=\"hljs-literal\">False<\/span>)\n    created_at = db.Column(db.DateTime, default=datetime.utcnow)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">5. Database Migrations<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Initializing Migrations<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Initialize migrations with Flask-Migrate:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">flask db init\nflask db migrate -m <span class=\"hljs-string\">\"Initial migration\"<\/span>\nflask db upgrade<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Running Migrations<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Whenever you make changes to your models, run the following commands to update the database schema:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">flask db migrate -m <span class=\"hljs-string\">\"Describe your change\"<\/span>\nflask db upgrade<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">6. Creating and Registering Blueprints<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Blueprints help you organize your application into modules. In <code>app\/routes\/user_routes.py<\/code>, define routes related to users:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> flask <span class=\"hljs-keyword\">import<\/span> Blueprint, request, jsonify\n<span class=\"hljs-keyword\">from<\/span> app.models <span class=\"hljs-keyword\">import<\/span> User, db\n\nbp = Blueprint(<span class=\"hljs-string\">'user_routes'<\/span>, __name__)\n\n<span class=\"hljs-meta\">@bp.route('\/users', methods=&#91;'POST'])<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">create_user<\/span><span class=\"hljs-params\">()<\/span>:<\/span>\n    data = request.get_json()\n    username = data.get(<span class=\"hljs-string\">'username'<\/span>)\n    email = data.get(<span class=\"hljs-string\">'email'<\/span>)\n    password = data.get(<span class=\"hljs-string\">'password'<\/span>)\n\n    <span class=\"hljs-keyword\">if<\/span> <span class=\"hljs-keyword\">not<\/span> username <span class=\"hljs-keyword\">or<\/span> <span class=\"hljs-keyword\">not<\/span> email <span class=\"hljs-keyword\">or<\/span> <span class=\"hljs-keyword\">not<\/span> password:\n        <span class=\"hljs-keyword\">return<\/span> jsonify({<span class=\"hljs-string\">'error'<\/span>: <span class=\"hljs-string\">'Missing required fields'<\/span>}), <span class=\"hljs-number\">400<\/span>\n\n    user = User(username=username, email=email)\n    user.set_password(password)\n\n    db.session.add(user)\n    db.session.commit()\n\n    <span class=\"hljs-keyword\">return<\/span> jsonify({<span class=\"hljs-string\">'id'<\/span>: user.id, <span class=\"hljs-string\">'username'<\/span>: user.username, <span class=\"hljs-string\">'email'<\/span>: user.email}), <span class=\"hljs-number\">201<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In <code>app\/routes\/item_routes.py<\/code>, define routes related to items:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> flask <span class=\"hljs-keyword\">import<\/span> Blueprint, request, jsonify\n<span class=\"hljs-keyword\">from<\/span> app.models <span class=\"hljs-keyword\">import<\/span> Item, db\n\nbp = Blueprint(<span class=\"hljs-string\">'item_routes'<\/span>, __name__)\n\n<span class=\"hljs-meta\">@bp.route('\/items', methods=&#91;'POST'])<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">create_item<\/span><span class=\"hljs-params\">()<\/span>:<\/span>\n    data = request.get_json()\n    name = data.get(<span class=\"hljs-string\">'name'<\/span>)\n    description = data.get(<span class=\"hljs-string\">'description'<\/span>)\n    user_id = data.get(<span class=\"hljs-string\">'user_id'<\/span>)\n\n    <span class=\"hljs-keyword\">if<\/span> <span class=\"hljs-keyword\">not<\/span> name <span class=\"hljs-keyword\">or<\/span> <span class=\"hljs-keyword\">not<\/span> user_id:\n        <span class=\"hljs-keyword\">return<\/span> jsonify({<span class=\"hljs-string\">'error'<\/span>: <span class=\"hljs-string\">'Missing required fields'<\/span>}), <span class=\"hljs-number\">400<\/span>\n\n    item = Item(name=name, description=description, user_id=user_id)\n\n    db.session.add(item)\n    db.session.commit()\n\n    <span class=\"hljs-keyword\">return<\/span> jsonify({<span class=\"hljs-string\">'id'<\/span>: item.id, <span class=\"hljs-string\">'name'<\/span>: item.name, <span class=\"hljs-string\">'description'<\/span>: item.description, <span class=\"hljs-string\">'user_id'<\/span>: item.user_id}), <span class=\"hljs-number\">201<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">7. Implementing CRUD Operations<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">User Routes<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Extend the <code>user_routes.py<\/code> with additional CRUD operations:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-meta\">@bp.route('\/users\/&lt;int:id&gt;', methods=&#91;'GET'])<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">get_user<\/span><span class=\"hljs-params\">(id)<\/span>:<\/span>\n    user = User.query.get_or_404(id)\n    <span class=\"hljs-keyword\">return<\/span> jsonify({<span class=\"hljs-string\">'id'<\/span>: user.id, <span class=\"hljs-string\">'username'<\/span>: user.username, <span class=\"hljs-string\">'email'<\/span>: user.email})\n\n<span class=\"hljs-meta\">@bp.route('\/users\/&lt;int:id&gt;', methods=&#91;'PUT'])<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">update_user<\/span><span class=\"hljs-params\">(id)<\/span>:<\/span>\n    user = User.query.get_or_404(id)\n    data = request.get_json()\n\n    user.username = data.get(<span class=\"hljs-string\">'username'<\/span>, user.username)\n    user.email = data.get(<span class=\"hljs-string\">'email'<\/span>, user.email)\n    <span class=\"hljs-keyword\">if<\/span> <span class=\"hljs-string\">'password'<\/span> <span class=\"hljs-keyword\">in<\/span> data:\n        user.set_password(data&#91;<span class=\"hljs-string\">'password'<\/span>])\n\n    db.session.commit()\n    <span class=\"hljs-keyword\">return<\/span> jsonify({<span class=\"hljs-string\">'id'<\/span>: user.id, <span class=\"hljs-string\">'username'<\/span>: user.username, <span class=\"hljs-string\">'email'<\/span>: user.email})\n\n<span class=\"hljs-meta\">@bp.route('\/users\/&lt;int:id&gt;', methods=&#91;'DELETE'])<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">delete_user<\/span><span class=\"hljs-params\">(id)<\/span>:<\/span>\n    user = User.query.get_or_404(id)\n    db.session.delete(user)\n    db.session.commit()\n    <span class=\"hljs-keyword\">return<\/span> jsonify({<span class=\"hljs-string\">'message'<\/span>: <span class=\"hljs-string\">'User deleted'<\/span>})<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Item Routes<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Extend the <code>item_routes.py<\/code> with additional CRUD operations:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-meta\">@bp.route('\/items\/&lt;int:id&gt;', methods=&#91;'GET'])<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">get_item<\/span><span class=\"hljs-params\">(id)<\/span>:<\/span>\n    item = Item.query.get_or_404(id)\n    <span class=\"hljs-keyword\">return<\/span> jsonify({<span class=\"hljs-string\">'id'<\/span>: item.id, <span class=\"hljs-string\">'name'<\/span>: item.name, <span class=\"hljs-string\">'description'<\/span>: item.description, <span class=\"hljs-string\">'user_id'<\/span>: item.user_id})\n\n<span class=\"hljs-meta\">@bp.route('\/items\/&lt;int:id&gt;', methods=&#91;'PUT'])<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">update_item<\/span>\n\n<span class=\"hljs-params\">(id)<\/span>:<\/span>\n    item = Item.query.get_or_404(id)\n    data = request.get_json()\n\n    item.name = data.get(<span class=\"hljs-string\">'name'<\/span>, item.name)\n    item.description = data.get(<span class=\"hljs-string\">'description'<\/span>, item.description)\n\n    db.session.commit()\n    <span class=\"hljs-keyword\">return<\/span> jsonify({<span class=\"hljs-string\">'id'<\/span>: item.id, <span class=\"hljs-string\">'name'<\/span>: item.name, <span class=\"hljs-string\">'description'<\/span>: item.description, <span class=\"hljs-string\">'user_id'<\/span>: item.user_id})\n\n<span class=\"hljs-meta\">@bp.route('\/items\/&lt;int:id&gt;', methods=&#91;'DELETE'])<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">delete_item<\/span><span class=\"hljs-params\">(id)<\/span>:<\/span>\n    item = Item.query.get_or_404(id)\n    db.session.delete(item)\n    db.session.commit()\n    <span class=\"hljs-keyword\">return<\/span> jsonify({<span class=\"hljs-string\">'message'<\/span>: <span class=\"hljs-string\">'Item deleted'<\/span>})<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">8. Adding Authentication and Authorization<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">User Registration and Login<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In <code>user_routes.py<\/code>, add routes for user registration and login:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> flask_jwt_extended <span class=\"hljs-keyword\">import<\/span> create_access_token, jwt_required, get_jwt_identity\n\n<span class=\"hljs-meta\">@bp.route('\/register', methods=&#91;'POST'])<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">register<\/span><span class=\"hljs-params\">()<\/span>:<\/span>\n    data = request.get_json()\n    username = data.get(<span class=\"hljs-string\">'username'<\/span>)\n    email = data.get(<span class=\"hljs-string\">'email'<\/span>)\n    password = data.get(<span class=\"hljs-string\">'password'<\/span>)\n\n    <span class=\"hljs-keyword\">if<\/span> <span class=\"hljs-keyword\">not<\/span> username <span class=\"hljs-keyword\">or<\/span> <span class=\"hljs-keyword\">not<\/span> email <span class=\"hljs-keyword\">or<\/span> <span class=\"hljs-keyword\">not<\/span> password:\n        <span class=\"hljs-keyword\">return<\/span> jsonify({<span class=\"hljs-string\">'error'<\/span>: <span class=\"hljs-string\">'Missing required fields'<\/span>}), <span class=\"hljs-number\">400<\/span>\n\n    <span class=\"hljs-keyword\">if<\/span> User.query.filter_by(username=username).first():\n        <span class=\"hljs-keyword\">return<\/span> jsonify({<span class=\"hljs-string\">'error'<\/span>: <span class=\"hljs-string\">'Username already exists'<\/span>}), <span class=\"hljs-number\">400<\/span>\n\n    <span class=\"hljs-keyword\">if<\/span> User.query.filter_by(email=email).first():\n        <span class=\"hljs-keyword\">return<\/span> jsonify({<span class=\"hljs-string\">'error'<\/span>: <span class=\"hljs-string\">'Email already exists'<\/span>}), <span class=\"hljs-number\">400<\/span>\n\n    user = User(username=username, email=email)\n    user.set_password(password)\n\n    db.session.add(user)\n    db.session.commit()\n\n    access_token = create_access_token(identity=user.id)\n    <span class=\"hljs-keyword\">return<\/span> jsonify({<span class=\"hljs-string\">'access_token'<\/span>: access_token}), <span class=\"hljs-number\">201<\/span>\n\n<span class=\"hljs-meta\">@bp.route('\/login', methods=&#91;'POST'])<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">login<\/span><span class=\"hljs-params\">()<\/span>:<\/span>\n    data = request.get_json()\n    username = data.get(<span class=\"hljs-string\">'username'<\/span>)\n    password = data.get(<span class=\"hljs-string\">'password'<\/span>)\n\n    <span class=\"hljs-keyword\">if<\/span> <span class=\"hljs-keyword\">not<\/span> username <span class=\"hljs-keyword\">or<\/span> <span class=\"hljs-keyword\">not<\/span> password:\n        <span class=\"hljs-keyword\">return<\/span> jsonify({<span class=\"hljs-string\">'error'<\/span>: <span class=\"hljs-string\">'Missing required fields'<\/span>}), <span class=\"hljs-number\">400<\/span>\n\n    user = User.query.filter_by(username=username).first()\n\n    <span class=\"hljs-keyword\">if<\/span> user <span class=\"hljs-keyword\">is<\/span> <span class=\"hljs-literal\">None<\/span> <span class=\"hljs-keyword\">or<\/span> <span class=\"hljs-keyword\">not<\/span> user.check_password(password):\n        <span class=\"hljs-keyword\">return<\/span> jsonify({<span class=\"hljs-string\">'error'<\/span>: <span class=\"hljs-string\">'Invalid credentials'<\/span>}), <span class=\"hljs-number\">400<\/span>\n\n    access_token = create_access_token(identity=user.id)\n    <span class=\"hljs-keyword\">return<\/span> jsonify({<span class=\"hljs-string\">'access_token'<\/span>: access_token}), <span class=\"hljs-number\">200<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Protecting Routes<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Protect routes using JWT:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-meta\">@bp.route('\/protected', methods=&#91;'GET'])<\/span>\n<span class=\"hljs-meta\">@jwt_required()<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">protected<\/span><span class=\"hljs-params\">()<\/span>:<\/span>\n    current_user = get_jwt_identity()\n    user = User.query.get(current_user)\n    <span class=\"hljs-keyword\">return<\/span> jsonify({<span class=\"hljs-string\">'username'<\/span>: user.username, <span class=\"hljs-string\">'email'<\/span>: user.email}), <span class=\"hljs-number\">200<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">9. Implementing Pagination and Filtering<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Create a utility for pagination in <code>app\/utils\/pagination.py<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> flask <span class=\"hljs-keyword\">import<\/span> request\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">paginate<\/span><span class=\"hljs-params\">(query, model)<\/span>:<\/span>\n    page = request.args.get(<span class=\"hljs-string\">'page'<\/span>, <span class=\"hljs-number\">1<\/span>, type=int)\n    per_page = request.args.get(<span class=\"hljs-string\">'per_page'<\/span>, <span class=\"hljs-number\">10<\/span>, type=int)\n    pagination = query.paginate(page, per_page, <span class=\"hljs-literal\">False<\/span>)\n    items = &#91;item.to_dict() <span class=\"hljs-keyword\">for<\/span> item <span class=\"hljs-keyword\">in<\/span> pagination.items]\n    <span class=\"hljs-keyword\">return<\/span> {\n        <span class=\"hljs-string\">'items'<\/span>: items,\n        <span class=\"hljs-string\">'total'<\/span>: pagination.total,\n        <span class=\"hljs-string\">'page'<\/span>: page,\n        <span class=\"hljs-string\">'per_page'<\/span>: per_page,\n    }<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Add a method in the models to convert objects to dictionaries:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">User<\/span><span class=\"hljs-params\">(db.Model)<\/span>:<\/span>\n    <span class=\"hljs-comment\"># ...<\/span>\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">to_dict<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        <span class=\"hljs-keyword\">return<\/span> {\n            <span class=\"hljs-string\">'id'<\/span>: self.id,\n            <span class=\"hljs-string\">'username'<\/span>: self.username,\n            <span class=\"hljs-string\">'email'<\/span>: self.email,\n            <span class=\"hljs-string\">'created_at'<\/span>: self.created_at.isoformat()\n        }\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Item<\/span><span class=\"hljs-params\">(db.Model)<\/span>:<\/span>\n    <span class=\"hljs-comment\"># ...<\/span>\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">to_dict<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        <span class=\"hljs-keyword\">return<\/span> {\n            <span class=\"hljs-string\">'id'<\/span>: self.id,\n            <span class=\"hljs-string\">'name'<\/span>: self.name,\n            <span class=\"hljs-string\">'description'<\/span>: self.description,\n            <span class=\"hljs-string\">'user_id'<\/span>: self.user_id,\n            <span class=\"hljs-string\">'created_at'<\/span>: self.created_at.isoformat()\n        }<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Use pagination in your routes:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> app.utils.pagination <span class=\"hljs-keyword\">import<\/span> paginate\n\n<span class=\"hljs-meta\">@bp.route('\/users', methods=&#91;'GET'])<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">get_users<\/span><span class=\"hljs-params\">()<\/span>:<\/span>\n    query = User.query\n    <span class=\"hljs-keyword\">return<\/span> jsonify(paginate(query, User))<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">10. Error Handling<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Create custom error handlers in <code>app\/utils\/error_handlers.py<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-19\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> flask <span class=\"hljs-keyword\">import<\/span> jsonify\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">register_error_handlers<\/span><span class=\"hljs-params\">(app)<\/span>:<\/span>\n<span class=\"hljs-meta\">    @app.errorhandler(404)<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">not_found_error<\/span><span class=\"hljs-params\">(error)<\/span>:<\/span>\n        <span class=\"hljs-keyword\">return<\/span> jsonify({<span class=\"hljs-string\">'error'<\/span>: <span class=\"hljs-string\">'Not found'<\/span>}), <span class=\"hljs-number\">404<\/span>\n\n<span class=\"hljs-meta\">    @app.errorhandler(500)<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">internal_error<\/span><span class=\"hljs-params\">(error)<\/span>:<\/span>\n        <span class=\"hljs-keyword\">return<\/span> jsonify({<span class=\"hljs-string\">'error'<\/span>: <span class=\"hljs-string\">'Internal server error'<\/span>}), <span class=\"hljs-number\">500<\/span>\n\n<span class=\"hljs-meta\">    @app.errorhandler(400)<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">bad_request_error<\/span><span class=\"hljs-params\">(error)<\/span>:<\/span>\n        <span class=\"hljs-keyword\">return<\/span> jsonify({<span class=\"hljs-string\">'error'<\/span>: <span class=\"hljs-string\">'Bad request'<\/span>}), <span class=\"hljs-number\">400<\/span>\n\n<span class=\"hljs-meta\">    @app.errorhandler(401)<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">unauthorized_error<\/span><span class=\"hljs-params\">(error)<\/span>:<\/span>\n        <span class=\"hljs-keyword\">return<\/span> jsonify({<span class=\"hljs-string\">'error'<\/span>: <span class=\"hljs-string\">'Unauthorized'<\/span>}), <span class=\"hljs-number\">401<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-19\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Register error handlers in the application factory:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-20\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">create_app<\/span><span class=\"hljs-params\">(config_class=Config)<\/span>:<\/span>\n    app = Flask(__name__)\n    app.config.from_object(config_class)\n\n    db.init_app(app)\n    migrate.init_app(app, db)\n    jwt.init_app(app)\n\n    <span class=\"hljs-keyword\">from<\/span> .routes <span class=\"hljs-keyword\">import<\/span> user_routes, item_routes\n    app.register_blueprint(user_routes.bp)\n    app.register_blueprint(item_routes.bp)\n\n    <span class=\"hljs-keyword\">from<\/span> .utils.error_handlers <span class=\"hljs-keyword\">import<\/span> register_error_handlers\n    register_error_handlers(app)\n\n    <span class=\"hljs-keyword\">return<\/span> app<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-20\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">11. Testing the API<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Setting Up Testing Environment<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Create a <code>tests<\/code> directory with an <code>__init__.py<\/code> file to hold your test cases.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Writing Tests<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Write tests for user routes in <code>tests\/test_user.py<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-21\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">import<\/span> unittest\n<span class=\"hljs-keyword\">from<\/span> app <span class=\"hljs-keyword\">import<\/span> create_app, db\n<span class=\"hljs-keyword\">from<\/span> app.models <span class=\"hljs-keyword\">import<\/span> User\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">UserTestCase<\/span><span class=\"hljs-params\">(unittest.TestCase)<\/span>:<\/span>\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">setUp<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        self.app = create_app()\n        self.app_context = self.app.app_context()\n        self.app_context.push()\n        self.client = self.app.test_client()\n\n        db.create_all()\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">tearDown<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        db.session.remove()\n        db.drop_all()\n        self.app_context.pop()\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">test_user_registration<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        response = self.client.post(<span class=\"hljs-string\">'\/users'<\/span>, json={\n            <span class=\"hljs-string\">'username'<\/span>: <span class=\"hljs-string\">'testuser'<\/span>,\n            <span class=\"hljs-string\">'email'<\/span>: <span class=\"hljs-string\">'test@example.com'<\/span>,\n            <span class=\"hljs-string\">'password'<\/span>: <span class=\"hljs-string\">'password'<\/span>\n        })\n        self.assertEqual(response.status_code, <span class=\"hljs-number\">201<\/span>)\n        self.assertIn(<span class=\"hljs-string\">'access_token'<\/span>, response.get_json())\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">test_user_login<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        user = User(username=<span class=\"hljs-string\">'testuser'<\/span>, email=<span class=\"hljs-string\">'test@example.com'<\/span>)\n        user.set_password(<span class=\"hljs-string\">'password'<\/span>)\n        db.session.add(user)\n        db.session.commit()\n\n        response = self.client.post(<span class=\"hljs-string\">'\/login'<\/span>, json={\n            <span class=\"hljs-string\">'username'<\/span>: <span class=\"hljs-string\">'testuser'<\/span>,\n            <span class=\"hljs-string\">'password'<\/span>: <span class=\"hljs-string\">'password'<\/span>\n        })\n        self.assertEqual(response.status_code, <span class=\"hljs-number\">200<\/span>)\n        self.assertIn(<span class=\"hljs-string\">'access_token'<\/span>, response.get_json())\n\n<span class=\"hljs-keyword\">if<\/span> __name__ == <span class=\"hljs-string\">'__main__'<\/span>:\n    unittest.main()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-21\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Run your tests:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-22\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">python -m unittest discover tests<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-22\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">12. Optimizing for Scalability<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Database Indexing<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Ensure you have proper indexing on frequently queried columns:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-23\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">User<\/span><span class=\"hljs-params\">(db.Model)<\/span>:<\/span>\n    __tablename__ = <span class=\"hljs-string\">'users'<\/span>\n    id = db.Column(db.Integer, primary_key=<span class=\"hljs-literal\">True<\/span>)\n    username = db.Column(db.String(<span class=\"hljs-number\">64<\/span>), index=<span class=\"hljs-literal\">True<\/span>, unique=<span class=\"hljs-literal\">True<\/span>, nullable=<span class=\"hljs-literal\">False<\/span>)\n    email = db.Column(db.String(<span class=\"hljs-number\">120<\/span>), index=<span class=\"hljs-literal\">True<\/span>, unique=<span class=\"hljs-literal\">True<\/span>, nullable=<span class=\"hljs-literal\">False<\/span>)\n    <span class=\"hljs-comment\"># ...<\/span>\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Item<\/span><span class=\"hljs-params\">(db.Model)<\/span>:<\/span>\n    __tablename__ = <span class=\"hljs-string\">'items'<\/span>\n    id = db.Column(db.Integer, primary_key=<span class=\"hljs-literal\">True<\/span>)\n    name = db.Column(db.String(<span class=\"hljs-number\">128<\/span>), index=<span class=\"hljs-literal\">True<\/span>, nullable=<span class=\"hljs-literal\">False<\/span>)\n    user_id = db.Column(db.Integer, db.ForeignKey(<span class=\"hljs-string\">'users.id'<\/span>), index=<span class=\"hljs-literal\">True<\/span>, nullable=<span class=\"hljs-literal\">False<\/span>)\n    <span class=\"hljs-comment\"># ...<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-23\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Caching<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Implement caching to reduce database load:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-24\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> flask_caching <span class=\"hljs-keyword\">import<\/span> Cache\n\ncache = Cache()\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">create_app<\/span><span class=\"hljs-params\">(config_class=Config)<\/span>:<\/span>\n    app = Flask(__name__)\n    app.config.from_object(config_class)\n\n    db.init_app(app)\n    migrate.init_app(app, db)\n    jwt.init_app(app)\n    cache.init_app(app, config={<span class=\"hljs-string\">'CACHE_TYPE'<\/span>: <span class=\"hljs-string\">'simple'<\/span>})\n\n    <span class=\"hljs-comment\"># ...<\/span>\n\n    <span class=\"hljs-keyword\">return<\/span> app\n\n<span class=\"hljs-meta\">@bp.route('\/items\/&lt;int:id&gt;', methods=&#91;'GET'])<\/span>\n<span class=\"hljs-meta\">@cache.cached(timeout=60, key_prefix='item_{id}')<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">get_item<\/span><span class=\"hljs-params\">(id)<\/span>:<\/span>\n    item = Item.query.get_or_404(id)\n    <span class=\"hljs-keyword\">return<\/span> jsonify(item.to_dict())<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-24\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Load Balancing<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Use a load balancer like Nginx to distribute incoming traffic across multiple instances of your Flask application.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">13. Deployment with Docker<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Dockerfile<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Create a <code>Dockerfile<\/code> at the root of your project:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-25\" data-shcb-language-name=\"Dockerfile\" data-shcb-language-slug=\"dockerfile\"><span><code class=\"hljs language-dockerfile\"><span class=\"hljs-comment\"># Use an official Python runtime as a parent image<\/span>\n<span class=\"hljs-keyword\">FROM<\/span> python:<span class=\"hljs-number\">3.9<\/span>-slim\n\n<span class=\"hljs-comment\"># Set the working directory<\/span>\n<span class=\"hljs-keyword\">WORKDIR<\/span><span class=\"bash\"> \/app<\/span>\n\n<span class=\"hljs-comment\"># Copy the current directory contents into the container<\/span>\n<span class=\"hljs-keyword\">ADD<\/span><span class=\"bash\"> . \/app<\/span>\n\n<span class=\"hljs-comment\"># Install any needed packages specified in requirements.txt<\/span>\n<span class=\"hljs-keyword\">RUN<\/span><span class=\"bash\"> pip install --upgrade pip<\/span>\n<span class=\"hljs-keyword\">RUN<\/span><span class=\"bash\"> pip install -r requirements.txt<\/span>\n\n<span class=\"hljs-comment\"># Make port 80 available to the world outside this container<\/span>\n<span class=\"hljs-keyword\">EXPOSE<\/span> <span class=\"hljs-number\">80<\/span>\n\n<span class=\"hljs-comment\"># Run app.py when the container launches<\/span>\n<span class=\"hljs-keyword\">CMD<\/span><span class=\"bash\"> &#91;<span class=\"hljs-string\">\"python\"<\/span>, <span class=\"hljs-string\">\"run.py\"<\/span>]<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-25\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Dockerfile<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">dockerfile<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Docker Compose<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Create a <code>docker-compose.yml<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-26\" data-shcb-language-name=\"YAML\" data-shcb-language-slug=\"yaml\"><span><code class=\"hljs language-yaml\"><span class=\"hljs-attr\">version:<\/span> <span class=\"hljs-string\">'3.8'<\/span>\n\n<span class=\"hljs-attr\">services:<\/span>\n  <span class=\"hljs-attr\">db:<\/span>\n    <span class=\"hljs-attr\">image:<\/span> <span class=\"hljs-string\">postgres:13<\/span>\n    <span class=\"hljs-attr\">environment:<\/span>\n      <span class=\"hljs-attr\">POSTGRES_USER:<\/span> <span class=\"hljs-string\">your_db_user<\/span>\n      <span class=\"hljs-attr\">POSTGRES_PASSWORD:<\/span> <span class=\"hljs-string\">your_db_password<\/span>\n      <span class=\"hljs-attr\">POSTGRES_DB:<\/span> <span class=\"hljs-string\">flask_api_db<\/span>\n    <span class=\"hljs-attr\">ports:<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">\"5432:5432\"<\/span>\n\n  <span class=\"hljs-attr\">web:<\/span>\n    <span class=\"hljs-attr\">build:<\/span> <span class=\"hljs-string\">.<\/span>\n    <span class=\"hljs-attr\">command:<\/span> <span class=\"hljs-string\">python<\/span> <span class=\"hljs-string\">run.py<\/span>\n    <span class=\"hljs-attr\">ports:<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">\"5000:80\"<\/span>\n    <span class=\"hljs-attr\">depends_on:<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">db<\/span>\n    <span class=\"hljs-attr\">environment:<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">DATABASE_URL=postgresql:\/\/your_db_user:your_db_password@db\/flask_api_db<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">SECRET_KEY=your<\/span>\n\n<span class=\"hljs-string\">_secret_key<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">JWT_SECRET_KEY=your_jwt_secret_key<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-26\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">YAML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">yaml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Building and Running the Containers<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Build and run your Docker containers:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-27\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">docker-compose up --build<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-27\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">14. Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Congratulations! You have built a scalable web API using Flask and SQLAlchemy. This tutorial covered setting up the environment, project structure, initializing Flask and SQLAlchemy, creating models, implementing CRUD operations, adding authentication and authorization, implementing pagination and filtering, error handling, testing, optimizing for scalability, and deploying with Docker.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Building scalable web APIs is a critical skill in modern software development. Flask, a micro web framework for Python, and SQLAlchemy, a SQL toolkit and Object-Relational Mapping (ORM) library, are two powerful tools that can help you achieve this. This tutorial will guide you through creating a scalable web API using Flask and SQLAlchemy, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[4,6],"tags":[],"class_list":["post-1985","post","type-post","status-publish","format-standard","category-programming-languages","category-python","entry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Building Scalable Web APIs with Flask and SQLAlchemy<\/title>\n<meta name=\"description\" content=\"Flask, combined with SQLAlchemy, a powerful SQL toolkit and ORM library, provides a robust foundation for building scalable APIs.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.w3computing.com\/articles\/building-scalable-web-apis-with-flask-and-sqlalchemy\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Building Scalable Web APIs with Flask and SQLAlchemy\" \/>\n<meta property=\"og:description\" content=\"Flask, combined with SQLAlchemy, a powerful SQL toolkit and ORM library, provides a robust foundation for building scalable APIs.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.w3computing.com\/articles\/building-scalable-web-apis-with-flask-and-sqlalchemy\/\" \/>\n<meta property=\"article:published_time\" content=\"2024-06-26T18:18:07+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-06-26T18:27:01+00:00\" \/>\n<meta name=\"author\" content=\"w3compadmin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"w3compadmin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"TechArticle\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/building-scalable-web-apis-with-flask-and-sqlalchemy\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/building-scalable-web-apis-with-flask-and-sqlalchemy\\\/\"},\"author\":{\"name\":\"w3compadmin\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\"},\"headline\":\"Building Scalable Web APIs with Flask and SQLAlchemy\",\"datePublished\":\"2024-06-26T18:18:07+00:00\",\"dateModified\":\"2024-06-26T18:27:01+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/building-scalable-web-apis-with-flask-and-sqlalchemy\\\/\"},\"wordCount\":506,\"articleSection\":[\"Programming Languages\",\"Python\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/building-scalable-web-apis-with-flask-and-sqlalchemy\\\/\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/building-scalable-web-apis-with-flask-and-sqlalchemy\\\/\",\"name\":\"Building Scalable Web APIs with Flask and SQLAlchemy\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#website\"},\"datePublished\":\"2024-06-26T18:18:07+00:00\",\"dateModified\":\"2024-06-26T18:27:01+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\"},\"description\":\"Flask, combined with SQLAlchemy, a powerful SQL toolkit and ORM library, provides a robust foundation for building scalable APIs.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/building-scalable-web-apis-with-flask-and-sqlalchemy\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/building-scalable-web-apis-with-flask-and-sqlalchemy\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/building-scalable-web-apis-with-flask-and-sqlalchemy\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Articles Home\",\"item\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Programming Languages\",\"item\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/programming-languages\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Python\",\"item\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/programming-languages\\\/python\\\/\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Building Scalable Web APIs with Flask and SQLAlchemy\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#website\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/\",\"name\":\"Developer Articles Hub\",\"description\":\"\",\"alternateName\":\"Developer Articles\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\",\"name\":\"w3compadmin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266\",\"contentUrl\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266\",\"caption\":\"w3compadmin\"},\"sameAs\":[\"http:\\\/\\\/w3computing.com\\\/articles\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Building Scalable Web APIs with Flask and SQLAlchemy","description":"Flask, combined with SQLAlchemy, a powerful SQL toolkit and ORM library, provides a robust foundation for building scalable APIs.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.w3computing.com\/articles\/building-scalable-web-apis-with-flask-and-sqlalchemy\/","og_locale":"en_US","og_type":"article","og_title":"Building Scalable Web APIs with Flask and SQLAlchemy","og_description":"Flask, combined with SQLAlchemy, a powerful SQL toolkit and ORM library, provides a robust foundation for building scalable APIs.","og_url":"https:\/\/www.w3computing.com\/articles\/building-scalable-web-apis-with-flask-and-sqlalchemy\/","article_published_time":"2024-06-26T18:18:07+00:00","article_modified_time":"2024-06-26T18:27:01+00:00","author":"w3compadmin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"w3compadmin","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"TechArticle","@id":"https:\/\/www.w3computing.com\/articles\/building-scalable-web-apis-with-flask-and-sqlalchemy\/#article","isPartOf":{"@id":"https:\/\/www.w3computing.com\/articles\/building-scalable-web-apis-with-flask-and-sqlalchemy\/"},"author":{"name":"w3compadmin","@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561"},"headline":"Building Scalable Web APIs with Flask and SQLAlchemy","datePublished":"2024-06-26T18:18:07+00:00","dateModified":"2024-06-26T18:27:01+00:00","mainEntityOfPage":{"@id":"https:\/\/www.w3computing.com\/articles\/building-scalable-web-apis-with-flask-and-sqlalchemy\/"},"wordCount":506,"articleSection":["Programming Languages","Python"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.w3computing.com\/articles\/building-scalable-web-apis-with-flask-and-sqlalchemy\/","url":"https:\/\/www.w3computing.com\/articles\/building-scalable-web-apis-with-flask-and-sqlalchemy\/","name":"Building Scalable Web APIs with Flask and SQLAlchemy","isPartOf":{"@id":"https:\/\/www.w3computing.com\/articles\/#website"},"datePublished":"2024-06-26T18:18:07+00:00","dateModified":"2024-06-26T18:27:01+00:00","author":{"@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561"},"description":"Flask, combined with SQLAlchemy, a powerful SQL toolkit and ORM library, provides a robust foundation for building scalable APIs.","breadcrumb":{"@id":"https:\/\/www.w3computing.com\/articles\/building-scalable-web-apis-with-flask-and-sqlalchemy\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.w3computing.com\/articles\/building-scalable-web-apis-with-flask-and-sqlalchemy\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.w3computing.com\/articles\/building-scalable-web-apis-with-flask-and-sqlalchemy\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Articles Home","item":"https:\/\/www.w3computing.com\/articles\/"},{"@type":"ListItem","position":2,"name":"Programming Languages","item":"https:\/\/www.w3computing.com\/articles\/programming-languages\/"},{"@type":"ListItem","position":3,"name":"Python","item":"https:\/\/www.w3computing.com\/articles\/programming-languages\/python\/"},{"@type":"ListItem","position":4,"name":"Building Scalable Web APIs with Flask and SQLAlchemy"}]},{"@type":"WebSite","@id":"https:\/\/www.w3computing.com\/articles\/#website","url":"https:\/\/www.w3computing.com\/articles\/","name":"Developer Articles Hub","description":"","alternateName":"Developer Articles","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.w3computing.com\/articles\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561","name":"w3compadmin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266","url":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266","contentUrl":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266","caption":"w3compadmin"},"sameAs":["http:\/\/w3computing.com\/articles"]}]}},"featured_image_src":null,"featured_image_src_square":null,"author_info":{"display_name":"w3compadmin","author_link":"https:\/\/www.w3computing.com\/articles\/author\/w3compadmin\/"},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/1985","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/comments?post=1985"}],"version-history":[{"count":1,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/1985\/revisions"}],"predecessor-version":[{"id":1986,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/1985\/revisions\/1986"}],"wp:attachment":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/media?parent=1985"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/categories?post=1985"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/tags?post=1985"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}