Skip to content

Commit f6b8cbf

Browse files
committed
Fix data directory creation
1 parent 4c17adf commit f6b8cbf

File tree

2 files changed

+64
-19
lines changed

2 files changed

+64
-19
lines changed

investing_algorithm_framework/app/app.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
PortfolioConfiguration, SnapshotInterval, DataType, combine_backtests, \
2121
PortfolioProvider, OrderExecutor, ImproperlyConfigured, TimeFrame, \
2222
DataProvider, INDEX_DATETIME, tqdm, BacktestPermutationTest, \
23-
LAST_SNAPSHOT_DATETIME, BACKTESTING_FLAG, generate_backtest_summary_metrics
23+
LAST_SNAPSHOT_DATETIME, BACKTESTING_FLAG, \
24+
generate_backtest_summary_metrics, DATA_DIRECTORY
2425
from investing_algorithm_framework.infrastructure import setup_sqlalchemy, \
2526
create_all_tables, CCXTOrderExecutor, CCXTPortfolioProvider, \
2627
BacktestOrderExecutor, CCXTOHLCVDataProvider, clear_db, \
@@ -368,6 +369,17 @@ def initialize_storage(self, remove_database_if_exists: bool = False):
368369
setup_sqlalchemy(self)
369370
create_all_tables()
370371

372+
# Create the DATA_DIRECTORY if it does not exist
373+
data_directory_dir_name = self.config[DATA_DIRECTORY]
374+
data_directory_path = os.path.join(
375+
resource_directory_path, data_directory_dir_name
376+
)
377+
if not os.path.exists(data_directory_path):
378+
os.makedirs(data_directory_path)
379+
logger.info(
380+
f"Data directory created at {data_directory_path}"
381+
)
382+
371383
def initialize_data_sources(
372384
self,
373385
data_sources: List[DataSource],

investing_algorithm_framework/infrastructure/services/aws/state_handler.py

Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
import logging
33
import boto3
4+
import stat
45
from botocore.exceptions import NoCredentialsError, PartialCredentialsError
56
from investing_algorithm_framework.domain import OperationalException, \
67
StateHandler
@@ -17,22 +18,25 @@ def _fix_permissions(target_directory: str):
1718
"""
1819
try:
1920
# Fix the target directory itself
20-
os.chmod(target_directory, 0o755)
21+
os.chmod(target_directory, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
2122

2223
# Recursively fix all subdirectories and files
2324
for root, dirs, files in os.walk(target_directory):
2425
# Fix current directory permissions
25-
os.chmod(root, 0o755)
26+
os.chmod(root, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
2627

2728
# Fix all subdirectories
2829
for dir_name in dirs:
2930
dir_path = os.path.join(root, dir_name)
30-
os.chmod(dir_path, 0o755)
31+
os.chmod(dir_path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
3132

3233
# Fix all files - make them readable and writable
3334
for file_name in files:
3435
file_path = os.path.join(root, file_name)
35-
os.chmod(file_path, 0o644)
36+
os.chmod(
37+
file_path,
38+
stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH
39+
)
3640

3741
logger.info(f"Update permissions for {target_directory}")
3842
except Exception as e:
@@ -86,8 +90,9 @@ def save(self, source_directory: str):
8690
file_path = os.path.join(root, file_name)
8791

8892
# Construct the S3 object key (relative path in the bucket)
89-
s3_key = os.path.relpath(file_path, source_directory) \
90-
.replace("\\", "/")
93+
s3_key = os.path.relpath(file_path, source_directory)
94+
# Convert to forward slashes for S3 compatibility
95+
s3_key = s3_key.replace(os.sep, "/")
9196

9297
self.s3_client.upload_file(
9398
file_path,
@@ -113,38 +118,66 @@ def load(self, target_directory: str):
113118

114119
try:
115120
if not os.path.exists(target_directory):
116-
os.makedirs(target_directory, mode=0o755)
121+
os.makedirs(
122+
target_directory,
123+
mode=stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO
124+
)
117125

118-
os.chmod(target_directory, 0o755)
126+
os.chmod(
127+
target_directory, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO
128+
)
119129

120130
response = self.s3_client.list_objects_v2(Bucket=self.bucket_name)
121131

122132
if "Contents" in response:
123133
for obj in response["Contents"]:
124134
s3_key = obj["Key"]
125-
file_path = os.path.join(target_directory, s3_key)
135+
# Convert S3 forward slashes to OS-specific separators
136+
file_path = os.path.join(
137+
target_directory, s3_key.replace("/", os.sep)
138+
)
126139

127-
os.makedirs(os.path.dirname(file_path), exist_ok=True,
128-
mode=0o755)
140+
os.makedirs(
141+
os.path.dirname(file_path),
142+
exist_ok=True,
143+
mode=stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO
144+
)
129145

130146
self.s3_client.download_file(
131147
self.bucket_name, s3_key, file_path
132148
)
133149

134150
if os.path.isfile(file_path):
135-
os.chmod(file_path, 0o644)
151+
os.chmod(
152+
file_path,
153+
stat.S_IRUSR |
154+
stat.S_IWUSR |
155+
stat.S_IRGRP |
156+
stat.S_IROTH
157+
)
136158
else:
137-
os.chmod(file_path, 0o755)
159+
os.chmod(
160+
file_path,
161+
stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO
162+
)
138163

139164
# Final recursive fix
140165
_fix_permissions(target_directory)
141166

142-
# Add write permission to file (
143-
# 0o666 = rw-rw-rw-, then masked by umask)
144-
db_file = os.path.join(target_directory,
145-
'databases/prod-database.sqlite3')
167+
# Add write permission to database file
168+
db_file = os.path.join(
169+
target_directory, "databases", "prod-database.sqlite3"
170+
)
146171
if os.path.exists(db_file):
147-
os.chmod(db_file, 0o666)
172+
os.chmod(
173+
db_file,
174+
stat.S_IRUSR |
175+
stat.S_IWUSR |
176+
stat.S_IRGRP |
177+
stat.S_IWGRP |
178+
stat.S_IROTH |
179+
stat.S_IWOTH
180+
)
148181
logger.info(
149182
f"Database file permissions "
150183
f"after fix: {oct(os.stat(db_file).st_mode)}"

0 commit comments

Comments
 (0)