ref: Add ruff rules for Pathlib (PTH) (#4035)

Add ruff rules for Pathlib (PTH)
This commit is contained in:
Christophe Bornet 2024-10-07 14:24:00 +02:00 • committed by GitHub
commit a021009ee5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 90 additions and 76 deletions

View file

@ -94,7 +94,8 @@ def partition_file_to_data(file_path: str, silent_errors: bool) -> Data | None:
def read_text_file(file_path: str) -> str: def read_text_file(file_path: str) -> str:
with open(file_path, "rb") as f: _file_path = Path(file_path)
with _file_path.open("rb") as f:
raw_data = f.read() raw_data = f.read()
result = chardet.detect(raw_data) result = chardet.detect(raw_data)
encoding = result["encoding"] encoding = result["encoding"]
@ -102,7 +103,7 @@ def read_text_file(file_path: str) -> str:
if encoding in ["Windows-1252", "Windows-1254", "MacRoman"]: if encoding in ["Windows-1252", "Windows-1254", "MacRoman"]:
encoding = "utf-8" encoding = "utf-8"
with open(file_path, encoding=encoding) as f: with _file_path.open(encoding=encoding) as f:
return f.read() return f.read()
@ -116,7 +117,7 @@ def read_docx_file(file_path: str) -> str:
def parse_pdf_to_text(file_path: str) -> str: def parse_pdf_to_text(file_path: str) -> str:
from pypdf import PdfReader # type: ignore from pypdf import PdfReader # type: ignore
with open(file_path, "rb") as f: with Path(file_path).open("rb") as f:
reader = PdfReader(f) reader = PdfReader(f)
return "\n\n".join([page.extract_text() for page in reader.pages]) return "\n\n".join([page.extract_text() for page in reader.pages])

View file

@ -22,12 +22,13 @@ class JsonAgentComponent(LCAgentComponent):
] ]
def build_agent(self) -> AgentExecutor: def build_agent(self) -> AgentExecutor:
path = Path(self.path)
if self.path.endswith("yaml") or self.path.endswith("yml"): if self.path.endswith("yaml") or self.path.endswith("yml"):
with open(self.path) as file: with path.open() as file:
yaml_dict = yaml.load(file, Loader=yaml.FullLoader) yaml_dict = yaml.load(file, Loader=yaml.FullLoader)
spec = JsonSpec(dict_=yaml_dict) spec = JsonSpec(dict_=yaml_dict)
else: else:
spec = JsonSpec.from_file(Path(self.path)) spec = JsonSpec.from_file(path)
toolkit = JsonToolkit(spec=spec) toolkit = JsonToolkit(spec=spec)
return create_json_agent(llm=self.llm, toolkit=toolkit, **self.get_agent_kwargs()) return create_json_agent(llm=self.llm, toolkit=toolkit, **self.get_agent_kwargs())

View file

@ -24,12 +24,13 @@ class OpenAPIAgentComponent(LCAgentComponent):
] ]
def build_agent(self) -> AgentExecutor: def build_agent(self) -> AgentExecutor:
path = Path(self.path)
if self.path.endswith("yaml") or self.path.endswith("yml"): if self.path.endswith("yaml") or self.path.endswith("yml"):
with open(self.path) as file: with path.open() as file:
yaml_dict = yaml.load(file, Loader=yaml.FullLoader) yaml_dict = yaml.load(file, Loader=yaml.FullLoader)
spec = JsonSpec(dict_=yaml_dict) spec = JsonSpec(dict_=yaml_dict)
else: else:
spec = JsonSpec.from_file(Path(self.path)) spec = JsonSpec.from_file(path)
requests_wrapper = TextRequestsWrapper() requests_wrapper = TextRequestsWrapper()
toolkit = OpenAPIToolkit.from_llm( toolkit = OpenAPIToolkit.from_llm(
llm=self.llm, llm=self.llm,

View file

@ -1,4 +1,4 @@
import os from pathlib import Path
import assemblyai as aai import assemblyai as aai
from loguru import logger from loguru import logger
@ -161,7 +161,7 @@ class AssemblyAITranscriptionJobCreator(Component):
logger.warning("Both an audio file an audio URL were specified. The audio URL was ignored.") logger.warning("Both an audio file an audio URL were specified. The audio URL was ignored.")
# Check if the file exists # Check if the file exists
if not os.path.exists(self.audio_file): if not Path(self.audio_file).exists():
self.status = "Error: Audio file not found" self.status = "Error: Audio file not found"
return Data(data={"error": "Error: Audio file not found"}) return Data(data={"error": "Error: Audio file not found"})
audio = self.audio_file audio = self.audio_file

View file

@ -64,7 +64,7 @@ class GitLoaderComponent(Component):
This is necessary because when searches are performed using This is necessary because when searches are performed using
the content_filter, binary files need to be ignored. the content_filter, binary files need to be ignored.
""" """
with open(file_path, "rb") as file: with Path(file_path).open("rb") as file:
return b"\x00" in file.read(1024) return b"\x00" in file.read(1024)
def build_gitloader(self) -> GitLoader: def build_gitloader(self) -> GitLoader:

View file

@ -51,7 +51,7 @@ class CSVToDataComponent(Component):
if file_path.suffix.lower() != ".csv": if file_path.suffix.lower() != ".csv":
msg = "The provided file must be a CSV file." msg = "The provided file must be a CSV file."
raise ValueError(msg) raise ValueError(msg)
with open(file_path, newline="", encoding="utf-8") as csvfile: with file_path.open(newline="", encoding="utf-8") as csvfile:
csv_data = csvfile.read() csv_data = csvfile.read()
elif self.csv_path: elif self.csv_path:
@ -59,7 +59,7 @@ class CSVToDataComponent(Component):
if file_path.suffix.lower() != ".csv": if file_path.suffix.lower() != ".csv":
msg = "The provided file must be a CSV file." msg = "The provided file must be a CSV file."
raise ValueError(msg) raise ValueError(msg)
with open(file_path, newline="", encoding="utf-8") as csvfile: with file_path.open(newline="", encoding="utf-8") as csvfile:
csv_data = csvfile.read() csv_data = csvfile.read()
elif self.csv_string: elif self.csv_string:

View file

@ -54,7 +54,7 @@ class JSONToDataComponent(Component):
if file_path.suffix.lower() != ".json": if file_path.suffix.lower() != ".json":
msg = "The provided file must be a JSON file." msg = "The provided file must be a JSON file."
raise ValueError(msg) raise ValueError(msg)
with open(file_path, encoding="utf-8") as jsonfile: with file_path.open(encoding="utf-8") as jsonfile:
json_data = jsonfile.read() json_data = jsonfile.read()
elif self.json_path: elif self.json_path:
@ -62,7 +62,7 @@ class JSONToDataComponent(Component):
if file_path.suffix.lower() != ".json": if file_path.suffix.lower() != ".json":
msg = "The provided file must be a JSON file." msg = "The provided file must be a JSON file."
raise ValueError(msg) raise ValueError(msg)
with open(file_path, encoding="utf-8") as jsonfile: with file_path.open(encoding="utf-8") as jsonfile:
json_data = jsonfile.read() json_data = jsonfile.read()
elif self.json_string: elif self.json_string:

View file

@ -1,3 +1,5 @@
from pathlib import Path
from langchain.text_splitter import CharacterTextSplitter from langchain.text_splitter import CharacterTextSplitter
from langchain_community.vectorstores.redis import Redis from langchain_community.vectorstores.redis import Redis
@ -53,7 +55,7 @@ class RedisVectorStoreComponent(LCVectorStoreComponent):
documents.append(_input.to_lc_document()) documents.append(_input.to_lc_document())
else: else:
documents.append(_input) documents.append(_input)
with open("docuemnts.txt", "w") as f: with Path("docuemnts.txt").open("w") as f:
f.write(str(documents)) f.write(str(documents))
if not documents: if not documents:

View file

@ -2,6 +2,7 @@ import ast
import contextlib import contextlib
import inspect import inspect
import traceback import traceback
from pathlib import Path
from typing import Any from typing import Any
from cachetools import TTLCache, keys from cachetools import TTLCache, keys
@ -30,7 +31,7 @@ def find_class_ast_node(class_obj):
return None, [] return None, []
# Read the source code from the file # Read the source code from the file
with open(source_file) as file: with Path(source_file).open() as file:
source_code = file.read() source_code = file.read()
# Parse the source code into an AST # Parse the source code into an AST

View file

@ -1,6 +1,5 @@
import ast import ast
import asyncio import asyncio
import os
import zlib import zlib
from pathlib import Path from pathlib import Path
@ -58,8 +57,8 @@ class DirectoryReader:
def is_valid_path(self) -> bool: def is_valid_path(self) -> bool:
"""Check if the directory path is valid by comparing it to the base path.""" """Check if the directory path is valid by comparing it to the base path."""
fullpath = os.path.normpath(os.path.join(self.directory_path)) fullpath = Path(self.directory_path).resolve()
return fullpath.startswith(self.base_path) return not self.base_path or fullpath.is_relative_to(self.base_path)
def is_empty_file(self, file_content): def is_empty_file(self, file_content):
""" """
@ -107,16 +106,17 @@ class DirectoryReader:
""" """
Read and return the content of a file. Read and return the content of a file.
""" """
if not os.path.isfile(file_path): _file_path = Path(file_path)
if not _file_path.is_file():
return None return None
with open(file_path, encoding="utf-8") as file: with _file_path.open(encoding="utf-8") as file:
# UnicodeDecodeError: 'charmap' codec can't decode byte 0x9d in position 3069: character maps to <undefined> # UnicodeDecodeError: 'charmap' codec can't decode byte 0x9d in position 3069: character maps to <undefined>
try: try:
return file.read() return file.read()
except UnicodeDecodeError: except UnicodeDecodeError:
# This is happening in Windows, so we need to open the file in binary mode # This is happening in Windows, so we need to open the file in binary mode
# The file is always just a python file, so we can safely read it as utf-8 # The file is always just a python file, so we can safely read it as utf-8
with open(file_path, "rb") as file: with _file_path.open("rb") as file:
return file.read().decode("utf-8") return file.read().decode("utf-8")
def get_files(self): def get_files(self):
@ -245,15 +245,16 @@ class DirectoryReader:
logger.debug("-------------------- Building component menu list --------------------") logger.debug("-------------------- Building component menu list --------------------")
for file_path in file_paths: for file_path in file_paths:
menu_name = os.path.basename(os.path.dirname(file_path)) _file_path = Path(file_path)
filename = os.path.basename(file_path) menu_name = _file_path.parent.name
filename = _file_path.name
validation_result, result_content = self.process_file(file_path) validation_result, result_content = self.process_file(file_path)
if not validation_result: if not validation_result:
logger.error(f"Error while processing file {file_path}") logger.error(f"Error while processing file {file_path}")
menu_result = self.find_menu(response, menu_name) or { menu_result = self.find_menu(response, menu_name) or {
"name": menu_name, "name": menu_name,
"path": os.path.dirname(file_path), "path": str(_file_path.parent),
"components": [], "components": [],
} }
component_name = filename.split(".")[0] component_name = filename.split(".")[0]
@ -323,15 +324,16 @@ class DirectoryReader:
results = await asyncio.gather(*tasks) results = await asyncio.gather(*tasks)
for file_path, (validation_result, result_content) in zip(file_paths, results, strict=True): for file_path, (validation_result, result_content) in zip(file_paths, results, strict=True):
menu_name = os.path.basename(os.path.dirname(file_path)) _file_path = Path(file_path)
filename = os.path.basename(file_path) menu_name = _file_path.parent.name
filename = _file_path.name
if not validation_result: if not validation_result:
logger.error(f"Error while processing file {file_path}") logger.error(f"Error while processing file {file_path}")
menu_result = self.find_menu(response, menu_name) or { menu_result = self.find_menu(response, menu_name) or {
"name": menu_name, "name": menu_name,
"path": os.path.dirname(file_path), "path": str(_file_path.parent),
"components": [], "components": [],
} }
component_name = filename.split(".")[0] component_name = filename.split(".")[0]

View file

@ -1,6 +1,5 @@
import copy import copy
import json import json
import os
import shutil import shutil
import time import time
from collections import defaultdict from collections import defaultdict
@ -352,7 +351,7 @@ def load_starter_projects(retries=3, delay=1) -> list[tuple[Path, dict]]:
for file in folder.glob("*.json"): for file in folder.glob("*.json"):
attempt = 0 attempt = 0
while attempt < retries: while attempt < retries:
with open(file, encoding="utf-8") as f: with file.open(encoding="utf-8") as f:
try: try:
project = orjson.loads(f.read()) project = orjson.loads(f.read())
starter_projects.append((file, project)) starter_projects.append((file, project))
@ -372,12 +371,12 @@ def copy_profile_pictures():
origin = Path(__file__).parent / "profile_pictures" origin = Path(__file__).parent / "profile_pictures"
target = Path(config_dir) / "profile_pictures" target = Path(config_dir) / "profile_pictures"
if not os.path.exists(origin): if not origin.exists():
msg = f"The source folder '{origin}' does not exist." msg = f"The source folder '{origin}' does not exist."
raise ValueError(msg) raise ValueError(msg)
if not os.path.exists(target): if not target.exists():
os.makedirs(target) target.mkdir(parents=True)
try: try:
shutil.copytree(origin, target, dirs_exist_ok=True) shutil.copytree(origin, target, dirs_exist_ok=True)
@ -411,9 +410,9 @@ def get_project_data(project):
) )
def update_project_file(project_path, project, updated_project_data): def update_project_file(project_path: Path, project: dict, updated_project_data):
project["data"] = updated_project_data project["data"] = updated_project_data
with open(project_path, "w", encoding="utf-8") as f: with project_path.open("w", encoding="utf-8") as f:
f.write(orjson.dumps(project, option=ORJSON_OPTIONS).decode()) f.write(orjson.dumps(project, option=ORJSON_OPTIONS).decode())
logger.info(f"Updated starter project {project['name']} file") logger.info(f"Updated starter project {project['name']} file")
@ -516,14 +515,15 @@ def load_flows_from_directory():
with session_scope() as session: with session_scope() as session:
user_id = get_user_by_username(session, settings_service.auth_settings.SUPERUSER).id user_id = get_user_by_username(session, settings_service.auth_settings.SUPERUSER).id
files = [f for f in os.listdir(flows_path) if os.path.isfile(os.path.join(flows_path, f))] _flows_path = Path(flows_path)
for filename in files: files = [f for f in _flows_path.iterdir() if f.is_file()]
if not filename.endswith(".json"): for f in files:
if f.suffix != ".json":
continue continue
logger.info(f"Loading flow from file: {filename}") logger.info(f"Loading flow from file: {f.name}")
with open(os.path.join(flows_path, filename), encoding="utf-8") as file: with f.open(encoding="utf-8") as file:
flow = orjson.loads(file.read()) flow = orjson.loads(file.read())
no_json_name = filename.replace(".json", "") no_json_name = f.stem
flow_endpoint_name = flow.get("endpoint_name") flow_endpoint_name = flow.get("endpoint_name")
if _is_valid_uuid(no_json_name): if _is_valid_uuid(no_json_name):
flow["id"] = no_json_name flow["id"] = no_json_name

View file

@ -3,6 +3,7 @@ import json
import os import os
import re import re
from io import BytesIO from io import BytesIO
from pathlib import Path
import yaml import yaml
from langchain_core.language_models import BaseLanguageModel from langchain_core.language_models import BaseLanguageModel
@ -14,12 +15,13 @@ from langflow.services.deps import get_settings_service
def load_file_into_dict(file_path: str) -> dict: def load_file_into_dict(file_path: str) -> dict:
if not os.path.exists(file_path): _file_path = Path(file_path)
if not _file_path.exists():
msg = f"File not found: {file_path}" msg = f"File not found: {file_path}"
raise FileNotFoundError(msg) raise FileNotFoundError(msg)
# Files names are UUID, so we can't find the extension # Files names are UUID, so we can't find the extension
with open(file_path) as file: with _file_path.open() as file:
try: try:
data = json.load(file) data = json.load(file)
except json.JSONDecodeError: except json.JSONDecodeError:

View file

@ -53,7 +53,7 @@ def load_flow_from_json(
update_settings(cache=cache) update_settings(cache=cache)
if isinstance(flow, str | Path): if isinstance(flow, str | Path):
with open(flow, encoding="utf-8") as f: with Path(flow).open(encoding="utf-8") as f:
flow_graph = json.load(f) flow_graph = json.load(f)
# If input is a dictionary, assume it's a JSON object # If input is a dictionary, assume it's a JSON object
elif isinstance(flow, dict): elif isinstance(flow, dict):

View file

@ -1,9 +1,11 @@
from pathlib import Path
import httpx import httpx
from langflow.services.database.models.flow.model import FlowBase from langflow.services.database.models.flow.model import FlowBase
def upload(file_path, host, flow_id): def upload(file_path: str, host: str, flow_id: str):
""" """
Upload a file to Langflow and return the file path. Upload a file to Langflow and return the file path.
@ -20,7 +22,7 @@ def upload(file_path, host, flow_id):
""" """
try: try:
url = f"{host}/api/v1/upload/{flow_id}" url = f"{host}/api/v1/upload/{flow_id}"
with open(file_path, "rb") as file: with Path(file_path).open("rb") as file:
response = httpx.post(url, files={"file": file}) response = httpx.post(url, files={"file": file})
if response.status_code == 200 or response.status_code == 201: if response.status_code == 200 or response.status_code == 201:
return response.json() return response.json()

View file

@ -1,7 +1,6 @@
import base64 import base64
import contextlib import contextlib
import hashlib import hashlib
import os
import tempfile import tempfile
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING, Any from typing import TYPE_CHECKING, Any
@ -33,7 +32,7 @@ def create_cache_folder(func):
cache_path = Path(CACHE_DIR) / PREFIX cache_path = Path(CACHE_DIR) / PREFIX
# Create the destination folder if it doesn't exist # Create the destination folder if it doesn't exist
os.makedirs(cache_path, exist_ok=True) cache_path.mkdir(parents=True, exist_ok=True)
return func(*args, **kwargs) return func(*args, **kwargs)
@ -50,7 +49,7 @@ def clear_old_cache_files(max_cache_size: int = 3):
for cache_file in cache_files_sorted_by_mtime[max_cache_size:]: for cache_file in cache_files_sorted_by_mtime[max_cache_size:]:
with contextlib.suppress(OSError): with contextlib.suppress(OSError):
os.remove(cache_file) cache_file.unlink()
def filter_json(json_data): def filter_json(json_data):
@ -102,13 +101,13 @@ def save_binary_file(content: str, file_name: str, accepted_types: list[str]) ->
decoded_bytes = base64.b64decode(data) decoded_bytes = base64.b64decode(data)
# Create the full file path # Create the full file path
file_path = os.path.join(cache_path, file_name) file_path = cache_path / file_name
# Save the binary content to the file # Save the binary content to the file
with open(file_path, "wb") as file: with file_path.open("wb") as file:
file.write(decoded_bytes) file.write(decoded_bytes)
return file_path return str(file_path)
@create_cache_folder @create_cache_folder
@ -150,7 +149,8 @@ def save_uploaded_file(file: UploadFile, folder_name):
# Save the file with the hash as its name # Save the file with the hash as its name
file_path = folder_path / file_name file_path = folder_path / file_name
with open(file_path, "wb") as new_file:
with file_path.open("wb") as new_file:
while chunk := file_object.read(8192): while chunk := file_object.read(8192):
new_file.write(chunk) new_file.write(chunk)

View file

@ -175,7 +175,7 @@ class DatabaseService(Service):
# which is a buffer # which is a buffer
# I don't want to output anything # I don't want to output anything
# subprocess.DEVNULL is an int # subprocess.DEVNULL is an int
with open(self.script_location / "alembic.log", "w") as buffer: with (self.script_location / "alembic.log").open("w") as buffer:
alembic_cfg = Config(stdout=buffer) alembic_cfg = Config(stdout=buffer)
# alembic_cfg.attributes["connection"] = session # alembic_cfg.attributes["connection"] = session
alembic_cfg.set_main_option("script_location", str(self.script_location)) alembic_cfg.set_main_option("script_location", str(self.script_location))

View file

@ -2,7 +2,7 @@ from __future__ import annotations
import importlib import importlib
import inspect import inspect
import os from pathlib import Path
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from loguru import logger from loguru import logger
@ -20,15 +20,15 @@ class PluginService(Service):
def __init__(self, settings_service: SettingsService): def __init__(self, settings_service: SettingsService):
self.plugins: dict[str, BasePlugin] = {} self.plugins: dict[str, BasePlugin] = {}
# plugin_dir = settings_service.settings.PLUGIN_DIR # plugin_dir = settings_service.settings.PLUGIN_DIR
self.plugin_dir = os.path.dirname(__file__) self.plugin_dir = Path(__file__).parent
self.plugins_base_module = "langflow.services.plugins" self.plugins_base_module = "langflow.services.plugins"
self.load_plugins() self.load_plugins()
def load_plugins(self): def load_plugins(self):
base_files = ["base.py", "service.py", "factory.py", "__init__.py"] base_files = ["base.py", "service.py", "factory.py", "__init__.py"]
for module in os.listdir(self.plugin_dir): for module in self.plugin_dir.iterdir():
if module.endswith(".py") and module not in base_files: if module.suffix == ".py" and module.name not in base_files:
plugin_name = module[:-3] plugin_name = module.stem
module_path = f"{self.plugins_base_module}.{plugin_name}" module_path = f"{self.plugins_base_module}.{plugin_name}"
try: try:
mod = importlib.import_module(module_path) mod = importlib.import_module(module_path)

View file

@ -360,7 +360,7 @@ class Settings(BaseSettings):
def save_settings_to_yaml(settings: Settings, file_path: str): def save_settings_to_yaml(settings: Settings, file_path: str):
with open(file_path, "w") as f: with Path(file_path).open("w") as f:
settings_dict = settings.model_dump() settings_dict = settings.model_dump()
yaml.dump(settings_dict, f) yaml.dump(settings_dict, f)
@ -369,11 +369,12 @@ def load_settings_from_yaml(file_path: str) -> Settings:
# Check if a string is a valid path or a file name # Check if a string is a valid path or a file name
if "/" not in file_path: if "/" not in file_path:
# Get current path # Get current path
current_path = os.path.dirname(os.path.abspath(__file__)) current_path = Path(__file__).resolve().parent
_file_path = Path(current_path) / file_path
else:
_file_path = Path(file_path)
file_path = os.path.join(current_path, file_path) with _file_path.open() as f:
with open(file_path) as f:
settings_dict = yaml.safe_load(f) settings_dict = yaml.safe_load(f)
settings_dict = {k.upper(): v for k, v in settings_dict.items()} settings_dict = {k.upper(): v for k, v in settings_dict.items()}

View file

@ -1,6 +1,6 @@
from __future__ import annotations from __future__ import annotations
import os from pathlib import Path
import yaml import yaml
from loguru import logger from loguru import logger
@ -23,11 +23,12 @@ class SettingsService(Service):
# Check if a string is a valid path or a file name # Check if a string is a valid path or a file name
if "/" not in file_path: if "/" not in file_path:
# Get current path # Get current path
current_path = os.path.dirname(os.path.abspath(__file__)) current_path = Path(__file__).resolve().parent
_file_path = Path(current_path) / file_path
else:
_file_path = Path(file_path)
file_path = os.path.join(current_path, file_path) with _file_path.open() as f:
with open(file_path) as f:
settings_dict = yaml.safe_load(f) settings_dict = yaml.safe_load(f)
settings_dict = {k.upper(): v for k, v in settings_dict.items()} settings_dict = {k.upper(): v for k, v in settings_dict.items()}

View file

@ -1,20 +1,19 @@
import os
import platform import platform
from pathlib import Path from pathlib import Path
from loguru import logger from loguru import logger
def set_secure_permissions(file_path): def set_secure_permissions(file_path: Path):
if platform.system() in ["Linux", "Darwin"]: # Unix/Linux/Mac if platform.system() in ["Linux", "Darwin"]: # Unix/Linux/Mac
os.chmod(file_path, 0o600) file_path.chmod(0o600)
elif platform.system() == "Windows": elif platform.system() == "Windows":
import win32api import win32api
import win32con import win32con
import win32security import win32security
user, domain, _ = win32security.LookupAccountName("", win32api.GetUserName()) user, domain, _ = win32security.LookupAccountName("", win32api.GetUserName())
sd = win32security.GetFileSecurity(file_path, win32security.DACL_SECURITY_INFORMATION) sd = win32security.GetFileSecurity(str(file_path), win32security.DACL_SECURITY_INFORMATION)
dacl = win32security.ACL() dacl = win32security.ACL()
# Set the new DACL for the file: read and write access for the owner, no access for everyone else # Set the new DACL for the file: read and write access for the owner, no access for everyone else
@ -24,7 +23,7 @@ def set_secure_permissions(file_path):
user, user,
) )
sd.SetSecurityDescriptorDacl(1, dacl, 0) sd.SetSecurityDescriptorDacl(1, dacl, 0)
win32security.SetFileSecurity(file_path, win32security.DACL_SECURITY_INFORMATION, sd) win32security.SetFileSecurity(str(file_path), win32security.DACL_SECURITY_INFORMATION, sd)
else: else:
print("Unsupported OS") print("Unsupported OS")

View file

@ -35,7 +35,7 @@ class LocalStorageService(StorageService):
file_path = folder_path / file_name file_path = folder_path / file_name
def write_file(file_path: Path, data: bytes) -> None: def write_file(file_path: Path, data: bytes) -> None:
with open(file_path, "wb") as f: with Path(file_path).open("wb") as f:
f.write(data) f.write(data)
try: try:
@ -61,7 +61,7 @@ class LocalStorageService(StorageService):
raise FileNotFoundError(msg) raise FileNotFoundError(msg)
def read_file(file_path: Path) -> bytes: def read_file(file_path: Path) -> bytes:
with open(file_path, "rb") as f: with Path(file_path).open("rb") as f:
return f.read() return f.read()
content = await asyncio.get_event_loop().run_in_executor(None, read_file, file_path) content = await asyncio.get_event_loop().run_in_executor(None, read_file, file_path)

View file

@ -64,6 +64,7 @@ select = [
"PD", "PD",
"PIE", "PIE",
"PT", "PT",
"PTH",
"PYI", "PYI",
"Q", "Q",
"RET", "RET",