Python Flask 및 Docker를 사용하여 REST API 마이크로 서비스 구축 및 배포
41416 단어 pythondockerflaskmicroservices
대상:
사용된 기술:
선결 조건:
어려움:⚡⚡중간의
설정:
pipenv가 설치되어 있는지 확인합니다.
pip install pipenv
그리고 프로젝트를 위한 디렉터리를 만들고 cd를 넣습니다mkdir FlaskBookApi/
cd FlaskBookApi/
그리고 pipenv를 사용하여 플라스크와 플라스크restful 패키지를 설치합니다.이것은 몇 가지 일을 할 것이다.pipenv install flask flask-restful
이것은python 가상 환경을 만들고 디렉터리 이름을 중심에 놓고 지정한 패키지를 설치합니다. (이 예는flask와flaskrestful입니다.)또한 작업 디렉터리에 모든 프로젝트 의존 항목과 그에 상응하는 버전 번호, 프로젝트에 사용된 Python 버전을 포함하는 Pipfile을 만들었습니다.PIP 파일도 작성했습니다.생산에서 확정적인 구축을 사용하기 위해 잠금합니다.이것은 pipenv 튜토리얼이 아니기 때문에 상세하게 소개하지 않겠습니다.
API 작성:
자, 이제 재미있는 부분!이 물건을 만들자!
먼저 작업 디렉토리에 Python 파일을 만듭니다.
touch api.py
위대하다flask 및 flask restful 가져오기 및 초기화from flask import Flask
from flask_restful import Resource, Api, reqparse, abort, marshal, fields
# Initialize Flask
app = Flask(__name__)
api = Api(app)
위에서 보듯이 flask restful에서 필요한 모듈을 가져오십시오.도서 데이터 저장소에서 기본적인 CRUD 작업을 수행하는 데 사용되는 간단한 API를 구축할 것입니다. (공교롭게도 이 예는 사전 목록입니다.)
우리는 간단한 Python 사전을 사용하여 저장할 것입니다. 그러나 필요하면 진정한 데이터베이스 솔루션과 쉽게 교환할 수 있습니다.그러나 간단하게 보기 위해서 나는 간단한 사전 목록을 사용하기로 결정했다
자, 시작합시다.먼저 단일 "Book"요소를 나타내는 여러 사전이 포함된 목록을 선언합니다.
# A List of Dicts to store all of the books
books = [{
"id": 1,
"title": "Zero to One",
"author": "Peter Thiel",
"length": 195,
"rating": 4.17
},
{
"id": 2,
"title": "Atomic Habits ",
"author": "James Clear",
"length": 319,
"rating": 4.35
}
]
그런 다음 API에서 예상한 대로 사전을 설정하여 책 객체의 모드를 결정합니다.이것은 나중에 요청을 검증하는 데 도움이 될 것이다.# Schema For the Book Request JSON
bookFields = {
"id": fields.Integer,
"title": fields.String,
"author": fields.String,
"length": fields.Integer,
"rating": fields.Float
}
Flask Restful은 Flask 마이크로 프레임워크의 확장으로 Restful API 구축이 더욱 쉬워졌습니다.restful이 제공하는 기본 구축 블록은 자원입니다.리소스는 리소스 클래스에서 메서드를 정의하여 여러 HTTP 메서드에 쉽게 액세스할 수 있습니다.
이것은 도서 자원 클래스입니다. 모든 도서 실체를 방문, 수정, 삭제하는 데 사용되는 HTTP 루트를 포함합니다.이제 우리 분석해 보자...
# Resource: Individual Book Routes
class Book(Resource):
def __init__(self):
# Initialize The Flsak Request Parser and add arguments as in an expected request
self.reqparse = reqparse.RequestParser()
self.reqparse.add_argument("title", type=str, location="json")
self.reqparse.add_argument("author", type=str, location="json")
self.reqparse.add_argument("length", type=int, location="json")
self.reqparse.add_argument("rating", type=float, location="json")
super(Book, self).__init__()
# GET - Returns a single book object given a matching id
def get(self, id):
book = [book for book in books if book['id'] == id]
if(len(book) == 0):
abort(404)
return{"book": marshal(book[0], bookFields)}
# PUT - Given an id
def put(self, id):
book = [book for book in books if book['id'] == id]
if len(book) == 0:
abort(404)
book = book[0]
# Loop Through all the passed agruments
args = self.reqparse.parse_args()
for k, v in args.items():
# Check if the passed value is not null
if v is not None:
# if not, set the element in the books dict with the 'k' object to the value provided in the request.
book[k] = v
return{"book": marshal(book, bookFields)}
# Delete - Given an id
def delete(self, id):
book = [book for book in books if book['id'] == id]
if(len(book) == 0):
abort(404)
books.remove(book[0])
return 201
우선, 클래스의 init 방법에서 요청 해상도를 초기화합니다.그것은 너로 하여금 플라스크의 어떤 변수도 쉽게 접근할 수 있게 할 수 있다.요청 및 제공된 매개 변수에 따라 응답 검증class Book(Resource):
def __init__(self):
# Initialize The Flsak Request Parser and add arguments as in an expected request
self.reqparse = reqparse.RequestParser()
self.reqparse.add_argument("title", type=str, location="json")
self.reqparse.add_argument("author", type=str, location="json")
self.reqparse.add_argument("length", type=int, location="json")
self.reqparse.add_argument("rating", type=float, location="json")
super(Book, self).__init__()
다음은 GET 방법입니다. 이 방법은 매우 간단합니다. 이 방법은 하나의 id를 받아들여 책 목록을 반복해서 훑어보고, 모든 요소의 id와 지정한 id를 검사합니다. 일치하는 항목을 찾으면 이 dict를 되돌려줍니다. marshal 방법은 되돌아오는 대상이 책 Fields dict에 정의된 필드를 통해 필터를 하는지 확인하는 것입니다.# GET - Returns a single book object given a matching id
def get(self, id):
book = [book for book in books if book['id'] == id]
if(len(book) == 0):
abort(404)
return{"book": marshal(book[0], bookFields)}
Put 방법은 지정한 id로 요소를 업데이트하는 데 사용됩니다. 우선 업데이트할 필드가 있는 응답 대상을 가져옵니다. 책 목록에서 순환하고, 지정한 id로 모든 요소의 id를 검사합니다. 일치하는 항목을 찾으면, Reqparser를 사용하여 모든 인자를 분석합니다.그리고 해석된 파라미터를 반복해서 반복해서 요청 대상의 필드를 업데이트합니다.
# PUT - Given an id
def put(self, id):
book = [book for book in books if book['id'] == id]
if len(book) == 0:
abort(404)
book = book[0]
# Loop Through all the passed agruments
args = self.reqparse.parse_args()
for k, v in args.items():
# Check if the passed value is not null
if v is not None:
# if not, set the element in the books dict with the 'k' object to the value provided in the request.
book[k] = v
return{"book": marshal(book, bookFields)}
Delete 방법은 단순히 id를 받아들인 다음 책의 목록에 있는 요소를 삭제합니다.# Delete - Given an id
def delete(self, id):
book = [book for book in books if book['id'] == id]
if(len(book) == 0):
abort(404)
books.remove(book[0])
return 201
다음은 전체 데이터베이스 작업을 처리하는 라우트를 포함하는 BookList 클래스입니다.class BookList(Resource):
def __init__(self):
self.reqparse = reqparse.RequestParser()
self.reqparse.add_argument(
"title", type=str, required=True, help="The title of the book must be provided", location="json")
self.reqparse.add_argument(
"author", type=str, required=True, help="The author of the book must be provided", location="json")
self.reqparse.add_argument("length", type=int, required=True,
help="The length of the book (in pages)", location="json")
self.reqparse.add_argument(
"rating", type=float, required=True, help="The rating must be provided", location="json")
def get(self):
return{"books": [marshal(book, bookFields) for book in books]}
def post(self):
args = self.reqparse.parse_args()
book = {
"id": books[-1]['id'] + 1 if len(books) > 0 else 1,
"title": args["title"],
"author": args["author"],
"length": args["length"],
"rating": args["rating"]
}
books.append(book)
return{"book": marshal(book, bookFields)}, 201
Init 메서드가 요청 파서를 초기화합니다.이것은 요청한 JSON 대상을 분석하고 제공된 매개 변수에 따라 검증합니다.def __init__(self):
self.reqparse = reqparse.RequestParser()
self.reqparse.add_argument(
"title", type=str, required=True, help="The title of the book must be provided", location="json")
self.reqparse.add_argument(
"author", type=str, required=True, help="The author of the book must be provided", location="json")
self.reqparse.add_argument("length", type=int, required=True,
help="The length of the book (in pages)", location="json")
self.reqparse.add_argument(
"rating", type=float, required=True, help="The rating must be provided", location="json")
Get 메서드는 books 목록의 모든 요소만 반환합니다.def get(self):
return{"books": [marshal(book, bookFields) for book in books]}
Post 메서드는 JSON 객체를 수락합니다.그것을 해석하고 새 dict를 만들어서 도서 목록에 추가합니다.def post(self):
args = self.reqparse.parse_args()
book = {
"id": books[-1]['id'] + 1 if len(books) > 0 else 1,
"title": args["title"],
"author": args["author"],
"length": args["length"],
"rating": args["rating"]
}
books.append(book)
return{"book": marshal(book, bookFields)}, 201
이렇게!이제 이 자원 클래스를 일부 단점에 추가하여 테스트하기만 하면 됩니다!api.add_resource(BookList, "/books")
api.add_resource(Book, "/books/<int:id>")
if __name__ == "__main__":
app.run(debug=True)
Docker에 배치하기
자, 이제 이 마이크로 서비스 API를 docker 용기에 배치합시다.
먼저 프로젝트 디렉토리에 Dockerfile을 만듭니다.
Docker 파일은 본질적으로 컨테이너가 사용할 청사진인 이미지를 구성하는 데 사용되는 명령 세트입니다.
우리 한 줄 한 줄 봅시다.
FROM python:3.8
RUN pip3 install pipenv
ENV PROJECT_DIR /usr/src/flaskbookapi
WORKDIR ${PROJECT_DIR}
COPY Pipfile .
COPY Pipfile.lock .
COPY . .
RUN pipenv install --deploy --ignore-pipfile
EXPOSE 5000
CMD ["pipenv", "run", "python", "api.py"]
이것은 Docker Hub의python 3.8 이미지를 우리의 기본 이미지로 사용하여python과 용기에 대한 모든 의존 관계를 확보합니다FROM python:3.8
이것은 용기에 pipenv를 설치할 것입니다.RUN pip3 install pipenv
첫 번째 줄은 환경 변수를 프로젝트 코드를 저장하는 디렉터리 경로로 설정합니다.그런 다음 다음 다음 명령을 사용하여 디렉토리를 작업 디렉토리로 설정합니다.
ENV PROJECT_DIR /usr/src/flaskbookapi
WORKDIR ${PROJECT_DIR}
다음에, 우리는 모든 파일을 용기에 복사할 것이다COPY Pipfile .
COPY Pipfile.lock .
COPY . .
이 명령은 - deploy 로고를 사용하여pipenv install를 실행하고 pipfile를 무시하고 pipfile만 사용하도록 설정합니다.종속성 설치를 위한 잠금RUN pipenv install --deploy --ignore-pipfile
다음은 5000 포트를 공개하여 사용하도록 하겠습니다.EXPOSE 5000
마지막으로 CMD 명령을 사용하여 프로그램을 실행합니다.CMD ["pipenv", "run", "python", "api.py"]
이제 Dockerfile을 사용하여 컨테이너를 만드는 데 사용할 이미지를 만듭니다.docker build -t flaskbookapi:1.0 .
이제, 드디어!우리가 방금 만든 그림으로 용기를 시작합니다!docker run -p 5000:5000 --name FlaskBookAPI flaskbookapi:1.0
쾅!Out API가 시작되고 실행됩니다!부두 컨테이너 위에서$ docker run -p 5000:5000 --name FlaskBookAPI flaskbookapi:1.0
* Serving Flask app "api" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
GitHub에서 항목을 다운로드하려면 다음과 같이 하십시오.
https://github.com/SwarnimWalavalkar/rest-api-microservice-docker
자세히 보기:
플라스크 파일: https://flask.palletsprojects.com/en/1.1.x/
Flast Restful 문서: https://flask-restful.readthedocs.io/en/latest/
Docker 문서: https://docs.docker.com/
Pipenv:https://pipenv-fork.readthedocs.io/en/latest/
Reference
이 문제에 관하여(Python Flask 및 Docker를 사용하여 REST API 마이크로 서비스 구축 및 배포), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/swarnimwalavalkar/build-and-deploy-a-rest-api-microservice-with-python-flask-and-docker-5c2d텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)