Skip to content

Commit b4db209

Browse files
authored
Merge pull request #2573 from opencb/TASK-7508
TASK-7508 - Fail to download files programmatically
2 parents df08868 + d115c82 commit b4db209

8 files changed

Lines changed: 61 additions & 36 deletions

File tree

opencga-app/src/main/java/org/opencb/opencga/app/cli/main/custom/CustomFilesCommandExecutor.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import org.opencb.opencga.core.response.RestResponse;
2424
import org.slf4j.Logger;
2525

26+
import java.io.DataInputStream;
27+
2628
public class CustomFilesCommandExecutor extends CustomCommandExecutor {
2729

2830
public CustomFilesCommandExecutor(ObjectMap options, String token, ClientConfiguration clientConfiguration,
@@ -52,4 +54,9 @@ public RestResponse<File> upload(CustomFilesCommandOptions.UploadCommandOptions
5254
return openCGAClient.getFileClient().upload(options);
5355
}
5456

57+
public RestResponse<DataInputStream> download(CustomFilesCommandOptions.DownloadCommandOptions commandOptions) throws Exception {
58+
options.put("OPENCGA_DESTINY", commandOptions.to);
59+
return openCGAClient.getFileClient().download(commandOptions.file, options);
60+
}
61+
5562
}

opencga-app/src/main/java/org/opencb/opencga/app/cli/main/custom/CustomFilesCommandOptions.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public class CustomFilesCommandOptions {
1717
public JCommander jCommander;
1818
public CommonCommandOptions commonCommandOptions;
1919
public UploadCommandOptions uploadCommandOptions;
20+
public DownloadCommandOptions downloadCommandOptions;
2021

2122
public CustomFilesCommandOptions(CommonCommandOptions commonCommandOptions, JCommander jCommander) {
2223

@@ -82,4 +83,22 @@ public class UploadCommandOptions {
8283
" UUID", required = false, arity = 1)
8384
public String study;
8485
}
86+
87+
@Parameters(commandNames = {"download"}, commandDescription ="Download file")
88+
public class DownloadCommandOptions {
89+
90+
@ParametersDelegate
91+
public CommonCommandOptions commonOptions = commonCommandOptions;
92+
93+
@Parameter(names = {"--file"}, description = "File id, name or path. Paths must be separated by : instead of /", required = true, arity = 1)
94+
public String file;
95+
96+
@Parameter(names = {"--study", "-s"}, description = "Study [[organization@]project:]study where study and project can be either the ID or UUID", required = false, arity = 1)
97+
public String study;
98+
99+
@Parameter(names = {"--to"}, description = "Path where the file will be downloaded", arity = 1, required = true)
100+
public String to;
101+
102+
}
103+
85104
}

opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/FilesCommandExecutor.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -737,15 +737,15 @@ private RestResponse<File> updateAnnotationSetsAnnotations() throws Exception {
737737
private RestResponse<DataInputStream> download() throws Exception {
738738
logger.debug("Executing download in Files command line");
739739

740-
FilesCommandOptions.DownloadCommandOptions commandOptions = filesCommandOptions.downloadCommandOptions;
741-
740+
CustomFilesCommandOptions.DownloadCommandOptions commandOptions = filesCommandOptions.downloadCommandOptions;
742741
ObjectMap queryParams = new ObjectMap();
742+
queryParams.putIfNotEmpty("file", commandOptions.file);
743743
queryParams.putIfNotEmpty("study", commandOptions.study);
744744
if (queryParams.get("study") == null && OpencgaMain.isShellMode()) {
745745
queryParams.putIfNotEmpty("study", sessionManager.getSession().getCurrentStudy());
746746
}
747-
748-
return openCGAClient.getFileClient().download(commandOptions.file, queryParams);
747+
CustomFilesCommandExecutor customFilesCommandExecutor = new CustomFilesCommandExecutor(queryParams, token, clientConfiguration, getSessionManager(), appHome, getLogger());
748+
return customFilesCommandExecutor.download(commandOptions);
749749
}
750750

751751
private RestResponse<FileContent> grep() throws Exception {

opencga-app/src/main/java/org/opencb/opencga/app/cli/main/io/TextOutputWriter.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,7 @@ private void manageEvents(final List<Event> events) {
188188
}
189189

190190
private boolean isNotAnIdOrMessage(List<DataResult> queryResultList) {
191-
return !(queryResultList.get(0).getResultType().equals("java.lang.String") &&
192-
((OpenCGAResult) queryResultList.get(0)).getNumMatches() == 1);
191+
return !"java.lang.String".equals(queryResultList.get(0).getResultType()) && queryResultList.get(0).getNumMatches() == 1;
193192
}
194193

195194
private boolean isEdition(List<DataResult> queryResultList) {

opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/FilesCommandOptions.java

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -870,20 +870,6 @@ public class UpdateAnnotationSetsAnnotationsCommandOptions {
870870

871871
}
872872

873-
@Parameters(commandNames = {"download"}, commandDescription ="Download file")
874-
public class DownloadCommandOptions {
875-
876-
@ParametersDelegate
877-
public CommonCommandOptions commonOptions = commonCommandOptions;
878-
879-
@Parameter(names = {"--file"}, description = "File id, name or path. Paths must be separated by : instead of /", required = true, arity = 1)
880-
public String file;
881-
882-
@Parameter(names = {"--study", "-s"}, description = "Study [[organization@]project:]study where study and project can be either the ID or UUID", required = false, arity = 1)
883-
public String study;
884-
885-
}
886-
887873
@Parameters(commandNames = {"grep"}, commandDescription ="Filter lines of the file containing the pattern")
888874
public class GrepCommandOptions {
889875

opencga-client/src/main/python/pyopencga/commons.py

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -176,23 +176,28 @@ def _fetch(config, sid, category, resource, method, subcategory=None, query_id=N
176176
raise OpencgaInvalidToken(r.content)
177177
elif r.status_code == 403:
178178
raise OpencgaAuthorisationError(r.content)
179-
180179
elif r.status_code != 200:
181180
raise Exception(r.content)
182181

183-
try:
184-
response = r.json()
185-
186-
# TODO Remove deprecated response and result in future release. Added for backwards compatibility
187-
if 'response' in response:
188-
response['responses'] = response['response']
189-
for query_result in response['responses']:
190-
if 'result' in query_result:
191-
query_result['results'] = query_result['result']
192-
193-
except ValueError:
194-
msg = 'Bad JSON format retrieved from server'
195-
raise ValueError(msg)
182+
if r.headers['Content-Type'] == 'application/json':
183+
try:
184+
response = r.json()
185+
186+
# TODO Remove deprecated response and result in future release. Added for backwards compatibility
187+
if 'response' in response:
188+
response['responses'] = response['response']
189+
for query_result in response['responses']:
190+
if 'result' in query_result:
191+
query_result['results'] = query_result['result']
192+
193+
except ValueError:
194+
raise ValueError('Bad JSON format retrieved from server')
195+
elif r.headers['Content-Type'] == 'application/octet-stream':
196+
return r.content
197+
else:
198+
raise ValueError('Unexpected content type retrieved from server ("{}"): "{}"'.format(
199+
r.headers['Content-Type'], r.content)
200+
)
196201

197202
# Setting up final_response
198203
if final_response is None:
@@ -324,7 +329,7 @@ def execute(config, sid, category, resource, method, subcategory=None, query_id=
324329
'options': options})
325330
# Setting threads as "daemon" allows main program to exit eventually
326331
# even if these do not finish correctly
327-
t.setDaemon(True)
332+
t.daemon = True
328333
t.start()
329334

330335
# Loading up the queue with index and id batches for each job

opencga-client/src/main/python/pyopencga/rest_clients/_parent_rest_clients.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import json
2+
13
from pyopencga.commons import execute
24
from pyopencga.rest_response import RestResponse
35
from pyopencga.retry import retry
@@ -66,7 +68,11 @@ def notify_retry(exc_type, exc_val, exc_tb):
6668

6769
if self.auto_refresh:
6870
self._refresh_token_client()
69-
return RestResponse(response)
71+
72+
if isinstance(response, dict):
73+
return RestResponse(response)
74+
else: # Not a JSON (e.g. /{apiVersion}/files/{file}/download)
75+
return response
7076

7177
def _get(self, category, resource, query_id=None, subcategory=None,
7278
second_query_id=None, **options):

opencga-server/src/main/resources/cli-config.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ apiConfig:
8484
- name: upload
8585
executorExtended: True
8686
optionExtended: True
87+
- name: download
88+
executorExtended: True
89+
optionExtended: True
8790
- name: update
8891
subcommands:
8992
- name: annotationSetsAction

0 commit comments

Comments
 (0)