Skip to content

Commit f14e3a1

Browse files
authored
Merge pull request #199 from wltrimbl/master
Maintenance, removed dependency on legacy poster package
2 parents 5cc355c + 95214ed commit f14e3a1

7 files changed

Lines changed: 50 additions & 47 deletions

File tree

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@
77
/dist/*
88
/mglib.egg-info/*
99

10+
# testing files
11+
/.cache/*
12+
/.pytest_cache/*
13+
/htmlcov/*
14+
.coverage
15+
1016
# ignore files with # and ~
1117
*\#*
1218
*\~*

mglib/mglib.py

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
from __future__ import print_function
2-
import io
32
import os
43
import sys
54
import time
@@ -10,12 +9,6 @@
109
import random
1110
import hashlib
1211
import subprocess
13-
try:
14-
from StringIO import StringIO
15-
except ImportError:
16-
from io import StringIO
17-
from poster.encode import multipart_encode
18-
from poster.streaminghttp import register_openers
1912
import requests
2013
from requests_toolbelt import MultipartEncoder
2114

@@ -151,19 +144,19 @@ def async_rest_api(url, auth=None, data=None, debug=False, delay=60):
151144

152145
# POST file to MG-RAST or Shock
153146
def post_file(url, keyname, filename, data={}, auth=None, debug=False):
154-
register_openers()
155147
if debug:
156-
print("data:\t"+json.dumps(data))
157-
data[keyname] = open(filename)
158-
datagen, header = multipart_encode(data)
148+
print("post_file", url)
149+
data[keyname] = (filename, open(filename, 'rb'))
150+
datagen = MultipartEncoder(data)
151+
header = {"Content-Type": datagen.content_type}
159152
if auth:
160153
header['Authorization'] = 'mgrast '+auth
161154
if debug:
162-
print("header:\t"+json.dumps(header))
155+
print("data:\t"+repr(data))
156+
print("header:\t"+repr(header))
163157
print("url:\t"+url)
164158
try:
165-
req = Request(url, datagen, header)
166-
res = urlopen(req)
159+
res = requests.post(url, data=datagen, headers=header, stream=True)
167160
except HTTPError as error:
168161
try:
169162
eobj = json.loads(error.read())
@@ -178,14 +171,11 @@ def post_file(url, keyname, filename, data={}, auth=None, debug=False):
178171
if not res:
179172
sys.stderr.write("ERROR: no results returned\n")
180173
sys.exit(1)
181-
obj = json.loads(res.read().decode("utf8"))
174+
obj = json.loads(res.content.decode("utf8"))
175+
if debug:
176+
print(json.dumps(obj))
182177
if obj is None:
183178
sys.stderr.write("ERROR: return structure not valid json format\n")
184-
while True:
185-
chunk = res.read(8192)
186-
if not chunk:
187-
break
188-
handle.write(chunk.decode('utf8'))
189179
return(obj)
190180

191181
# safe handling of stdout for piping

scripts/mg-export-research-object.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,19 @@
66
import yaml
77
import shutil
88
import hashlib
9-
from optparse import OptionParser
9+
from argparse import ArgumentParser
1010
from prettytable import PrettyTable
1111
from mglib import VERSION, get_auth_token, AUTH_LIST, API_URL, obj_from_url, file_from_url, random_str
1212

13-
VERSION = 'alpha'
13+
RO_VERSION = 'alpha'
1414

1515
prehelp = """
1616
NAME
1717
mg-export-research-object
1818
1919
VERSION
20-
%s
21-
20+
MGRAST-Tools %s
21+
mg-export-research-object %s
2222
SYNOPSIS
2323
mg-export-research-object [ --help, --user <user>, --passwd <password>, --token <oAuth token>, --metagenome <metagenome id>, --dir <directory name> --list <list manifest>]
2424
@@ -73,19 +73,19 @@ def edit_input(text, mg):
7373
return yaml.dump(info, allow_unicode=True, default_flow_style=False)
7474

7575
def main(args):
76-
OptionParser.format_description = lambda self, formatter: self.description
77-
OptionParser.format_epilog = lambda self, formatter: self.epilog
78-
parser = OptionParser(usage='', description=prehelp%VERSION, epilog=posthelp%AUTH_LIST)
79-
parser.add_option("", "--url", dest="url", default=API_URL, help="MG-RAST API url")
80-
parser.add_option("", "--user", dest="user", default=None, help="OAuth username")
81-
parser.add_option("", "--passwd", dest="passwd", default=None, help="OAuth password")
82-
parser.add_option("", "--token", dest="token", default=None, help="OAuth token")
83-
parser.add_option("", "--metagenome", dest="metagenome", default=None, help="metagenome ID")
84-
parser.add_option("", "--dir", dest="dir", default=".", help="directory to export to")
85-
parser.add_option("", "--list", dest="list", action="store_true", default=False, help="list files in manifest")
76+
ArgumentParser.format_description = lambda self, formatter: self.description
77+
ArgumentParser.format_epilog = lambda self, formatter: self.epilog
78+
parser = ArgumentParser(usage='', description=prehelp.format(VERSION, RO_VERSION), epilog=posthelp%AUTH_LIST)
79+
parser.add_argument("--url", dest="url", default=API_URL, help="MG-RAST API url")
80+
parser.add_argument("--user", dest="user", default=None, help="OAuth username")
81+
parser.add_argument("--passwd", dest="passwd", default=None, help="OAuth password")
82+
parser.add_argument("--token", dest="token", default=None, help="OAuth token")
83+
parser.add_argument("--metagenome", dest="metagenome", default=None, help="metagenome ID")
84+
parser.add_argument("--dir", dest="dir", default=".", help="directory to export to")
85+
parser.add_argument("--list", dest="list", action="store_true", default=False, help="list files in manifest")
8686

8787
# get inputs
88-
(opts, args) = parser.parse_args()
88+
opts = parser.parse_args()
8989
if not opts.metagenome:
9090
sys.stderr.write("ERROR: a metagenome id is required\n")
9191
return 1

scripts/mg-inbox.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ def upload(files):
179179
data = {
180180
"attributes_str": attr
181181
}
182-
result = post_file(SHOCK_URL+"/node", fformat, f, data=data, auth=mgrast_auth['token'])
182+
result = post_file(SHOCK_URL+"/node", fformat, f, data=data, auth=mgrast_auth['token'], debug=DEBUG)
183183
# compute file info
184184
info = obj_from_url(API_URL+"/inbox/info/"+result['data']['id'], auth=mgrast_auth['token'], debug=DEBUG)
185185
print(info['status'])
@@ -212,7 +212,7 @@ def upload_archive(afile):
212212
"file_name": os.path.basename(afile),
213213
"attributes_str": attr
214214
}
215-
result = post_file(SHOCK_URL+"/node", "upload", afile, data=data, auth=mgrast_auth['token'])
215+
result = post_file(SHOCK_URL+"/node", "upload", afile, data=data, auth=mgrast_auth['token'], debug=DEBUG)
216216
data = {
217217
"unpack_node": result['data']['id'],
218218
"archive_format": aformat,
@@ -286,7 +286,7 @@ def compute(action, files, retain, joinfile, rc_index):
286286
"rc_index": 1 if rc_index else 0
287287
}
288288
else:
289-
sys.stderr.write("ERROR: invalid compute ion. use one of: %s\n"%", ".join(compute_options))
289+
sys.stderr.write("ERROR: invalid compute action. use one of: %s\n"%", ".join(compute_actions))
290290
info = obj_from_url(API_URL+"/inbox/"+action, data=json.dumps(data), auth=mgrast_auth['token'], debug=DEBUG)
291291
print(info['status'])
292292

@@ -408,8 +408,8 @@ def main(args):
408408
sys.stderr.write("ERROR: validate missing file\n")
409409
return 1
410410
elif action == "compute":
411-
if (len(args) < 2) or (args[1] not in compute_options):
412-
sys.stderr.write("ERROR: invalid compute ion. use one of: %s\n"%", ".join(compute_options))
411+
if (len(args) < 2) or (args[1] not in compute_actions):
412+
sys.stderr.write("ERROR: invalid compute action. use one of: %s\n"%", ".join(compute_actions))
413413
return 1
414414
if (((args[1] == "sff2fastq") and (len(args) != 3)) or
415415
((args[1] == "demultiplex") and (len(args) < 4)) or

scripts/mg-project.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
from argparse import ArgumentParser
66
from mglib import get_auth_token, post_file, obj_from_url, VERSION, AUTH_LIST, API_URL
77

8+
try:
9+
import raw_input as input # python2
10+
except:
11+
pass
12+
813
prehelp = """
914
NAME
1015
mg-project
@@ -59,6 +64,7 @@ def main(args):
5964
parser.add_argument("-f", "--file", dest="mdfile", default=None, help="metadata .xlsx file")
6065
parser.add_argument("--taxa", dest="taxa", default=None, help="metagenome_taxonomy for project: http://www.ebi.ac.uk/ena/data/view/Taxon:408169")
6166
parser.add_argument("--debug", dest="debug", action="store_true", default=False, help="Run in debug mode")
67+
parser.add_argument("-v", "--verbose", dest="verbose", action="store_true", default=False, help="Verbose STDOUT")
6268
parser.add_argument("args",type=str, nargs="+", help="Action (" + ",".join(valid_actions)+")" )
6369

6470
# get inputs
@@ -78,11 +84,11 @@ def main(args):
7884
sys.stderr.write("ERROR: missing Project ID\n")
7985
return 1
8086
pid = args[1]
81-
87+
DEBUG = opts.verbose + opts.debug
8288
# get token
8389
token = get_auth_token(opts)
8490
if not token:
85-
token = raw_input('Enter your MG-RAST auth token: ')
91+
token = input('Enter your MG-RAST auth token: ')
8692

8793
# actions
8894
if action == "get-info":
@@ -92,7 +98,7 @@ def main(args):
9298
data = obj_from_url(opts.url+'/metadata/export/'+pid, auth=token)
9399
print(json.dumps(data, sort_keys=True, indent=4))
94100
elif action == "update-metadata":
95-
result = post_file(opts.url+'/metadata/update', 'upload', opts.mdfile, auth=token, data=json.dumps({'project': pid}, separators=(',',':')))
101+
result = post_file(opts.url+'/metadata/update', 'upload', opts.mdfile, auth=token, data=json.dumps({'project': pid}, separators=(',',':')), debug=DEBUG)
96102
print(json.dumps(data, sort_keys=True, indent=4))
97103
elif action == "make-public":
98104
data = obj_from_url(opts.url+'/project/'+pid+'/makepublic', auth=token)

scripts/mg-search-metagenomes.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
VERSION
1212
%s
1313
14+
%s
15+
1416
SYNOPSIS
1517
mg-search-metagenomes [ --help, --user <user>, --passwd <password>, --token <oAuth token>, --order <field name> --direction <cv: 'asc', 'desc'> --match <cv: 'all, 'any'> --public ]
1618
@@ -55,8 +57,10 @@ def main(args):
5557
parser.add_argument("--user", dest="user", default=None, help="OAuth username")
5658
parser.add_argument("--passwd", dest="passwd", default=None, help="OAuth password")
5759
parser.add_argument("--token", dest="token", default=None, help="OAuth token")
60+
parser.add_argument("--limit", dest="limit", type=int, default=15, help="Number of results to show, if > 50 will use paginated queries to get all, default 15")
5861
parser.add_argument("--order", dest="order", default=None, help="field metagenomes are ordered by, default is no ordering")
5962
parser.add_argument("--direction", dest="direction", default="asc", help="direction of order. 'asc' for ascending order, 'desc' for descending order, default is asc")
63+
parser.add_argument("--public", dest="public", action="store_true", default=False, help="return both private and pubulic data if using authenticated search, default is private only. Non-authenticated search only returns public.")
6064
parser.add_argument("--match", dest="match", default="all", help="search logic. 'all' for metagenomes that match all search parameters, 'any' for metagenomes that match any search parameters, default is all")
6165
parser.add_argument("--status", dest="status", default="public", help="types of metagenomes to return. 'both' for all data (public and private), 'public' for public data, 'private' for users private data, default is public")
6266
parser.add_argument("--verbosity", dest="verbosity", default='minimal', help="amount of information to display. use keyword 'minimal' for id and name, use keyword 'full' for MIxS GSC metadata, default is minimal")
@@ -74,8 +78,6 @@ def main(args):
7478
maxLimit = 50
7579
params = [ ('limit', opts.limit if opts.limit < maxLimit else maxLimit),
7680
('public', 'yes' if opts.public or (not token) else 'no') ]
77-
if opts.index:
78-
params.append( ('index', opts.index) )
7981
for sfield in SEARCH_FIELDS:
8082
if hasattr(opts, sfield) and getattr(opts, sfield):
8183
params.append((sfield, getattr(opts, sfield)))

setup.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@
1313
packages=['mglib'],
1414
scripts=glob.glob('scripts/[a-z]*') + glob.glob('examples/python/*.py'),
1515
install_requires= ['prettytable >= 0.7',
16-
'requests_toolbelt >= 0.8', 'setuptools > 28.0',
17-
'poster >= 0.8.1' ]
16+
'requests_toolbelt >= 0.8', 'setuptools > 28.0' ]
1817
)
1918

2019

0 commit comments

Comments
 (0)