Coverage for nexusLIMS/__init__.py: 100%

18 statements  

« prev     ^ index     » next       coverage.py v7.11.3, created at 2026-03-24 05:23 +0000

1r"""The NexusLIMS back-end software. 

2 

3This module contains the software required to monitor a database for sessions 

4logged by users on electron microscopy instruments. Based off this information, 

5records representing individual experiments are automatically generated and 

6uploaded to the front-end NexusLIMS CDCS instance for users to browse, query, 

7and edit. 

8 

9Example 

10------- 

11In most cases, the only code that needs to be run directly is initiating the 

12record builder to look for new sessions, which can be done by running the 

13:py:mod:`~nexusLIMS.builder.record_builder` module directly: 

14 

15```bash 

16$ python -m nexusLIMS.builder.record_builder 

17``` 

18 

19Refer to :ref:`record-building` for more details. 

20 

21**Configuration variables** 

22 

23The following variables should be defined as environment variables in your 

24session, or in the ``.env`` file in the root of this package's repository. 

25See the ``.env.example`` file for more documentation and examples. 

26 

27(NexusLIMS-file-strategy)= 

28 

29`NX_FILE_STRATEGY` 

30 Defines the strategy used to find files associated with experimental records. 

31 A value of ``exclusive`` will `only` add files for which NexusLIMS knows how 

32 to generate preview images and extract metadata. A value of ``inclusive`` 

33 will include all files found, even if preview generation/detailed metadata 

34 extraction is not possible. 

35 

36(NexusLIMS-ignore-patterns)= 

37 

38`NX_IGNORE_PATTERNS` 

39 The patterns defined in this variable (which should be provided as a 

40 JSON-formatted string) will be ignored when finding files. A default value 

41 is provided in the ``.env.example`` file that should work for most users, 

42 but this setting allows for further customization of the file-finding routine. 

43 

44(nexuslims-cdcs-token)= 

45 

46`NX_CDCS_TOKEN` 

47 API token used to authenticate to CDCS API 

48 

49(nexuslims-cdcs-url)= 

50 

51`NX_CDCS_URL` 

52 The root URL of the NexusLIMS CDCS front-end. This will be the target for 

53 record uploads that are authenticated using the CDCS token. 

54 

55(nexuslims-instrument-data-path)= 

56 

57`NX_INSTRUMENT_DATA_PATH` 

58 The path (should be already mounted) to the root folder containing data 

59 from the Electron Microscopy Nexus. This folder is accessible read-only, 

60 and it is where data is written to by instruments in the Electron 

61 Microscopy Nexus. The file paths for specific instruments (specified in 

62 the NexusLIMS database) are relative to this root. 

63 

64(nexuslims-data-path)= 

65 

66`NX_DATA_PATH` 

67 The root path used by NexusLIMS for various needs. This folder is used to 

68 store the NexusLIMS database, generated records, individual file metadata 

69 dumps and preview images, and anything else that is needed by the back-end 

70 system. 

71 

72(nexuslims-db-path)= 

73 

74`NX_DB_PATH` 

75 The direct path to the NexusLIMS SQLite database file that contains 

76 information about the instruments in the Nexus Facility, as well as logs 

77 for the sessions created by users using the Session Logger Application. 

78 

79(nexuslims-log-path)= 

80 

81`NX_LOG_PATH` 

82 Directory for application logs. If not specified, defaults to 

83 ``${NX_DATA_PATH}/logs/``. Logs are organized by date: ``logs/YYYY/MM/DD/`` 

84 

85(nexuslims-records-path)= 

86 

87`NX_RECORDS_PATH` 

88 Directory for generated XML records. If not specified, defaults to 

89 ``${NX_DATA_PATH}/records/``. Successfully uploaded records are moved to 

90 an 'uploaded' subdirectory upon upload. 

91 

92(nexuslims-cert-bundle-file)= 

93 

94`NX_CERT_BUNDLE_FILE` 

95 If needed, a custom SSL certificate CA bundle can be used to verify 

96 requests to the CDCS or NEMO APIs. Provide this value with the full 

97 path to a certificate bundle and any certificates provided in the 

98 bundle will be appended to the existing system for all requests made 

99 by NexusLIMS. 

100 

101(nexuslims-cert-bundle)= 

102 

103`NX_CERT_BUNDLE` 

104 As an alternative to ``NX_CERT_BUNDLE_FILE``, you can provide the entire 

105 certificate bundle as a single string (this can be useful for CI/CD 

106 pipelines). Lines should be separated by a single ``\n`` character. If 

107 defined, this value will take precedence over ``NX_CERT_BUNDLE_FILE``. 

108 

109(nexuslims-file-delay-days)= 

110 

111`NX_FILE_DELAY_DAYS` 

112 Controls the maximum delay between observing a session ending and when 

113 the files are expected to be present. For the number of days set (can be 

114 a fraction of a day, if desired), record building will not fail if no 

115 files are found, and the builder will search again until the delay has 

116 passed. For example, if the value is ``2``, and a session ended Monday 

117 at 5PM, the record builder will continue to try looking for files until 

118 Wednesday at 5PM. Default is ``2.0`` days. 

119 

120(nexuslims-local-profiles-path)= 

121 

122`NX_LOCAL_PROFILES_PATH` 

123 Directory for site-specific instrument profiles. These profiles customize 

124 metadata extraction for instruments unique to your deployment without 

125 modifying the core NexusLIMS codebase. Profile files should be Python 

126 modules that register ``InstrumentProfile`` objects. If not specified, 

127 only built-in profiles will be loaded. 

128 

129(nemo-address)= 

130 

131`NX_NEMO_ADDRESS_X` 

132 The path to a NEMO instance's API endpoint. Should be something like 

133 ``https://www.nemo.com/api/`` (make sure to include the trailing slash). 

134 The value ``_X`` can be replaced with any value (such as 

135 ``NX_NEMO_ADDRESS_1``). NexusLIMS supports having multiple NEMO reservation 

136 systems enabled at once (useful if your instruments are split over a few 

137 different management systems). To enable this behavior, create multiple 

138 pairs of environment variables for each instance, where the suffix ``_X`` 

139 changes for each pair (`e.g.` you could have ``NX_NEMO_ADDRESS_1`` paired with 

140 ``NX_NEMO_TOKEN_1``, ``NX_NEMO_ADDRESS_2`` paired with ``NX_NEMO_TOKEN_2``, etc.). 

141 

142(nemo-token)= 

143 

144`NX_NEMO_TOKEN_X` 

145 An API authentication token from the corresponding NEMO installation 

146 (specified in ``NX_NEMO_ADDRESS_X``) that 

147 will be used to authorize requests to the NEMO API. This token can be 

148 obtained by visiting the "Detailed Administration" page in the NEMO 

149 instance, and then creating a new token under the "Tokens" menu. Note that 

150 this token will authenticate as a particular user, so you may wish to set 

151 up a "dummy" or "functional" user account in the NEMO instance for these 

152 operations. 

153 

154(nemo-strftime-fmt)= 

155(nemo-strptime-fmt)= 

156 

157`NX_NEMO_STRFTIME_FMT_X` and `NX_NEMO_STRPTIME_FMT_X` 

158 These options are optional, and control how dates/times are sent to 

159 (`strftime`) and interpreted from (`strptime`) the API. If "`strftime_fmt`" 

160 and/or "`strptime_fmt`" are not provided, the standard ISO 8601 format 

161 for datetime representation will be used (which should work with the 

162 default NEMO settings). These options are configurable to allow for 

163 support of non-default date format settings on a NEMO server. The formats 

164 should be provided using the standard datetime library syntax for 

165 encoding date and time information (see :ref:`strftime-strptime-behavior` 

166 for details). 

167 

168(nemo-tz)= 

169 

170`NX_NEMO_TZ_X` 

171 Also optional; If the "`tz`" option is provided, the datetime 

172 strings received from the NEMO API will be coerced into the given timezone. 

173 The timezone should be specified using the IANA "tz database" name (see 

174 https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). This option 

175 should not be supplied for NEMO servers that return time zone information in 

176 their API response, since it will override the timezone of the returned 

177 data. It is mostly useful for servers that return reservation/usage event 

178 times without any timezone information. Providing it helps properly map 

179 file creation times to usage event times. 

180 

181(email-smtp-host)= 

182 

183`NX_EMAIL_SMTP_HOST` 

184 SMTP server hostname for sending email notifications from the 

185 ``nexuslims build-records`` script (e.g., ``smtp.gmail.com``). 

186 Required for email notifications. 

187 

188(email-smtp-port)= 

189 

190`NX_EMAIL_SMTP_PORT` 

191 SMTP server port. Default is ``587`` for STARTTLS. 

192 

193(email-smtp-username)= 

194 

195`NX_EMAIL_SMTP_USERNAME` 

196 SMTP username for authentication (if required by your SMTP server). 

197 

198(email-smtp-password)= 

199 

200`NX_EMAIL_SMTP_PASSWORD` 

201 SMTP password for authentication (if required by your SMTP server). 

202 

203(email-use-tls)= 

204 

205`NX_EMAIL_USE_TLS` 

206 Use TLS encryption for SMTP connection. Default is ``true``. 

207 

208(email-sender)= 

209 

210`NX_EMAIL_SENDER` 

211 Email address to send notifications from. Required for email notifications. 

212 

213(email-recipients)= 

214 

215`NX_EMAIL_RECIPIENTS` 

216 Comma-separated list of recipient email addresses for error notifications 

217 (e.g., ``admin@example.com,team@example.com``). Required for email notifications. 

218""" 

219 

220# pylint: disable=invalid-name 

221 

222import logging 

223 

224# Defer heavy imports to reduce CLI startup time 

225# These will be imported on-demand when accessing the attributes 

226from .version import __version__ 

227 

228 

229def __getattr__(name): 

230 """Lazy import submodules to speed up CLI startup.""" 

231 if name in ("builder", "db", "extractors", "instruments", "utils"): 

232 import importlib # noqa: PLC0415 

233 

234 module = importlib.import_module(f".{name}", __package__) 

235 globals()[name] = module 

236 return module 

237 msg = f"module {__name__!r} has no attribute {name!r}" 

238 raise AttributeError(msg) 

239 

240 

241def __dir__(): 

242 """Support for dir() to show lazy-loaded attributes.""" 

243 return ["__version__", "builder", "db", "extractors", "instruments", "utils"] 

244 

245 

246def _filter_hyperspy_messages(record): # pragma: no cover 

247 """Filter HyperSpy API import warnings within the NexusLIMS codebase.""" 

248 # this only triggers if the hs.preferences.GUIs.warn_if_guis_are_missing 

249 # preference is set to True 

250 return not ( 

251 record.msg.startswith("The ipywidgets GUI") 

252 or record.msg.startswith( 

253 "The traitsui GUI", 

254 ) 

255 ) 

256 

257 

258# connect the filter function to the HyperSpy logger 

259logging.getLogger("hyperspy.api").addFilter(_filter_hyperspy_messages) 

260 

261# tweak some logger levels 

262logging.getLogger("matplotlib.font_manager").disabled = True 

263logging.getLogger("matplotlib").setLevel(logging.WARNING) 

264logging.getLogger("PIL.PngImagePlugin").setLevel(logging.WARNING) 

265 

266# set log message format 

267logging.basicConfig(format="%(asctime)s %(name)s %(levelname)s: %(message)s") 

268 

269__all__ = ["__version__", "builder", "db", "extractors", "instruments", "utils"]