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.
@@ -1 +1 @@
1
- __VERSION__ = "2.2.0a0"
1
+ __VERSION__ = "2.2.0a1"
@@ -63,7 +63,7 @@ class DB:
63
63
  }
64
64
 
65
65
  cls._engine_async = create_async_engine(
66
- settings.DATABASE_URL,
66
+ settings.DATABASE_ASYNC_URL,
67
67
  echo=settings.DB_ECHO,
68
68
  future=True,
69
69
  **engine_kwargs_async,
@@ -126,41 +126,57 @@ async def submit_workflow(
126
126
  db_sync.close()
127
127
  return
128
128
 
129
- # Create WORKFLOW_DIR
130
- original_umask = os.umask(0)
131
- WORKFLOW_DIR_LOCAL.mkdir(parents=True, mode=0o755)
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
- (WORKFLOW_DIR_LOCAL / subfolder_name).mkdir(mode=0o755)
133
+ WORKFLOW_DIR_LOCAL.mkdir(parents=True, mode=0o755)
134
+
158
135
  os.umask(original_umask)
159
- if FRACTAL_RUNNER_BACKEND == "slurm":
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 / subfolder_name),
162
- user=slurm_user,
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 DATABASE_URL(self) -> URL:
205
- if self.DB_ENGINE == "sqlite":
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="sqlite+aiosqlite",
213
- database=sqlite_path,
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
- return url
216
- elif "postgres":
214
+ elif self.DB_ENGINE == "postgres-psycopg":
217
215
  url = URL.create(
218
- drivername="postgresql+asyncpg",
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
- return url
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 == "sqlite":
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.DATABASE_URL.set(drivername="sqlite")
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(
@@ -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.DATABASE_URL,
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.0a0
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=SlW0tbws1kw-jGFxFPps51tRVcdJnYWiGo7Se8A6BwY,24
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=WZEVfdJAX7ZyBM1ngfEGeqWWcjK_NygtCbawpmbwGpU,4042
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=blmnUJTpZn8uYPbQIb0xmwB93xNKpEoFIAi4UDqKbWM,13418
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=ZRD-Mwim6gmWnL2JKT2v6KS3uRgthd1FZQRHwN7MYOE,16392
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=bsl0HGZpjhommztgcs7wQ94sJzI1Orgnij97K8P_uyo,2630
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.0a0.dist-info/LICENSE,sha256=QKAharUuhxL58kSoLizKJeZE3mTCBnX6ucmz8W0lxlk,1576
172
- fractal_server-2.2.0a0.dist-info/METADATA,sha256=0lsKheVy4TMM296RuFQsLpVjEh4dhdeYzTi6pTTzrCw,4224
173
- fractal_server-2.2.0a0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
174
- fractal_server-2.2.0a0.dist-info/entry_points.txt,sha256=8tV2kynvFkjnhbtDnxAqImL6HMVKsopgGfew0DOp5UY,58
175
- fractal_server-2.2.0a0.dist-info/RECORD,,
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,,