fractal-server 2.1.0__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.
Files changed (48) hide show
  1. fractal_server/__init__.py +1 -1
  2. fractal_server/app/db/__init__.py +1 -1
  3. fractal_server/app/routes/admin/v1.py +2 -4
  4. fractal_server/app/routes/admin/v2.py +2 -4
  5. fractal_server/app/routes/api/v1/_aux_functions.py +24 -0
  6. fractal_server/app/routes/api/v1/job.py +3 -4
  7. fractal_server/app/routes/api/v1/project.py +28 -18
  8. fractal_server/app/routes/api/v2/_aux_functions.py +35 -12
  9. fractal_server/app/routes/api/v2/job.py +3 -4
  10. fractal_server/app/routes/api/v2/project.py +21 -0
  11. fractal_server/app/routes/api/v2/submit.py +33 -7
  12. fractal_server/app/routes/aux/_job.py +3 -1
  13. fractal_server/app/routes/aux/_runner.py +3 -3
  14. fractal_server/app/runner/executors/slurm/executor.py +157 -68
  15. fractal_server/app/runner/shutdown.py +88 -0
  16. fractal_server/app/runner/task_files.py +59 -27
  17. fractal_server/app/runner/v1/__init__.py +35 -19
  18. fractal_server/app/runner/v1/_common.py +53 -51
  19. fractal_server/app/runner/v1/_local/__init__.py +12 -11
  20. fractal_server/app/runner/v1/_local/_submit_setup.py +4 -4
  21. fractal_server/app/runner/v1/_slurm/__init__.py +16 -16
  22. fractal_server/app/runner/v1/_slurm/_submit_setup.py +11 -10
  23. fractal_server/app/runner/v1/_slurm/get_slurm_config.py +6 -6
  24. fractal_server/app/runner/v2/__init__.py +65 -17
  25. fractal_server/app/runner/v2/_local/__init__.py +12 -11
  26. fractal_server/app/runner/v2/_local/_local_config.py +1 -1
  27. fractal_server/app/runner/v2/_local/_submit_setup.py +4 -4
  28. fractal_server/app/runner/v2/_local_experimental/__init__.py +145 -0
  29. fractal_server/app/runner/v2/_local_experimental/_local_config.py +108 -0
  30. fractal_server/app/runner/v2/_local_experimental/_submit_setup.py +42 -0
  31. fractal_server/app/runner/v2/_local_experimental/executor.py +152 -0
  32. fractal_server/app/runner/v2/_slurm/__init__.py +10 -10
  33. fractal_server/app/runner/v2/_slurm/_submit_setup.py +11 -10
  34. fractal_server/app/runner/v2/_slurm/get_slurm_config.py +6 -6
  35. fractal_server/app/runner/v2/runner.py +17 -15
  36. fractal_server/app/runner/v2/runner_functions.py +38 -38
  37. fractal_server/app/runner/v2/runner_functions_low_level.py +12 -6
  38. fractal_server/config.py +52 -19
  39. fractal_server/gunicorn_fractal.py +40 -0
  40. fractal_server/{logger/__init__.py → logger.py} +2 -2
  41. fractal_server/main.py +24 -1
  42. fractal_server/migrations/env.py +1 -1
  43. {fractal_server-2.1.0.dist-info → fractal_server-2.2.0a1.dist-info}/METADATA +3 -1
  44. {fractal_server-2.1.0.dist-info → fractal_server-2.2.0a1.dist-info}/RECORD +47 -42
  45. fractal_server/logger/gunicorn_logger.py +0 -19
  46. {fractal_server-2.1.0.dist-info → fractal_server-2.2.0a1.dist-info}/LICENSE +0 -0
  47. {fractal_server-2.1.0.dist-info → fractal_server-2.2.0a1.dist-info}/WHEEL +0 -0
  48. {fractal_server-2.1.0.dist-info → fractal_server-2.2.0a1.dist-info}/entry_points.txt +0 -0
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
@@ -310,7 +322,9 @@ class Settings(BaseSettings):
310
322
  )
311
323
  return FRACTAL_RUNNER_WORKING_BASE_DIR_path
312
324
 
313
- FRACTAL_RUNNER_BACKEND: Literal["local", "slurm"] = "local"
325
+ FRACTAL_RUNNER_BACKEND: Literal[
326
+ "local", "local_experimental", "slurm"
327
+ ] = "local"
314
328
  """
315
329
  Select which runner backend to use.
316
330
  """
@@ -334,6 +348,17 @@ class Settings(BaseSettings):
334
348
  Path of JSON file with configuration for the local backend.
335
349
  """
336
350
 
351
+ FRACTAL_API_MAX_JOB_LIST_LENGTH: int = 50
352
+ """
353
+ Number of ids that can be stored in the `jobsV1` and `jobsV2` attributes of
354
+ `app.state`.
355
+ """
356
+
357
+ FRACTAL_GRACEFUL_SHUTDOWN_TIME: int = 30
358
+ """
359
+ Waiting time for the shutdown phase of executors
360
+ """
361
+
337
362
  FRACTAL_SLURM_CONFIG_FILE: Optional[Path]
338
363
  """
339
364
  Path of JSON file with configuration for the SLURM backend.
@@ -407,6 +432,14 @@ class Settings(BaseSettings):
407
432
  "DB engine is `postgres` but `psycopg2` or `asyncpg` "
408
433
  "are not available"
409
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
+ )
410
443
  else:
411
444
  if not self.SQLITE_PATH:
412
445
  raise FractalConfigurationError(
@@ -0,0 +1,40 @@
1
+ import logging
2
+ import os
3
+ import signal
4
+
5
+ from gunicorn.glogging import Logger as GunicornLogger
6
+ from uvicorn.workers import UvicornWorker
7
+
8
+ logger = logging.getLogger("uvicorn.error")
9
+
10
+
11
+ class FractalGunicornLogger(GunicornLogger):
12
+ error_fmt = r"%(asctime)s - gunicorn.error - %(levelname)s - [pid %(process)d] - %(message)s" # noqa: E501
13
+ datefmt = r"%Y-%m-%d %H:%M:%S,%u"
14
+
15
+
16
+ class FractalWorker(UvicornWorker):
17
+ """
18
+ Subclass of uvicorn workers, which also captures SIGABRT and handles
19
+ it within the `custom_handle_abort` method.
20
+ """
21
+
22
+ def init_signals(self) -> None:
23
+ super().init_signals()
24
+ signal.signal(signal.SIGABRT, self.custom_handle_abort)
25
+ logger.info(
26
+ f"[FractalWorker.init_signals - pid={self.pid}] "
27
+ "Set `custom_handle_abort` for SIGABRT"
28
+ )
29
+
30
+ def custom_handle_abort(self, sig, frame):
31
+ """
32
+ Custom version of `gunicorn.workers.base.Worker.handle_abort`,
33
+ transforming SIGABRT into SIGTERM.
34
+ """
35
+ self.alive = False
36
+ logger.info(
37
+ f"[FractalWorker.custom_handle_abort - pid={self.pid}] "
38
+ "Now send SIGTERM to process."
39
+ )
40
+ os.kill(self.pid, signal.SIGTERM)
@@ -17,8 +17,8 @@ from pathlib import Path
17
17
  from typing import Optional
18
18
  from typing import Union
19
19
 
20
- from ..config import get_settings
21
- from ..syringe import Inject
20
+ from .config import get_settings
21
+ from .syringe import Inject
22
22
 
23
23
 
24
24
  LOG_FORMAT = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
fractal_server/main.py CHANGED
@@ -15,13 +15,16 @@
15
15
 
16
16
  This module sets up the FastAPI application that serves the Fractal Server.
17
17
  """
18
+ import os
18
19
  from contextlib import asynccontextmanager
19
20
 
20
21
  from fastapi import FastAPI
21
22
 
23
+ from .app.runner.shutdown import cleanup_after_shutdown
22
24
  from .app.security import _create_first_user
23
25
  from .config import get_settings
24
26
  from .logger import config_uvicorn_loggers
27
+ from .logger import get_logger
25
28
  from .logger import reset_logger_handlers
26
29
  from .logger import set_logger
27
30
  from .syringe import Inject
@@ -81,6 +84,8 @@ def check_settings() -> None:
81
84
 
82
85
  @asynccontextmanager
83
86
  async def lifespan(app: FastAPI):
87
+ app.state.jobsV1 = []
88
+ app.state.jobsV2 = []
84
89
  logger = set_logger("fractal_server.lifespan")
85
90
  logger.info("Start application startup")
86
91
  check_settings()
@@ -96,8 +101,26 @@ async def lifespan(app: FastAPI):
96
101
  logger.info("End application startup")
97
102
  reset_logger_handlers(logger)
98
103
  yield
99
- logger = set_logger("fractal_server.lifespan")
104
+ logger = get_logger("fractal_server.lifespan")
100
105
  logger.info("Start application shutdown")
106
+ logger.info(
107
+ f"Current worker with pid {os.getpid()} is shutting down. "
108
+ f"Current jobs: {app.state.jobsV1=}, {app.state.jobsV2=}"
109
+ )
110
+ if settings.FRACTAL_RUNNER_BACKEND == "slurm":
111
+ try:
112
+ await cleanup_after_shutdown(
113
+ jobsV1=app.state.jobsV1,
114
+ jobsV2=app.state.jobsV2,
115
+ logger_name="fractal_server.lifespan",
116
+ )
117
+ except Exception as e:
118
+ logger.error(
119
+ "Something went wrong during shutdown phase, "
120
+ "some of running jobs are not shutdown properly. "
121
+ f"Original error: {e}"
122
+ )
123
+
101
124
  logger.info("End application shutdown")
102
125
  reset_logger_handlers(logger)
103
126
 
@@ -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.1.0
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=M-UCl3baEQIODOL7Zae_0jXfPyeyyPZypKzTHK83oM0,22
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
@@ -23,26 +23,26 @@ fractal_server/app/models/v2/workflow.py,sha256=YBgFGCziUgU0aJ5EM3Svu9W2c46AewZO
23
23
  fractal_server/app/models/v2/workflowtask.py,sha256=3jEkObsSnlI05Pur_dSsXYdJxRqPL60Z7tK5-EJLOks,1532
24
24
  fractal_server/app/routes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
25
  fractal_server/app/routes/admin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
- fractal_server/app/routes/admin/v1.py,sha256=uMupmRkicaoWazX8qSX5fgh00O3MbuSfim8QayP6NkE,13996
27
- fractal_server/app/routes/admin/v2.py,sha256=e0A6RMWfmTO5dVL95XO-P2EljdEwR00FErxahEPzODQ,13757
26
+ fractal_server/app/routes/admin/v1.py,sha256=jTTCq_NXEwnPJR5QEBImt58xoGuUVsAlZDiPX4iCtlo,13955
27
+ fractal_server/app/routes/admin/v2.py,sha256=zqLTdxs1pU_EBkdoQL912CQUWTZJhIr-PBdAOMymgSA,13716
28
28
  fractal_server/app/routes/api/__init__.py,sha256=EVyZrEq3I_1643QGTPCC5lgCp4xH_auYbrFfogTm4pc,315
29
29
  fractal_server/app/routes/api/v1/__init__.py,sha256=Y2HQdG197J0a7DyQEE2jn53IfxD0EHGhzK1I2JZuEck,958
30
- fractal_server/app/routes/api/v1/_aux_functions.py,sha256=lFfGJxbJc-Ryah_pPkiTH2SBncWQ15n0iqVFolzIOCM,11976
30
+ fractal_server/app/routes/api/v1/_aux_functions.py,sha256=CeaVrNVYs_lEbiJbu4uaTeeiajljeXfdq1iLkt5RoRo,12636
31
31
  fractal_server/app/routes/api/v1/dataset.py,sha256=HRE-8vPmVkeXf7WFYkI19mDtbY-iJZeJ7PmMiV0LMgY,16923
32
- fractal_server/app/routes/api/v1/job.py,sha256=NwXyhvvzdPDor0ts8Im__9-I0P1H943s4NXIRgaz7PM,5436
33
- fractal_server/app/routes/api/v1/project.py,sha256=DKQ6n1CPmHqsKieBaJlKnOhKaHWgQTZIA_asJTT9Uxo,15802
32
+ fractal_server/app/routes/api/v1/job.py,sha256=xdRtTR9NUwC98n3H1Tt0eOVJQ79GlBE1D2Opqk-MeeE,5342
33
+ fractal_server/app/routes/api/v1/project.py,sha256=MxbJUc9H14ZZ8mmMbX3LXGTVR3sHdD26YSw4TKI7WtU,16108
34
34
  fractal_server/app/routes/api/v1/task.py,sha256=udbKnenzc-Q10elYCVB9JmOPWATraa9tZi0AaByvWo0,6129
35
35
  fractal_server/app/routes/api/v1/task_collection.py,sha256=mFaYyCWtCPRqvs3j6zx_zaiDXn31Uzoa7UHZS-Lu_L0,8882
36
36
  fractal_server/app/routes/api/v1/workflow.py,sha256=7r9IoIevg_rvYCrerMOsIsUabSOQatxdPCfLdkP0dRs,10942
37
37
  fractal_server/app/routes/api/v1/workflowtask.py,sha256=qcHQlzlSFf_k8gtId-mA3tnyzgSR7i1m7pvR4R86blE,5582
38
38
  fractal_server/app/routes/api/v2/__init__.py,sha256=UNgODxoEXfQpQDjvsnMvHaUWbZOrcHhEXNisLcU-0tE,1487
39
- fractal_server/app/routes/api/v2/_aux_functions.py,sha256=IL1JKVqRcGfqiVbptDzpMKqi9QTYDYCCcsqIG0x0Nl8,14301
39
+ fractal_server/app/routes/api/v2/_aux_functions.py,sha256=tYJr5EPaA0CVGp-Y4jottFJUVToWvjcSY6PJqN_d--s,14938
40
40
  fractal_server/app/routes/api/v2/dataset.py,sha256=_HjKNP9XsMGoqyubGdF2ZyeW7vXC3VdK_0_TaUxgIF0,8248
41
41
  fractal_server/app/routes/api/v2/images.py,sha256=4r_HblPWyuKSZSJZfn8mbDaLv1ncwZU0gWdKneZcNG4,7894
42
- fractal_server/app/routes/api/v2/job.py,sha256=BtaxErBDbLwjY2zgGD1I6eRpsffoMonifcS1CMEXmLU,5325
43
- fractal_server/app/routes/api/v2/project.py,sha256=qyvizYZ4aUFgF3tGdfp4z8AwWgfo19N_KbFEljfUaC8,5594
42
+ fractal_server/app/routes/api/v2/job.py,sha256=dBwOJmGtMLDmjCj-ZNXYcqYrikzqx9VHDySB7ogNaKE,5231
43
+ fractal_server/app/routes/api/v2/project.py,sha256=U4TxD-J4TtQuu1D4BOhL1kTse5fCiNc3BwGH7bnlo38,6592
44
44
  fractal_server/app/routes/api/v2/status.py,sha256=osLexiMOSqmYcEV-41tlrwt9ofyFbtRm5HmPS5BU0t4,6394
45
- fractal_server/app/routes/api/v2/submit.py,sha256=mdY1fN9VA8-8DkqeAGrzHa4n37QSPP-gN3sc4z-c-wc,7592
45
+ fractal_server/app/routes/api/v2/submit.py,sha256=sqfeVw18mqzfgBTpb6Ix6KFdapGiaZ8u3BSyIUteLEc,8488
46
46
  fractal_server/app/routes/api/v2/task.py,sha256=bRTtGgL8BBGbT7csVeRB-a54clgU2xHydi5XpcByDxg,8297
47
47
  fractal_server/app/routes/api/v2/task_collection.py,sha256=eN3NkZaZHkrqnLGRKE7Xd5mo0cHc8aK2lojCt26ErOQ,8988
48
48
  fractal_server/app/routes/api/v2/task_legacy.py,sha256=P_VJv9v0yzFUBuS-DQHhMVSOe20ecGJJcFBqiiFciOM,1628
@@ -50,8 +50,8 @@ fractal_server/app/routes/api/v2/workflow.py,sha256=2GlcYNjpvCdjwC_Kn7y0UP16B3pO
50
50
  fractal_server/app/routes/api/v2/workflowtask.py,sha256=l4eTD5IIun5cOdYzsxh3ajmnOISaSccYA_mVf15Cjtw,8802
51
51
  fractal_server/app/routes/auth.py,sha256=Xv80iqdyfY3lyicYs2Y8B6zEDEnyUu_H6_6psYtv3R4,4885
52
52
  fractal_server/app/routes/aux/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
- fractal_server/app/routes/aux/_job.py,sha256=7OP3B_FqYJUQ8hVn-7G8oYEEaZrM4hxLF9FoSyjudTo,1251
54
- fractal_server/app/routes/aux/_runner.py,sha256=psW6fsoo_VrAHrD5UQPbqFYikCp0m16VRymC-U1yUTk,675
53
+ fractal_server/app/routes/aux/_job.py,sha256=EShKa9AMHy7zqlwPHGsKO6uE0LtXkqutO9wCCHbZzcU,1321
54
+ fractal_server/app/routes/aux/_runner.py,sha256=1PcWhJlxl9xyYo_BLoVcb1mJt2j6IGrj7AxPIIjckrw,724
55
55
  fractal_server/app/runner/.gitignore,sha256=ytzN_oyHWXrGU7iFAtoHSTUbM6Rn6kG0Zkddg0xZk6s,16
56
56
  fractal_server/app/runner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
57
  fractal_server/app/runner/async_wrap.py,sha256=_O6f8jftKYXG_DozkmlrDBhoiK9QhE9MablOyECq2_M,829
@@ -64,36 +64,41 @@ fractal_server/app/runner/executors/slurm/_check_jobs_status.py,sha256=8d29a7DQ2
64
64
  fractal_server/app/runner/executors/slurm/_executor_wait_thread.py,sha256=J3tjAx33nBgW4eHAXDte7hDs7Oe9FLEZaElEt8inrbg,4421
65
65
  fractal_server/app/runner/executors/slurm/_slurm_config.py,sha256=rF37XDImX1QoWx37MC5hSM9AuY_KfHU5gaWwN4vl4Zk,15552
66
66
  fractal_server/app/runner/executors/slurm/_subprocess_run_as_user.py,sha256=YwfJzZr_y4FL_hirHJdWK0vWzrldjoZZhXVFlO2AOMU,5131
67
- fractal_server/app/runner/executors/slurm/executor.py,sha256=z2MbI9He1lPhKBPMs0pqoQ9wUiAsxOIZY62s5VFHs-0,45044
67
+ fractal_server/app/runner/executors/slurm/executor.py,sha256=jieZE5LhsFqzjDAegynRV0jrNByEb-7Yx8YmtPr6ZS0,48208
68
68
  fractal_server/app/runner/executors/slurm/remote.py,sha256=wLziIsGdSMiO-jIXM8x77JRK82g_2hx0iBKTiMghuIo,5852
69
69
  fractal_server/app/runner/filenames.py,sha256=9lwu3yB4C67yiijYw8XIKaLFn3mJUt6_TCyVFM_aZUQ,206
70
70
  fractal_server/app/runner/set_start_and_last_task_index.py,sha256=-q4zVybAj8ek2XlbENKlfOAJ39hT_zoJoZkqzDqiAMY,1254
71
- fractal_server/app/runner/task_files.py,sha256=b5aRDi35QemBQnHT_AU6L_IPJJU_k_f5sJn-JXzkzy0,3180
72
- fractal_server/app/runner/v1/__init__.py,sha256=kMiQJJ-XUp2ecI0tUAUYD_Em1vcct9iXULMoI5SGdU4,13520
73
- fractal_server/app/runner/v1/_common.py,sha256=2-NScI-7qCIw14Od90so1onw-psIt8x1kx6EXq489Vk,21246
74
- fractal_server/app/runner/v1/_local/__init__.py,sha256=ZcWftuGRLmN8-S6QZXm6FhNehsxwmwZRhuRv-a7zA6s,6839
71
+ fractal_server/app/runner/shutdown.py,sha256=I_o2iYKJwzku0L3E85ETjrve3QPECygR5xhhsAo5huM,2910
72
+ fractal_server/app/runner/task_files.py,sha256=mPxOokb5ha4sXzOXP-_-3978Tmuf5KOn2FbYRbDLQ0g,4044
73
+ fractal_server/app/runner/v1/__init__.py,sha256=BlOkhuUbLLCavyXT0ZqHrW0VvgW-pq5sjW8IZffU7DM,14155
74
+ fractal_server/app/runner/v1/_common.py,sha256=rF9IsOo_h_UyeCZ2hkHYPHsdgTjqLlGGig4wyrDS5CQ,21544
75
+ fractal_server/app/runner/v1/_local/__init__.py,sha256=KlSML4LqF4p1IfhSd8tAkiu3aeDzifeanuNXjATDsYE,6929
75
76
  fractal_server/app/runner/v1/_local/_local_config.py,sha256=hM7SPxR07luXPcXdrWXRpEB2uOyjSSRUdqW3QBKJn9c,3147
76
- fractal_server/app/runner/v1/_local/_submit_setup.py,sha256=kvNPT7ey2mEamORzPMMVThbFHtzZcSr-0A9tYw9uVDA,1493
77
+ fractal_server/app/runner/v1/_local/_submit_setup.py,sha256=XyBDPb4IYdKEEnzLYdcYteIHWVWofJxKMmQCyRkn5Bc,1509
77
78
  fractal_server/app/runner/v1/_local/executor.py,sha256=QrJlD77G6q4WohoJQO7XXbvi2RlCUsNvMnPDEZIoAqA,3620
78
- fractal_server/app/runner/v1/_slurm/__init__.py,sha256=KN98RO8E3EG4MLNFa--D3DilRHjUyHrVicC6pHtu5L0,10853
79
- fractal_server/app/runner/v1/_slurm/_submit_setup.py,sha256=llTgSOCnCVMvm7Q0SoVpLZshorAOZZUDz927ij0LZEA,2738
80
- fractal_server/app/runner/v1/_slurm/get_slurm_config.py,sha256=6TLWQon8hSicsD7c3yXK4P9xeId0s_H3HOOeMUVGVss,5977
79
+ fractal_server/app/runner/v1/_slurm/__init__.py,sha256=u2rMOLAlvmnm9r4fYecIlZYhjYAWWvA5c8hVczTdJSs,10941
80
+ fractal_server/app/runner/v1/_slurm/_submit_setup.py,sha256=KO9c694d318adoPQh9UGwxLkw4fRIgybQ5h7QHQKLXQ,2828
81
+ fractal_server/app/runner/v1/_slurm/get_slurm_config.py,sha256=6pQNNx997bLIfLp0guF09t_O0ZYRXnbEGLktSAcKnic,5999
81
82
  fractal_server/app/runner/v1/common.py,sha256=_L-vjLnWato80VdlB_BFN4G8P4jSM07u-5cnl1T3S34,3294
82
83
  fractal_server/app/runner/v1/handle_failed_job.py,sha256=bHzScC_aIlU3q-bQxGW6rfWV4xbZ2tho_sktjsAs1no,4684
83
- fractal_server/app/runner/v2/__init__.py,sha256=U6FwKhiIF1INKU8LCoGHBCb04S2xOa3rpbltcodWXLw,11952
84
- fractal_server/app/runner/v2/_local/__init__.py,sha256=Q1s-DwXleUq6w1ZNv6tlh3tZv6cyBqxB_hMvZlqVYaM,5881
85
- fractal_server/app/runner/v2/_local/_local_config.py,sha256=lR0Js-l63mQUzN9hK0HkfdLsrTf-W6GHvPvbPC64amY,3630
86
- fractal_server/app/runner/v2/_local/_submit_setup.py,sha256=deagsLSy6A3ZHKaSDcQqrdvbQVM3i4kgyTcbVc0tC5U,1614
84
+ fractal_server/app/runner/v2/__init__.py,sha256=989hkJIy601BewBtpl0w_cL_wBKhDmKJq4N3idLbD5s,13999
85
+ fractal_server/app/runner/v2/_local/__init__.py,sha256=KTj14K6jH8fXGUi5P7u5_RqEE1zF4aXtgPxCKzw46iw,5971
86
+ fractal_server/app/runner/v2/_local/_local_config.py,sha256=9oi209Dlp35ANfxb_DISqmMKKc6DPaMsmYVWbZLseME,3630
87
+ fractal_server/app/runner/v2/_local/_submit_setup.py,sha256=MucNOo8Er0F5ZIwH7CnTeXgnFMc6d3pKPkv563QNVi0,1630
87
88
  fractal_server/app/runner/v2/_local/executor.py,sha256=QrJlD77G6q4WohoJQO7XXbvi2RlCUsNvMnPDEZIoAqA,3620
88
- fractal_server/app/runner/v2/_slurm/__init__.py,sha256=srxn5-KdQxqD8cWJmOJlSoctbXYlyCMM249xWGY9bhI,4409
89
- fractal_server/app/runner/v2/_slurm/_submit_setup.py,sha256=tsZHQdVy3VxENMdsBzHltrVWzugBppq0cFrHtaVzoUA,2793
90
- fractal_server/app/runner/v2/_slurm/get_slurm_config.py,sha256=I_lOS75iGYyJ74-gNwwcPadvZ9vI9HYe04WMln5GJ5Q,6726
89
+ fractal_server/app/runner/v2/_local_experimental/__init__.py,sha256=1aFDk61VqhFfbceRc1JEj6S4pik8kXk0xV_bSqRivTI,5260
90
+ fractal_server/app/runner/v2/_local_experimental/_local_config.py,sha256=QiS5ODe-iGmUQdIT8QgpbyMc7-ZpIRv1V_f2q3qfPQ8,3211
91
+ fractal_server/app/runner/v2/_local_experimental/_submit_setup.py,sha256=we7r-sQf0CJ9gxbfbgHcYdC6pKjx8eXweljIjthxkv8,1212
92
+ fractal_server/app/runner/v2/_local_experimental/executor.py,sha256=2rcWDAmxeNdV4UHqeusLStJ8ijSiDbcMJutdqkq0xZU,5258
93
+ fractal_server/app/runner/v2/_slurm/__init__.py,sha256=OUPsEpu37f9ohu7NfXtaqlQevxeg1Q3Gl4LwTkwl2So,4475
94
+ fractal_server/app/runner/v2/_slurm/_submit_setup.py,sha256=rvhMOK1QkqsxVWUvekT62KbDDlqpw49nq9mzQXSY3H0,2883
95
+ fractal_server/app/runner/v2/_slurm/get_slurm_config.py,sha256=btGmbZB0fO6bg2WujFxbGEV2iWzaMKbHgV1r2hm_4a0,6748
91
96
  fractal_server/app/runner/v2/deduplicate_list.py,sha256=-imwO7OB7ATADEnqVbTElUwoY0YIJCTf_SbWJNN9OZg,639
92
97
  fractal_server/app/runner/v2/handle_failed_job.py,sha256=M1r3dnrbUMo_AI2qjaVuGhieMAyLh5gcvB10YOBpjvI,5415
93
98
  fractal_server/app/runner/v2/merge_outputs.py,sha256=IHuHqbKmk97K35BFvTrKVBs60z3e_--OzXTnsvmA02c,1281
94
- fractal_server/app/runner/v2/runner.py,sha256=pZDRYXibPs6lYz8hg-F7KbibR_cl0sjCa5s9yaFE_-s,14160
95
- fractal_server/app/runner/v2/runner_functions.py,sha256=jwLfIL1gdmL-KqSKb-5CDG-g7rQYZdywn24bJ92R2qI,11067
96
- fractal_server/app/runner/v2/runner_functions_low_level.py,sha256=nPxmoSTIAQRwEf8iwfCdwTq4Eo3eDAHcgGn3GejPgqk,3710
99
+ fractal_server/app/runner/v2/runner.py,sha256=uyO71VObtqLVfnFjazZH-UMpea02g8kS0DW2YoCVN2s,14278
100
+ fractal_server/app/runner/v2/runner_functions.py,sha256=3DSzdY11g97iXjTud-6rNxF8JKxCW8GDKfUFXis58M8,11311
101
+ fractal_server/app/runner/v2/runner_functions_low_level.py,sha256=kcmqX9gV8zBC1kiSpJJpNhWo62gH0vFPOwPbxNOwEMs,3884
97
102
  fractal_server/app/runner/v2/task_interface.py,sha256=myS-kT0DsJ8xIJZBVEzgD8g54VbiwL6i7Im3e1zcVHQ,1866
98
103
  fractal_server/app/runner/v2/v1_compat.py,sha256=t0ficzAHUFaaeI56nqTb4YEKxfARF7L9Y6ijtJCwjP8,912
99
104
  fractal_server/app/schemas/__init__.py,sha256=jiIf54owztXupv3PO6Ilh0qcrkh2RUzKq4bcEFqEfc4,40
@@ -121,16 +126,16 @@ fractal_server/app/schemas/v2/task_collection.py,sha256=sY29NQfJrbjiidmVkVjSIH-2
121
126
  fractal_server/app/schemas/v2/workflow.py,sha256=Zzx3e-qgkH8le0FUmAx9UrV5PWd7bj14PPXUh_zgZXM,1827
122
127
  fractal_server/app/schemas/v2/workflowtask.py,sha256=atVuVN4aXsVEOmSd-vyg-8_8OnPmqx-gT75rXcn_AlQ,6552
123
128
  fractal_server/app/security/__init__.py,sha256=2-QbwuR-nsuHM_uwKS_WzYvkhnuhO5jUv8UVROetyVk,11169
124
- fractal_server/config.py,sha256=7fF_lTGH_mH_16aYr8m3E5Dv81jH9wdJuGu-2p1x9H0,16081
129
+ fractal_server/config.py,sha256=XiSTdx7wI2Eem-lzeMQhhGAwUwsACCKdUnbiGqDIChY,17219
125
130
  fractal_server/data_migrations/README.md,sha256=_3AEFvDg9YkybDqCLlFPdDmGJvr6Tw7HRI14aZ3LOIw,398
131
+ fractal_server/gunicorn_fractal.py,sha256=2AOkgxu-oQ-XB578_voT0VuhmAXFTmb0c-nYn1XLy_Q,1231
126
132
  fractal_server/images/__init__.py,sha256=xO6jTLE4EZKO6cTDdJsBmK9cdeh9hFTaSbSuWgQg7y4,196
127
133
  fractal_server/images/models.py,sha256=9ipU5h4N6ogBChoB-2vHoqtL0TXOHCv6kRR-fER3mkM,4167
128
134
  fractal_server/images/tools.py,sha256=gxeniYy4Z-cp_ToK2LHPJUTVVUUrdpogYdcBUvBuLiY,2209
129
- fractal_server/logger/__init__.py,sha256=Q_e03Lj30VWdCqGBJrKw9A2QEeDbCKC_OOkDQVW9Dyw,5132
130
- fractal_server/logger/gunicorn_logger.py,sha256=vb5s7mruCHPkKWGrTTOPyrB_658Y2Z05ECdHhCCBhp0,644
131
- fractal_server/main.py,sha256=faQfINM4k3G7Oakkn8R_EfHLma6Dd-U_TeyWesjs0js,3613
135
+ fractal_server/logger.py,sha256=56wfka6fHaa3Rx5qO009nEs_y8gx5wZ2NUNZZ1I-uvc,5130
136
+ fractal_server/main.py,sha256=U50BfL1cxpkSMglRmEHILZE1yDpiUhyb4tlrNuE3j6s,4417
132
137
  fractal_server/migrations/README,sha256=4rQvyDfqodGhpJw74VYijRmgFP49ji5chyEemWGHsuw,59
133
- fractal_server/migrations/env.py,sha256=bsl0HGZpjhommztgcs7wQ94sJzI1Orgnij97K8P_uyo,2630
138
+ fractal_server/migrations/env.py,sha256=Bvg-FJzRJZIH_wqS_ZyZNXANIaathjo22_IY7c3fCjo,2636
134
139
  fractal_server/migrations/script.py.mako,sha256=oMXw9LC3zRbinWWPPDgeZ4z9FJrV2zhRWiYdS5YgNbI,526
135
140
  fractal_server/migrations/versions/4c308bcaea2b_add_task_args_schema_and_task_args_.py,sha256=-wHe-fOffmYeAm0JXVl_lxZ7hhDkaEVqxgxpHkb_uL8,954
136
141
  fractal_server/migrations/versions/4cedeb448a53_workflowtask_foreign_keys_not_nullables.py,sha256=Mob8McGYAcmgvrseyyYOa54E6Gsgr-4SiGdC-r9O4_A,1157
@@ -163,8 +168,8 @@ fractal_server/tasks/v2/background_operations.py,sha256=MAMBn6W2bhkdK59kfUGiD7a1
163
168
  fractal_server/tasks/v2/get_collection_data.py,sha256=Qhf2T_aaqAfqu9_KpUSlXsS7EJoZQbEPEreHHa2jco8,502
164
169
  fractal_server/urls.py,sha256=5o_qq7PzKKbwq12NHSQZDmDitn5RAOeQ4xufu-2v9Zk,448
165
170
  fractal_server/utils.py,sha256=b7WwFdcFZ8unyT65mloFToYuEDXpQoHRcmRNqrhd_dQ,2115
166
- fractal_server-2.1.0.dist-info/LICENSE,sha256=QKAharUuhxL58kSoLizKJeZE3mTCBnX6ucmz8W0lxlk,1576
167
- fractal_server-2.1.0.dist-info/METADATA,sha256=kyfeNStKB16vegug3_OV6wxtnxDT1Mo1pqj5HKKXG1w,4222
168
- fractal_server-2.1.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
169
- fractal_server-2.1.0.dist-info/entry_points.txt,sha256=8tV2kynvFkjnhbtDnxAqImL6HMVKsopgGfew0DOp5UY,58
170
- fractal_server-2.1.0.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,,
@@ -1,19 +0,0 @@
1
- """
2
- This module (which is only executed if `gunicorn` can be imported) subclasses
3
- the gunicorn `Logger` class in order to slightly change its log formats.
4
-
5
- This class can be used by including this `gunicorn` command-line option:
6
- ```
7
- --logger-class fractal_server.logger.gunicorn_logger.FractalGunicornLogger
8
- ```
9
- """
10
-
11
- try:
12
- from gunicorn.glogging import Logger as GunicornLogger
13
-
14
- class FractalGunicornLogger(GunicornLogger):
15
- error_fmt = r"%(asctime)s - gunicorn.error - %(levelname)s - [pid %(process)d] - %(message)s" # noqa: E501
16
- datefmt = r"%Y-%m-%d %H:%M:%S,%u"
17
-
18
- except (ModuleNotFoundError, ImportError):
19
- pass