Skip to content

Commit 3f14a51

Browse files
authored
Merge pull request #58 from faekiva/ruff #none
Added formatter
2 parents 5202624 + 1cbf3f5 commit 3f14a51

File tree

20 files changed

+714
-537
lines changed

20 files changed

+714
-537
lines changed

.github/workflows/pr-verify.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,15 @@ jobs:
2929
uv sync --locked --directory src/
3030
uv run --directory src/ pytest
3131
32+
code-quality:
33+
runs-on: ubuntu-latest
34+
steps:
35+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
36+
- uses: astral-sh/ruff-action@v3
37+
with:
38+
args: "format --check --diff"
39+
src: ./src
40+
version-file: ./src/pyproject.toml
3241
build:
3342
runs-on: ubuntu-latest
3443
steps:

src/pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ dev = [
1212
"black>=25.1.0",
1313
"pre-commit>=4.2.0",
1414
"pytest>=7.4.0",
15+
"ruff>=0.12.3",
1516
]
1617

1718
[tool.pytest.ini_options]

src/restic_compose_backup/alerts/__init__.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,26 @@
55

66
logger = logging.getLogger(__name__)
77

8-
ALERT_INFO = 'INFO',
9-
ALERT_ERROR = 'ERROR'
8+
ALERT_INFO = ("INFO",)
9+
ALERT_ERROR = "ERROR"
1010
ALERT_TYPES = [ALERT_INFO, ALERT_ERROR]
1111
BACKENDS = [SMTPAlert, DiscordWebhookAlert]
1212

1313

14-
def send(subject: str = None, body: str = None, alert_type: str = 'INFO'):
14+
def send(subject: str = None, body: str = None, alert_type: str = "INFO"):
1515
"""Send alert to all configured backends"""
1616
alert_classes = configured_alert_types()
1717
for instance in alert_classes:
18-
logger.info('Configured: %s', instance.name)
18+
logger.info("Configured: %s", instance.name)
1919
try:
2020
instance.send(
21-
subject=f'[{alert_type}] {subject}',
21+
subject=f"[{alert_type}] {subject}",
2222
body=body,
2323
)
2424
except Exception as ex:
25-
logger.error("Exception raised when sending alert [%s]: %s", instance.name, ex)
25+
logger.error(
26+
"Exception raised when sending alert [%s]: %s", instance.name, ex
27+
)
2628
logger.exception(ex)
2729

2830
if len(alert_classes) == 0:
@@ -31,12 +33,14 @@ def send(subject: str = None, body: str = None, alert_type: str = 'INFO'):
3133

3234
def configured_alert_types():
3335
"""Returns a list of configured alert class instances"""
34-
logger.debug('Getting alert backends')
36+
logger.debug("Getting alert backends")
3537
entires = []
3638

3739
for cls in BACKENDS:
3840
instance = cls.create_from_env()
39-
logger.debug("Alert backend '%s' configured: %s", cls.name, instance is not None)
41+
logger.debug(
42+
"Alert backend '%s' configured: %s", cls.name, instance is not None
43+
)
4044
if instance:
4145
entires.append(instance)
4246

src/restic_compose_backup/alerts/base.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
2-
31
class BaseAlert:
42
name = None
53

src/restic_compose_backup/alerts/discord.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88

99

1010
class DiscordWebhookAlert(BaseAlert):
11-
name = 'discord_webhook'
11+
name = "discord_webhook"
1212
success_codes = [200]
1313

1414
def __init__(self, webhook_url):
1515
self.url = webhook_url
1616

1717
@classmethod
1818
def create_from_env(cls):
19-
instance = cls(os.environ.get('DISCORD_WEBHOOK'))
19+
instance = cls(os.environ.get("DISCORD_WEBHOOK"))
2020

2121
if instance.properly_configured:
2222
return instance
@@ -34,15 +34,17 @@ def send(self, subject: str = None, body: str = None, alert_type: str = None):
3434
# The max description size is 2048
3535
# Total embed size limit is 6000 characters (per embed)
3636
data = {
37-
'embeds': [
37+
"embeds": [
3838
{
39-
'title': subject[-256:],
40-
'description': body[-2048:] if body else "",
39+
"title": subject[-256:],
40+
"description": body[-2048:] if body else "",
4141
},
4242
]
4343
}
44-
response = requests.post(self.url, params={'wait': True}, json=data)
44+
response = requests.post(self.url, params={"wait": True}, json=data)
4545
if response.status_code not in self.success_codes:
46-
logger.error("Discord webhook failed: %s: %s", response.status_code, response.content)
46+
logger.error(
47+
"Discord webhook failed: %s: %s", response.status_code, response.content
48+
)
4749
else:
48-
logger.info('Discord webhook successful')
50+
logger.info("Discord webhook successful")

src/restic_compose_backup/alerts/smtp.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010

1111
class SMTPAlert(BaseAlert):
12-
name = 'smtp'
12+
name = "smtp"
1313

1414
def __init__(self, host, port, user, password, to):
1515
self.host = host
@@ -21,11 +21,11 @@ def __init__(self, host, port, user, password, to):
2121
@classmethod
2222
def create_from_env(cls):
2323
instance = cls(
24-
os.environ.get('EMAIL_HOST'),
25-
os.environ.get('EMAIL_PORT'),
26-
os.environ.get('EMAIL_HOST_USER'),
27-
os.environ.get('EMAIL_HOST_PASSWORD'),
28-
(os.environ.get('EMAIL_SEND_TO') or "").split(','),
24+
os.environ.get("EMAIL_HOST"),
25+
os.environ.get("EMAIL_PORT"),
26+
os.environ.get("EMAIL_HOST_USER"),
27+
os.environ.get("EMAIL_HOST_PASSWORD"),
28+
(os.environ.get("EMAIL_SEND_TO") or "").split(","),
2929
)
3030
if instance.properly_configured:
3131
return instance
@@ -36,11 +36,11 @@ def create_from_env(cls):
3636
def properly_configured(self) -> bool:
3737
return self.host and self.port and self.user and len(self.to) > 0
3838

39-
def send(self, subject: str = None, body: str = None, alert_type: str = 'INFO'):
39+
def send(self, subject: str = None, body: str = None, alert_type: str = "INFO"):
4040
msg = MIMEText(body)
41-
msg['Subject'] = f"[{alert_type}] {subject}"
42-
msg['From'] = self.user
43-
msg['To'] = ', '.join(self.to)
41+
msg["Subject"] = f"[{alert_type}] {subject}"
42+
msg["From"] = self.user
43+
msg["To"] = ", ".join(self.to)
4444

4545
try:
4646
logger.info("Connecting to %s port %s", self.host, self.port)
@@ -52,15 +52,17 @@ def send(self, subject: str = None, body: str = None, alert_type: str = 'INFO'):
5252
try:
5353
server.starttls()
5454
except smtplib.SMTPHeloError:
55-
logger.error("The server didn't reply properly to the HELO greeting. Email not sent.")
55+
logger.error(
56+
"The server didn't reply properly to the HELO greeting. Email not sent."
57+
)
5658
return
5759
except smtplib.SMTPNotSupportedError:
5860
logger.error("STARTTLS not supported on server. Email not sent.")
5961
return
6062
server.ehlo()
6163
server.login(self.user, self.password)
6264
server.sendmail(self.user, self.to, msg.as_string())
63-
logger.info('Email sent')
65+
logger.info("Email sent")
6466
except Exception as ex:
6567
logger.exception(ex)
6668
finally:

src/restic_compose_backup/backup_runner.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,14 @@
66
logger = logging.getLogger(__name__)
77

88

9-
def run(image: str = None, command: str = None, volumes: dict = None,
10-
environment: dict = None, labels: dict = None, source_container_id: str = None):
9+
def run(
10+
image: str = None,
11+
command: str = None,
12+
volumes: dict = None,
13+
environment: dict = None,
14+
labels: dict = None,
15+
source_container_id: str = None,
16+
):
1117
logger.info("Starting backup container")
1218
client = utils.docker_client()
1319

@@ -17,9 +23,9 @@ def run(image: str = None, command: str = None, volumes: dict = None,
1723
labels=labels,
1824
# auto_remove=True, # We remove the container further down
1925
detach=True,
20-
environment=environment + ['BACKUP_PROCESS_CONTAINER=true'],
26+
environment=environment + ["BACKUP_PROCESS_CONTAINER=true"],
2127
volumes=volumes,
22-
network_mode=f'container:{source_container_id}', # Reuse original container's network stack.
28+
network_mode=f"container:{source_container_id}", # Reuse original container's network stack.
2329
working_dir=os.getcwd(),
2430
tty=True,
2531
)
@@ -40,7 +46,7 @@ def readlines(stream):
4046
line += data.decode()
4147
elif isinstance(data, str):
4248
line += data
43-
if line.endswith('\n'):
49+
if line.endswith("\n"):
4450
break
4551
except StopIteration:
4652
break
@@ -49,15 +55,15 @@ def readlines(stream):
4955
else:
5056
break
5157

52-
with open('backup.log', 'w') as fd:
58+
with open("backup.log", "w") as fd:
5359
for line in readlines(log_generator):
5460
fd.write(line)
55-
fd.write('\n')
61+
fd.write("\n")
5662
print(line)
5763

5864
container.wait()
5965
container.reload()
60-
logger.debug("Container ExitCode %s", container.attrs['State']['ExitCode'])
66+
logger.debug("Container ExitCode %s", container.attrs["State"]["ExitCode"])
6167
container.remove()
6268

63-
return container.attrs['State']['ExitCode']
69+
return container.attrs["State"]["ExitCode"]

0 commit comments

Comments
 (0)