fractal-server 2.2.0a0__py3-none-any.whl → 2.2.0a1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fractal_server/__init__.py +1 -1
- fractal_server/app/db/__init__.py +1 -1
- fractal_server/app/runner/v2/__init__.py +47 -31
- fractal_server/config.py +38 -18
- fractal_server/migrations/env.py +1 -1
- {fractal_server-2.2.0a0.dist-info → fractal_server-2.2.0a1.dist-info}/METADATA +3 -1
- {fractal_server-2.2.0a0.dist-info → fractal_server-2.2.0a1.dist-info}/RECORD +10 -10
- {fractal_server-2.2.0a0.dist-info → fractal_server-2.2.0a1.dist-info}/LICENSE +0 -0
- {fractal_server-2.2.0a0.dist-info → fractal_server-2.2.0a1.dist-info}/WHEEL +0 -0
- {fractal_server-2.2.0a0.dist-info → fractal_server-2.2.0a1.dist-info}/entry_points.txt +0 -0
fractal_server/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__VERSION__ = "2.2.
|
1
|
+
__VERSION__ = "2.2.0a1"
|
@@ -126,41 +126,57 @@ async def submit_workflow(
|
|
126
126
|
db_sync.close()
|
127
127
|
return
|
128
128
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
os.umask(original_umask)
|
133
|
-
|
134
|
-
# Define and create WORKFLOW_DIR_REMOTE
|
135
|
-
if FRACTAL_RUNNER_BACKEND == "local":
|
136
|
-
WORKFLOW_DIR_REMOTE = WORKFLOW_DIR_LOCAL
|
137
|
-
elif FRACTAL_RUNNER_BACKEND == "local_experimental":
|
138
|
-
WORKFLOW_DIR_REMOTE = WORKFLOW_DIR_LOCAL
|
139
|
-
elif FRACTAL_RUNNER_BACKEND == "slurm":
|
140
|
-
WORKFLOW_DIR_REMOTE = (
|
141
|
-
Path(user_cache_dir) / WORKFLOW_DIR_LOCAL.name
|
142
|
-
)
|
143
|
-
_mkdir_as_user(folder=str(WORKFLOW_DIR_REMOTE), user=slurm_user)
|
144
|
-
|
145
|
-
# Create all tasks subfolders
|
146
|
-
for order in range(job.first_task_index, job.last_task_index + 1):
|
147
|
-
this_wftask = workflow.task_list[order]
|
148
|
-
if this_wftask.is_legacy_task:
|
149
|
-
task_name = this_wftask.task_legacy.name
|
150
|
-
else:
|
151
|
-
task_name = this_wftask.task.name
|
152
|
-
subfolder_name = task_subfolder_name(
|
153
|
-
order=order,
|
154
|
-
task_name=task_name,
|
155
|
-
)
|
129
|
+
try:
|
130
|
+
|
131
|
+
# Create WORKFLOW_DIR
|
156
132
|
original_umask = os.umask(0)
|
157
|
-
|
133
|
+
WORKFLOW_DIR_LOCAL.mkdir(parents=True, mode=0o755)
|
134
|
+
|
158
135
|
os.umask(original_umask)
|
159
|
-
|
136
|
+
|
137
|
+
# Define and create WORKFLOW_DIR_REMOTE
|
138
|
+
if FRACTAL_RUNNER_BACKEND == "local":
|
139
|
+
WORKFLOW_DIR_REMOTE = WORKFLOW_DIR_LOCAL
|
140
|
+
elif FRACTAL_RUNNER_BACKEND == "local_experimental":
|
141
|
+
WORKFLOW_DIR_REMOTE = WORKFLOW_DIR_LOCAL
|
142
|
+
elif FRACTAL_RUNNER_BACKEND == "slurm":
|
143
|
+
WORKFLOW_DIR_REMOTE = (
|
144
|
+
Path(user_cache_dir) / WORKFLOW_DIR_LOCAL.name
|
145
|
+
)
|
160
146
|
_mkdir_as_user(
|
161
|
-
folder=str(WORKFLOW_DIR_REMOTE
|
162
|
-
|
147
|
+
folder=str(WORKFLOW_DIR_REMOTE), user=slurm_user
|
148
|
+
)
|
149
|
+
|
150
|
+
# Create all tasks subfolders
|
151
|
+
for order in range(job.first_task_index, job.last_task_index + 1):
|
152
|
+
this_wftask = workflow.task_list[order]
|
153
|
+
if this_wftask.is_legacy_task:
|
154
|
+
task_name = this_wftask.task_legacy.name
|
155
|
+
else:
|
156
|
+
task_name = this_wftask.task.name
|
157
|
+
subfolder_name = task_subfolder_name(
|
158
|
+
order=order,
|
159
|
+
task_name=task_name,
|
163
160
|
)
|
161
|
+
original_umask = os.umask(0)
|
162
|
+
(WORKFLOW_DIR_LOCAL / subfolder_name).mkdir(mode=0o755)
|
163
|
+
os.umask(original_umask)
|
164
|
+
if FRACTAL_RUNNER_BACKEND == "slurm":
|
165
|
+
_mkdir_as_user(
|
166
|
+
folder=str(WORKFLOW_DIR_REMOTE / subfolder_name),
|
167
|
+
user=slurm_user,
|
168
|
+
)
|
169
|
+
except Exception as e:
|
170
|
+
job.status = JobStatusTypeV2.FAILED
|
171
|
+
job.end_timestamp = get_timestamp()
|
172
|
+
job.log = (
|
173
|
+
"An error occurred while creating job folder and subfolders.\n"
|
174
|
+
f"Original error: {str(e)}"
|
175
|
+
)
|
176
|
+
db_sync.merge(job)
|
177
|
+
db_sync.commit()
|
178
|
+
db_sync.close()
|
179
|
+
return
|
164
180
|
|
165
181
|
# After Session.commit() is called, either explicitly or when using a
|
166
182
|
# context manager, all objects associated with the Session are expired.
|
fractal_server/config.py
CHANGED
@@ -166,7 +166,7 @@ class Settings(BaseSettings):
|
|
166
166
|
###########################################################################
|
167
167
|
# DATABASE
|
168
168
|
###########################################################################
|
169
|
-
DB_ENGINE: Literal["sqlite", "postgres"] = "sqlite"
|
169
|
+
DB_ENGINE: Literal["sqlite", "postgres", "postgres-psycopg"] = "sqlite"
|
170
170
|
"""
|
171
171
|
Select which database engine to use (supported: `sqlite` and `postgres`).
|
172
172
|
"""
|
@@ -201,39 +201,51 @@ class Settings(BaseSettings):
|
|
201
201
|
"""
|
202
202
|
|
203
203
|
@property
|
204
|
-
def
|
205
|
-
if self.DB_ENGINE == "
|
206
|
-
if not self.SQLITE_PATH:
|
207
|
-
raise FractalConfigurationError(
|
208
|
-
"SQLITE_PATH path cannot be None"
|
209
|
-
)
|
210
|
-
sqlite_path = abspath(self.SQLITE_PATH)
|
204
|
+
def DATABASE_ASYNC_URL(self) -> URL:
|
205
|
+
if self.DB_ENGINE == "postgres":
|
211
206
|
url = URL.create(
|
212
|
-
drivername="
|
213
|
-
|
207
|
+
drivername="postgresql+asyncpg",
|
208
|
+
username=self.POSTGRES_USER,
|
209
|
+
password=self.POSTGRES_PASSWORD,
|
210
|
+
host=self.POSTGRES_HOST,
|
211
|
+
port=self.POSTGRES_PORT,
|
212
|
+
database=self.POSTGRES_DB,
|
214
213
|
)
|
215
|
-
|
216
|
-
elif "postgres":
|
214
|
+
elif self.DB_ENGINE == "postgres-psycopg":
|
217
215
|
url = URL.create(
|
218
|
-
drivername="postgresql+
|
216
|
+
drivername="postgresql+psycopg",
|
219
217
|
username=self.POSTGRES_USER,
|
220
218
|
password=self.POSTGRES_PASSWORD,
|
221
219
|
host=self.POSTGRES_HOST,
|
222
220
|
port=self.POSTGRES_PORT,
|
223
221
|
database=self.POSTGRES_DB,
|
224
222
|
)
|
225
|
-
|
223
|
+
else:
|
224
|
+
if not self.SQLITE_PATH:
|
225
|
+
raise FractalConfigurationError(
|
226
|
+
"SQLITE_PATH path cannot be None"
|
227
|
+
)
|
228
|
+
sqlite_path = abspath(self.SQLITE_PATH)
|
229
|
+
url = URL.create(
|
230
|
+
drivername="sqlite+aiosqlite",
|
231
|
+
database=sqlite_path,
|
232
|
+
)
|
233
|
+
return url
|
226
234
|
|
227
235
|
@property
|
228
236
|
def DATABASE_SYNC_URL(self):
|
229
|
-
if self.DB_ENGINE == "
|
237
|
+
if self.DB_ENGINE == "postgres":
|
238
|
+
return self.DATABASE_ASYNC_URL.set(
|
239
|
+
drivername="postgresql+psycopg2"
|
240
|
+
)
|
241
|
+
elif self.DB_ENGINE == "postgres-psycopg":
|
242
|
+
return self.DATABASE_ASYNC_URL.set(drivername="postgresql+psycopg")
|
243
|
+
else:
|
230
244
|
if not self.SQLITE_PATH:
|
231
245
|
raise FractalConfigurationError(
|
232
246
|
"SQLITE_PATH path cannot be None"
|
233
247
|
)
|
234
|
-
return self.
|
235
|
-
elif self.DB_ENGINE == "postgres":
|
236
|
-
return self.DATABASE_URL.set(drivername="postgresql+psycopg2")
|
248
|
+
return self.DATABASE_ASYNC_URL.set(drivername="sqlite")
|
237
249
|
|
238
250
|
###########################################################################
|
239
251
|
# FRACTAL SPECIFIC
|
@@ -420,6 +432,14 @@ class Settings(BaseSettings):
|
|
420
432
|
"DB engine is `postgres` but `psycopg2` or `asyncpg` "
|
421
433
|
"are not available"
|
422
434
|
)
|
435
|
+
elif self.DB_ENGINE == "postgres-psycopg":
|
436
|
+
try:
|
437
|
+
import psycopg # noqa: F401
|
438
|
+
except ModuleNotFoundError:
|
439
|
+
raise FractalConfigurationError(
|
440
|
+
"DB engine is `postgres-psycopg` but `psycopg` is not "
|
441
|
+
"available"
|
442
|
+
)
|
423
443
|
else:
|
424
444
|
if not self.SQLITE_PATH:
|
425
445
|
raise FractalConfigurationError(
|
fractal_server/migrations/env.py
CHANGED
@@ -54,7 +54,7 @@ def run_migrations_offline() -> None:
|
|
54
54
|
settings = Inject(get_settings)
|
55
55
|
settings.check_db()
|
56
56
|
context.configure(
|
57
|
-
url=settings.
|
57
|
+
url=settings.DATABASE_ASYNC_URL,
|
58
58
|
target_metadata=target_metadata,
|
59
59
|
literal_binds=True,
|
60
60
|
dialect_opts={"paramstyle": "named"},
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: fractal-server
|
3
|
-
Version: 2.2.
|
3
|
+
Version: 2.2.0a1
|
4
4
|
Summary: Server component of the Fractal analytics platform
|
5
5
|
Home-page: https://github.com/fractal-analytics-platform/fractal-server
|
6
6
|
License: BSD-3-Clause
|
@@ -15,6 +15,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.12
|
16
16
|
Provides-Extra: gunicorn
|
17
17
|
Provides-Extra: postgres
|
18
|
+
Provides-Extra: postgres-psycopg-binary
|
18
19
|
Requires-Dist: aiosqlite (>=0.19.0,<0.20.0)
|
19
20
|
Requires-Dist: alembic (>=1.13.1,<2.0.0)
|
20
21
|
Requires-Dist: asyncpg (>=0.29.0,<0.30.0) ; extra == "postgres"
|
@@ -26,6 +27,7 @@ Requires-Dist: fastapi-users[oauth] (>=12.1.0,<13.0.0)
|
|
26
27
|
Requires-Dist: gunicorn (>=21.2,<23.0) ; extra == "gunicorn"
|
27
28
|
Requires-Dist: packaging (>=23.2,<24.0)
|
28
29
|
Requires-Dist: psycopg2 (>=2.9.5,<3.0.0) ; extra == "postgres"
|
30
|
+
Requires-Dist: psycopg[binary] (>=3.1.0,<4.0.0) ; extra == "postgres-psycopg-binary"
|
29
31
|
Requires-Dist: pydantic (>=1.10.8,<2)
|
30
32
|
Requires-Dist: python-dotenv (>=1.0.0,<2.0.0)
|
31
33
|
Requires-Dist: sqlalchemy[asyncio] (>=2.0.23,<2.1)
|
@@ -1,8 +1,8 @@
|
|
1
|
-
fractal_server/__init__.py,sha256=
|
1
|
+
fractal_server/__init__.py,sha256=OybDAJMDuOmSHsn4iMvNgAcwadADya5I7nZmG0SV3VY,24
|
2
2
|
fractal_server/__main__.py,sha256=CocbzZooX1UtGqPi55GcHGNxnrJXFg5tUU5b3wyFCyo,4958
|
3
3
|
fractal_server/alembic.ini,sha256=MWwi7GzjzawI9cCAK1LW7NxIBQDUqD12-ptJoq5JpP0,3153
|
4
4
|
fractal_server/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
|
-
fractal_server/app/db/__init__.py,sha256=
|
5
|
+
fractal_server/app/db/__init__.py,sha256=KpS_mfmRfew0kieFDlwkSrDFvpzxftcvPALBBZ0LxsY,4048
|
6
6
|
fractal_server/app/models/__init__.py,sha256=QGRjxBgk6GzHyyXh_7RuHvpLoe5PTl1g5KLkGqhFYMQ,199
|
7
7
|
fractal_server/app/models/linkuserproject.py,sha256=eQaourbGRshvlMVlKzLYJKHEjfsW1CbWws9yW4eHXhA,567
|
8
8
|
fractal_server/app/models/security.py,sha256=0oYj_cqPcQFsPFDyN4OTsqbXsLlXRcweawjP_iSiRI0,2900
|
@@ -81,7 +81,7 @@ fractal_server/app/runner/v1/_slurm/_submit_setup.py,sha256=KO9c694d318adoPQh9UG
|
|
81
81
|
fractal_server/app/runner/v1/_slurm/get_slurm_config.py,sha256=6pQNNx997bLIfLp0guF09t_O0ZYRXnbEGLktSAcKnic,5999
|
82
82
|
fractal_server/app/runner/v1/common.py,sha256=_L-vjLnWato80VdlB_BFN4G8P4jSM07u-5cnl1T3S34,3294
|
83
83
|
fractal_server/app/runner/v1/handle_failed_job.py,sha256=bHzScC_aIlU3q-bQxGW6rfWV4xbZ2tho_sktjsAs1no,4684
|
84
|
-
fractal_server/app/runner/v2/__init__.py,sha256=
|
84
|
+
fractal_server/app/runner/v2/__init__.py,sha256=989hkJIy601BewBtpl0w_cL_wBKhDmKJq4N3idLbD5s,13999
|
85
85
|
fractal_server/app/runner/v2/_local/__init__.py,sha256=KTj14K6jH8fXGUi5P7u5_RqEE1zF4aXtgPxCKzw46iw,5971
|
86
86
|
fractal_server/app/runner/v2/_local/_local_config.py,sha256=9oi209Dlp35ANfxb_DISqmMKKc6DPaMsmYVWbZLseME,3630
|
87
87
|
fractal_server/app/runner/v2/_local/_submit_setup.py,sha256=MucNOo8Er0F5ZIwH7CnTeXgnFMc6d3pKPkv563QNVi0,1630
|
@@ -126,7 +126,7 @@ fractal_server/app/schemas/v2/task_collection.py,sha256=sY29NQfJrbjiidmVkVjSIH-2
|
|
126
126
|
fractal_server/app/schemas/v2/workflow.py,sha256=Zzx3e-qgkH8le0FUmAx9UrV5PWd7bj14PPXUh_zgZXM,1827
|
127
127
|
fractal_server/app/schemas/v2/workflowtask.py,sha256=atVuVN4aXsVEOmSd-vyg-8_8OnPmqx-gT75rXcn_AlQ,6552
|
128
128
|
fractal_server/app/security/__init__.py,sha256=2-QbwuR-nsuHM_uwKS_WzYvkhnuhO5jUv8UVROetyVk,11169
|
129
|
-
fractal_server/config.py,sha256=
|
129
|
+
fractal_server/config.py,sha256=XiSTdx7wI2Eem-lzeMQhhGAwUwsACCKdUnbiGqDIChY,17219
|
130
130
|
fractal_server/data_migrations/README.md,sha256=_3AEFvDg9YkybDqCLlFPdDmGJvr6Tw7HRI14aZ3LOIw,398
|
131
131
|
fractal_server/gunicorn_fractal.py,sha256=2AOkgxu-oQ-XB578_voT0VuhmAXFTmb0c-nYn1XLy_Q,1231
|
132
132
|
fractal_server/images/__init__.py,sha256=xO6jTLE4EZKO6cTDdJsBmK9cdeh9hFTaSbSuWgQg7y4,196
|
@@ -135,7 +135,7 @@ fractal_server/images/tools.py,sha256=gxeniYy4Z-cp_ToK2LHPJUTVVUUrdpogYdcBUvBuLi
|
|
135
135
|
fractal_server/logger.py,sha256=56wfka6fHaa3Rx5qO009nEs_y8gx5wZ2NUNZZ1I-uvc,5130
|
136
136
|
fractal_server/main.py,sha256=U50BfL1cxpkSMglRmEHILZE1yDpiUhyb4tlrNuE3j6s,4417
|
137
137
|
fractal_server/migrations/README,sha256=4rQvyDfqodGhpJw74VYijRmgFP49ji5chyEemWGHsuw,59
|
138
|
-
fractal_server/migrations/env.py,sha256=
|
138
|
+
fractal_server/migrations/env.py,sha256=Bvg-FJzRJZIH_wqS_ZyZNXANIaathjo22_IY7c3fCjo,2636
|
139
139
|
fractal_server/migrations/script.py.mako,sha256=oMXw9LC3zRbinWWPPDgeZ4z9FJrV2zhRWiYdS5YgNbI,526
|
140
140
|
fractal_server/migrations/versions/4c308bcaea2b_add_task_args_schema_and_task_args_.py,sha256=-wHe-fOffmYeAm0JXVl_lxZ7hhDkaEVqxgxpHkb_uL8,954
|
141
141
|
fractal_server/migrations/versions/4cedeb448a53_workflowtask_foreign_keys_not_nullables.py,sha256=Mob8McGYAcmgvrseyyYOa54E6Gsgr-4SiGdC-r9O4_A,1157
|
@@ -168,8 +168,8 @@ fractal_server/tasks/v2/background_operations.py,sha256=MAMBn6W2bhkdK59kfUGiD7a1
|
|
168
168
|
fractal_server/tasks/v2/get_collection_data.py,sha256=Qhf2T_aaqAfqu9_KpUSlXsS7EJoZQbEPEreHHa2jco8,502
|
169
169
|
fractal_server/urls.py,sha256=5o_qq7PzKKbwq12NHSQZDmDitn5RAOeQ4xufu-2v9Zk,448
|
170
170
|
fractal_server/utils.py,sha256=b7WwFdcFZ8unyT65mloFToYuEDXpQoHRcmRNqrhd_dQ,2115
|
171
|
-
fractal_server-2.2.
|
172
|
-
fractal_server-2.2.
|
173
|
-
fractal_server-2.2.
|
174
|
-
fractal_server-2.2.
|
175
|
-
fractal_server-2.2.
|
171
|
+
fractal_server-2.2.0a1.dist-info/LICENSE,sha256=QKAharUuhxL58kSoLizKJeZE3mTCBnX6ucmz8W0lxlk,1576
|
172
|
+
fractal_server-2.2.0a1.dist-info/METADATA,sha256=_EjXCIJCW7vFuEVg66y-Px3GUfi-ynAEPuNVJwg2dZo,4349
|
173
|
+
fractal_server-2.2.0a1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
174
|
+
fractal_server-2.2.0a1.dist-info/entry_points.txt,sha256=8tV2kynvFkjnhbtDnxAqImL6HMVKsopgGfew0DOp5UY,58
|
175
|
+
fractal_server-2.2.0a1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|