Coverage for src/backend/InvenTree/InvenTree/setting/storages.py: 63%
24 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 17:47 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 17:47 +0000
1"""Settings for storage backends."""
3from enum import Enum
4from typing import Optional
6from InvenTree.config import get_boolean_setting, get_setting
9class StorageBackends(str, Enum):
10 """Enumeration of available storage backends."""
12 LOCAL = 'local'
13 S3 = 's3'
14 SFTP = 'sftp'
17STORAGE_BACKEND_MAPPING = {
18 StorageBackends.LOCAL: 'django.core.files.storage.FileSystemStorage',
19 StorageBackends.S3: 'storages.backends.s3.S3Storage',
20 StorageBackends.SFTP: 'storages.backends.sftpstorage.SFTPStorage',
21}
24def init_storages() -> tuple[str, dict, Optional[str]]:
25 """Initialize storage backend settings."""
26 target = get_setting(
27 'INVENTREE_STORAGE_TARGET',
28 'storage.target',
29 StorageBackends.LOCAL.value,
30 typecast=str,
31 )
33 # Check that the target is valid
34 if target not in STORAGE_BACKEND_MAPPING: 34 ↛ 35line 34 didn't jump to line 35 because the condition on line 34 was never true
35 raise ValueError(f"Invalid storage target: '{target}'")
37 options = {}
38 media_url: Optional[str] = None
39 if target == StorageBackends.S3.value: 39 ↛ 40line 39 didn't jump to line 40 because the condition on line 39 was never true
40 s3_bucket = get_setting(
41 'INVENTREE_S3_BUCKET_NAME', 'storage.s3.bucket_name', None, typecast=str
42 )
43 s3_acl = get_setting(
44 'INVENTREE_S3_DEFAULT_ACL', 'storage.s3.default_acl', None, typecast=str
45 )
46 s3_endpoint = get_setting(
47 'INVENTREE_S3_ENDPOINT_URL', 'storage.s3.endpoint_url', None, typecast=str
48 )
49 s3_location = get_setting(
50 'INVENTREE_S3_LOCATION',
51 'storage.s3.location',
52 'inventree-server',
53 typecast=str,
54 )
56 media_url = f'{s3_endpoint}/{s3_bucket}/{s3_location}/'
57 options = {
58 'access_key': get_setting(
59 'INVENTREE_S3_ACCESS_KEY', 'storage.s3.access_key', None, typecast=str
60 ),
61 'secret_key': get_setting(
62 'INVENTREE_S3_SECRET_KEY', 'storage.s3.secret_key', None, typecast=str
63 ),
64 'bucket_name': s3_bucket,
65 'default_acl': s3_acl,
66 'region_name': get_setting(
67 'INVENTREE_S3_REGION_NAME', 'storage.s3.region_name', None, typecast=str
68 ),
69 'endpoint_url': s3_endpoint,
70 'verify': get_boolean_setting(
71 'INVENTREE_S3_VERIFY_SSL', 'storage.s3.verify_ssl', True
72 ),
73 'location': s3_location,
74 'file_overwrite': get_boolean_setting(
75 'INVENTREE_S3_OVERWRITE', 'storage.s3.overwrite', True
76 ),
77 'addressing_style': 'virtual'
78 if get_boolean_setting('INVENTREE_S3_VIRTUAL', 'storage.s3.virtual', False)
79 else 'path',
80 'object_parameters': {'CacheControl': 'public,max-age=86400'},
81 }
82 elif target == StorageBackends.SFTP: 82 ↛ 83line 82 didn't jump to line 83 because the condition on line 82 was never true
83 options = {
84 'host': get_setting('INVENTREE_SFTP_HOST', 'sftp.host', None, typecast=str),
85 'uid': get_setting('INVENTREE_SFTP_UID', 'sftp.uid', None, typecast=int),
86 'gid': get_setting('INVENTREE_SFTP_GID', 'sftp.gid', None, typecast=int),
87 'location': get_setting(
88 'INVENTREE_SFTP_LOCATION',
89 'sftp.location',
90 'inventree-server',
91 typecast=str,
92 ),
93 'params': get_setting(
94 'INVENTREE_SFTP_PARAMS', 'sftp.params', {}, typecast=dict
95 ),
96 }
97 return (
98 target,
99 {
100 'default': {
101 'BACKEND': STORAGE_BACKEND_MAPPING.get(
102 target, STORAGE_BACKEND_MAPPING[StorageBackends.LOCAL]
103 ),
104 'OPTIONS': options,
105 },
106 'staticfiles': {
107 'BACKEND': 'whitenoise.storage.CompressedStaticFilesStorage'
108 },
109 },
110 media_url,
111 )