diff --git a/.github/workflows/lint-python.yml b/.github/workflows/lint-python.yml index 396c8155fea..5146da647d3 100644 --- a/.github/workflows/lint-python.yml +++ b/.github/workflows/lint-python.yml @@ -26,7 +26,7 @@ jobs: - name: Install dependencies run: | - pip install black pylint + pip install black==23.9.1 pylint - name: Run Black & Pylint if: steps.changed-files.outputs.any_changed == 'true' diff --git a/python/cross_service/apigateway_covid-19_tracker/app.py b/python/cross_service/apigateway_covid-19_tracker/app.py index 05de7b21ebb..f720f8672ab 100644 --- a/python/cross_service/apigateway_covid-19_tracker/app.py +++ b/python/cross_service/apigateway_covid-19_tracker/app.py @@ -16,6 +16,7 @@ import json import logging import urllib.parse + import chalice import chalicelib.covid_data diff --git a/python/cross_service/apigateway_covid-19_tracker/chalicelib/covid_data.py b/python/cross_service/apigateway_covid-19_tracker/chalicelib/covid_data.py index 136c0544363..54b3ae44ea9 100644 --- a/python/cross_service/apigateway_covid-19_tracker/chalicelib/covid_data.py +++ b/python/cross_service/apigateway_covid-19_tracker/chalicelib/covid_data.py @@ -12,6 +12,7 @@ import datetime import os import random + import boto3 from boto3.dynamodb.conditions import Key diff --git a/python/cross_service/apigateway_covid-19_tracker/client_demo.py b/python/cross_service/apigateway_covid-19_tracker/client_demo.py index 8ba400e3866..d21e3d09cfc 100644 --- a/python/cross_service/apigateway_covid-19_tracker/client_demo.py +++ b/python/cross_service/apigateway_covid-19_tracker/client_demo.py @@ -13,6 +13,7 @@ import pprint import random import urllib.parse + import boto3 import requests diff --git a/python/cross_service/apigateway_covid-19_tracker/test/conftest.py b/python/cross_service/apigateway_covid-19_tracker/test/conftest.py index f1ceaccd2ae..fd7589f0814 100644 --- a/python/cross_service/apigateway_covid-19_tracker/test/conftest.py +++ b/python/cross_service/apigateway_covid-19_tracker/test/conftest.py @@ -8,5 +8,15 @@ import sys # This is needed so Python can find test_tools on the path. -sys.path.append("../..") -from test_tools.fixtures.common import * +sys.path.append("../..") # noqa + +from test_tools.fixtures.common import ( + pytest_configure, + fixture_make_stubber, + fixture_make_unique_name, + fixture_make_bucket, + StubRunner, + stub_runner, + InputMocker, + input_mocker, +) diff --git a/python/cross_service/apigateway_covid-19_tracker/test/test_app.py b/python/cross_service/apigateway_covid-19_tracker/test/test_app.py index 9ca9ae9c85d..4f24f57d255 100644 --- a/python/cross_service/apigateway_covid-19_tracker/test/test_app.py +++ b/python/cross_service/apigateway_covid-19_tracker/test/test_app.py @@ -4,11 +4,10 @@ import datetime import json import unittest.mock -import chalice -import pytest import app -import chalicelib +import chalice +import pytest def test_list_states(): diff --git a/python/cross_service/apigateway_covid-19_tracker/test/test_covid_data.py b/python/cross_service/apigateway_covid-19_tracker/test/test_covid_data.py index a4bf604faea..0a5c8ba7c28 100644 --- a/python/cross_service/apigateway_covid-19_tracker/test/test_covid_data.py +++ b/python/cross_service/apigateway_covid-19_tracker/test/test_covid_data.py @@ -1,11 +1,11 @@ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 import datetime + import boto3 +import pytest from boto3.dynamodb.conditions import Key from botocore.exceptions import ClientError -import pytest - from chalicelib.covid_data import Storage diff --git a/python/cross_service/apigateway_websocket_chat/lambda_chat.py b/python/cross_service/apigateway_websocket_chat/lambda_chat.py index 11b8631bfd2..721bc57e88a 100644 --- a/python/cross_service/apigateway_websocket_chat/lambda_chat.py +++ b/python/cross_service/apigateway_websocket_chat/lambda_chat.py @@ -16,6 +16,7 @@ import json import logging import os + import boto3 from botocore.exceptions import ClientError @@ -101,7 +102,7 @@ def handle_message(table, connection_id, event_body, apig_management_client): logger.exception("Couldn't get connections.") status_code = 404 - message = f"{user_name}: {event_body['msg']}".encode("utf-8") + message = f"{user_name}: {event_body['msg']}".encode() # utf-8 logger.info("Message: %s", message) for other_conn_id in connection_ids: diff --git a/python/cross_service/apigateway_websocket_chat/test/conftest.py b/python/cross_service/apigateway_websocket_chat/test/conftest.py index 3ffb09531a2..c2f9e6da0b5 100644 --- a/python/cross_service/apigateway_websocket_chat/test/conftest.py +++ b/python/cross_service/apigateway_websocket_chat/test/conftest.py @@ -8,5 +8,15 @@ import sys # This is needed so Python can find test_tools on the path. -sys.path.append("../..") -from test_tools.fixtures.common import * +sys.path.append("../..") # noqa + +from test_tools.fixtures.common import ( + pytest_configure, + fixture_make_stubber, + fixture_make_unique_name, + fixture_make_bucket, + StubRunner, + stub_runner, + InputMocker, + input_mocker, +) diff --git a/python/cross_service/apigateway_websocket_chat/test/test_lambda_chat.py b/python/cross_service/apigateway_websocket_chat/test/test_lambda_chat.py index 3fd6796da78..238dc88f53e 100644 --- a/python/cross_service/apigateway_websocket_chat/test/test_lambda_chat.py +++ b/python/cross_service/apigateway_websocket_chat/test/test_lambda_chat.py @@ -6,10 +6,10 @@ """ import json -import boto3 -import pytest +import boto3 import lambda_chat +import pytest @pytest.mark.parametrize( @@ -87,7 +87,7 @@ def test_handle_message( ) if error_method != "stub_scan": apig_management_stubber.stub_post_to_connection( - f"{user_name}: {msg}".encode("utf-8"), + f"{user_name}: {msg}".encode(), # utf-8 other_connection_id, error_code=error_code if error_method == "stub_post_to_connection" diff --git a/python/cross_service/apigateway_websocket_chat/test/test_websocket_chat.py b/python/cross_service/apigateway_websocket_chat/test/test_websocket_chat.py index 24e8b7df787..8ea30d3a1bf 100644 --- a/python/cross_service/apigateway_websocket_chat/test/test_websocket_chat.py +++ b/python/cross_service/apigateway_websocket_chat/test/test_websocket_chat.py @@ -6,9 +6,8 @@ """ import boto3 -from botocore.exceptions import ClientError import pytest - +from botocore.exceptions import ClientError from websocket_chat import ApiGatewayWebsocket diff --git a/python/cross_service/apigateway_websocket_chat/websocket_chat.py b/python/cross_service/apigateway_websocket_chat/websocket_chat.py index 07ac44d439f..eebc8debf85 100644 --- a/python/cross_service/apigateway_websocket_chat/websocket_chat.py +++ b/python/cross_service/apigateway_websocket_chat/websocket_chat.py @@ -15,9 +15,10 @@ import io import json import logging -import websockets import zipfile + import boto3 +import websockets from botocore.exceptions import ClientError logger = logging.getLogger(__name__) diff --git a/python/cross_service/aurora_item_tracker/app.py b/python/cross_service/aurora_item_tracker/app.py index 77d7f777e52..cf60d3d0448 100644 --- a/python/cross_service/aurora_item_tracker/app.py +++ b/python/cross_service/aurora_item_tracker/app.py @@ -20,7 +20,6 @@ import boto3 from flask import Flask from flask_cors import CORS - from item_list import ItemList from report import Report from storage import Storage diff --git a/python/cross_service/aurora_item_tracker/item_list.py b/python/cross_service/aurora_item_tracker/item_list.py index c03a81386cc..410ac0dc6ae 100644 --- a/python/cross_service/aurora_item_tracker/item_list.py +++ b/python/cross_service/aurora_item_tracker/item_list.py @@ -9,12 +9,13 @@ """ import logging + from flask import jsonify from flask.views import MethodView from marshmallow import Schema +from storage import DataServiceNotReadyException, StorageError from webargs import fields from webargs.flaskparser import use_args, use_kwargs -from storage import DataServiceNotReadyException, StorageError logger = logging.getLogger(__name__) diff --git a/python/cross_service/aurora_item_tracker/report.py b/python/cross_service/aurora_item_tracker/report.py index cb4e07638d9..5b4de78fd17 100644 --- a/python/cross_service/aurora_item_tracker/report.py +++ b/python/cross_service/aurora_item_tracker/report.py @@ -11,20 +11,20 @@ """ import csv +import logging from datetime import datetime +from email.mime.application import MIMEApplication from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText -from email.mime.application import MIMEApplication -import logging from io import StringIO + from botocore.exceptions import ClientError from flask import jsonify, render_template from flask.views import MethodView +from storage import StorageError from webargs import fields from webargs.flaskparser import use_kwargs -from storage import StorageError - logger = logging.getLogger(__name__) @@ -106,7 +106,7 @@ def post(self, email): try: work_items = self.storage.get_work_items(archived=False) snap_time = datetime.now() - logger.info(f"Sending report of %s items to %s.", len(work_items), email) + logger.info(f"Sending report of {len(work_items)} items to {email}.") html_report = render_template( "report.html", work_items=work_items, @@ -134,7 +134,7 @@ def post(self, email): Source=self.email_sender, Destination={"ToAddresses": [email]}, Message={ - "Subject": {"Data": f"Work items"}, + "Subject": {"Data": "Work items"}, "Body": { "Html": {"Data": html_report}, "Text": {"Data": text_report}, diff --git a/python/cross_service/aurora_item_tracker/storage.py b/python/cross_service/aurora_item_tracker/storage.py index 43b63787688..cd68aeb818c 100644 --- a/python/cross_service/aurora_item_tracker/storage.py +++ b/python/cross_service/aurora_item_tracker/storage.py @@ -9,6 +9,7 @@ """ import logging + from botocore.exceptions import ClientError logger = logging.getLogger(__name__) @@ -128,10 +129,10 @@ def add_work_item(self, work_item): :return: The generated ID of the new work item. """ sql = ( - f"WITH t1 AS ( " + "WITH t1 AS ( " f"INSERT INTO {self._table_name} (description, guide, status, username) " - f" VALUES (:description, :guide, :status, :username) RETURNING iditem " - f") SELECT iditem FROM t1" + " VALUES (:description, :guide, :status, :username) RETURNING iditem " + ") SELECT iditem FROM t1" ) sql_params = [ {"name": "description", "value": {"stringValue": work_item["description"]}}, diff --git a/python/cross_service/aurora_item_tracker/test/conftest.py b/python/cross_service/aurora_item_tracker/test/conftest.py index 3938de50078..5f0c9ea5145 100644 --- a/python/cross_service/aurora_item_tracker/test/conftest.py +++ b/python/cross_service/aurora_item_tracker/test/conftest.py @@ -7,6 +7,16 @@ import sys -# This is needed so Python can find test_tools in the path. -sys.path.append("../..") -from test_tools.fixtures.common import * +# This is needed so Python can find test_tools on the path. +sys.path.append("../..") # noqa + +from test_tools.fixtures.common import ( + pytest_configure, + fixture_make_stubber, + fixture_make_unique_name, + fixture_make_bucket, + StubRunner, + stub_runner, + InputMocker, + input_mocker, +) diff --git a/python/cross_service/aurora_item_tracker/test/test_app.py b/python/cross_service/aurora_item_tracker/test/test_app.py index a6617186f8f..5ace531ed4f 100644 --- a/python/cross_service/aurora_item_tracker/test/test_app.py +++ b/python/cross_service/aurora_item_tracker/test/test_app.py @@ -6,10 +6,9 @@ """ import boto3 -from botocore.stub import ANY import pytest - -from app import create_app +from app import create_app # pylint: disable=E0611 +from botocore.stub import ANY class MockManager: @@ -82,7 +81,7 @@ def setup_stubs(self, err, stop_on, sql, sql_params, report=None, **kwargs): self.ses_stubber.stub_send_email, self.sender, {"ToAddresses": [self.recipient]}, - f"Work items", + "Work items", ANY, ANY, "test-msg-id", @@ -101,7 +100,7 @@ def make_query(self, kind, data): if kind == "SELECT": if data is not None: sql = ( - f"SELECT iditem, description, guide, status, username, archived " + "SELECT iditem, description, guide, status, username, archived " f"FROM {self.table_name} WHERE archived=:archived" ) sql_params = [ @@ -109,14 +108,14 @@ def make_query(self, kind, data): ] else: sql = ( - f"SELECT iditem, description, guide, status, username, archived " + "SELECT iditem, description, guide, status, username, archived " f"FROM {self.table_name} " ) sql_params = None elif kind == "INSERT": sql = ( f"INSERT INTO {self.table_name} (description, guide, status, username) " - f" VALUES (:description, :guide, :status, :username)" + " VALUES (:description, :guide, :status, :username)" ) sql_params = [ {"name": "description", "value": {"stringValue": data["description"]}}, @@ -283,7 +282,7 @@ def test_report_small(mock_mgr): mock_mgr.setup_stubs(None, None, sql, sql_params, report="small") with mock_mgr.app.test_client() as client: - rte = f"/api/items:report" + rte = "/api/items:report" rv = client.post(rte, json={"email": mock_mgr.recipient}) assert rv.status_code == 200 @@ -293,7 +292,7 @@ def test_report_large(mock_mgr): mock_mgr.setup_stubs(None, None, sql, sql_params, report="large") with mock_mgr.app.test_client() as client: - rte = f"/api/items:report" + rte = "/api/items:report" rv = client.post(rte, json={"email": mock_mgr.recipient}) assert rv.status_code == 200 @@ -310,7 +309,7 @@ def test_report_error(mock_mgr, err, stop_on, msg): mock_mgr.setup_stubs(err, stop_on, sql, sql_params, report="small") with mock_mgr.app.test_client() as client: - rte = f"/api/items:report" + rte = "/api/items:report" rv = client.post(rte, json={"email": mock_mgr.recipient}) assert rv.status_code == 500 assert msg in rv.json diff --git a/python/cross_service/aurora_rest_lending_library/library_api/app.py b/python/cross_service/aurora_rest_lending_library/library_api/app.py index 3d32018c515..bd2f9d931a8 100644 --- a/python/cross_service/aurora_rest_lending_library/library_api/app.py +++ b/python/cross_service/aurora_rest_lending_library/library_api/app.py @@ -12,9 +12,10 @@ import logging import urllib.parse + +import chalicelib.library_data from chalice import Chalice from chalice.app import RequestTimeoutError -import chalicelib.library_data logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) @@ -138,7 +139,7 @@ def add_patron(): logger.exception( f"Got exception in add_patron() inside library_api/app.py: {str(err)}" ) - logger.exception(f"Returning None instead of patron_id.") + logger.exception("Returning None instead of patron_id.") return None @@ -169,7 +170,7 @@ def list_borrowed_books(): logger.exception( f"Exception while calling get_storage().get_borrowed_books(): {str(err)}" ) - logger.exception(f"Continuing with blank list of borrowed books...") + logger.exception("Continuing with blank list of borrowed books...") return {"books": []} diff --git a/python/cross_service/aurora_rest_lending_library/library_api/chalicelib/library_data.py b/python/cross_service/aurora_rest_lending_library/library_api/chalicelib/library_data.py index 7d2f0bdd94c..f699ab8d970 100644 --- a/python/cross_service/aurora_rest_lending_library/library_api/chalicelib/library_data.py +++ b/python/cross_service/aurora_rest_lending_library/library_api/chalicelib/library_data.py @@ -13,23 +13,26 @@ import datetime import logging import os + import boto3 from botocore.exceptions import ClientError -from .postgresql_helper import Table, Column, ForeignKey + from .postgresql_helper import ( + Column, + ForeignKey, + Table, create_table, + delete, insert, - insert_without_batch, insert_returning, - update, + insert_without_batch, query, - unpack_query_results, unpack_insert_results, unpack_insert_results_v2, - delete, + unpack_query_results, + update, ) - logger = logging.getLogger(__name__) @@ -292,7 +295,7 @@ def add_books(self, books): "Added %s authors to the database. Result set included updateResults field.", author_count, ) - except: + except Exception: pass try: author_count = len(result["records"]) @@ -300,7 +303,7 @@ def add_books(self, books): "Added %s authors to the database. Result set included records field.", author_count, ) - except: + except Exception: pass auth_ids = [ @@ -492,9 +495,9 @@ def get_borrowed_books(self): }, ], ) - except Exception as err: + except Exception: logger.exception( - f"Couldn't call query() to construct the query for the Lending table." + "Couldn't call query() to construct the query for the Lending table." ) raise try: @@ -575,7 +578,7 @@ def return_book(self, book_id, patron_id): ], ) try: - results = self._run_statement(sql, sql_params) + self._run_statement(sql, sql_params) except Exception as err: logger.exception( f"Error running SQL statement for return_book(): {str(err)}" diff --git a/python/cross_service/aurora_rest_lending_library/library_api/chalicelib/mysql_helper.py b/python/cross_service/aurora_rest_lending_library/library_api/chalicelib/mysql_helper.py index 4eff14f24d3..df10740eb79 100644 --- a/python/cross_service/aurora_rest_lending_library/library_api/chalicelib/mysql_helper.py +++ b/python/cross_service/aurora_rest_lending_library/library_api/chalicelib/mysql_helper.py @@ -268,7 +268,7 @@ def unpack_insert_results(results): """ try: return results["generatedFields"][0]["longValue"] - except: + except Exception: print( f"Error trying to unpack generatedFields value from result of INSERT statement: {str(results)}" ) diff --git a/python/cross_service/aurora_rest_lending_library/library_api/chalicelib/postgresql_helper.py b/python/cross_service/aurora_rest_lending_library/library_api/chalicelib/postgresql_helper.py index 31ddf9f6d63..c1a1678adfc 100644 --- a/python/cross_service/aurora_rest_lending_library/library_api/chalicelib/postgresql_helper.py +++ b/python/cross_service/aurora_rest_lending_library/library_api/chalicelib/postgresql_helper.py @@ -13,6 +13,9 @@ """ import datetime +import logging + +logger = logging.getLogger(__name__) # Maps from Python types to PostgreSQL columns types used in a CREATE TABLE statement. COL_TYPES = {int: "int", str: "varchar", datetime.date: "date"} @@ -182,7 +185,7 @@ def insert(table, value_sets): the RDS Data Service. """ insert_clause = f"INSERT INTO {table.name}" - returning_clause = f"RETURNING *" + returning_clause = "RETURNING *" cols = [col.name for col in table.cols if not col.auto_increment] vals = [f":{col}" for col in cols] # Currently, the RETURNING clause does not have a material effect on the result set as seen by the Data API. @@ -214,7 +217,7 @@ def insert_returning(table, value_sets): the RDS Data Service. """ insert_clause = f"INSERT INTO {table.name}" - returning_clause = f"RETURNING *" + returning_clause = "RETURNING *" cols = [col.name for col in table.cols if not col.auto_increment] vals = [f":{col}" for col in cols] sql = f"WITH derived AS ({insert_clause} ({', '.join(cols)}) VALUES ({', '.join(vals)}) {returning_clause}) SELECT * FROM derived" @@ -237,7 +240,7 @@ def insert_without_batch(table, values_clause): """ insert_clause = f"INSERT INTO {table.name}" - returning_clause = f"RETURNING *" + returning_clause = "RETURNING *" cols = [col.name for col in table.cols if not col.auto_increment] # The RETURNING clause currently does not have a material effect on the result set as seen by the Data API. # This might not be a permanent limitation. If RETURNING does start to have an effect on the elements in @@ -337,7 +340,7 @@ def unpack_insert_results(results): """ try: return results["generatedFields"][0]["longValue"] - except: + except Exception: logger.exception( f"Error trying to unpack generatedFields value from result of INSERT statement: {str(results)}" ) @@ -356,7 +359,7 @@ def unpack_insert_results_v2(results): try: new_id = results["records"][0][0]["longValue"] return new_id - except: + except Exception: logger.exception( f"Error in unpack_insert_results_v2() trying to unpack generatedFields value from result of INSERT statement: {str(results)}" ) diff --git a/python/cross_service/aurora_rest_lending_library/library_api/test/conftest.py b/python/cross_service/aurora_rest_lending_library/library_api/test/conftest.py index 782ca24c7b0..ba5f8d1fab8 100644 --- a/python/cross_service/aurora_rest_lending_library/library_api/test/conftest.py +++ b/python/cross_service/aurora_rest_lending_library/library_api/test/conftest.py @@ -4,9 +4,18 @@ """ Contains common test fixtures used to run tests. """ - import sys # This is needed so Python can find test_tools in the path. -sys.path.append("../../..") -from test_tools.fixtures.common import * +sys.path.append("../..") # noqa + +from test_tools.fixtures.common import ( + pytest_configure, + fixture_make_stubber, + fixture_make_unique_name, + fixture_make_bucket, + StubRunner, + stub_runner, + InputMocker, + input_mocker, +) diff --git a/python/cross_service/aurora_rest_lending_library/library_api/test/test_library_api_app.py b/python/cross_service/aurora_rest_lending_library/library_api/test/test_library_api_app.py index 48cda8d02be..63e1c321f6d 100644 --- a/python/cross_service/aurora_rest_lending_library/library_api/test/test_library_api_app.py +++ b/python/cross_service/aurora_rest_lending_library/library_api/test/test_library_api_app.py @@ -8,10 +8,10 @@ class provided by AWS Chalice to simplify route testing. import json from unittest.mock import MagicMock + +import app import pytest -from chalice.app import RequestTimeoutError from chalice.test import Client -import app from chalicelib.library_data import DataServiceNotReadyException diff --git a/python/cross_service/aurora_rest_lending_library/library_api/test/test_library_data.py b/python/cross_service/aurora_rest_lending_library/library_api/test/test_library_data.py index 3d933d1b417..04350330e52 100644 --- a/python/cross_service/aurora_rest_lending_library/library_api/test/test_library_data.py +++ b/python/cross_service/aurora_rest_lending_library/library_api/test/test_library_data.py @@ -6,8 +6,9 @@ """ import datetime -import pytest + import boto3 +import pytest from botocore.exceptions import ClientError from botocore.stub import ANY from chalicelib.library_data import Storage diff --git a/python/cross_service/aurora_rest_lending_library/library_api/test/test_mysql_helper.py b/python/cross_service/aurora_rest_lending_library/library_api/test/test_mysql_helper.py index 33b44533f17..4a2ca18e5fd 100644 --- a/python/cross_service/aurora_rest_lending_library/library_api/test/test_mysql_helper.py +++ b/python/cross_service/aurora_rest_lending_library/library_api/test/test_mysql_helper.py @@ -6,8 +6,9 @@ """ import datetime -from chalicelib.mysql_helper import Table, Column, ForeignKey + import chalicelib.mysql_helper as mysql_helper +from chalicelib.mysql_helper import Column, ForeignKey, Table def make_table(): diff --git a/python/cross_service/aurora_rest_lending_library/library_demo.py b/python/cross_service/aurora_rest_lending_library/library_demo.py index eb893bd3a34..44776ba794b 100644 --- a/python/cross_service/aurora_rest_lending_library/library_demo.py +++ b/python/cross_service/aurora_rest_lending_library/library_demo.py @@ -11,20 +11,21 @@ import argparse import logging import os -from pprint import pprint import random import time +from pprint import pprint from urllib.parse import urljoin -import requests + import boto3 +import requests import yaml - from library_api.chalicelib.library_data import Storage +import rds_tools.aurora_tools as aurora_tools logger = logging.getLogger(__name__) # Read YAML configuration -with open("config.yml", "r") as file: +with open("config.yml") as file: config = yaml.safe_load(file) @@ -104,7 +105,7 @@ def create_resources( # With Aurora Serverless v2, the cluster might be 'Available' while the # writer instance is still 'Creating'. Wait for the instance to be available too. instance_available_waiter = aurora_tools.DBInstanceAvailableWaiter(rds_client) - instance_available_waiter.wait("%s-instance" % cluster_name) + instance_available_waiter.wait(f"{cluster_name}-instance") return cluster, secret @@ -289,7 +290,15 @@ def main(): if args.action == "deploy_database": print("Deploying the serverless database and supporting resources.") - do_deploy_database(cluster_name, secret_name) + cluster, secret = create_resources( + config["cluster"]["cluster_name"], + config["db_name"], + config["cluster"]["admin_name"], + config["cluster"]["admin_password"], + boto3.client("rds"), + config["secret"]["name"], + boto3.client("secretsmanager"), + ) print("Next, run 'python library_demo.py deploy_rest' to deploy the REST API.") elif args.action == "populate_database": print("Populating serverless database cluster with data.") diff --git a/python/cross_service/aurora_rest_lending_library/rds_tools/aurora_tools.py b/python/cross_service/aurora_rest_lending_library/rds_tools/aurora_tools.py index 8b97cf0266e..3d276d7745a 100644 --- a/python/cross_service/aurora_rest_lending_library/rds_tools/aurora_tools.py +++ b/python/cross_service/aurora_rest_lending_library/rds_tools/aurora_tools.py @@ -8,14 +8,15 @@ (Aurora) database cluster and create and delete an AWS Secrets Manager secret. """ +from demo_tools.custom_waiter import CustomWaiter, WaitState import json import logging import sys + from botocore.exceptions import ClientError # Add relative path to include demo_tools in this code example without need for setup. sys.path.append("../..") -from demo_tools.custom_waiter import CustomWaiter, WaitState logger = logging.getLogger(__name__) @@ -92,12 +93,11 @@ def create_db_cluster(cluster_name, db_name, admin_name, admin_password, rds_cli ) except ClientError: logger.exception( - "Couldn't create cluster %s containing database %s." - % (cluster_name, db_name) + f"Couldn't create cluster {cluster_name} containing database {db_name}." ) raise - instance_name = "%s-instance" % cluster_name + instance_name = f"{cluster_name}-instance" try: create_instance_response = rds_client.create_db_instance( DBInstanceIdentifier=instance_name, @@ -105,9 +105,9 @@ def create_db_cluster(cluster_name, db_name, admin_name, admin_password, rds_cli Engine="aurora-postgresql", DBInstanceClass="db.serverless", ) - instance = create_instance_response["DBInstance"] + create_instance_response["DBInstance"] except ClientError: - logger.exception("Couldn't create instance %s." % db_name) + logger.exception(f"Couldn't create instance {db_name}.") raise else: return cluster @@ -122,7 +122,7 @@ def delete_db_cluster(cluster_name, rds_client): """ try: rds_client.delete_db_instance( - DBInstanceIdentifier="%s-instance" % cluster_name, SkipFinalSnapshot=True + DBInstanceIdentifier=f"{cluster_name}-instance", SkipFinalSnapshot=True ) rds_client.delete_db_cluster( DBClusterIdentifier=cluster_name, SkipFinalSnapshot=True diff --git a/python/cross_service/dynamodb_item_tracker/app.py b/python/cross_service/dynamodb_item_tracker/app.py index 71d6de904a7..96092865105 100644 --- a/python/cross_service/dynamodb_item_tracker/app.py +++ b/python/cross_service/dynamodb_item_tracker/app.py @@ -22,10 +22,9 @@ import boto3 from flask import Flask from flask_cors import CORS - from item_list import ItemList from report import Report -from storage import Storage, StorageError +from storage import Storage logger = logging.getLogger(__name__) @@ -67,7 +66,7 @@ def create_app(test_config=None): dynamodb_resource = boto3.resource("dynamodb") ses_client = boto3.client("ses") table = dynamodb_resource.Table(app.config["TABLE_NAME"]) - storage = Storage(table) + storage = Storage(table) # pylint: disable=E1120 item_list_view = ItemList.as_view("item_list_api", storage) report_view = Report.as_view("report_api", storage, sender_email, ses_client) diff --git a/python/cross_service/dynamodb_item_tracker/item_list.py b/python/cross_service/dynamodb_item_tracker/item_list.py index f29f35e4dc3..58550179cb7 100644 --- a/python/cross_service/dynamodb_item_tracker/item_list.py +++ b/python/cross_service/dynamodb_item_tracker/item_list.py @@ -9,12 +9,13 @@ """ import logging + from flask import jsonify from flask.views import MethodView from marshmallow import Schema +from storage import StorageError from webargs import fields from webargs.flaskparser import use_args, use_kwargs -from storage import StorageError logger = logging.getLogger(__name__) diff --git a/python/cross_service/dynamodb_item_tracker/report.py b/python/cross_service/dynamodb_item_tracker/report.py index d14c12b28b3..48c5bc41c64 100644 --- a/python/cross_service/dynamodb_item_tracker/report.py +++ b/python/cross_service/dynamodb_item_tracker/report.py @@ -10,19 +10,19 @@ attachment to the email instead of in the body of the email itself. """ +import logging from datetime import datetime +from email.mime.application import MIMEApplication from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText -from email.mime.application import MIMEApplication -import logging + from botocore.exceptions import ClientError from flask import jsonify, render_template from flask.views import MethodView +from storage import StorageError from webargs import fields from webargs.flaskparser import use_kwargs -from storage import StorageError - logger = logging.getLogger(__name__) @@ -113,7 +113,7 @@ def post(self, email): Source=self.email_sender, Destination={"ToAddresses": [email]}, Message={ - "Subject": {"Data": f"Work items"}, + "Subject": {"Data": "Work items"}, "Body": { "Html": {"Data": html_report}, "Text": {"Data": text_report}, diff --git a/python/cross_service/dynamodb_item_tracker/storage.py b/python/cross_service/dynamodb_item_tracker/storage.py index ea9a2f2e5dd..4896bc7ecd6 100644 --- a/python/cross_service/dynamodb_item_tracker/storage.py +++ b/python/cross_service/dynamodb_item_tracker/storage.py @@ -10,10 +10,10 @@ import logging from uuid import uuid4 + from boto3.dynamodb.conditions import Attr from botocore.exceptions import ClientError - logger = logging.getLogger(__name__) diff --git a/python/cross_service/dynamodb_item_tracker/test/conftest.py b/python/cross_service/dynamodb_item_tracker/test/conftest.py index 3938de50078..5f0c9ea5145 100644 --- a/python/cross_service/dynamodb_item_tracker/test/conftest.py +++ b/python/cross_service/dynamodb_item_tracker/test/conftest.py @@ -7,6 +7,16 @@ import sys -# This is needed so Python can find test_tools in the path. -sys.path.append("../..") -from test_tools.fixtures.common import * +# This is needed so Python can find test_tools on the path. +sys.path.append("../..") # noqa + +from test_tools.fixtures.common import ( + pytest_configure, + fixture_make_stubber, + fixture_make_unique_name, + fixture_make_bucket, + StubRunner, + stub_runner, + InputMocker, + input_mocker, +) diff --git a/python/cross_service/dynamodb_item_tracker/test/test_app.py b/python/cross_service/dynamodb_item_tracker/test/test_app.py index e2b9cda6ab4..16a5a625cc2 100644 --- a/python/cross_service/dynamodb_item_tracker/test/test_app.py +++ b/python/cross_service/dynamodb_item_tracker/test/test_app.py @@ -4,14 +4,11 @@ """ Unit tests for the dynamodb_item_tracker example. """ - -import json import boto3 -from botocore.stub import ANY import pytest - -from app import create_app import storage +from app import create_app # pylint: disable=E0611 +from botocore.stub import ANY from storage import Storage @@ -23,7 +20,7 @@ def __init__(self, resource, stubber, ses_client, ses_stubber, stub_runner): self.ses_stubber = ses_stubber self.stub_runner = stub_runner self.table = resource.Table("test-table") - self.storage = Storage(self.table) + self.storage = Storage(self.table) # pylint: disable=E1120 self.web_items = [ { "id": f"id-{index}", @@ -257,14 +254,14 @@ def test_report_small(mock_mgr, monkeypatch): mock_mgr.ses_stubber.stub_send_email, mock_mgr.sender, {"ToAddresses": [mock_mgr.recipient]}, - f"Work items", + "Work items", ANY, ANY, "test-msg-id", ) with mock_mgr.app.test_client() as client: - rte = f"/api/items:report" + rte = "/api/items:report" rv = client.post(rte, json={"email": mock_mgr.recipient}) assert rv.status_code == 200 @@ -286,7 +283,7 @@ def test_report_large(mock_mgr, monkeypatch): ) with mock_mgr.app.test_client() as client: - rte = f"/api/items:report" + rte = "/api/items:report" rv = client.post(rte, json={"email": mock_mgr.recipient}) assert rv.status_code == 200 @@ -306,13 +303,13 @@ def test_report_error(mock_mgr, monkeypatch, err, stop_on): mock_mgr.ses_stubber.stub_send_email, mock_mgr.sender, {"ToAddresses": [mock_mgr.recipient]}, - f"Work items", + "Work items", ANY, ANY, "test-msg-id", ) with mock_mgr.app.test_client() as client: - rte = f"/api/items:report" + rte = "/api/items:report" rv = client.post(rte, json={"email": mock_mgr.recipient}) assert rv.status_code == 500 diff --git a/python/cross_service/photo_analyzer/api/analysis.py b/python/cross_service/photo_analyzer/api/analysis.py index ab81a3091f3..e48899a52f3 100644 --- a/python/cross_service/photo_analyzer/api/analysis.py +++ b/python/cross_service/photo_analyzer/api/analysis.py @@ -2,6 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 import logging + from botocore.exceptions import ClientError from flask_restful import Resource diff --git a/python/cross_service/photo_analyzer/api/app.py b/python/cross_service/photo_analyzer/api/app.py index 12503950c93..7121e6facff 100644 --- a/python/cross_service/photo_analyzer/api/app.py +++ b/python/cross_service/photo_analyzer/api/app.py @@ -15,13 +15,14 @@ """ import logging + import boto3 +from analysis import Analysis from flask import Flask -from flask_restful import Api from flask_cors import CORS -from analysis import Analysis -from photo_list import PhotoList +from flask_restful import Api from photo import Photo +from photo_list import PhotoList from report import Report logger = logging.getLogger(__name__) diff --git a/python/cross_service/photo_analyzer/api/photo.py b/python/cross_service/photo_analyzer/api/photo.py index 015dfff2b6c..1c48e5f4f0f 100644 --- a/python/cross_service/photo_analyzer/api/photo.py +++ b/python/cross_service/photo_analyzer/api/photo.py @@ -2,6 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 import logging + from flask_restful import Resource logger = logging.getLogger(__name__) diff --git a/python/cross_service/photo_analyzer/api/photo_list.py b/python/cross_service/photo_analyzer/api/photo_list.py index 54d8a1ef28c..eabfba39537 100644 --- a/python/cross_service/photo_analyzer/api/photo_list.py +++ b/python/cross_service/photo_analyzer/api/photo_list.py @@ -2,10 +2,11 @@ # SPDX-License-Identifier: Apache-2.0 import logging + +import werkzeug.datastructures from boto3.s3.transfer import S3UploadFailedError from botocore.exceptions import ClientError from flask_restful import Resource, reqparse -import werkzeug.datastructures logger = logging.getLogger(__name__) diff --git a/python/cross_service/photo_analyzer/api/report.py b/python/cross_service/photo_analyzer/api/report.py index 58b2505417d..5827d89f844 100644 --- a/python/cross_service/photo_analyzer/api/report.py +++ b/python/cross_service/photo_analyzer/api/report.py @@ -2,6 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 import logging + from botocore.exceptions import ClientError from flask import render_template from flask_restful import Resource, reqparse @@ -109,7 +110,6 @@ def post(self): ) text_labels = "\n".join(args["analysis_labels"]) try: - pass self.ses_client.send_email( Source=args["sender"], Destination={"ToAddresses": [args["recipient"]]}, diff --git a/python/cross_service/photo_analyzer/api/test/conftest.py b/python/cross_service/photo_analyzer/api/test/conftest.py index 782ca24c7b0..7f521c6df66 100644 --- a/python/cross_service/photo_analyzer/api/test/conftest.py +++ b/python/cross_service/photo_analyzer/api/test/conftest.py @@ -9,4 +9,3 @@ # This is needed so Python can find test_tools in the path. sys.path.append("../../..") -from test_tools.fixtures.common import * diff --git a/python/cross_service/photo_analyzer/api/test/test_analysis.py b/python/cross_service/photo_analyzer/api/test/test_analysis.py index 4cc9af8ec04..30844667c37 100644 --- a/python/cross_service/photo_analyzer/api/test/test_analysis.py +++ b/python/cross_service/photo_analyzer/api/test/test_analysis.py @@ -6,9 +6,9 @@ """ from unittest.mock import MagicMock + import boto3 import pytest - from analysis import Analysis diff --git a/python/cross_service/photo_analyzer/api/test/test_photo.py b/python/cross_service/photo_analyzer/api/test/test_photo.py index d8eebaaf81c..870a8fb69eb 100644 --- a/python/cross_service/photo_analyzer/api/test/test_photo.py +++ b/python/cross_service/photo_analyzer/api/test/test_photo.py @@ -5,10 +5,8 @@ Unit tests for photo.py. """ -from unittest.mock import MagicMock -import boto3 -import pytest +import boto3 from photo import Photo diff --git a/python/cross_service/photo_analyzer/api/test/test_photo_list.py b/python/cross_service/photo_analyzer/api/test/test_photo_list.py index 4d9d735722d..82c9f1e1756 100644 --- a/python/cross_service/photo_analyzer/api/test/test_photo_list.py +++ b/python/cross_service/photo_analyzer/api/test/test_photo_list.py @@ -6,11 +6,11 @@ """ from unittest.mock import MagicMock + import boto3 +import pytest from boto3.s3.transfer import S3UploadFailedError from botocore.exceptions import ClientError -import pytest - from photo_list import PhotoList, reqparse diff --git a/python/cross_service/photo_analyzer/api/test/test_report.py b/python/cross_service/photo_analyzer/api/test/test_report.py index c77060e3bc0..febc018bb5d 100644 --- a/python/cross_service/photo_analyzer/api/test/test_report.py +++ b/python/cross_service/photo_analyzer/api/test/test_report.py @@ -6,10 +6,11 @@ """ from unittest.mock import MagicMock + import boto3 import pytest - -from report import Report, reqparse, render_template +from report import Report +from flask_restful import reqparse @pytest.mark.parametrize( @@ -91,7 +92,7 @@ def test_post_report(make_stubber, monkeypatch, error_code): error_code=error_code, ) - _, result = report.post() + _, result = report.post() # pylint: disable=E1120 if error_code is None: assert result == 200 else: diff --git a/python/cross_service/rekognition_content_moderation/src/rek-moderator.py b/python/cross_service/rekognition_content_moderation/src/rek-moderator.py index faf93551a71..c792a03c109 100644 --- a/python/cross_service/rekognition_content_moderation/src/rek-moderator.py +++ b/python/cross_service/rekognition_content_moderation/src/rek-moderator.py @@ -7,11 +7,11 @@ Shows how to create a fully serverless REST API for Rekognition Content Moderation Solution with URL Support. """ +import io import json + import boto3 import urllib3 -import io - client = boto3.client("rekognition") manager = urllib3.PoolManager() diff --git a/python/cross_service/resilient_service/auto_scaler.py b/python/cross_service/resilient_service/auto_scaler.py index d4dfd06577b..3c385cb7fb6 100644 --- a/python/cross_service/resilient_service/auto_scaler.py +++ b/python/cross_service/resilient_service/auto_scaler.py @@ -96,7 +96,6 @@ def create_policy(self, policy_file: str, policy_name: str) -> str: log.info(f"Policy '{policy_name}' already exists. ARN: {policy_arn}") return policy_arn log.error(f"Full error:\n\t{err}") - pass def create_role(self, role_name: str, assume_role_doc: dict) -> str: """ @@ -123,7 +122,6 @@ def create_role(self, role_name: str, assume_role_doc: dict) -> str: log.info(f"Role '{role_name}' already exists. ARN: {role_arn}") return role_arn log.error(f"Full error:\n\t{err}") - pass def attach_policy( self, @@ -149,7 +147,6 @@ def attach_policy( except ClientError as err: log.error(f"Failed to attach policy {policy_arn} to role {role_name}.") log.error(f"Full error:\n\t{err}") - pass # snippet-start:[python.cross_service.resilient_service.iam.CreateInstanceProfile] def create_instance_profile( @@ -212,7 +209,6 @@ def create_instance_profile( "Instance profile %s already exists, nothing to do.", profile_name ) log.error(f"Full error:\n\t{err}") - pass return profile_arn # snippet-end:[python.cross_service.resilient_service.iam.CreateInstanceProfile] @@ -242,7 +238,6 @@ def get_instance_profile(self, instance_id: str) -> Dict[str, Any]: if error_code == "InvalidInstanceID.NotFound": log.error(f"The instance ID '{instance_id}' does not exist.") log.error(f"Full error:\n\t{err}") - pass # snippet-end:[python.cross_service.resilient_service.ec2.DescribeIamInstanceProfileAssociations] @@ -303,7 +298,6 @@ def replace_instance_profile( f"Please verify the instance ID and try again." ) log.error(f"Full error:\n\t{err}") - pass # snippet-end:[python.cross_service.resilient_service.ec2.ReplaceIamInstanceProfileAssociation] @@ -343,7 +337,6 @@ def delete_instance_profile(self, profile_name: str, role_name: str) -> None: log.info( "Instance profile %s doesn't exist, nothing to do.", profile_name ) - pass # snippet-end:[python.cross_service.resilient_service.iam.DeleteInstanceProfile] @@ -366,7 +359,6 @@ def create_key_pair(self, key_pair_name: str) -> None: if error_code == "InvalidKeyPair.Duplicate": log.error(f"A key pair with the name '{key_pair_name}' already exists.") log.error(f"Full error:\n\t{err}") - pass # snippet-end:[python.cross_service.resilient_service.ec2.CreateKeyPair] @@ -382,11 +374,9 @@ def delete_key_pair(self) -> None: except ClientError as err: log.error(f"Couldn't delete key pair '{self.key_pair_name}'.") log.error(f"Full error:\n\t{err}") - pass except FileNotFoundError as err: log.info("Key pair %s doesn't exist, nothing to do.", self.key_pair_name) log.error(f"Full error:\n\t{err}") - pass # snippet-end:[python.cross_service.resilient_service.ec2.DeleteKeyPair] @@ -450,7 +440,6 @@ def create_template( f"Launch template {self.launch_template_name} already exists, nothing to do." ) log.error(f"Full error:\n\t{err}") - pass return template # snippet-end:[python.cross_service.resilient_service.ec2.CreateLaunchTemplate] @@ -478,7 +467,6 @@ def delete_template(self): self.launch_template_name, ) log.error(f"Full error:\n\t{err}") - pass # snippet-end:[python.cross_service.resilient_service.ec2.DeleteLaunchTemplate] @@ -496,7 +484,6 @@ def get_availability_zones(self) -> List[str]: except ClientError as err: log.error("Failed to retrieve availability zones.") log.error(f"Full error:\n\t{err}") - pass else: return zones @@ -535,7 +522,6 @@ def create_autoscaling_group(self, group_size: int) -> List[str]: else: log.error(f"Failed to create EC2 Auto Scaling group {self.group_name}.") log.error(f"Full error:\n\t{err}") - pass else: return zones @@ -567,7 +553,6 @@ def get_instances(self) -> List[str]: if error_code == "ResourceNotFound": log.error(f"The Auto Scaling group '{self.group_name}' does not exist.") log.error(f"Full error:\n\t{err}") - pass else: return instance_ids @@ -610,7 +595,6 @@ def terminate_instance(self, instance_id: str, decrementsetting=False) -> None: "Ensure that no conflicting operations are being performed on the resource." ) log.error(f"Full error:\n\t{err}") - pass # snippet-start:[python.cross_service.resilient_service.auto-scaling.AttachLoadBalancerTargetGroups] def attach_load_balancer_target_group( @@ -649,7 +633,6 @@ def attach_load_balancer_target_group( "Check that the service-linked role exists and is correctly configured." ) log.error(f"Full error:\n\t{err}") - pass # snippet-end:[python.cross_service.resilient_service.auto-scaling.AttachLoadBalancerTargetGroups] @@ -695,7 +678,6 @@ def delete_autoscaling_group(self, group_name: str) -> None: "Ensure that no conflicting operations are being performed on the group." ) log.error(f"Full error:\n\t{err}") - pass # snippet-end:[python.cross_service.resilient_service.auto-scaling.DeleteAutoScalingGroup] @@ -724,7 +706,6 @@ def get_default_vpc(self) -> Dict[str, Any]: ) log.error(f"Full error:\n\t{err}") - pass else: if "Vpcs" in response and response["Vpcs"]: log.info(f"Retrieved default VPC: {response['Vpcs'][0]['VpcId']}") @@ -789,7 +770,6 @@ def verify_inbound_port( f"The specified VPC ID '{vpc['VpcId']}' does not exist. Please check the VPC ID." ) log.error(f"Full error:\n\t{err}") - pass else: return sec_group, port_is_open @@ -835,7 +815,6 @@ def open_inbound_port(self, sec_group_id: str, port: int, ip_address: str) -> No "Check the existing rules for this security group." ) log.error(f"Full error:\n\t{err}") - pass # snippet-end:[python.cross_service.resilient_service.ec2.AuthorizeSecurityGroupIngress] @@ -879,7 +858,6 @@ def get_subnets(self, vpc_id: str, zones: List[str] = None) -> List[Dict[str, An ) # Add more error-specific handling as needed log.error(f"Full error:\n\t{err}") - pass # snippet-end:[python.cross_service.resilient_service.ec2.DescribeSubnets] diff --git a/python/cross_service/resilient_service/conftest.py b/python/cross_service/resilient_service/conftest.py index 8afcfaf575a..5de39952ba4 100644 --- a/python/cross_service/resilient_service/conftest.py +++ b/python/cross_service/resilient_service/conftest.py @@ -4,11 +4,11 @@ """ Contains common test fixtures used to run unit tests. """ + from datetime import datetime import boto3 import pytest - import runner from auto_scaler import AutoScalingWrapper from load_balancer import ElasticLoadBalancerWrapper diff --git a/python/cross_service/resilient_service/load_balancer.py b/python/cross_service/resilient_service/load_balancer.py index 4d5bb2f18e8..ce043263d9a 100644 --- a/python/cross_service/resilient_service/load_balancer.py +++ b/python/cross_service/resilient_service/load_balancer.py @@ -77,7 +77,6 @@ def create_target_group( "Consider deleting unused target groups to create space for new ones." ) log.error(f"Full error:\n\t{err}") - pass # snippet-end:[python.cross_service.resilient_service.elbv2.CreateTargetGroup] @@ -113,7 +112,6 @@ def delete_target_group(self, target_group_name) -> None: "Ensure that the target group is no longer associated with any load balancers or resources.", ) log.error(f"Full error:\n\t{err}") - pass def wait_for_target_group_deletion( self, elb_client, target_group_arn, max_attempts=10, delay=30 @@ -185,7 +183,6 @@ def create_load_balancer( "You can delete unused load balancers or request an increase in the service quota from AWS Support." ) log.error(f"Full error:\n\t{err}") - pass else: return load_balancer @@ -248,7 +245,6 @@ def create_listener( "Please review the provided protocol, port, and target group settings." ) log.error(f"Full error:\n\t{err}") - pass # snippet-end:[python.cross_service.resilient_service.elbv2.CreateListener] @@ -281,7 +277,6 @@ def delete_load_balancer(self, load_balancer_name) -> None: "Please check the name and try again." ) log.error(f"Full error:\n\t{err}") - pass # snippet-end:[python.cross_service.resilient_service.elbv2.DeleteLoadBalancer] @@ -307,7 +302,6 @@ def get_endpoint(self, load_balancer_name) -> str: "Verify load balancer name and ensure it exists in the AWS console." ) log.error(f"Full error:\n\t{err}") - pass # snippet-end:[python.cross_service.resilient_service.elbv2.DescribeLoadBalancers] @staticmethod @@ -369,7 +363,6 @@ def check_target_health(self, target_group_name: str) -> List[Dict[str, Any]]: "and ensure it has not been deleted or created in a different account.", ) log.error(f"Full error:\n\t{err}") - pass else: return health_response["TargetHealthDescriptions"] diff --git a/python/cross_service/resilient_service/parameters.py b/python/cross_service/resilient_service/parameters.py index 75e6fc65299..c2f16368eb9 100644 --- a/python/cross_service/resilient_service/parameters.py +++ b/python/cross_service/resilient_service/parameters.py @@ -69,7 +69,6 @@ def put(self, name: str, value: str) -> None: "Use Overwrite=True to update the parameter." ) log.error(f"Full error:\n\t{err}") - pass # snippet-end:[python.example_code.workflow.ResilientService_ParameterHelper] diff --git a/python/cross_service/resilient_service/runner.py b/python/cross_service/resilient_service/runner.py index 1e14e97a924..42f7ece85f3 100644 --- a/python/cross_service/resilient_service/runner.py +++ b/python/cross_service/resilient_service/runner.py @@ -18,7 +18,6 @@ import boto3 import coloredlogs import requests - from auto_scaler import AutoScalingWrapper from load_balancer import ElasticLoadBalancerWrapper from parameters import ParameterHelper diff --git a/python/cross_service/resilient_service/test/test_runner_integ.py b/python/cross_service/resilient_service/test/test_runner_integ.py index d247a698c54..752f569c07a 100644 --- a/python/cross_service/resilient_service/test/test_runner_integ.py +++ b/python/cross_service/resilient_service/test/test_runner_integ.py @@ -6,9 +6,8 @@ import boto3 import pytest -from botocore.exceptions import ClientError - from auto_scaler import AutoScalingWrapper +from botocore.exceptions import ClientError from load_balancer import ElasticLoadBalancerWrapper from parameters import ParameterHelper from recommendation_service import RecommendationService diff --git a/python/cross_service/stepfunctions_messenger/stepfunctions_demo.py b/python/cross_service/stepfunctions_messenger/stepfunctions_demo.py index 5d80d686c76..0546b2cd2ff 100644 --- a/python/cross_service/stepfunctions_messenger/stepfunctions_demo.py +++ b/python/cross_service/stepfunctions_messenger/stepfunctions_demo.py @@ -11,8 +11,9 @@ import argparse import logging -from pprint import pprint import time +from pprint import pprint + import boto3 from state_definitions import make_definition from stepfunctions_statemachine import StepFunctionsStateMachine diff --git a/python/cross_service/stepfunctions_messenger/stepfunctions_statemachine.py b/python/cross_service/stepfunctions_messenger/stepfunctions_statemachine.py index bd95be715b6..3326e7c38fa 100644 --- a/python/cross_service/stepfunctions_messenger/stepfunctions_statemachine.py +++ b/python/cross_service/stepfunctions_messenger/stepfunctions_statemachine.py @@ -10,6 +10,7 @@ import json import logging + from botocore.exceptions import ClientError logger = logging.getLogger(__name__) diff --git a/python/cross_service/stepfunctions_messenger/test/conftest.py b/python/cross_service/stepfunctions_messenger/test/conftest.py index 3ffb09531a2..c2f9e6da0b5 100644 --- a/python/cross_service/stepfunctions_messenger/test/conftest.py +++ b/python/cross_service/stepfunctions_messenger/test/conftest.py @@ -8,5 +8,15 @@ import sys # This is needed so Python can find test_tools on the path. -sys.path.append("../..") -from test_tools.fixtures.common import * +sys.path.append("../..") # noqa + +from test_tools.fixtures.common import ( + pytest_configure, + fixture_make_stubber, + fixture_make_unique_name, + fixture_make_bucket, + StubRunner, + stub_runner, + InputMocker, + input_mocker, +) diff --git a/python/cross_service/stepfunctions_messenger/test/test_stepfunctions_statemachine.py b/python/cross_service/stepfunctions_messenger/test/test_stepfunctions_statemachine.py index e8628d8824b..292fbf5c080 100644 --- a/python/cross_service/stepfunctions_messenger/test/test_stepfunctions_statemachine.py +++ b/python/cross_service/stepfunctions_messenger/test/test_stepfunctions_statemachine.py @@ -6,10 +6,10 @@ """ import json + import boto3 -from botocore.exceptions import ClientError import pytest - +from botocore.exceptions import ClientError from stepfunctions_statemachine import StepFunctionsStateMachine diff --git a/python/cross_service/textract_comprehend_notebook/TextractAndComprehendNotebook.ipynb b/python/cross_service/textract_comprehend_notebook/TextractAndComprehendNotebook.ipynb index 9871fd64c31..eb312e2f89a 100644 --- a/python/cross_service/textract_comprehend_notebook/TextractAndComprehendNotebook.ipynb +++ b/python/cross_service/textract_comprehend_notebook/TextractAndComprehendNotebook.ipynb @@ -52,6 +52,7 @@ "# SPDX-License-Identifier: Apache-2.0\n", "\n", "import getpass\n", + "\n", "access_key = getpass.getpass()\n", "secret_key = getpass.getpass()" ] @@ -73,15 +74,15 @@ "source": [ "import boto3\n", "import io\n", - "from PIL import Image \n", - "from IPython.display import display \n", + "from PIL import Image\n", + "from IPython.display import display\n", "import json\n", "import pandas as pd\n", "import os\n", "\n", - "bucket = 'DOC-EXAMPLE-BUCKET'\n", - "document = 'Name of your document'\n", - "region_name = 'Name of your region'" + "bucket = \"DOC-EXAMPLE-BUCKET\"\n", + "document = \"Name of your document\"\n", + "region_name = \"Name of your region\"" ] }, { @@ -100,20 +101,23 @@ "outputs": [], "source": [ "def process_text_detection(bucket, document, access_code, secret_code, region):\n", - " \n", " # Get the document from Amazon S3\n", " s3_connection = boto3.resource(\"s3\")\n", "\n", " # Connect to Amazon Textract to detect text in the document\n", - " client = boto3.client(\"textract\", region_name=region, aws_access_key_id=access_code, \n", - " aws_secret_access_key=secret_code)\n", + " client = boto3.client(\n", + " \"textract\",\n", + " region_name=region,\n", + " aws_access_key_id=access_code,\n", + " aws_secret_access_key=secret_code,\n", + " )\n", "\n", " # Get the response from Amazon S3\n", " s3_object = s3_connection.Object(bucket, document)\n", " s3_response = s3_object.get()\n", "\n", " # open binary stream using an in-memory bytes buffer\n", - " stream = io.BytesIO(s3_response['Body'].read())\n", + " stream = io.BytesIO(s3_response[\"Body\"].read())\n", "\n", " # load stream into image\n", " image = Image.open(stream)\n", @@ -122,10 +126,12 @@ " display(image)\n", "\n", " # process using Amazon S3 object\n", - " response = client.detect_document_text(Document={'S3Object': {'Bucket': bucket, 'Name': document}})\n", + " response = client.detect_document_text(\n", + " Document={\"S3Object\": {\"Bucket\": bucket, \"Name\": document}}\n", + " )\n", "\n", " # Get the text blocks\n", - " blocks = response['Blocks']\n", + " blocks = response[\"Blocks\"]\n", "\n", " # List to store image lines in document\n", " line_list = []\n", @@ -165,24 +171,24 @@ "outputs": [], "source": [ "def entity_detection(lines, access_code, secret_code, region):\n", - " \n", " # Create a list to hold the entities found for every line\n", " response_entities = []\n", - " \n", - " \n", + "\n", " # Connect to Amazon Comprehend\n", - " comprehend = boto3.client(service_name='comprehend', region_name=region, aws_access_key_id=access_code, \n", - " aws_secret_access_key=secret_code)\n", + " comprehend = boto3.client(\n", + " service_name=\"comprehend\",\n", + " region_name=region,\n", + " aws_access_key_id=access_code,\n", + " aws_secret_access_key=secret_code,\n", + " )\n", "\n", - " \n", " # Iterate through the lines in the list of lines\n", " for line in lines:\n", - "\n", " # construct a list to hold all found entities for a single line\n", " entities_list = []\n", "\n", " # Call the DetectEntities operation and pass it a line from lines\n", - " found_entities = comprehend.detect_entities(Text=line, LanguageCode='en')\n", + " found_entities = comprehend.detect_entities(Text=line, LanguageCode=\"en\")\n", " for response_data, values in found_entities.items():\n", " for item in values:\n", " if \"Text\" in item:\n", @@ -205,7 +211,7 @@ "metadata": {}, "outputs": [], "source": [ - "print('Calling DetectEntities:')\n", + "print(\"Calling DetectEntities:\")\n", "print(\"------\")\n", "response_ents = entity_detection(lines, access_key, secret_key, region_name)" ] @@ -225,8 +231,8 @@ "metadata": {}, "outputs": [], "source": [ - "entities_dict = {\"Lines\":lines, \"Entities\":response_ents}\n", - "df = pd.DataFrame(entities_dict, columns=[\"Lines\",\"Entities\"])\n", + "entities_dict = {\"Lines\": lines, \"Entities\": response_ents}\n", + "df = pd.DataFrame(entities_dict, columns=[\"Lines\", \"Entities\"])\n", "print(df)" ] } diff --git a/python/cross_service/textract_comprehend_notebook/test-texttract-comprehend.py b/python/cross_service/textract_comprehend_notebook/test-texttract-comprehend.py index b61cde52d54..1cfe8c017ae 100644 --- a/python/cross_service/textract_comprehend_notebook/test-texttract-comprehend.py +++ b/python/cross_service/textract_comprehend_notebook/test-texttract-comprehend.py @@ -1,8 +1,8 @@ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 -from testbook import testbook import boto3 +from testbook import testbook # Get AWS credentials session = boto3.Session() diff --git a/python/cross_service/textract_explorer/test/conftest.py b/python/cross_service/textract_explorer/test/conftest.py index 3ffb09531a2..c2f9e6da0b5 100644 --- a/python/cross_service/textract_explorer/test/conftest.py +++ b/python/cross_service/textract_explorer/test/conftest.py @@ -8,5 +8,15 @@ import sys # This is needed so Python can find test_tools on the path. -sys.path.append("../..") -from test_tools.fixtures.common import * +sys.path.append("../..") # noqa + +from test_tools.fixtures.common import ( + pytest_configure, + fixture_make_stubber, + fixture_make_unique_name, + fixture_make_bucket, + StubRunner, + stub_runner, + InputMocker, + input_mocker, +) diff --git a/python/cross_service/textract_explorer/test/test_textract_wrapper.py b/python/cross_service/textract_explorer/test/test_textract_wrapper.py index 8b6e1377eaf..05f981bd57a 100644 --- a/python/cross_service/textract_explorer/test/test_textract_wrapper.py +++ b/python/cross_service/textract_explorer/test/test_textract_wrapper.py @@ -5,13 +5,13 @@ Unit tests for textract_wrapper.py. """ -from io import BytesIO import json -from unittest.mock import patch, mock_open +from io import BytesIO +from unittest.mock import mock_open, patch + import boto3 -from botocore.exceptions import ClientError import pytest - +from botocore.exceptions import ClientError from textract_wrapper import TextractWrapper diff --git a/python/cross_service/textract_explorer/textract_app.py b/python/cross_service/textract_explorer/textract_app.py index 7fe177cf6ae..b460d8424db 100644 --- a/python/cross_service/textract_explorer/textract_app.py +++ b/python/cross_service/textract_explorer/textract_app.py @@ -9,12 +9,12 @@ image. """ -from io import BytesIO import logging -import tkinter import threading +import tkinter +from io import BytesIO + from PIL import Image, ImageTk -from textract_wrapper import TextractWrapper logger = logging.getLogger(__name__) diff --git a/python/cross_service/textract_explorer/textract_demo_launcher.py b/python/cross_service/textract_explorer/textract_demo_launcher.py index d29b7c8ffc5..8224cdfb509 100644 --- a/python/cross_service/textract_explorer/textract_demo_launcher.py +++ b/python/cross_service/textract_explorer/textract_demo_launcher.py @@ -10,11 +10,12 @@ """ import argparse -from io import BytesIO import logging +from io import BytesIO + import boto3 -from textract_wrapper import TextractWrapper from textract_app import TextractExplorer +from textract_wrapper import TextractWrapper logger = logging.getLogger(__name__) @@ -118,7 +119,7 @@ def main(): print("-" * 88) print("Demonstrating how to use Amazon Textract.") print("-" * 88) - usage_demo(outputs) + usage_demo(outputs) # pylint: disable=E0606 print("-" * 88) print( "To clean up all AWS resources created for the demo, run this script " diff --git a/python/cross_service/textract_explorer/textract_wrapper.py b/python/cross_service/textract_explorer/textract_wrapper.py index 78379b690fa..816c7608885 100644 --- a/python/cross_service/textract_explorer/textract_wrapper.py +++ b/python/cross_service/textract_explorer/textract_wrapper.py @@ -10,6 +10,7 @@ import json import logging + from botocore.exceptions import ClientError logger = logging.getLogger(__name__) diff --git a/python/example_code/auto-scaling/README.md b/python/example_code/auto-scaling/README.md index 90818c5420c..c23134f9860 100644 --- a/python/example_code/auto-scaling/README.md +++ b/python/example_code/auto-scaling/README.md @@ -50,9 +50,9 @@ Code examples that show you how to perform the essential operations within a ser Code excerpts that show you how to call individual service functions. -- [AttachLoadBalancerTargetGroups](../../cross_service/resilient_service/auto_scaler.py#L615) +- [AttachLoadBalancerTargetGroups](../../cross_service/resilient_service/auto_scaler.py#L599) - [CreateAutoScalingGroup](action_wrapper.py#L31) -- [DeleteAutoScalingGroup](../../cross_service/resilient_service/auto_scaler.py#L656) +- [DeleteAutoScalingGroup](../../cross_service/resilient_service/auto_scaler.py#L639) - [DescribeAutoScalingGroups](action_wrapper.py#L167) - [DescribeAutoScalingInstances](action_wrapper.py#L284) - [DescribeScalingActivities](action_wrapper.py#L317) diff --git a/python/example_code/ec2/README.md b/python/example_code/ec2/README.md index 590ff78290d..6d19b3851f3 100644 --- a/python/example_code/ec2/README.md +++ b/python/example_code/ec2/README.md @@ -54,24 +54,24 @@ Code excerpts that show you how to call individual service functions. - [AssociateAddress](elastic_ip.py#L82) - [AuthorizeSecurityGroupIngress](security_group.py#L68) - [CreateKeyPair](key_pair.py#L57) -- [CreateLaunchTemplate](../../cross_service/resilient_service/auto_scaler.py#L393) +- [CreateLaunchTemplate](../../cross_service/resilient_service/auto_scaler.py#L383) - [CreateSecurityGroup](security_group.py#L42) - [DeleteKeyPair](key_pair.py#L118) -- [DeleteLaunchTemplate](../../cross_service/resilient_service/auto_scaler.py#L458) +- [DeleteLaunchTemplate](../../cross_service/resilient_service/auto_scaler.py#L447) - [DeleteSecurityGroup](security_group.py#L148) -- [DescribeAvailabilityZones](../../cross_service/resilient_service/auto_scaler.py#L485) -- [DescribeIamInstanceProfileAssociations](../../cross_service/resilient_service/auto_scaler.py#L220) +- [DescribeAvailabilityZones](../../cross_service/resilient_service/auto_scaler.py#L473) +- [DescribeIamInstanceProfileAssociations](../../cross_service/resilient_service/auto_scaler.py#L216) - [DescribeImages](instance.py#L253) - [DescribeInstanceTypes](instance.py#L274) - [DescribeInstances](instance.py#L106) - [DescribeKeyPairs](key_pair.py#L89) - [DescribeSecurityGroups](security_group.py#L108) -- [DescribeSubnets](../../cross_service/resilient_service/auto_scaler.py#L842) -- [DescribeVpcs](../../cross_service/resilient_service/auto_scaler.py#L702) +- [DescribeSubnets](../../cross_service/resilient_service/auto_scaler.py#L821) +- [DescribeVpcs](../../cross_service/resilient_service/auto_scaler.py#L684) - [DisassociateAddress](elastic_ip.py#L121) - [RebootInstances](../../cross_service/resilient_service/auto_scaler.py#L18) - [ReleaseAddress](elastic_ip.py#L162) -- [ReplaceIamInstanceProfileAssociation](../../cross_service/resilient_service/auto_scaler.py#L249) +- [ReplaceIamInstanceProfileAssociation](../../cross_service/resilient_service/auto_scaler.py#L244) - [RunInstances](instance.py#L43) - [StartInstances](instance.py#L190) - [StopInstances](instance.py#L221) diff --git a/python/example_code/elastic-load-balancing/README.md b/python/example_code/elastic-load-balancing/README.md index a38b6073b4b..452902b1321 100644 --- a/python/example_code/elastic-load-balancing/README.md +++ b/python/example_code/elastic-load-balancing/README.md @@ -47,13 +47,13 @@ python -m pip install -r requirements.txt Code excerpts that show you how to call individual service functions. -- [CreateListener](../../cross_service/resilient_service/load_balancer.py#L194) -- [CreateLoadBalancer](../../cross_service/resilient_service/load_balancer.py#L142) +- [CreateListener](../../cross_service/resilient_service/load_balancer.py#L191) +- [CreateLoadBalancer](../../cross_service/resilient_service/load_balancer.py#L140) - [CreateTargetGroup](../../cross_service/resilient_service/load_balancer.py#L28) -- [DeleteLoadBalancer](../../cross_service/resilient_service/load_balancer.py#L255) -- [DeleteTargetGroup](../../cross_service/resilient_service/load_balancer.py#L84) -- [DescribeLoadBalancers](../../cross_service/resilient_service/load_balancer.py#L288) -- [DescribeTargetHealth](../../cross_service/resilient_service/load_balancer.py#L342) +- [DeleteLoadBalancer](../../cross_service/resilient_service/load_balancer.py#L251) +- [DeleteTargetGroup](../../cross_service/resilient_service/load_balancer.py#L83) +- [DescribeLoadBalancers](../../cross_service/resilient_service/load_balancer.py#L283) +- [DescribeTargetHealth](../../cross_service/resilient_service/load_balancer.py#L336) ### Scenarios diff --git a/python/example_code/iam/README.md b/python/example_code/iam/README.md index 611634ed2e3..e8b6c53585d 100644 --- a/python/example_code/iam/README.md +++ b/python/example_code/iam/README.md @@ -47,7 +47,7 @@ Code excerpts that show you how to call individual service functions. - [AttachUserPolicy](user_wrapper.py#L107) - [CreateAccessKey](access_key_wrapper.py#L21) - [CreateAccountAlias](account_wrapper.py#L23) -- [CreateInstanceProfile](../../cross_service/resilient_service/auto_scaler.py#L154) +- [CreateInstanceProfile](../../cross_service/resilient_service/auto_scaler.py#L151) - [CreatePolicy](policy_wrapper.py#L25) - [CreatePolicyVersion](policy_wrapper.py#L79) - [CreateRole](role_wrapper.py#L23) @@ -55,7 +55,7 @@ Code excerpts that show you how to call individual service functions. - [CreateUser](user_wrapper.py#L25) - [DeleteAccessKey](access_key_wrapper.py#L47) - [DeleteAccountAlias](account_wrapper.py#L44) -- [DeleteInstanceProfile](../../cross_service/resilient_service/auto_scaler.py#L310) +- [DeleteInstanceProfile](../../cross_service/resilient_service/auto_scaler.py#L304) - [DeletePolicy](policy_wrapper.py#L61) - [DeleteRole](role_wrapper.py#L102) - [DeleteUser](user_wrapper.py#L46)