geoseeq 0.5.6a10__tar.gz → 0.5.6a12__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/PKG-INFO +1 -1
  2. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/cli/main.py +1 -1
  3. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/cli/upload/upload.py +10 -3
  4. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/cli/upload/upload_reads.py +86 -0
  5. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/result/file_download.py +5 -0
  6. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/result/file_upload.py +31 -7
  7. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/upload_download_manager.py +10 -3
  8. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq.egg-info/PKG-INFO +1 -1
  9. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/pyproject.toml +1 -1
  10. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/LICENSE +0 -0
  11. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/README.md +0 -0
  12. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/__init__.py +0 -0
  13. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/app.py +0 -0
  14. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/blob_constructors.py +0 -0
  15. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/bulk_creators.py +0 -0
  16. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/cli/__init__.py +0 -0
  17. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/cli/constants.py +0 -0
  18. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/cli/copy.py +0 -0
  19. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/cli/detail.py +0 -0
  20. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/cli/download.py +0 -0
  21. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/cli/fastq_utils.py +0 -0
  22. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/cli/get_eula.py +0 -0
  23. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/cli/manage.py +0 -0
  24. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/cli/progress_bar.py +0 -0
  25. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/cli/run.py +0 -0
  26. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/cli/search.py +0 -0
  27. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/cli/shared_params/__init__.py +0 -0
  28. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/cli/shared_params/common_state.py +0 -0
  29. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/cli/shared_params/config.py +0 -0
  30. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/cli/shared_params/id_handlers.py +0 -0
  31. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/cli/shared_params/obj_getters.py +0 -0
  32. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/cli/shared_params/opts_and_args.py +0 -0
  33. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/cli/upload/__init__.py +0 -0
  34. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/cli/upload/upload_advanced.py +0 -0
  35. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/cli/user.py +0 -0
  36. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/cli/utils.py +0 -0
  37. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/cli/view.py +0 -0
  38. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/constants.py +0 -0
  39. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/contrib/__init__.py +0 -0
  40. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/contrib/ncbi/__init__.py +0 -0
  41. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/contrib/ncbi/api.py +0 -0
  42. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/contrib/ncbi/bioproject.py +0 -0
  43. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/contrib/ncbi/cli.py +0 -0
  44. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/contrib/ncbi/setup_logging.py +0 -0
  45. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/file_system_cache.py +0 -0
  46. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/id_constructors/__init__.py +0 -0
  47. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/id_constructors/from_blobs.py +0 -0
  48. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/id_constructors/from_ids.py +0 -0
  49. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/id_constructors/from_names.py +0 -0
  50. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/id_constructors/from_uuids.py +0 -0
  51. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/id_constructors/resolvers.py +0 -0
  52. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/id_constructors/utils.py +0 -0
  53. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/knex.py +0 -0
  54. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/organization.py +0 -0
  55. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/pipeline.py +0 -0
  56. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/plotting/__init__.py +0 -0
  57. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/plotting/constants.py +0 -0
  58. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/plotting/highcharts.py +0 -0
  59. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/plotting/map/__init__.py +0 -0
  60. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/plotting/map/base_layer.py +0 -0
  61. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/plotting/map/map.py +0 -0
  62. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/plotting/map/overlay.py +0 -0
  63. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/plotting/selectable.py +0 -0
  64. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/project.py +0 -0
  65. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/remote_object.py +0 -0
  66. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/result/__init__.py +0 -0
  67. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/result/bioinfo.py +0 -0
  68. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/result/result_file.py +0 -0
  69. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/result/result_folder.py +0 -0
  70. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/result/utils.py +0 -0
  71. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/sample.py +0 -0
  72. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/search.py +0 -0
  73. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/user.py +0 -0
  74. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/utils.py +0 -0
  75. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/vc/__init__.py +0 -0
  76. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/vc/checksum.py +0 -0
  77. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/vc/cli.py +0 -0
  78. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/vc/clone.py +0 -0
  79. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/vc/constants.py +0 -0
  80. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/vc/vc_cache.py +0 -0
  81. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/vc/vc_dir.py +0 -0
  82. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/vc/vc_sample.py +0 -0
  83. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/vc/vc_stub.py +0 -0
  84. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq/work_orders.py +0 -0
  85. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq.egg-info/SOURCES.txt +0 -0
  86. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq.egg-info/dependency_links.txt +0 -0
  87. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq.egg-info/entry_points.txt +0 -0
  88. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/geoseeq.egg-info/top_level.txt +0 -0
  89. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/setup.cfg +0 -0
  90. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/setup.py +0 -0
  91. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/tests/__init__.py +0 -0
  92. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/tests/test_api_client.py +0 -0
  93. {geoseeq-0.5.6a10 → geoseeq-0.5.6a12}/tests/test_plotting.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: geoseeq
3
- Version: 0.5.6a10
3
+ Version: 0.5.6a12
4
4
  Summary: GeoSeeq command line tools and python API
5
5
  Author: David C. Danko
6
6
  Author-email: "David C. Danko" <dcdanko@biotia.io>
@@ -53,7 +53,7 @@ def version():
53
53
  Use of this tool implies acceptance of the GeoSeeq End User License Agreement.
54
54
  Run `geoseeq eula show` to view the EULA.
55
55
  """
56
- click.echo('0.5.6a10') # remember to update setup
56
+ click.echo('0.5.6a12') # remember to update setup
57
57
 
58
58
 
59
59
  @main.group('advanced')
@@ -36,7 +36,9 @@ hidden_option = click.option('--hidden/--no-hidden', default=False, help='Upload
36
36
 
37
37
  @click.command('files')
38
38
  @use_common_state
39
- @click.option('--cores', default=1, help='Number of uploads to run in parallel')
39
+ @click.option('--cores', default=1, help='Number of uploads to run in parallel', show_default=True)
40
+ @click.option('--threads-per-upload', default=4, help='Number of threads used to upload each file', show_default=True)
41
+ @click.option('--num-retries', default=3, help='Number of times to retry a failed upload', show_default=True)
40
42
  @yes_option
41
43
  @private_option
42
44
  @link_option
@@ -44,10 +46,11 @@ hidden_option = click.option('--hidden/--no-hidden', default=False, help='Upload
44
46
  @hidden_option
45
47
  @no_new_versions_option
46
48
  @click.option('-n', '--geoseeq-file-name', default=None, multiple=True,
47
- help='Specify a different name for the file on GeoSeeq than the local file name.')
49
+ help='Specify a different name for the file on GeoSeeq than the local file name.',
50
+ show_default=True)
48
51
  @folder_id_arg
49
52
  @click.argument('file_paths', type=click.Path(exists=True), nargs=-1)
50
- def cli_upload_file(state, cores, yes, private, link_type, recursive, hidden, no_new_versions, geoseeq_file_name, folder_id, file_paths):
53
+ def cli_upload_file(state, cores, threads_per_upload, num_retries, yes, private, link_type, recursive, hidden, no_new_versions, geoseeq_file_name, folder_id, file_paths):
51
54
  """Upload files to GeoSeeq.
52
55
 
53
56
  This command uploads files to either a sample or project on GeoSeeq. It can be used to upload
@@ -92,6 +95,8 @@ def cli_upload_file(state, cores, yes, private, link_type, recursive, hidden, no
92
95
 
93
96
  ---
94
97
  """
98
+ if num_retries < 1:
99
+ raise click.UsageError('--num-retries must be at least 1')
95
100
  knex = state.get_knex()
96
101
  result_folder = handle_folder_id(knex, folder_id, yes=yes, private=private, create=True)
97
102
  if geoseeq_file_name:
@@ -106,11 +111,13 @@ def cli_upload_file(state, cores, yes, private, link_type, recursive, hidden, no
106
111
 
107
112
  upload_manager = GeoSeeqUploadManager(
108
113
  n_parallel_uploads=cores,
114
+ threads_per_upload=threads_per_upload,
109
115
  link_type=link_type,
110
116
  progress_tracker_factory=PBarManager().get_new_bar,
111
117
  log_level=state.log_level,
112
118
  no_new_versions=no_new_versions,
113
119
  use_cache=state.use_cache,
120
+ num_retries=num_retries,
114
121
  )
115
122
  for geoseeq_file_name, file_path in name_pairs:
116
123
  if isfile(file_path):
@@ -132,6 +132,28 @@ def flatten_list_of_fastqs(filepaths):
132
132
  return flattened
133
133
 
134
134
 
135
+ def _is_bam(path):
136
+ for ext in ['.bam', '.bai']:
137
+ if path.endswith(ext):
138
+ return True
139
+ return False
140
+
141
+
142
+ def flatten_list_of_bams(filepaths):
143
+ """Turn a list of bam filepaths and txt files containing bam filepaths into a single list of bam filepaths."""
144
+ flattened = []
145
+ for path in filepaths:
146
+ if _is_bam(path):
147
+ flattened.append(path)
148
+ else:
149
+ with open(path) as f:
150
+ for line in f:
151
+ line = line.strip()
152
+ if line and not line.startswith('#'):
153
+ flattened.append(line)
154
+ return flattened
155
+
156
+
135
157
 
136
158
  @click.command('reads')
137
159
  @use_common_state
@@ -200,3 +222,67 @@ def cli_upload_reads_wizard(state, cores, overwrite, yes, regex, private, link_t
200
222
  regex = _get_regex(knex, filepaths, module_name, proj, regex)
201
223
  groups = _group_files(knex, filepaths, module_name, regex, yes)
202
224
  _do_upload(groups, module_name, link_type, proj, filepaths, overwrite, no_new_versions, cores, state)
225
+
226
+
227
+ # @click.command('bam')
228
+ # @use_common_state
229
+ # @click.option('--genome', default=None, help='The genome aligned to the BAM files. Should be in 2bit format.')
230
+ # @click.option('--cores', default=1, help='Number of uploads to run in parallel')
231
+ # @overwrite_option
232
+ # @yes_option
233
+ # @click.option('--regex', default=None, help='An optional regex to use to extract sample names from the file names')
234
+ # @private_option
235
+ # @link_option
236
+ # @no_new_versions_option
237
+ # @project_id_arg
238
+ # @click.argument('files', type=click.Path(exists=True), nargs=-1)
239
+ # def cli_upload_bams(state, genome, cores, overwrite, yes, regex, private, link_type, no_new_versions, project_id, files):
240
+ """Upload BAM files to GeoSeeq.
241
+
242
+ This command automatically groups bams with their index files.
243
+
244
+ ---
245
+
246
+ Example Usage:
247
+
248
+ \b
249
+ # Upload a list of BAM files to a project, useful if you have hundreds of files
250
+ $ ls -1 path/to/bam/files/*.bam > file_list.txt
251
+ $ geoseeq upload bams "GeoSeeq/Example CLI Project" file_list.txt
252
+
253
+ \b
254
+ # Upload all the BAM files in a directory to a project with BAM indexes
255
+ $ geoseeq upload bams ed59b913-91ec-489b-a1b9-4ea137a6e5cf path/to/bam/files/*.bam path/to/bam/files/*.bam.bai
256
+
257
+ \b
258
+ # Upload all the BAM files in a directory to a project, performing 4 uploads in parallel
259
+ $ geoseeq upload bams --cores 4 ed59b913-91ec-489b-a1b9-4ea137a6e5cf path/to/bam/files/*.bam
260
+
261
+ \b
262
+ # Upload a list of BAM files to a project, automatically creating a new project and overwriting existing files
263
+ $ ls -1 path/to/bam/files/*.bam > file_list.txt
264
+ $ geoseeq upload bams --yes --overwrite "GeoSeeq/Example CLI Project" file_list.txt
265
+
266
+ ---
267
+
268
+ Command Arguments:
269
+
270
+ [PROJECT_ID] Can be a project UUID, GeoSeeq Resource Number (GRN), or an
271
+ organization name and project name separated by a slash.
272
+
273
+ \b
274
+ Examples:
275
+ - Name pair: "GeoSeeq/Example CLI Project"
276
+ - UUID: "ed59b913-91ec-489b-a1b9-4ea137a6e5cf"
277
+ - GRN: "grn:gs1:project:ed59b913-91ec-489b-a1b9-4ea137a6e5cf"
278
+
279
+ \b
280
+ [FILES...] can be paths to BAM files or a file containing a list of paths, or a mix of both.
281
+ Example: "path/to/bam/files
282
+ """
283
+ knex = state.get_knex()
284
+ proj = handle_project_id(knex, project_id, yes, private)
285
+ filepaths = {basename(line): line for line in flatten_list_of_bams(files)}
286
+ click.echo(f'Found {len(filepaths)} files to upload.', err=True)
287
+ groups = _group_files(knex, filepaths, 'bam::bam', regex, yes)
288
+ _do_upload(groups, 'bam::bam', link_type, proj, filepaths, overwrite, no_new_versions, cores, state)
@@ -46,6 +46,11 @@ def guess_download_kind(url):
46
46
 
47
47
  def download_url(url, kind='guess', filename=None, head=None, progress_tracker=None):
48
48
  """Return a local filepath to the downloaded file. Download the file."""
49
+ if filename and isfile(filename):
50
+ file_size = getsize(filename)
51
+ if file_size > 0:
52
+ logger.info(f"File already exists: {filename}. Not overwriting.")
53
+ return filename
49
54
  if kind == 'guess':
50
55
  kind = guess_download_kind(url)
51
56
  logger.info(f"Guessed download kind: {kind} for {url}")
@@ -31,14 +31,30 @@ class FileChunker:
31
31
  chunk = f.read(self.chunk_size)
32
32
  self.loaded_parts.append(chunk)
33
33
  return self # convenience for chaining
34
+
35
+ def chunk_is_preloaded(self, num):
36
+ return len(self.loaded_parts) > num and self.loaded_parts[num]
37
+
38
+ def read_one_chunk(self, num):
39
+ if not self.chunk_is_preloaded(num):
40
+ logger.debug(f"Reading chunk {num} from {self.filepath}")
41
+ with open(self.filepath, "rb") as f:
42
+ f.seek(num * self.chunk_size)
43
+ chunk = f.read(self.chunk_size)
44
+ return chunk
45
+ return self.loaded_parts[num]
34
46
 
35
47
  def get_chunk(self, num):
36
- self.load_all_chunks()
37
- return self.loaded_parts[num]
48
+ if self.chunk_is_preloaded(num):
49
+ return self.loaded_parts[num]
50
+ return self.read_one_chunk(num)
38
51
 
39
52
  def get_chunk_size(self, num):
40
- self.load_all_chunks()
41
- return len(self.loaded_parts[num])
53
+ if num < (self.n_parts - 1): # all but the last chunk
54
+ return self.chunk_size
55
+ if self.chunk_is_preloaded(num): # last chunk, pre-loaded
56
+ return len(self.loaded_parts[num])
57
+ return len(self.read_one_chunk(num)) # last chunk, not pre-loaded
42
58
 
43
59
 
44
60
  class ResumableUploadTracker:
@@ -159,6 +175,7 @@ class ResultFileUpload:
159
175
  attempts = 0
160
176
  while attempts < max_retries:
161
177
  try:
178
+ logger.debug(f"Uploading part {num + 1} to {url}. Size: {len(file_chunk)} bytes.")
162
179
  if session:
163
180
  http_response = session.put(url, data=file_chunk)
164
181
  else:
@@ -171,9 +188,11 @@ class ResultFileUpload:
171
188
  f"Upload for part {num + 1} failed. Attempt {attempts + 1} of {max_retries}."
172
189
  )
173
190
  attempts += 1
174
- if attempts == max_retries:
191
+ if attempts >= max_retries:
175
192
  raise e
176
- time.sleep(10**attempts) # exponential backoff, (10 ** 2)s default max
193
+
194
+ retry_time = min(8 ** attempts, 120) # exponential backoff, max 120s
195
+ time.sleep(retry_time)
177
196
 
178
197
  etag = http_response.headers["ETag"].replace('"', "")
179
198
  blob = {"ETag": etag, "PartNumber": num + 1}
@@ -251,7 +270,12 @@ class ResultFileUpload:
251
270
  resumable_upload_tracker.start_upload(upload_id, urls)
252
271
  logger.info(f'Starting upload for "{filepath}"')
253
272
  complete_parts = []
254
- file_chunker = FileChunker(filepath, chunk_size).load_all_chunks()
273
+ file_chunker = FileChunker(filepath, chunk_size)
274
+ if file_chunker.file_size < 10 * FIVE_MB:
275
+ file_chunker.load_all_chunks()
276
+ logger.debug(f"Preloaded all chunks for {filepath}")
277
+ else:
278
+ logger.debug(f"Did not preload chunks for {filepath}")
255
279
  if progress_tracker: progress_tracker.set_num_chunks(file_chunker.file_size)
256
280
  complete_parts = self._upload_parts(
257
281
  file_chunker,
@@ -21,7 +21,8 @@ def _make_in_process_logger(log_level):
21
21
  def _upload_one_file(args):
22
22
  (result_file, filepath, session, progress_tracker,
23
23
  link_type, overwrite, log_level, parallel_uploads,
24
- use_cache, no_new_versions) = args
24
+ use_cache, no_new_versions, threads_per_upload,
25
+ num_retries) = args
25
26
  if parallel_uploads:
26
27
  _make_in_process_logger(log_level)
27
28
  if link_type == 'upload':
@@ -29,7 +30,8 @@ def _upload_one_file(args):
29
30
  result_file.upload_file(
30
31
  filepath,
31
32
  session=session, overwrite=overwrite, progress_tracker=progress_tracker,
32
- threads=4, use_cache=use_cache, no_new_versions=no_new_versions
33
+ threads=threads_per_upload, use_cache=use_cache,
34
+ no_new_versions=no_new_versions, max_retries=num_retries,
33
35
  )
34
36
  else:
35
37
  result_file.link_file(link_type, filepath)
@@ -40,12 +42,14 @@ class GeoSeeqUploadManager:
40
42
 
41
43
  def __init__(self,
42
44
  n_parallel_uploads=1,
45
+ threads_per_upload=4,
43
46
  session=None,
44
47
  link_type='upload',
45
48
  progress_tracker_factory=None,
46
49
  log_level=logging.WARNING,
47
50
  overwrite=True,
48
51
  no_new_versions=False,
52
+ num_retries=3,
49
53
  use_cache=True):
50
54
  self.session = session
51
55
  self.n_parallel_uploads = n_parallel_uploads
@@ -56,6 +60,8 @@ class GeoSeeqUploadManager:
56
60
  self._result_files = []
57
61
  self.no_new_versions = no_new_versions
58
62
  self.use_cache = use_cache
63
+ self.threads_per_upload = threads_per_upload
64
+ self.num_retries = num_retries
59
65
 
60
66
  def add_result_file(self, result_file, local_path):
61
67
  self._result_files.append((result_file, local_path))
@@ -80,7 +86,8 @@ class GeoSeeqUploadManager:
80
86
  result_file, local_path,
81
87
  self.session, self.progress_tracker_factory(local_path),
82
88
  self.link_type, self.overwrite, self.log_level,
83
- self.n_parallel_uploads > 1, self.use_cache, self.no_new_versions
89
+ self.n_parallel_uploads > 1, self.use_cache, self.no_new_versions,
90
+ self.threads_per_upload, self.num_retries
84
91
  ) for result_file, local_path in self._result_files
85
92
  ]
86
93
  out = []
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: geoseeq
3
- Version: 0.5.6a10
3
+ Version: 0.5.6a12
4
4
  Summary: GeoSeeq command line tools and python API
5
5
  Author: David C. Danko
6
6
  Author-email: "David C. Danko" <dcdanko@biotia.io>
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "geoseeq"
7
- version = "0.5.6a10"
7
+ version = "0.5.6a12"
8
8
  authors = [
9
9
  { name="David C. Danko", email="dcdanko@biotia.io" },
10
10
  ]
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