dxpy 0.383.1__tar.gz → 0.385.0__tar.gz

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 (187) hide show
  1. {dxpy-0.383.1 → dxpy-0.385.0}/PKG-INFO +9 -1
  2. {dxpy-0.383.1 → dxpy-0.385.0}/Readme.md +8 -0
  3. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/dxapplet.py +8 -4
  4. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/dxfile.py +1 -1
  5. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/dxjob.py +20 -14
  6. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/scripts/dx.py +20 -7
  7. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/scripts/dx_build_app.py +5 -5
  8. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/system_requirements.py +1 -1
  9. dxpy-0.385.0/dxpy/toolkit_version.py +1 -0
  10. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy.egg-info/PKG-INFO +9 -1
  11. {dxpy-0.383.1 → dxpy-0.385.0}/test/test_dx_bash_helpers.py +16 -0
  12. {dxpy-0.383.1 → dxpy-0.385.0}/test/test_dxclient.py +53 -3
  13. {dxpy-0.383.1 → dxpy-0.385.0}/test/test_dxpy.py +8 -2
  14. dxpy-0.383.1/dxpy/toolkit_version.py +0 -1
  15. {dxpy-0.383.1 → dxpy-0.385.0}/MANIFEST.in +0 -0
  16. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/__init__.py +0 -0
  17. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/api.py +0 -0
  18. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/app_builder.py +0 -0
  19. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/app_categories.py +0 -0
  20. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/asset_builder.py +0 -0
  21. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/__init__.py +0 -0
  22. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/apollo/__init__.py +0 -0
  23. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/apollo/cmd_line_options_validator.py +0 -0
  24. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/apollo/data_transformations.py +0 -0
  25. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/apollo/dataset.py +0 -0
  26. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/apollo/json_validation_by_schema.py +0 -0
  27. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/apollo/schemas/__init__.py +0 -0
  28. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/apollo/schemas/assay_filtering_conditions.py +0 -0
  29. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/apollo/schemas/assay_filtering_json_schemas.py +0 -0
  30. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/apollo/schemas/input_arguments_validation_schemas.py +0 -0
  31. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/apollo/vizclient.py +0 -0
  32. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/apollo/vizserver_filters_from_json_parser.py +0 -0
  33. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/apollo/vizserver_payload_builder.py +0 -0
  34. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/auth.py +0 -0
  35. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/download_all_inputs.py +0 -0
  36. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/dxanalysis.py +0 -0
  37. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/dxapp.py +0 -0
  38. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/dxapp_container_functions.py +0 -0
  39. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/dxdatabase.py +0 -0
  40. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/dxdatabase_functions.py +0 -0
  41. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/dxdataobject_functions.py +0 -0
  42. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/dxfile_functions.py +0 -0
  43. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/dxglobalworkflow.py +0 -0
  44. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/dxproject.py +0 -0
  45. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/dxrecord.py +0 -0
  46. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/dxworkflow.py +0 -0
  47. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/mount_all_inputs.py +0 -0
  48. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/bindings/search.py +0 -0
  49. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/cli/__init__.py +0 -0
  50. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/cli/cp.py +0 -0
  51. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/cli/dataset_utilities.py +0 -0
  52. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/cli/download.py +0 -0
  53. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/cli/exec_io.py +0 -0
  54. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/cli/help_messages.py +0 -0
  55. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/cli/org.py +0 -0
  56. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/cli/output_handling.py +0 -0
  57. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/cli/parsers.py +0 -0
  58. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/cli/workflow.py +0 -0
  59. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/compat.py +0 -0
  60. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/dx_extract_utils/Homo_sapiens_genes_manifest.json +0 -0
  61. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/dx_extract_utils/Homo_sapiens_genes_manifest_staging.json +0 -0
  62. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/dx_extract_utils/Homo_sapiens_genes_manifest_staging_vep.json +0 -0
  63. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/dx_extract_utils/Homo_sapiens_genes_manifest_vep.json +0 -0
  64. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/dx_extract_utils/__init__.py +0 -0
  65. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/dx_extract_utils/cohort_filter_payload.py +0 -0
  66. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/dx_extract_utils/column_conditions.json +0 -0
  67. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/dx_extract_utils/column_conversion.json +0 -0
  68. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/dx_extract_utils/filter_to_payload.py +0 -0
  69. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/dx_extract_utils/germline_utils.py +0 -0
  70. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/dx_extract_utils/input_validation.py +0 -0
  71. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/dx_extract_utils/input_validation_somatic.py +0 -0
  72. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/dx_extract_utils/retrieve_allele_schema.json +0 -0
  73. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/dx_extract_utils/retrieve_annotation_schema.json +0 -0
  74. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/dx_extract_utils/retrieve_bins.py +0 -0
  75. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/dx_extract_utils/retrieve_genotype_schema.json +0 -0
  76. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/dx_extract_utils/return_columns_allele.json +0 -0
  77. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/dx_extract_utils/return_columns_annotation.json +0 -0
  78. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/dx_extract_utils/return_columns_genotype.json +0 -0
  79. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/dx_extract_utils/return_columns_genotype_only.json +0 -0
  80. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/dx_extract_utils/somatic_filter_payload.py +0 -0
  81. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/dxlog.py +0 -0
  82. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/exceptions.py +0 -0
  83. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/executable_builder.py +0 -0
  84. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/nextflow/ImageRef.py +0 -0
  85. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/nextflow/ImageRefFactory.py +0 -0
  86. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/nextflow/__init__.py +0 -0
  87. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/nextflow/awscli_assets.json +0 -0
  88. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/nextflow/awscli_assets.staging.json +0 -0
  89. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/nextflow/collect_images.py +0 -0
  90. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/nextflow/nextaur_assets.json +0 -0
  91. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/nextflow/nextaur_assets.staging.json +0 -0
  92. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/nextflow/nextflow_assets.json +0 -0
  93. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/nextflow/nextflow_assets.staging.json +0 -0
  94. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/nextflow/nextflow_builder.py +0 -0
  95. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/nextflow/nextflow_templates.py +0 -0
  96. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/nextflow/nextflow_utils.py +0 -0
  97. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/packages/__init__.py +0 -0
  98. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/scripts/__init__.py +0 -0
  99. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/scripts/dx_app_wizard.py +0 -0
  100. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/scripts/dx_build_applet.py +0 -0
  101. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/ssh_tunnel_app_support.py +0 -0
  102. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/templating/__init__.py +0 -0
  103. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/templating/bash.py +0 -0
  104. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/templating/python.py +0 -0
  105. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/templating/templates/Readme.md +0 -0
  106. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/templating/templates/bash/basic/dxapp.json +0 -0
  107. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/templating/templates/bash/basic/src/code.sh +0 -0
  108. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/templating/templates/bash/parallelized/dxapp.json +0 -0
  109. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/templating/templates/bash/parallelized/src/code.sh +0 -0
  110. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/templating/templates/bash/scatter-process-gather/dxapp.json +0 -0
  111. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/templating/templates/bash/scatter-process-gather/src/code.sh +0 -0
  112. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/templating/templates/nextflow/dxapp.json +0 -0
  113. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/templating/templates/nextflow/src/nextflow.sh +0 -0
  114. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/templating/templates/python/basic/dxapp.json +0 -0
  115. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/templating/templates/python/basic/src/code.py +0 -0
  116. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/templating/templates/python/basic/test/test.py +0 -0
  117. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/templating/templates/python/parallelized/dxapp.json +0 -0
  118. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/templating/templates/python/parallelized/src/code.py +0 -0
  119. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/templating/templates/python/parallelized/test/test.py +0 -0
  120. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/templating/templates/python/scatter-process-gather/dxapp.json +0 -0
  121. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/templating/templates/python/scatter-process-gather/src/code.py +0 -0
  122. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/templating/templates/python/scatter-process-gather/test/test.py +0 -0
  123. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/templating/utils.py +0 -0
  124. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/utils/__init__.py +0 -0
  125. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/utils/batch_utils.py +0 -0
  126. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/utils/completer.py +0 -0
  127. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/utils/config.py +0 -0
  128. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/utils/describe.py +0 -0
  129. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/utils/exec_utils.py +0 -0
  130. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/utils/executable_unbuilder.py +0 -0
  131. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/utils/file_handle.py +0 -0
  132. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/utils/file_load_utils.py +0 -0
  133. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/utils/genomic_utils.py +0 -0
  134. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/utils/job_log_client.py +0 -0
  135. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/utils/local_exec_utils.py +0 -0
  136. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/utils/pathmatch.py +0 -0
  137. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/utils/pretty_print.py +0 -0
  138. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/utils/printing.py +0 -0
  139. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/utils/resolver.py +0 -0
  140. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/utils/spelling_corrector.py +0 -0
  141. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/utils/version.py +0 -0
  142. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy/workflow_builder.py +0 -0
  143. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy.egg-info/SOURCES.txt +0 -0
  144. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy.egg-info/dependency_links.txt +0 -0
  145. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy.egg-info/entry_points.txt +0 -0
  146. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy.egg-info/not-zip-safe +0 -0
  147. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy.egg-info/requires.txt +0 -0
  148. {dxpy-0.383.1 → dxpy-0.385.0}/dxpy.egg-info/top_level.txt +0 -0
  149. {dxpy-0.383.1 → dxpy-0.385.0}/requirements.txt +0 -0
  150. {dxpy-0.383.1 → dxpy-0.385.0}/requirements_setuptools.txt +0 -0
  151. {dxpy-0.383.1 → dxpy-0.385.0}/requirements_test.txt +0 -0
  152. {dxpy-0.383.1 → dxpy-0.385.0}/scripts/dx-clone-asset +0 -0
  153. {dxpy-0.383.1 → dxpy-0.385.0}/scripts/dx-docker +0 -0
  154. {dxpy-0.383.1 → dxpy-0.385.0}/scripts/dx-download-all-inputs +0 -0
  155. {dxpy-0.383.1 → dxpy-0.385.0}/scripts/dx-fetch-bundled-depends +0 -0
  156. {dxpy-0.383.1 → dxpy-0.385.0}/scripts/dx-generate-dxapp +0 -0
  157. {dxpy-0.383.1 → dxpy-0.385.0}/scripts/dx-jobutil-add-output +0 -0
  158. {dxpy-0.383.1 → dxpy-0.385.0}/scripts/dx-jobutil-dxlink +0 -0
  159. {dxpy-0.383.1 → dxpy-0.385.0}/scripts/dx-jobutil-get-identity-token +0 -0
  160. {dxpy-0.383.1 → dxpy-0.385.0}/scripts/dx-jobutil-new-job +0 -0
  161. {dxpy-0.383.1 → dxpy-0.385.0}/scripts/dx-jobutil-parse-link +0 -0
  162. {dxpy-0.383.1 → dxpy-0.385.0}/scripts/dx-jobutil-report-error +0 -0
  163. {dxpy-0.383.1 → dxpy-0.385.0}/scripts/dx-log-stream +0 -0
  164. {dxpy-0.383.1 → dxpy-0.385.0}/scripts/dx-mount-all-inputs +0 -0
  165. {dxpy-0.383.1 → dxpy-0.385.0}/scripts/dx-notebook-reconnect +0 -0
  166. {dxpy-0.383.1 → dxpy-0.385.0}/scripts/dx-print-bash-vars +0 -0
  167. {dxpy-0.383.1 → dxpy-0.385.0}/scripts/dx-upload-all-outputs +0 -0
  168. {dxpy-0.383.1 → dxpy-0.385.0}/setup.cfg +0 -0
  169. {dxpy-0.383.1 → dxpy-0.385.0}/setup.py +0 -0
  170. {dxpy-0.383.1 → dxpy-0.385.0}/test/test_batch.py +0 -0
  171. {dxpy-0.383.1 → dxpy-0.385.0}/test/test_create_cohort.py +0 -0
  172. {dxpy-0.383.1 → dxpy-0.385.0}/test/test_describe.py +0 -0
  173. {dxpy-0.383.1 → dxpy-0.385.0}/test/test_dx-docker.py +0 -0
  174. {dxpy-0.383.1 → dxpy-0.385.0}/test/test_dx_app_wizard.py +0 -0
  175. {dxpy-0.383.1 → dxpy-0.385.0}/test/test_dx_completion.py +0 -0
  176. {dxpy-0.383.1 → dxpy-0.385.0}/test/test_dx_symlink.py +0 -0
  177. {dxpy-0.383.1 → dxpy-0.385.0}/test/test_dxabs.py +0 -0
  178. {dxpy-0.383.1 → dxpy-0.385.0}/test/test_dxasset.py +0 -0
  179. {dxpy-0.383.1 → dxpy-0.385.0}/test/test_dxpy_utils.py +0 -0
  180. {dxpy-0.383.1 → dxpy-0.385.0}/test/test_dxunpack.py +0 -0
  181. {dxpy-0.383.1 → dxpy-0.385.0}/test/test_extract_assay.py +0 -0
  182. {dxpy-0.383.1 → dxpy-0.385.0}/test/test_extract_dataset.py +0 -0
  183. {dxpy-0.383.1 → dxpy-0.385.0}/test/test_extract_expression.py +0 -0
  184. {dxpy-0.383.1 → dxpy-0.385.0}/test/test_extract_somatic.py +0 -0
  185. {dxpy-0.383.1 → dxpy-0.385.0}/test/test_nextflow.py +0 -0
  186. {dxpy-0.383.1 → dxpy-0.385.0}/test/test_nextflow_ImageRef.py +0 -0
  187. {dxpy-0.383.1 → dxpy-0.385.0}/test/test_nextflow_ImageRefFactory.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dxpy
3
- Version: 0.383.1
3
+ Version: 0.385.0
4
4
  Summary: DNAnexus Platform API bindings for Python
5
5
  Home-page: https://github.com/dnanexus/dx-toolkit
6
6
  Author: Aleksandra Zalcman, Andrey Kislyuk, Anurag Biyani, Geet Duggal, Katherine Lai, Kurt Jensen, Marek Hrvol, Ohad Rodeh, Phil Sung
@@ -48,6 +48,14 @@ Example:
48
48
  $ _DX_DEBUG=1 dx ls
49
49
  ```
50
50
 
51
+ ### Debugging inside the IDE (PyCharm)
52
+ To be able to debug dx-toolkit (dx commands) directly in the IDE, 'Run/Debug Configurations' needs to be changed.
53
+ 1. Go to Run → Edit Configurations...
54
+ 2. Add New Configuration (Python)
55
+ 3. Change script to module (dxpy.scripts.dx)
56
+ 4. To Script parameters field write dx command you want to run (eg 'ls' runs 'dx ls')
57
+ 5. Apply and OK (now it is possible to start debugging via main() function in dx.py)
58
+
51
59
  Python coding style
52
60
  -------------------
53
61
 
@@ -27,6 +27,14 @@ Example:
27
27
  $ _DX_DEBUG=1 dx ls
28
28
  ```
29
29
 
30
+ ### Debugging inside the IDE (PyCharm)
31
+ To be able to debug dx-toolkit (dx commands) directly in the IDE, 'Run/Debug Configurations' needs to be changed.
32
+ 1. Go to Run → Edit Configurations...
33
+ 2. Add New Configuration (Python)
34
+ 3. Change script to module (dxpy.scripts.dx)
35
+ 4. To Script parameters field write dx command you want to run (eg 'ls' runs 'dx ls')
36
+ 5. Apply and OK (now it is possible to start debugging via main() function in dx.py)
37
+
30
38
  Python coding style
31
39
  -------------------
32
40
 
@@ -58,11 +58,12 @@ class DXExecutable:
58
58
  if kwargs.get(arg) is not None:
59
59
  run_input[arg] = kwargs[arg]
60
60
 
61
- if kwargs.get('instance_type') is not None or kwargs.get('cluster_spec') is not None or kwargs.get('fpga_driver') is not None:
61
+ if any(kwargs.get(key) is not None for key in ['instance_type', 'cluster_spec', 'fpga_driver', 'nvidia_driver']):
62
62
  instance_type_srd = SystemRequirementsDict.from_instance_type(kwargs.get('instance_type'))
63
63
  cluster_spec_srd = SystemRequirementsDict(kwargs.get('cluster_spec'))
64
64
  fpga_driver_srd = SystemRequirementsDict(kwargs.get('fpga_driver'))
65
- run_input["systemRequirements"] = (instance_type_srd + cluster_spec_srd + fpga_driver_srd).as_dict()
65
+ nvidia_driver_srd = SystemRequirementsDict(kwargs.get('nvidia_driver'))
66
+ run_input["systemRequirements"] = (instance_type_srd + cluster_spec_srd + fpga_driver_srd + nvidia_driver_srd).as_dict()
66
67
 
67
68
  if kwargs.get('system_requirements') is not None:
68
69
  run_input["systemRequirements"] = kwargs.get('system_requirements')
@@ -195,7 +196,7 @@ class DXExecutable:
195
196
  depends_on=None, allow_ssh=None, debug=None, delay_workspace_destruction=None, priority=None, head_job_on_demand=None,
196
197
  ignore_reuse=None, ignore_reuse_stages=None, detach=None, cost_limit=None, rank=None, max_tree_spot_wait_time=None,
197
198
  max_job_spot_wait_time=None, preserve_job_outputs=None, detailed_job_metrics=None, extra_args=None,
198
- fpga_driver=None, system_requirements=None, system_requirements_by_executable=None, **kwargs):
199
+ fpga_driver=None, system_requirements=None, system_requirements_by_executable=None, nvidia_driver=None, **kwargs):
199
200
  '''
200
201
  :param executable_input: Hash of the executable's input arguments
201
202
  :type executable_input: dict
@@ -252,6 +253,8 @@ class DXExecutable:
252
253
  :type system_requirements: dict
253
254
  :param system_requirements_by_executable: System requirement by executable double mapping
254
255
  :type system_requirements_by_executable: dict
256
+ :param nvidia_driver: a dict mapping function names to nvidia driver requests
257
+ :type nvidia_driver: dict
255
258
  :rtype: :class:`~dxpy.bindings.dxjob.DXJob`
256
259
 
257
260
  Creates a new job that executes the function "main" of this executable with
@@ -292,7 +295,8 @@ class DXExecutable:
292
295
  extra_args=extra_args,
293
296
  fpga_driver=fpga_driver,
294
297
  system_requirements=system_requirements,
295
- system_requirements_by_executable=system_requirements_by_executable)
298
+ system_requirements_by_executable=system_requirements_by_executable,
299
+ nvidia_driver=nvidia_driver)
296
300
  return self._run_impl(run_input, **kwargs)
297
301
 
298
302
 
@@ -728,7 +728,7 @@ class DXFile(DXDataObject):
728
728
  report_progress_fn(self, len(data))
729
729
 
730
730
  def wait_until_parts_uploaded(self, **kwargs):
731
- self._wait_until_parts_uploaded(self, **kwargs)
731
+ self._wait_until_parts_uploaded(**kwargs)
732
732
 
733
733
 
734
734
  def get_download_url(self, duration=None, preauthenticated=False, filename=None, project=None, **kwargs):
@@ -38,14 +38,15 @@ from ..system_requirements import SystemRequirementsDict
38
38
  from ..utils.local_exec_utils import queue_entry_point
39
39
  from ..compat import basestring
40
40
 
41
+
41
42
  #########
42
43
  # DXJob #
43
44
  #########
44
45
 
45
- def new_dxjob(fn_input, fn_name, name=None, tags=None, properties=None, details=None,
46
- instance_type=None, depends_on=None,
47
- cluster_spec=None, fpga_driver=None, system_requirements=None, system_requirements_by_executable=None,
48
- **kwargs):
46
+
47
+ def new_dxjob(fn_input, fn_name, name=None, tags=None, properties=None, details=None, instance_type=None,
48
+ depends_on=None, cluster_spec=None, fpga_driver=None, system_requirements=None,
49
+ system_requirements_by_executable=None, nvidia_driver=None, **kwargs):
49
50
  '''
50
51
  :param fn_input: Function input
51
52
  :type fn_input: dict
@@ -71,6 +72,8 @@ def new_dxjob(fn_input, fn_name, name=None, tags=None, properties=None, details=
71
72
  :type system_requirements: dict
72
73
  :param system_requirements_by_executable: System requirement by executable double mapping
73
74
  :type system_requirements_by_executable: dict
75
+ :param nvidia_driver: a dict mapping function names to nvidia driver requests
76
+ :type nvidia_driver: dict
74
77
  :rtype: :class:`~dxpy.bindings.dxjob.DXJob`
75
78
 
76
79
  Creates and enqueues a new job that will execute a particular
@@ -94,12 +97,13 @@ def new_dxjob(fn_input, fn_name, name=None, tags=None, properties=None, details=
94
97
 
95
98
  '''
96
99
  dxjob = DXJob()
97
- dxjob.new(fn_input, fn_name, name=name, tags=tags, properties=properties,
98
- details=details, instance_type=instance_type, depends_on=depends_on,
99
- cluster_spec=cluster_spec, fpga_driver=fpga_driver,
100
- system_requirements=system_requirements, system_requirements_by_executable=system_requirements_by_executable, **kwargs)
100
+ dxjob.new(fn_input, fn_name, name=name, tags=tags, properties=properties, details=details,
101
+ instance_type=instance_type, depends_on=depends_on, cluster_spec=cluster_spec, fpga_driver=fpga_driver,
102
+ system_requirements=system_requirements, system_requirements_by_executable=system_requirements_by_executable,
103
+ nvidia_driver=nvidia_driver, **kwargs)
101
104
  return dxjob
102
105
 
106
+
103
107
  class DXJob(DXObject):
104
108
  '''
105
109
  Remote job object handler.
@@ -112,10 +116,9 @@ class DXJob(DXObject):
112
116
  DXObject.__init__(self, dxid=dxid)
113
117
  self.set_id(dxid)
114
118
 
115
- def new(self, fn_input, fn_name, name=None, tags=None, properties=None, details=None,
116
- instance_type=None, depends_on=None,
117
- cluster_spec=None, fpga_driver=None, system_requirements=None, system_requirements_by_executable=None,
118
- **kwargs):
119
+ def new(self, fn_input, fn_name, name=None, tags=None, properties=None, details=None, instance_type=None,
120
+ depends_on=None, cluster_spec=None, fpga_driver=None, system_requirements=None,
121
+ system_requirements_by_executable=None, nvidia_driver=None, **kwargs):
119
122
  '''
120
123
  :param fn_input: Function input
121
124
  :type fn_input: dict
@@ -141,6 +144,8 @@ class DXJob(DXObject):
141
144
  :type system_requirements: dict
142
145
  :param system_requirements_by_executable: System requirement by executable double mapping
143
146
  :type system_requirements_by_executable: dict
147
+ :param nvidia_driver: a dict mapping function names to nvidia driver requests
148
+ :type nvidia_driver: dict
144
149
 
145
150
  Creates and enqueues a new job that will execute a particular
146
151
  function (from the same app or applet as the one the current job
@@ -179,11 +184,12 @@ class DXJob(DXObject):
179
184
  req_input["tags"] = tags
180
185
  if properties is not None:
181
186
  req_input["properties"] = properties
182
- if instance_type is not None or cluster_spec is not None or fpga_driver is not None:
187
+ if any(requirement is not None for requirement in [instance_type, cluster_spec, fpga_driver, nvidia_driver]):
183
188
  instance_type_srd = SystemRequirementsDict.from_instance_type(instance_type, fn_name)
184
189
  cluster_spec_srd = SystemRequirementsDict(cluster_spec)
185
190
  fpga_driver_srd = SystemRequirementsDict(fpga_driver)
186
- req_input["systemRequirements"] = (instance_type_srd + cluster_spec_srd + fpga_driver_srd).as_dict()
191
+ nvidia_driver_srd = SystemRequirementsDict(nvidia_driver)
192
+ req_input["systemRequirements"] = (instance_type_srd + cluster_spec_srd + fpga_driver_srd + nvidia_driver_srd).as_dict()
187
193
  if system_requirements is not None:
188
194
  req_input["systemRequirements"] = system_requirements
189
195
  if system_requirements_by_executable is not None:
@@ -1440,6 +1440,8 @@ def new_project(args):
1440
1440
  inputs["monthlyStorageLimit"] = args.monthly_storage_limit
1441
1441
  if args.default_symlink is not None:
1442
1442
  inputs["defaultSymlink"] = json.loads(args.default_symlink)
1443
+ if args.drive is not None:
1444
+ inputs["drive"] = args.drive
1443
1445
  try:
1444
1446
  resp = dxpy.api.project_new(inputs)
1445
1447
  if args.brief:
@@ -1511,14 +1513,18 @@ def set_visibility(args):
1511
1513
 
1512
1514
  def get_details(args):
1513
1515
  # Attempt to resolve name
1514
- _project, _folderpath, entity_result = try_call(resolve_existing_path,
1516
+ project, _folderpath, entity_result = try_call(resolve_existing_path,
1515
1517
  args.path, expected='entity')
1516
1518
 
1517
1519
  if entity_result is None:
1518
1520
  err_exit(fill('Could not resolve "' + args.path + '" to a name or ID'), 3)
1521
+
1522
+ input_params = {}
1523
+ if project is not None:
1524
+ input_params['project'] = project
1519
1525
 
1520
1526
  try:
1521
- print(json.dumps(dxpy.DXHTTPRequest('/' + entity_result['id'] + '/getDetails', {}), indent=4))
1527
+ print(json.dumps(dxpy.DXHTTPRequest('/' + entity_result['id'] + '/getDetails', input_params), indent=4))
1522
1528
  except:
1523
1529
  err_exit()
1524
1530
 
@@ -3191,10 +3197,12 @@ def run_body(args, executable, dest_proj, dest_path, preset_inputs=None, input_n
3191
3197
  cloned_instance_type = SystemRequirementsDict.from_sys_requirements(cloned_system_requirements, _type='instanceType')
3192
3198
  cloned_cluster_spec = SystemRequirementsDict.from_sys_requirements(cloned_system_requirements, _type='clusterSpec')
3193
3199
  cloned_fpga_driver = SystemRequirementsDict.from_sys_requirements(cloned_system_requirements, _type='fpgaDriver')
3200
+ cloned_nvidia_driver = SystemRequirementsDict.from_sys_requirements(cloned_system_requirements, _type='nvidiaDriver')
3194
3201
  cloned_system_requirements_by_executable = args.cloned_job_desc.get("mergedSystemRequirementsByExecutable", {}) or {}
3195
3202
  else:
3196
3203
  cloned_system_requirements = {}
3197
- cloned_instance_type, cloned_cluster_spec, cloned_fpga_driver = SystemRequirementsDict({}), SystemRequirementsDict({}), SystemRequirementsDict({})
3204
+ cloned_instance_type, cloned_cluster_spec, cloned_fpga_driver, cloned_nvidia_driver = (
3205
+ SystemRequirementsDict({}), SystemRequirementsDict({}), SystemRequirementsDict({}), SystemRequirementsDict({}))
3198
3206
  cloned_system_requirements_by_executable = {}
3199
3207
 
3200
3208
  # convert runtime --instance-type into mapping {entrypoint:{'instanceType':xxx}}
@@ -3223,12 +3231,15 @@ def run_body(args, executable, dest_proj, dest_path, preset_inputs=None, input_n
3223
3231
  else:
3224
3232
  requested_cluster_spec = cloned_cluster_spec
3225
3233
 
3226
- # fpga driver now does not have corresponding dx run option, so it can only be requested using the cloned value
3234
+ # fpga/nvidia driver now does not have corresponding dx run option,
3235
+ # so it can only be requested using the cloned value
3227
3236
  requested_fpga_driver = cloned_fpga_driver
3237
+ requested_nvidia_driver = cloned_nvidia_driver
3228
3238
 
3229
- # combine the requested instance type, full cluster spec, fpga spec
3239
+ # combine the requested instance type, full cluster spec, fpga spec, nvidia spec
3230
3240
  # into the runtime systemRequirements
3231
- requested_system_requirements = (requested_instance_type + requested_cluster_spec + requested_fpga_driver).as_dict()
3241
+ requested_system_requirements = (requested_instance_type + requested_cluster_spec + requested_fpga_driver +
3242
+ requested_nvidia_driver).as_dict()
3232
3243
 
3233
3244
  if (args.instance_type and cloned_system_requirements_by_executable):
3234
3245
  warning = BOLD("WARNING") + ": --instance-type argument: {} may get overridden by".format(args.instance_type)
@@ -3279,6 +3290,7 @@ def run_body(args, executable, dest_proj, dest_path, preset_inputs=None, input_n
3279
3290
  "instance_type": None,
3280
3291
  "cluster_spec": None,
3281
3292
  "fpga_driver": None,
3293
+ "nvidia_driver": None,
3282
3294
  "stage_instance_types": args.stage_instance_types,
3283
3295
  "stage_folders": args.stage_folders,
3284
3296
  "rerun_stages": args.rerun_stages,
@@ -5804,7 +5816,8 @@ parser_new_project.add_argument('--database-ui-view-only', help='Viewers on the
5804
5816
  parser_new_project.add_argument('--monthly-compute-limit', type=positive_integer, help='Monthly project spending limit for compute')
5805
5817
  parser_new_project.add_argument('--monthly-egress-bytes-limit', type=positive_integer, help='Monthly project spending limit for egress (in Bytes)')
5806
5818
  parser_new_project.add_argument('--monthly-storage-limit', type=positive_number, help='Monthly project spending limit for storage')
5807
- parser_new_project.add_argument('--default-symlink', help='Default symlink for external store account')
5819
+ parser_new_project.add_argument('--default-symlink', help='Default symlink for external storage account')
5820
+ parser_new_project.add_argument('--drive', help='Drive for external storage account')
5808
5821
  parser_new_project.set_defaults(func=new_project)
5809
5822
  register_parser(parser_new_project, subparsers_action=subparsers_new, categories='fs')
5810
5823
 
@@ -357,11 +357,11 @@ def _verify_app_source_dir_impl(src_dir, temp_dir, mode, enforce=True):
357
357
  if "interpreter" not in manifest['runSpec']:
358
358
  raise dxpy.app_builder.AppBuilderException('runSpec.interpreter field was not present')
359
359
 
360
- if "release" not in manifest['runSpec'] or "distribution" not in manifest['runSpec']:
361
- warn_message = 'runSpec.distribution or runSpec.release was not present. These fields '
362
- warn_message += 'will be required in a future version of the API. Recommended value '
363
- warn_message += 'for distribution is \"Ubuntu\" and release - \"14.04\".'
364
- logger.warn(warn_message)
360
+ if "distribution" not in manifest['runSpec']:
361
+ raise dxpy.app_builder.AppBuilderException('Required field runSpec.distribution is not present')
362
+
363
+ if "release" not in manifest['runSpec']:
364
+ raise dxpy.app_builder.AppBuilderException('Required field runSpec.release is not present')
365
365
 
366
366
  if manifest['runSpec']['interpreter'] in ["python2.7", "bash", "python3"]:
367
367
  if "file" in manifest['runSpec']:
@@ -85,7 +85,7 @@ class SystemRequirementsDict(object):
85
85
  It can extract only entrypoints with specific fields ('clusterSpec',
86
86
  'instanceType', etc), depending on the value of _type.
87
87
  """
88
- allowed_types = ['all', 'clusterSpec', 'instanceType', 'fpgaDriver']
88
+ allowed_types = ['all', 'clusterSpec', 'instanceType', 'fpgaDriver', 'nvidiaDriver']
89
89
  if _type not in (allowed_types):
90
90
  raise DXError("Expected '_type' to be one of the following: {}".format(allowed_types))
91
91
 
@@ -0,0 +1 @@
1
+ version = '0.385.0'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dxpy
3
- Version: 0.383.1
3
+ Version: 0.385.0
4
4
  Summary: DNAnexus Platform API bindings for Python
5
5
  Home-page: https://github.com/dnanexus/dx-toolkit
6
6
  Author: Aleksandra Zalcman, Andrey Kislyuk, Anurag Biyani, Geet Duggal, Katherine Lai, Kurt Jensen, Marek Hrvol, Ohad Rodeh, Phil Sung
@@ -48,6 +48,14 @@ Example:
48
48
  $ _DX_DEBUG=1 dx ls
49
49
  ```
50
50
 
51
+ ### Debugging inside the IDE (PyCharm)
52
+ To be able to debug dx-toolkit (dx commands) directly in the IDE, 'Run/Debug Configurations' needs to be changed.
53
+ 1. Go to Run → Edit Configurations...
54
+ 2. Add New Configuration (Python)
55
+ 3. Change script to module (dxpy.scripts.dx)
56
+ 4. To Script parameters field write dx command you want to run (eg 'ls' runs 'dx ls')
57
+ 5. Apply and OK (now it is possible to start debugging via main() function in dx.py)
58
+
51
59
  Python coding style
52
60
  -------------------
53
61
 
@@ -935,6 +935,22 @@ class TestDXJobutilNewJob(DXTestCase):
935
935
  "other_function": {"fpgaDriver": "edico-1.4.5"}}}})),
936
936
  {"systemRequirementsByExecutable": {"my_applet":{"main": { "instanceType": "mem2_hdd2_x2", "clusterSpec":{"initialInstanceCount": 3}},
937
937
  "other_function": { "instanceType": "mem3_ssd2_fpga1_x8", "fpgaDriver": "edico-1.4.5"} }}}),
938
+ # nvidia driver
939
+ ("--instance-type-by-executable " +
940
+ pipes.quote(json.dumps({
941
+ "my_applet": {
942
+ "main": "mem1_ssd1_v2_x2",
943
+ "other_function": "mem2_ssd1_gpu_x16"}})) +
944
+ " --extra-args " +
945
+ pipes.quote(json.dumps({
946
+ "systemRequirementsByExecutable": {
947
+ "my_applet": {
948
+ "main": {"instanceType": "mem2_hdd2_x2"},
949
+ "other_function": {"nvidiaDriver": "R535"}}}})),
950
+ {"systemRequirementsByExecutable": {
951
+ "my_applet": {"main": {"instanceType": "mem2_hdd2_x2"},
952
+ "other_function": {"instanceType": "mem2_ssd1_gpu_x16",
953
+ "nvidiaDriver": "R535"}}}}),
938
954
  # properties - mapping
939
955
  (
940
956
  "--property foo=foo_value --property bar=bar_value",
@@ -3332,6 +3332,53 @@ dx-jobutil-add-output record_array $second_record --array
3332
3332
  run("dx run " + applet_id +
3333
3333
  " --instance-type-by-executable not-a-JSON-string")
3334
3334
 
3335
+ def test_dx_run_clone_nvidia_driver(self):
3336
+ """
3337
+ Run the applet and clone the origin job. Verify nvidiaDriver value.
3338
+ """
3339
+ build_nvidia_version = "R535"
3340
+ run_nvidia_version = "R470"
3341
+
3342
+ applet_id = dxpy.api.applet_new({"project": self.project,
3343
+ "dxapi": "1.0.0",
3344
+ "runSpec": {"interpreter": "bash",
3345
+ "distribution": "Ubuntu",
3346
+ "release": "20.04",
3347
+ "version": "0",
3348
+ "code": "echo 'hello'",
3349
+ "systemRequirements": {
3350
+ "*": {
3351
+ "instanceType": "mem2_hdd2_x1",
3352
+ "nvidiaDriver": build_nvidia_version
3353
+ }
3354
+ }}
3355
+ })['id']
3356
+
3357
+ # Run with unchanged nvidia version (build value)
3358
+ origin_job_id = run(f"dx run {applet_id} --brief -y").strip().split('\n')[-1]
3359
+ origin_job_desc = dxpy.api.job_describe(origin_job_id)
3360
+ assert origin_job_desc["systemRequirements"]["*"]["nvidiaDriver"] == build_nvidia_version
3361
+
3362
+ cloned_job_id = run(f"dx run --clone {origin_job_id} --brief -y").strip()
3363
+ cloned_job_desc = dxpy.api.job_describe(cloned_job_id)
3364
+ assert cloned_job_desc["systemRequirements"]["*"]["nvidiaDriver"] == build_nvidia_version
3365
+
3366
+ # Change nvidia driver version in runtime - origin job (run value)
3367
+ extra_args = json.dumps({"systemRequirements": {"*": {"nvidiaDriver": run_nvidia_version}}})
3368
+ origin_job_id_nvidia_override = run(f"dx run {applet_id} --extra-args '{extra_args}' --brief -y").strip().split('\n')[-1]
3369
+ origin_job_desc = dxpy.api.job_describe(origin_job_id_nvidia_override)
3370
+ assert origin_job_desc["systemRequirements"]["*"]["nvidiaDriver"] == run_nvidia_version
3371
+
3372
+ cloned_job_id_nvidia_override = run(f"dx run --clone {origin_job_id_nvidia_override} --brief -y").strip()
3373
+ cloned_job_desc = dxpy.api.job_describe(cloned_job_id_nvidia_override)
3374
+ assert cloned_job_desc["systemRequirements"]["*"]["nvidiaDriver"] == run_nvidia_version
3375
+
3376
+ # Change nvidia driver version in runtime - cloned job (build value)
3377
+ extra_args = json.dumps({"systemRequirements": {"*": {"nvidiaDriver": build_nvidia_version}}})
3378
+ cloned_job_id_nvidia_override = run(f"dx run --clone {origin_job_id_nvidia_override} --extra-args '{extra_args}' --brief -y").strip()
3379
+ cloned_job_desc = dxpy.api.job_describe(cloned_job_id_nvidia_override)
3380
+ assert cloned_job_desc["systemRequirements"]["*"]["nvidiaDriver"] == build_nvidia_version
3381
+
3335
3382
  def test_dx_run_clone(self):
3336
3383
  applet_id = dxpy.api.applet_new({"project": self.project,
3337
3384
  "dxapi": "1.0.0",
@@ -3626,12 +3673,14 @@ dx-jobutil-add-output record_array $second_record --array
3626
3673
  check_new_job_metadata(new_job_desc, orig_job_desc,
3627
3674
  overridden_fields=['systemRequirements'])
3628
3675
 
3629
- # fpgaDriver override: new original job with extra_args
3676
+ # fpgaDriver/nvidiaDriver override: new original job with extra_args
3630
3677
  orig_job_id = run("dx run " + other_applet_id +
3631
3678
  " --instance-count 2 --brief -y " +
3632
3679
  "--extra-args '" +
3633
- json.dumps({"systemRequirements": {"some_ep": {"clusterSpec": {"initialInstanceCount": 12, "bootstrapScript": "z.sh"},
3634
- "fpgaDriver": "edico-1.4.5"}}}) + "'").strip()
3680
+ json.dumps({"systemRequirements": {"some_ep":
3681
+ {"clusterSpec": {"initialInstanceCount": 12, "bootstrapScript": "z.sh"},
3682
+ "fpgaDriver": "edico-1.4.5",
3683
+ "nvidiaDriver": "R535"}}}) + "'").strip()
3635
3684
  orig_job_desc = dxpy.api.job_describe(orig_job_id)
3636
3685
  check_instance_count(orig_job_desc, ["main", "some_ep","*"], [2, 12, 2])
3637
3686
  # --instance-type and --instance-count override: instance type and cluster spec are resolved independently
@@ -3650,6 +3699,7 @@ dx-jobutil-add-output record_array $second_record --array
3650
3699
  self.assertEqual(new_job_desc['systemRequirements']['*']['instanceType'], 'mem2_hdd2_v2_x2')
3651
3700
 
3652
3701
  self.assertEqual(new_job_desc['systemRequirements']['some_ep']['fpgaDriver'], 'edico-1.4.5')
3702
+ self.assertEqual(new_job_desc['systemRequirements']['some_ep']['nvidiaDriver'], 'R535')
3653
3703
  self.assertEqual(new_job_desc['systemRequirements']['some_ep']['clusterSpec']['bootstrapScript'], 'z.sh')
3654
3704
 
3655
3705
  # --instance-type and --instance-type-by-executable override
@@ -1319,14 +1319,19 @@ def main():
1319
1319
  "interpreter": "python3",
1320
1320
  "distribution": "Ubuntu", "release": "20.04",
1321
1321
  "version": "0",
1322
- "execDepends": [{"name": "python-numpy"}]})
1322
+ "execDepends": [{"name": "python-numpy"}],
1323
+ "systemRequirements": {
1324
+ "*": {
1325
+ "nvidiaDriver": "R535"
1326
+ }
1327
+ }})
1323
1328
  dxrecord = dxpy.new_dxrecord()
1324
1329
  dxrecord.close()
1325
1330
  prog_input = {"chromosomes": {"$dnanexus_link": dxrecord.get_id()},
1326
1331
  "rowFetchChunk": 100}
1327
1332
  dxjob = dxapplet.run(applet_input=prog_input, details={"$dnanexus_link": "hello world"},
1328
1333
  tags=['foo', '$foo.bar'], properties={'$dnanexus_link.foo': 'barbaz'},
1329
- priority="normal")
1334
+ priority="normal", nvidia_driver={"*": {"nvidiaDriver": "R470"}})
1330
1335
  jobdesc = dxjob.describe()
1331
1336
  self.assertEqual(jobdesc["class"], "job")
1332
1337
  self.assertEqual(jobdesc["function"], "main")
@@ -1346,6 +1351,7 @@ def main():
1346
1351
  self.assertEqual(len(jobdesc["properties"]), 1)
1347
1352
  self.assertEqual(jobdesc["properties"]["$dnanexus_link.foo"], "barbaz")
1348
1353
  self.assertEqual(jobdesc["priority"], "normal")
1354
+ self.assertEqual(jobdesc["systemRequirements"]["*"]["nvidiaDriver"], "R470")
1349
1355
 
1350
1356
  # Test setting tags and properties on job
1351
1357
  dxjob.add_tags(["foo", "bar", "foo"])
@@ -1 +0,0 @@
1
- version = '0.383.1'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes