Skip to content

Commit a0bb204

Browse files
authored
30881 - AUTH-API to use Ruff (bcgov#3527)
1 parent 10fc039 commit a0bb204

File tree

181 files changed

+1197
-1769
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

181 files changed

+1197
-1769
lines changed

auth-api/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""Root package for the auth-api application."""

auth-api/gunicorn_config.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14-
"""The configuration for gunicorn, which picks up the
15-
runtime options from environment variables.
14+
"""The configuration for gunicorn, which picks up the runtime options from environment variables.
1615
17-
The best practice so far is For environments with multiple CPU cores, increase the number of workers to be equal to
18-
the cores available. Timeout is set to 0 to disable the timeouts of the workers to allow Cloud Run to handle instance
19-
scaling. Adjust the number of workers and threads on a per-application basis.
16+
The best practice so far is For environments with multiple CPU cores, increase the number of workers to be equal to
17+
the cores available. Timeout is set to 0 to disable the timeouts of the workers to allow Cloud Run to handle instance
18+
scaling. Adjust the number of workers and threads on a per-application basis.
2019
"""
20+
2121
import os
2222

2323
workers = int(os.environ.get("GUNICORN_PROCESSES", "1")) # pylint: disable=invalid-name

auth-api/lint

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
poetry run isort . && poetry run black . && poetry run pylint . && poetry run flake8 .
1+
poetry run ruff format . && poetry run ruff check --fix .

auth-api/poetry.lock

Lines changed: 33 additions & 240 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

auth-api/pyproject.toml

Lines changed: 102 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -62,89 +62,121 @@ pytest-asyncio = "^0.23.8"
6262
lovely-pytest-docker = "^0.3.1"
6363

6464
[tool.poetry.group.dev.dependencies]
65-
black = "^24.8.0"
66-
pylint = "^3.2.6"
6765
bandit = "^1.7.9"
68-
flake8-pyproject = "^1.2.3"
69-
isort = "^5.13.2"
66+
ruff = "^0.14.1"
7067

7168
[tool.bandit]
7269
exclude_dirs = [".venv","tests"]
7370
skips = ["B104"]
7471

75-
[tool.flake8]
76-
ignore = ["F401","E402", "Q000", "E203", "W503"]
72+
[tool.ruff]
73+
# Exclude a variety of commonly ignored directories.
7774
exclude = [
78-
".venv",
79-
"./venv",
75+
".bzr",
76+
".direnv",
77+
".eggs",
8078
".git",
81-
".history",
79+
".git-rewrite",
80+
".hg",
81+
".mypy_cache",
82+
".nox",
83+
".pants.d",
84+
".pytype",
85+
".ruff_cache",
86+
".svn",
87+
".tox",
88+
".venv",
89+
"__pypackages__",
90+
"_build",
91+
"buck-out",
92+
"build",
93+
"dist",
94+
"node_modules",
95+
"venv",
96+
"migrations",
8297
"devops",
83-
"*migrations*",
98+
".history",
8499
]
85-
per-file-ignores = [
86-
"__init__.py:F401",
87-
"*.py:B902"
100+
101+
# Same as Black.
102+
line-length = 120
103+
indent-width = 4
104+
105+
# Assume Python 3.12
106+
target-version = "py312"
107+
108+
[tool.ruff.lint]
109+
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
110+
select = [
111+
"E4", # pycodestyle errors
112+
"E7", # pycodestyle errors
113+
"E9", # pycodestyle errors
114+
"F", # pyflakes
115+
"W", # pycodestyle warnings
116+
"B", # flake8-bugbear
117+
"C4", # flake8-comprehensions
118+
"UP", # pyupgrade
119+
"ARG", # unused-function-argument
120+
"D", # pydocstyle
121+
"I", # isort
122+
"N", # pep8-naming
123+
"Q", # flake8-quotes
124+
"S", # flake8-bandit
125+
"T", # flake8-type-checking
126+
"TCH", # flake8-type-checking
127+
"TID", # flake8-tidy-imports
88128
]
89-
max-line-length = 120
90-
docstring-min-length=10
91-
count = true
92129

93-
[tool.zimports]
94-
black-line-length = 120
95-
keep-unused-type-checking = true
130+
# Allow fix for all enabled rules (when `--fix`) is provided.
131+
fixable = ["ALL"]
132+
unfixable = []
96133

97-
[tool.black]
98-
target-version = ["py310", "py311", "py312"]
99-
line-length = 120
100-
include = '\.pyi?$'
101-
extend-exclude = '''
102-
/(
103-
# The following are specific to Black, you probably don't want those.
104-
migrations
105-
| devops
106-
| .history
107-
)/
108-
'''
109-
110-
[tool.isort]
111-
atomic = true
112-
profile = "black"
113-
line_length = 120
114-
skip_gitignore = true
115-
skip_glob = ["migrations", "devops"]
116-
117-
[tool.pylint.main]
118-
fail-under = 10
119-
max-line-length = 120
120-
ignore = [ "migrations", "devops", "tests"]
121-
ignore-patterns = ["^\\.#"]
122-
ignored-modules= ["flask_sqlalchemy", "sqlalchemy", "SQLAlchemy" , "alembic", "scoped_session"]
123-
ignored-classes= "scoped_session"
124-
ignore-long-lines = "^\\s*(# )?<?https?://\\S+>?$"
125-
extension-pkg-whitelist = "pydantic"
126-
notes = ["FIXME","XXX","TODO"]
127-
overgeneral-exceptions = ["builtins.BaseException", "builtins.Exception"]
128-
confidence = ["HIGH", "CONTROL_FLOW", "INFERENCE", "INFERENCE_FAILURE", "UNDEFINED"]
129-
disable = "C0209,C0301,W0511,W0613,W0703,W1514,W1203,R0801,R0902,R0903,R0911,R0401,R1705,R1718,W3101"
130-
argument-naming-style = "snake_case"
131-
attr-naming-style = "snake_case"
132-
class-attribute-naming-style = "any"
133-
class-const-naming-style = "UPPER_CASE"
134-
class-naming-style = "PascalCase"
135-
const-naming-style = "UPPER_CASE"
136-
function-naming-style = "snake_case"
137-
inlinevar-naming-style = "any"
138-
method-naming-style = "snake_case"
139-
module-naming-style = "any"
140-
variable-naming-style = "snake_case"
141-
docstring-min-length = -1
142-
good-names = ["i", "j", "k", "ex", "Run", "_"]
143-
bad-names = ["foo", "bar", "baz", "toto", "tutu", "tata"]
144-
defining-attr-methods = ["__init__", "__new__", "setUp", "asyncSetUp", "__post_init__"]
145-
exclude-protected = ["_asdict", "_fields", "_replace", "_source", "_make", "os._exit"]
146-
valid-classmethod-first-arg = ["cls"]
147-
valid-metaclass-classmethod-first-arg = ["mcs"]
134+
# Allow unused variables when underscore-prefixed.
135+
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
136+
137+
[tool.ruff.lint.per-file-ignores]
138+
# Tests can use magic values, assertions, and relative imports
139+
"tests/**/*.py" = ["PLR2004", "S101", "TID252", "ARG001", "B006", "B008", "S311", "T201"]
140+
# Allow magic values in tests
141+
"**/test_*.py" = ["PLR2004", "S101", "TID252", "ARG001", "B006", "B008", "S311", "T201"]
142+
# Allow magic values in conftest.py
143+
"conftest.py" = ["PLR2004", "S101", "TID252", "ARG001", "B006", "B008", "S311", "T201"]
144+
# Allow magic values in migrations
145+
"migrations/**/*.py" = ["PLR2004", "S101", "TID252"]
146+
# Allow magic values in devops
147+
"devops/**/*.py" = ["PLR2004", "S101", "TID252"]
148+
# Allow unused imports in __init__.py and ignore N999 (invalid module name)
149+
"__init__.py" = ["F401", "N999"]
150+
151+
[tool.ruff.lint.isort]
152+
known-first-party = ["pay_api"]
153+
154+
[tool.ruff.lint.flake8-quotes]
155+
docstring-quotes = "double"
156+
157+
[tool.ruff.lint.pydocstyle]
158+
convention = "google"
159+
160+
[tool.ruff.format]
161+
# Like Black, use double quotes for strings.
162+
quote-style = "double"
163+
164+
# Like Black, indent with spaces, rather than tabs.
165+
indent-style = "space"
166+
167+
# Like Black, respect magic trailing commas.
168+
skip-magic-trailing-comma = false
169+
170+
# Like Black, automatically detect the appropriate line ending.
171+
line-ending = "auto"
172+
173+
# Enable auto-formatting of code examples in docstrings. Markdown,
174+
# reStructuredText code/literal blocks and doctests are all supported.
175+
docstring-code-format = false
176+
177+
# Set the line length limit used when formatting code snippets in
178+
# docstrings.
179+
docstring-code-line-length = "dynamic"
148180

149181
[tool.pytest.ini_options]
150182
asyncio_mode = "auto"

auth-api/src/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""Source package for the auth-api application."""

auth-api/src/auth_api/__init__.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@
1515
1616
This module is the API for the Authroization system.
1717
"""
18+
1819
import os
1920
import traceback
2021

2122
from cloud_sql_connector import DBConfig, setup_search_path_event_listener
22-
from flask import Flask, request
23+
from flask import Flask, request # noqa: TC002
2324
from flask_cors import CORS
2425
from flask_migrate import Migrate, upgrade
2526
from sbc_common_components.utils.camel_case_response import convert_to_camel
@@ -40,8 +41,10 @@
4041
setup_logging(os.path.join(_Config.PROJECT_ROOT, "logging.conf"))
4142

4243

43-
def create_app(run_mode=os.getenv("DEPLOYMENT_ENV", "production")):
44+
def create_app(run_mode=None):
4445
"""Return a configured Flask App using the Factory method."""
46+
if run_mode is None:
47+
run_mode = os.getenv("DEPLOYMENT_ENV", "production")
4548
app = Flask(__name__)
4649
app.config["ENV"] = run_mode
4750
app.config.from_object(config.CONFIGURATION[run_mode])

auth-api/src/auth_api/config.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121

2222
import os
2323
import sys
24-
from typing import List
2524

2625
from dotenv import find_dotenv, load_dotenv
2726

@@ -58,7 +57,7 @@ class _Config: # pylint: disable=too-few-public-methods
5857

5958
PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
6059

61-
SECRET_KEY = "a secret"
60+
SECRET_KEY = "a secret" # noqa: S105
6261
TESTING = False
6362
DEBUG = False
6463

@@ -182,7 +181,7 @@ class _Config: # pylint: disable=too-few-public-methods
182181
API_GW_KC_CLIENT_ID_PATTERN = os.getenv("API_GW_KC_CLIENT_ID_PATTERN", "api-key-account-{account_id}")
183182

184183
# NR Supported Request types.
185-
NR_SUPPORTED_REQUEST_TYPES: List[str] = os.getenv("NR_SUPPORTED_REQUEST_TYPES", "BC").replace(" ", "").split(",")
184+
NR_SUPPORTED_REQUEST_TYPES: list[str] = os.getenv("NR_SUPPORTED_REQUEST_TYPES", "BC").replace(" ", "").split(",")
186185
AUTH_WEB_SANDBOX_HOST = os.getenv("AUTH_WEB_SANDBOX_HOST", "localhost")
187186

188187
# LaunchDarkly SDK key
@@ -322,7 +321,7 @@ class ProdConfig(_Config): # pylint: disable=too-few-public-methods
322321

323322
if not SECRET_KEY:
324323
SECRET_KEY = os.urandom(24)
325-
print("WARNING: SECRET_KEY being set as a one-shot", file=sys.stderr)
324+
print("WARNING: SECRET_KEY being set as a one-shot", file=sys.stderr) # noqa: T201
326325

327326
TESTING = False
328327
DEBUG = False

auth-api/src/auth_api/exceptions/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
status_code - where possible use HTTP Error Codes
88
"""
99

10-
from auth_api.exceptions.errors import Error # noqa: I001, I003
10+
from auth_api.exceptions.errors import Error # noqa: I001
1111
from auth_api.exceptions.exception_handler import ExceptionHandler
1212
from auth_api.exceptions.exceptions import (
1313
BCOLException,

auth-api/src/auth_api/exceptions/exception_handler.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414
"""Function to handle all exceptions."""
15+
1516
import logging
1617
import traceback
1718

@@ -47,7 +48,7 @@ def db_handler(self, error): # pylint: disable=useless-option-value
4748
logger.exception(error_message)
4849
error_text = error.__dict__["code"] if hasattr(error.__dict__, "code") else ""
4950
status_code = error.status_code if hasattr(error, "status_code") else 500
50-
return {"error": "{}".format(error_text), "message": "{}".format(message_text)}, status_code, RESPONSE_HEADERS
51+
return {"error": f"{error_text}", "message": f"{message_text}"}, status_code, RESPONSE_HEADERS
5152

5253
def std_handler(self, error): # pylint: disable=useless-option-value
5354
"""Handle standard exception."""
@@ -96,6 +97,7 @@ def _get_exc_class_and_code(exc_class_or_code):
9697
else:
9798
exc_class = exc_class_or_code
9899

99-
assert issubclass(exc_class, Exception)
100+
if not issubclass(exc_class, Exception):
101+
raise ValueError("exc_class must be a subclass of Exception")
100102

101103
return exc_class

0 commit comments

Comments
 (0)