В этом руководстве я подробно расскажу, как создать приложение CRUD с помощью API RESTful, используя Flask. Если у вас есть данные, которыми вы хотите поделиться со всем миром, API - это один из способов получить их в руки других. Однако API-интерфейсы не всегда являются лучшим способом обмена данными с пользователями. Если размер предоставляемых вами данных относительно невелик, вы можете вместо этого предоставить «дамп данных» в виде загружаемого файла JSON или XML. Мы будем тестировать наши конечные точки с помощью PostMan, чтобы убедиться, что наши конечные точки работают. MYSQL - самая популярная система управления реляционными базами данных с открытым исходным кодом. Мы будем использовать MYSQL для сохранения наших записей в базе данных.
Предварительные требования:
1. Python3.
2. Сервер MYSQL загружен и готов к работе (будет рассмотрен подробно).
3. Flask (будет рассмотрен более подробно).
Настройка нашей серверной среды
Мы можем начать с загрузки сервера MYSQL https://dev.mysql.com/downloads/ и запуска его на вашем компьютере.
- Затем мы можем выполнить несколько команд перед созданием приложения:
$ pip3 install flask $ brew install mysql
- Теперь у нас есть среда, готовая начать работу с учебником.
Создание наших учетных данных для базы данных
В этом разделе рассказывается, как создавать учетные записи пользователей MYSQL и предоставлять привилегии.
- Чтобы получить доступ к оболочке MYSQL, введите следующую команду и при появлении запроса введите пароль пользователя root MYSQL:
$ mysql -u root -p
- Чтобы создать новую учетную запись пользователя MYSQL, выполните следующую команду:
mysql> CREATE USER 'newuser'@'localhost' IDENTIFIED BY 'user_password';
- Предоставьте все привилегии учетной записи пользователя во всех базах данных:
mysql> GRANT ALL PRIVILEGES ON *.* TO 'database_user'@'localhost';
- Имя создания базы данных:
mysql>
CREATE DATABASE database_name;
Давайте создадим дерево нашего проекта, чтобы начать кодирование
- Ниже вы можете просмотреть дерево проекта:
fullstack-blog/ app.py config.py Model.py run.py migrate.py requirements.txt resources/ Details.py TemplateRender.py User.py templates/ addDetails.html addUser.html main.html
- Для построения дерева проекта предусмотрены следующие команды:
$ mkdir fullstack-blog $ cd fullstack-blog $ touch app.py config.py Model.py run.py migrate.py requirements.txt $ mkdir resources templates $ cd resources $ touch Details.py TemplateRender.py User.py $ cd templates $ touch addDetails.html addUser.html
Теперь, когда окружение и дерево нашего проекта готовы, давайте запачкаем руки!
- В этой части основное внимание уделяется созданию серверной части путем создания таблиц в
Model.py
файле.
from flask import Flask from marshmallow import Schema, fields, pre_load, validate, ValidationError from flask_marshmallow import Marshmallow from flask_sqlalchemy import SQLAlchemy ma = Marshmallow() db = SQLAlchemy() class User(db.Model): __tablename__ = 'user' id = db.Column(db.Integer, primary_key=True) first_name = db.Column(db.String(150), nullable=False) last_name = db.Column(db.String(150), unique=True, nullable=False) details = db.relationship('Detailes', backref=db.backref('user', lazy=True)) def __init__(self, first_name, last_name): self.first_name = first_name self.last_name = last_name class Detailes(db.Model): __tablename__ = 'details' id = db.Column(db.Integer, primary_key=True) age = db.Column(db.Integer, unique=True, nullable=False) address = db.Column(db.String(150), unique=True, nullable=False) country_origin = db.Column(db.String(150), unique=True, nullable=False) user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=True) def __init__(self, age, address, country_origin): self.age = age self.address = address self.country_origin = country_origin class UserSchema(ma.Schema): id = fields.Integer(dump_only=True) first_name = fields.String(required=True) last_name = fields.String(required=True) class DetailesSchema(ma.Schema): id = fields.Integer(dump_only=True) age = fields.Integer(required=True) address = fields.String(required=True) country_origin = fields.String(required=True) user_id = fields.Integer(required=False)
- Этот фрагмент кода создает две таблицы: User и Details. Он также создал свои схемы для сериализации и десериализации данных.
- Обе таблицы имеют назначенные отношения один-ко-многим с использованием details = db.relationship ('Detailes', backref = db.backref ('user', lazy = True)) и user_id = db.Column (db.Integer, db. ForeignKey ('user.id'), nullable = True), чтобы предоставить FK, на который ссылается таблица User.
2. Затем создайте соединение с сервером базы данных MYSQL под файлом config.py
import os basedir = os.path.abspath(os.path.dirname(__file__)) SQLALCHEMY_ECHO = False SQLALCHEMY_TRACK_MODIFICATIONS = True SQLALCHEMY_DATABASE_URI = "mysql+pymysql://flask_user:1234@localhost/flaskapp"
- Помните, что мы создали пользователя в оболочке MYSQL и предоставили все привилегии учетной записи пользователя во всех базах данных. Теперь мы можем заменить имя пользователя вместо
flask_user
и созданный пароль вместо1234
./flaskapp
- это имя нашей базы данных, которую мы можем создать.
3. Теперь добавьте следующие изменения в run.py
файл, отвечающий за локальный запуск приложения flask.
from flask import Flask from flask_cors import CORS def create_app(config_filename): app = Flask(__name__) CORS(app) app.config.from_object(config_filename) from app import api_bp, template_bp app.register_blueprint(api_bp, url_prefix='/api') app.register_blueprint(template_bp, url_prefix='/') from Model import db db.init_app(app) return app if __name__ == "__main__": app = create_app("config") app.run(host='0.0.0.0')
- В этой части мы добавили чертежи к нашим двум основным конечным точкам
/api
и/
, в которых мы разделяем конечные точки, связанные с нашими API, и конечные точки, которые обрабатывают отрисовку наших шаблонов. Также мы добавили все необходимые строки, которые обрабатывают запуск нашего приложения локально. Мы можем запустить наше приложение с помощью командыpython3 run.py
, но я предпочитаю создавать файлы миграции перед этим.
4. Создайте миграции, чтобы перенести все изменения, добавленные в сервер базы данных MYSQL.
from flask_script import Manager from flask_migrate import Migrate, MigrateCommand from Model import db from run import create_app app = create_app('config') migrate = Migrate(app, db) manager = Manager(app) manager.add_command('db', MigrateCommand) if __name__=="__main__": manager.run()
- Теперь мы можем запустить файл
migrate.py
, используя следующие команды:
$ python3 migrate.py db init $ python3 migrate.py db migrate $ python3 migrate.py db upgrade
5. Если до сих пор все работает нормально, перейдите и создайте файлы в каталоге ресурсов. Следующий код добавляет изменения в User.py
файл:
from flask import request from flask_restful import Resource from Model import db, User, UserSchema import json users_schema = UserSchema(many=True) user_schema = UserSchema() class UserResource(Resource): @staticmethod def get(): users = User.query.all() users = json.dumps(users) return {'status': 'success', 'data': users}, 200 @staticmethod def post(): json_data = request.get_json(force=True) if not json_data: return {'message': 'No input data provided'}, 400 # Validate and deserialize input response = json.dumps(json_data) data = user_schema.loads(response) user = User.query.filter_by(first_name=data['first_name']).first() if user: return {'message': 'User already exists'}, 400 user = User( first_name=data['first_name'], last_name=data['last_name'] ) db.session.add(user) db.session.commit() result = user_schema.dump(user) return {"status": 'success', 'data': result}, 201
В этой части мы создали два метода Restful, GET
и POST
.
Мы также позаботились о том, чтобы в случае POST
запроса мы обрабатывали некоторые ошибки, которые могут возникнуть во время тестирования. Метод GET
будет отвечать за получение всех пользовательских записей, сохраненных в нашей базе данных. Метод POST
будет отвечать за добавление новых записей в нашу базу данных.
- Мы можем сделать то же самое для
Details
таблицы, но изменить все поля ввода данных, которые связаны сDetails
таблицей. - Двигаясь дальше, добавьте в
TemplateRender.py
код, который поможет в рендеринге шаблонов. У нас есть три шаблона: шаблонmain.html
, который считается шаблоном индекса проекта,addUser.html
иaddDetails.html
шаблоны, содержащие код, который выполняетPOST
запрос на добавление записей в нашу базу данных.
from flask import request, render_template, make_response from flask_restful import Resource class IndexResource(Resource): @staticmethod def get(): headers = {'Content-Type': 'text/html'} return make_response(render_template('main.html'),200,headers) class AddUser(Resource): @staticmethod def get(): headers = {'Content-Type': 'text/html'} return make_response(render_template('addUser.html'),200,headers) class AddDetails(Resource): @staticmethod def get(): headers = {'Content-Type': 'text/html'} return = make_response(render_template('addDetails.html'),200,headers)
- Здесь добавлено
GET
запросов на получение отрисованных шаблонов.
6. Эта часть создает все наши маршруты в файле app.py
.
from flask import Blueprint from flask_restful import Api from resources.User import UserResource from resources.Details import DetailsResource from resources.TemplateRender import IndexResource, AddUser, AddDetails api_bp = Blueprint('api', __name__) api = Api(api_bp) template_bp = Blueprint('template', __name__) template = Api(template_bp) # Route template.add_resource(IndexResource, '/') template.add_resource(AddUser, 'addUser') template.add_resource(AddDetails, 'addDetails') api.add_resource(UserResource, '/User') api.add_resource(DetailsResource, '/Details')
- Используя схему, обратите внимание, что мы создали две схемы: одну для
APIs
, а другую - для шаблонов. Эта часть также содержит все маршруты, которые будут использоваться в проекте. - Ниже вы можете найти таблицу с разбивкой всех возможных маршрутов и методов Restful на данный момент:
- Выполнение некоторых тестов с использованием POSTMAN на наших созданных конечных точках API:
POST-запрос для пользователя:
POST-запрос для получения подробной информации:
Получить запрос подробностей:
Чтобы дважды проверить, что метод POST вставил записи, предоставленные в таблицы базы данных, я использовал «SequelPro»:
7. Переходя к созданному простому интерфейсу, давайте добавим следующий код HTML, JavaScript и CSS в наш addUser.html
файл в директории templates
.
<!DOCTYPE html> <html> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> body {font-family: Arial, Helvetica, sans-serif;} * {box-sizing: border-box;} input[type=text], select, textarea { width: 100%; padding: 12px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; margin-top: 6px; margin-bottom: 16px; resize: vertical; } input[type=submit] { background-color: #4CAF50; color: white; padding: 12px 20px; border: none; border-radius: 4px; cursor: pointer; } input[type=submit]:hover { background-color: #45a049; } .container { border-radius: 5px; background-color: #f2f2f2; padding: 20px; } </style> </head> <body> <h3>User Form</h3> <div class="container"> <form action="/action_page.php"> <label for="fname">FirstName</label> <input type="text" id="fname" name="firstname" placeholder="First Name.."> <label for="lname">LastName</label> <input type="text" id="lname" name="lastname" placeholder="Last Name.."> <input id= "submit" type="submit" value="Submit"> </form> </div> <script type=text/javascript> $(document).ready(function () { var first_name = $('#fname').val(); var last_name = $('#lname').val(); $("#submit").click(function () { $.ajax({ type: 'POST', data: {first_name: first_name, last_name: last_name}, url: "https://0.0.0.0:5000/api/User" }); }); }); </script> </body> </html>
8. Заключительные шаги: все вместе:
- Чтобы проверить наши изменения, давайте запустим наше приложение, используя следующую команду:
$ python3 run.py
Идите вперед и получите доступ к нему локально, используя ваш браузер по URL-адресу https://0.0.0.0:5000/.
Вы можете увидеть шаблон main.html
, отображаемый, поскольку он является нашей точкой входа.
Если мы перешли по URL-адресу https://0.0.0.0:5000/addUser, то увидим, что шаблон addUser.html
визуализирован.
Вывод
- Мы узнали, как получить доступ и создать пользователя базы данных с помощью сервера MYSQL.
- Мы узнали, как создать дерево нашего проекта.
- Мы создали все Restful API проекта, используя фляжку и зефир.
- Мы создали схемы, чтобы отделить конечные точки API от конечных точек рендеринга шаблонов.
- Мы протестировали наши конечные точки API с помощью PostMan.
- Мы протестировали наши шаблоны, отображаемые локально, с использованием наших URL-адресов.
- Исходный код: https://github.com/Islamnader94/FlaskApp