From 34907a044673b8558bcb898a4899cb9d5f0d0f6e Mon Sep 17 00:00:00 2001 From: Federico Pacheco Date: Sun, 10 Mar 2024 16:20:04 -0300 Subject: [PATCH] Update configurations and code formatting --- .env.dist | 1 + .github/pull_request_template.md | 16 +-- .github/workflows/linters.yml | 60 +++++----- Makefile | 52 ++++---- app/controller/calculator_controller.py | 28 ++--- app/controller/measurement_controller.py | 22 ++-- app/database/database.py | 9 +- app/exceptions/MeasurementsException.py | 8 +- app/exceptions/empty_package.py | 8 +- app/exceptions/invalid_insertion.py | 12 +- app/main.py | 112 +++++++++--------- app/main_rabbitmq.py | 64 +++++----- app/router/measurement_router.py | 34 +++--- app/schemas/schemas.py | 12 +- app/service/calculator_service.py | 9 +- app/service/rabbitmq/Dockerfile | 4 +- app/service/rabbitmq/consumer.py | 11 +- app/service/sql/Dockerfile | 30 ++--- app/service/sql/init_database_measurements.sh | 10 -- app/service/sql/init_table_device_plant.sh | 22 ---- app/service/sql/init_table_device_plant.sql | 17 +++ ...rements.sh => init_table_measurements.sql} | 11 +- docker-compose.yaml | 5 +- tox.ini | 2 +- 24 files changed, 259 insertions(+), 300 deletions(-) delete mode 100644 app/service/sql/init_database_measurements.sh delete mode 100644 app/service/sql/init_table_device_plant.sh create mode 100644 app/service/sql/init_table_device_plant.sql rename app/service/sql/{init_table_measurements.sh => init_table_measurements.sql} (69%) diff --git a/.env.dist b/.env.dist index e25f1ea..7467516 100644 --- a/.env.dist +++ b/.env.dist @@ -9,6 +9,7 @@ POSTGRES_HOST= POSTGRES_PORT= POSTGRES_DB= POSTGRES_SCHEMA= +DATABASE_URL= # RabbitMQ CLOUDAMQP_URL= diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index ab63f14..b4bcd61 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,8 +1,8 @@ -## Linked ticket in Jira -- https://hanagotchi.atlassian.net/jira/software/projects/HAN/boards/1/backlog - -## Describe your changes, marking the new features and possible risks -- - -## Media: upload photos or videos (if needed) -- +## Linked ticket in Jira +- https://hanagotchi.atlassian.net/jira/software/projects/HAN/boards/1/backlog + +## Describe your changes, marking the new features and possible risks +- + +## Media: upload photos or videos (if needed) +- diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index a12f030..dd17554 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -1,31 +1,31 @@ - -name: Linters - -on: 'push' - -jobs: - run-linters: - name: Run linters - runs-on: ubuntu-latest - - steps: - - name: Check out Git repository - uses: actions/checkout@v2 - - - name: Set up Python - uses: actions/setup-python@v1 - with: - python-version: 3.8 - - - name: Install Python dependencies - run: pip install black flake8 - - - name: Run linters - uses: wearerequired/lint-action@v1 - with: - black: true - - - name: flake8 Lint - uses: py-actions/flake8@v1.2.0 - with: + +name: Linters + +on: 'push' + +jobs: + run-linters: + name: Run linters + runs-on: ubuntu-latest + + steps: + - name: Check out Git repository + uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v1 + with: + python-version: 3.8 + + - name: Install Python dependencies + run: pip install black flake8 + + - name: Run linters + uses: wearerequired/lint-action@v1 + with: + black: true + + - name: flake8 Lint + uses: py-actions/flake8@v1.2.0 + with: max-line-length: "88" \ No newline at end of file diff --git a/Makefile b/Makefile index 7745f17..45df9b9 100644 --- a/Makefile +++ b/Makefile @@ -1,26 +1,26 @@ -default: docker-compose-up - -all: - -create-network: - @if ! docker network inspect common_network >/dev/null 2>&1; then \ - docker network create common_network; \ - fi -.PHONY: create-network - -docker-image: create-network - docker build -f ./Dockerfile -t "app:latest" . -.PHONY: docker-image - -docker-compose-up: docker-image - docker-compose -f docker-compose.yaml up -d --build -.PHONY: docker-compose-up - -docker-compose-down: - docker-compose -f docker-compose.yaml stop -t 20 - docker-compose -f docker-compose.yaml down --remove-orphans -.PHONY: docker-compose-down - -docker-compose-logs: - docker-compose -f docker-compose.yaml logs -f -.PHONY: docker-compose-logs +default: docker-compose-up + +all: + +create-network: + @if ! docker network inspect common_network >/dev/null 2>&1; then \ + docker network create common_network; \ + fi +.PHONY: create-network + +docker-image: create-network + docker build -f ./Dockerfile -t "app:latest" . +.PHONY: docker-image + +docker-compose-up: docker-image + docker-compose -f docker-compose.yaml up -d --build +.PHONY: docker-compose-up + +docker-compose-down: + docker-compose -f docker-compose.yaml stop -t 20 + docker-compose -f docker-compose.yaml down --remove-orphans +.PHONY: docker-compose-down + +docker-compose-logs: + docker-compose -f docker-compose.yaml logs -f +.PHONY: docker-compose-logs diff --git a/app/controller/calculator_controller.py b/app/controller/calculator_controller.py index c5e51f9..3c199a4 100644 --- a/app/controller/calculator_controller.py +++ b/app/controller/calculator_controller.py @@ -1,14 +1,14 @@ -from fastapi import status - - -class CalculatorController: - def __init__(self, service): - self.service = service - - def handle_sum(self, request): - sum = request.number1 + request.number2 - self.service.add_number(sum) - return { - 'result': sum, - 'status': status.HTTP_200_OK - } +from fastapi import status + + +class CalculatorController: + def __init__(self, service): + self.service = service + + def handle_sum(self, request): + sum = request.number1 + request.number2 + self.service.add_number(sum) + return { + 'result': sum, + 'status': status.HTTP_200_OK + } diff --git a/app/controller/measurement_controller.py b/app/controller/measurement_controller.py index 2081b56..786f038 100644 --- a/app/controller/measurement_controller.py +++ b/app/controller/measurement_controller.py @@ -1,11 +1,11 @@ -from controller.device_plant_controller import withSQLExceptionsHandle -from fastapi import Request - - -@withSQLExceptionsHandle -def last_measurement_made_by_plant(req: Request, id_plant: int): - try: - return req.app.database.get_last_measurement(id_plant) - except Exception as err: - req.app.database.rollback() - raise err +from controller.device_plant_controller import withSQLExceptionsHandle +from fastapi import Request + + +@withSQLExceptionsHandle +def last_measurement_made_by_plant(req: Request, id_plant: int): + try: + return req.app.database.get_last_measurement(id_plant) + except Exception as err: + req.app.database.rollback() + raise err diff --git a/app/database/database.py b/app/database/database.py index eba86dd..d405d14 100644 --- a/app/database/database.py +++ b/app/database/database.py @@ -12,14 +12,7 @@ class SQLAlchemyClient(): - db_url = environ.get("DATABASE_URL", engine.URL.create( - "postgres", - database=environ.get("POSTGRES_DB", "dev"), - username=environ.get("POSTGRES_USER", "user"), - password=environ.get("POSTGRES_PASSWORD", "1234"), - host=environ.get("POSTGRES_HOST", "sql"), - port=environ.get("POSTGRES_PORT", "5432") - )).replace("postgres://", "postgresql://", 1) + db_url = environ.get("DATABASE_URL").replace("postgres://", "postgresql://", 1) engine = create_engine(db_url) diff --git a/app/exceptions/MeasurementsException.py b/app/exceptions/MeasurementsException.py index 0f8dcff..e120ab3 100644 --- a/app/exceptions/MeasurementsException.py +++ b/app/exceptions/MeasurementsException.py @@ -1,4 +1,4 @@ -class MeasurementsException(Exception): - def __init__(self, status_code, message): - self.status_code = status_code - self.message = message +class MeasurementsException(Exception): + def __init__(self, status_code, message): + self.status_code = status_code + self.message = message diff --git a/app/exceptions/empty_package.py b/app/exceptions/empty_package.py index e4e579d..f3f7335 100644 --- a/app/exceptions/empty_package.py +++ b/app/exceptions/empty_package.py @@ -1,4 +1,4 @@ -class EmptyPackageError(Exception): - def __init__(self, empty_folds: list): - self.empty_folds = empty_folds - super().__init__(f"Package received with empty folds: {self.empty_folds}.") +class EmptyPackageError(Exception): + def __init__(self, empty_folds: list): + self.empty_folds = empty_folds + super().__init__(f"Package received with empty folds: {self.empty_folds}.") diff --git a/app/exceptions/invalid_insertion.py b/app/exceptions/invalid_insertion.py index e475325..dbd4394 100644 --- a/app/exceptions/invalid_insertion.py +++ b/app/exceptions/invalid_insertion.py @@ -1,6 +1,6 @@ -class InvalidInsertionError(Exception): - def __init__(self, item, name_table): - self.item = item - self.name_table = name_table - super().__init__( - f"Failed to insert {self.item} in {self.name_table.upper()} table.") +class InvalidInsertionError(Exception): + def __init__(self, item, name_table): + self.item = item + self.name_table = name_table + super().__init__( + f"Failed to insert {self.item} in {self.name_table.upper()} table.") diff --git a/app/main.py b/app/main.py index af2e18e..93a3a5a 100644 --- a/app/main.py +++ b/app/main.py @@ -1,56 +1,56 @@ -from fastapi import FastAPI -from database.database import SQLAlchemyClient -import logging -from controller.calculator_controller import CalculatorController -from schemas.schemas import Request as RequestSchema -from service.calculator_service import CalculatorService -from router import api_router - -app = FastAPI() -service = CalculatorService() -controller = CalculatorController(service) - -logger = logging.getLogger("measurements") -logger.setLevel("DEBUG") - - -@app.on_event("startup") -async def start_up(): - app.logger = logger - - try: - app.database = SQLAlchemyClient() - app.logger.info("Postgres connection established") - except Exception as e: - app.logger.error(e) - app.logger.error("Could not connect to Postgres client") - - -@app.on_event("shutdown") -async def shutdown_db_client(): - app.database.shutdown() - app.logger.info("Postgres shutdown succesfully") - - -@app.get("/") -async def root(): - return {"message": "Hello World"} - - -@app.post("/sum") -async def calculator(request: RequestSchema): - return controller.handle_sum(request) - - -""" # Endpoint only for DB conection testing. -@app.post("/device-plant") -async def add_new_device_plant(req: Request, - device_plant: DevicePlantSchema = Body(...)): - try: - req.app.database.add_new(DevicePlant.from_pydantic(device_plant)) - return req.app.database.find_device_plant(device_plant.id_device) - except Exception as e: - req.app.database.rollback() - raise e """ - -app.include_router(api_router) +from fastapi import FastAPI +from database.database import SQLAlchemyClient +import logging +from controller.calculator_controller import CalculatorController +from schemas.schemas import Request as RequestSchema +from service.calculator_service import CalculatorService +from router import api_router + +app = FastAPI() +service = CalculatorService() +controller = CalculatorController(service) + +logger = logging.getLogger("measurements") +logger.setLevel("DEBUG") + + +@app.on_event("startup") +async def start_up(): + app.logger = logger + + try: + app.database = SQLAlchemyClient() + app.logger.info("Postgres connection established") + except Exception as e: + app.logger.error(e) + app.logger.error("Could not connect to Postgres client") + + +@app.on_event("shutdown") +async def shutdown_db_client(): + app.database.shutdown() + app.logger.info("Postgres shutdown succesfully") + + +@app.get("/") +async def root(): + return {"message": "Hello World"} + + +@app.post("/sum") +async def calculator(request: RequestSchema): + return controller.handle_sum(request) + + +""" # Endpoint only for DB conection testing. +@app.post("/device-plant") +async def add_new_device_plant(req: Request, + device_plant: DevicePlantSchema = Body(...)): + try: + req.app.database.add_new(DevicePlant.from_pydantic(device_plant)) + return req.app.database.find_device_plant(device_plant.id_device) + except Exception as e: + req.app.database.rollback() + raise e """ + +app.include_router(api_router) diff --git a/app/main_rabbitmq.py b/app/main_rabbitmq.py index 95cdeb4..820d5e5 100644 --- a/app/main_rabbitmq.py +++ b/app/main_rabbitmq.py @@ -1,32 +1,32 @@ -import os -import logging -from service.rabbitmq.consumer import Consumer - - -def main(): - logger = logging.getLogger("rabbitmq_consumer") - # DEBUG, INFO, WARNING, ERROR, CRITICAL - logging_level = os.environ.get("LOGGING_LEVEL") - queue_name = os.environ.get("QUEUE_NAME") - initialize_log(logging_level) - consumer = Consumer(queue_name) - logger.info("[RABBITMQ] Starting consumer...") - consumer.run() - - -def initialize_log(logging_level): - """ - Python custom logging initialization - - Current timestamp is added to be able to identify in docker - compose logs the date when the log has arrived - """ - logging.basicConfig( - format='%(asctime)s %(levelname)-8s %(message)s', - level=logging_level, - datefmt='%Y-%m-%d %H:%M:%S', - ) - - -if __name__ == "__main__": - main() +import os +import logging +from service.rabbitmq.consumer import Consumer + + +def main(): + logger = logging.getLogger("rabbitmq_consumer") + # DEBUG, INFO, WARNING, ERROR, CRITICAL + logging_level = os.environ.get("LOGGING_LEVEL") + queue_name = os.environ.get("QUEUE_NAME") + initialize_log(logging_level) + consumer = Consumer(queue_name) + logger.info("[RABBITMQ] Starting consumer...") + consumer.run() + + +def initialize_log(logging_level): + """ + Python custom logging initialization + + Current timestamp is added to be able to identify in docker + compose logs the date when the log has arrived + """ + logging.basicConfig( + format='%(asctime)s %(levelname)-8s %(message)s', + level=logging_level, + datefmt='%Y-%m-%d %H:%M:%S', + ) + + +if __name__ == "__main__": + main() diff --git a/app/router/measurement_router.py b/app/router/measurement_router.py index d9dc607..6d2dcf6 100644 --- a/app/router/measurement_router.py +++ b/app/router/measurement_router.py @@ -1,17 +1,17 @@ -from fastapi import APIRouter, Request, status -from schemas.measurement import ( - MeasurementSavedSchema -) -from controller import measurement_controller as controller - - -measurement = APIRouter() - - -@measurement.get( - "/{id_plant}/last", - status_code=status.HTTP_200_OK, - response_model=MeasurementSavedSchema - ) -async def last_measurement_made_by_plant(id_plant: int, req: Request): - return controller.last_measurement_made_by_plant(req, id_plant) +from fastapi import APIRouter, Request, status +from schemas.measurement import ( + MeasurementSavedSchema +) +from controller import measurement_controller as controller + + +measurement = APIRouter() + + +@measurement.get( + "/{id_plant}/last", + status_code=status.HTTP_200_OK, + response_model=MeasurementSavedSchema + ) +async def last_measurement_made_by_plant(id_plant: int, req: Request): + return controller.last_measurement_made_by_plant(req, id_plant) diff --git a/app/schemas/schemas.py b/app/schemas/schemas.py index 1dc697f..3b014c6 100644 --- a/app/schemas/schemas.py +++ b/app/schemas/schemas.py @@ -1,6 +1,6 @@ -from pydantic import BaseModel - - -class Request(BaseModel): - number1: int - number2: int +from pydantic import BaseModel + + +class Request(BaseModel): + number1: int + number2: int diff --git a/app/service/calculator_service.py b/app/service/calculator_service.py index ab9419e..a3faaa7 100644 --- a/app/service/calculator_service.py +++ b/app/service/calculator_service.py @@ -6,14 +6,7 @@ class CalculatorService: def __init__(self): - engine_ = create_engine(environ.get("DATABASE_URL", engine.URL.create( - "postgres", - database=environ.get("POSTGRES_DB", "dev"), - username=environ.get("POSTGRES_USER", "user"), - password=environ.get("POSTGRES_PASSWORD", "1234"), - host=environ.get("POSTGRES_HOST", "sql"), - port=environ.get("POSTGRES_PORT", "5432") - )).replace("postgres://", "postgresql://", 1), echo=True) + engine_ = environ.get("DATABASE_URL").replace("postgres://", "postgresql://", 1) self.session = Session(engine_) def add_number(self, number): diff --git a/app/service/rabbitmq/Dockerfile b/app/service/rabbitmq/Dockerfile index 662c821..eeb1bda 100644 --- a/app/service/rabbitmq/Dockerfile +++ b/app/service/rabbitmq/Dockerfile @@ -1,3 +1,3 @@ -FROM rabbitmq:3.12-management -RUN apt-get update +FROM rabbitmq:3.12-management +RUN apt-get update RUN apt-get install -y curl \ No newline at end of file diff --git a/app/service/rabbitmq/consumer.py b/app/service/rabbitmq/consumer.py index 6a13a9d..2a7b7e2 100644 --- a/app/service/rabbitmq/consumer.py +++ b/app/service/rabbitmq/consumer.py @@ -18,19 +18,12 @@ from resources.parser import apply_rules from os import environ -Base = declarative_base(metadata=MetaData(schema='dev')) +Base = declarative_base(metadata=MetaData(schema=environ.get("POSTGRES_SCHEMA", "measurements"))) logger = logging.getLogger("rabbitmq_consumer") logging.getLogger("pika").setLevel(logging.WARNING) -dbUrl = environ.get("DATABASE_URL", engine.URL.create( - "postgres", - database=environ.get("POSTGRES_DB", "dev"), - username=environ.get("POSTGRES_USER", "user"), - password=environ.get("POSTGRES_PASSWORD", "1234"), - host=environ.get("POSTGRES_HOST", "sql"), - port=environ.get("POSTGRES_PORT", "5432") - )).replace("postgres://", "postgresql://", 1) +dbUrl = environ.get("DATABASE_URL").replace("postgres://", "postgresql://", 1) engine = create_engine(dbUrl, echo=True, future=True) session = Session(engine) diff --git a/app/service/sql/Dockerfile b/app/service/sql/Dockerfile index 66e5b99..6cdbc44 100644 --- a/app/service/sql/Dockerfile +++ b/app/service/sql/Dockerfile @@ -1,16 +1,16 @@ -FROM postgres:16 - -WORKDIR / - -ARG USE_POSTGIS=false - -RUN apt-get update \ - && apt-get install -f -y --no-install-recommends \ - ca-certificates \ - software-properties-common \ - build-essential \ - pkg-config \ - git \ - postgresql-server-dev-15 \ - && add-apt-repository "deb http://ftp.debian.org/debian testing main contrib" \ +FROM postgres:16 + +WORKDIR / + +ARG USE_POSTGIS=false + +RUN apt-get update \ + && apt-get install -f -y --no-install-recommends \ + ca-certificates \ + software-properties-common \ + build-essential \ + pkg-config \ + git \ + postgresql-server-dev-15 \ + && add-apt-repository "deb http://ftp.debian.org/debian testing main contrib" \ && apt-get update \ No newline at end of file diff --git a/app/service/sql/init_database_measurements.sh b/app/service/sql/init_database_measurements.sh deleted file mode 100644 index 852262c..0000000 --- a/app/service/sql/init_database_measurements.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -set -e -set -u - -echo " Creating user and database '$MEASUREMENTS_DB' " -psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL - CREATE DATABASE "$MEASUREMENTS_DB"; - GRANT ALL PRIVILEGES ON DATABASE "$MEASUREMENTS_DB" TO "$POSTGRES_USER"; -EOSQL \ No newline at end of file diff --git a/app/service/sql/init_table_device_plant.sh b/app/service/sql/init_table_device_plant.sh deleted file mode 100644 index 48fd4f3..0000000 --- a/app/service/sql/init_table_device_plant.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -set -e -psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$MEASUREMENTS_DB" <<-'EOSQL' - CREATE SCHEMA IF NOT EXISTS dev; - CREATE TABLE - IF NOT EXISTS dev.device_plant ( - id_device VARCHAR(32) PRIMARY KEY, - id_plant INT UNIQUE NOT NULL, - plant_type VARCHAR(70) NOT NULL, - id_user INT NOT NULL - ); - - DO $do$ BEGIN - IF (SELECT COUNT(*) FROM dev.device_plant) = 0 THEN - INSERT INTO dev.device_plant (id_device, id_plant, plant_type, id_user) VALUES - ('fd7c7531467748539f99d2bcef076c88', 1, 'Passiflora caerulea', 1), - ('fd8c7531467748539f99d2bcef076c88', 2, 'Kalanchoe daigremontiana', 2), - ('fd9c7531467748539f99d2bcef076c88', 3, 'Dracaena fragrans', 3); - END IF; - END $do$; -EOSQL \ No newline at end of file diff --git a/app/service/sql/init_table_device_plant.sql b/app/service/sql/init_table_device_plant.sql new file mode 100644 index 0000000..ffefdd9 --- /dev/null +++ b/app/service/sql/init_table_device_plant.sql @@ -0,0 +1,17 @@ + CREATE SCHEMA IF NOT EXISTS measurements; + CREATE TABLE + IF NOT EXISTS measurements.device_plant ( + id_device VARCHAR(32) PRIMARY KEY, + id_plant INT UNIQUE NOT NULL, + plant_type SMALLINT NOT NULL, + id_user INT NOT NULL + ); + + DO $do$ BEGIN + IF (SELECT COUNT(*) FROM measurements.device_plant) = 0 THEN + INSERT INTO measurements.device_plant (id_device, id_plant, plant_type, id_user) VALUES + ('fd7c7531467748539f99d2bcef076c88', 1, 1, 1), + ('fd8c7531467748539f99d2bcef076c88', 2, 2, 2), + ('fd9c7531467748539f99d2bcef076c88', 3, 3, 3); + END IF; + END $do$; \ No newline at end of file diff --git a/app/service/sql/init_table_measurements.sh b/app/service/sql/init_table_measurements.sql similarity index 69% rename from app/service/sql/init_table_measurements.sh rename to app/service/sql/init_table_measurements.sql index 5a7af7e..40f0deb 100644 --- a/app/service/sql/init_table_measurements.sh +++ b/app/service/sql/init_table_measurements.sql @@ -1,10 +1,6 @@ -#!/bin/bash - -set -e -psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$MEASUREMENTS_DB" <<-'EOSQL' - CREATE SCHEMA IF NOT EXISTS dev; + CREATE SCHEMA IF NOT EXISTS measurements; CREATE TABLE - IF NOT EXISTS dev.measurements ( + IF NOT EXISTS measurements.measurements ( id SERIAL PRIMARY KEY, id_plant INT, plant_type SMALLINT, @@ -19,5 +15,4 @@ psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$MEASUREMENTS_DB" watering >= 0 AND watering <= 100 ) - ); -EOSQL \ No newline at end of file + ); \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index 2a6b3a9..ef426cb 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -52,9 +52,8 @@ services: ports: - "5432:5432" volumes: - - ./app/service/sql/init_database_measurements.sh:/docker-entrypoint-initdb.d/init_database_measurements.sh - - ./app/service/sql/init_table_device_plant.sh:/docker-entrypoint-initdb.d/init_table_device_plant.sh - - ./app/service/sql/init_table_measurements.sh:/docker-entrypoint-initdb.d/init_table_measurements.sh + - ./app/service/sql/init_table_device_plant.sql:/docker-entrypoint-initdb.d/init_table_device_plant.sql + - ./app/service/sql/init_table_measurements.sql:/docker-entrypoint-initdb.d/init_table_measurements.sql healthcheck: test: [ diff --git a/tox.ini b/tox.ini index 1d36346..187f79c 100644 --- a/tox.ini +++ b/tox.ini @@ -1,2 +1,2 @@ -[flake8] +[flake8] max-line-length = 88 \ No newline at end of file