# Path: onecodex/vendored/potion_client/converter.py
# class PotionJSONEncoder(JSONEncoder):
#     def encode(self, o):
#         root_id = id(o)
#         if self.check_circular:
#             markers = {}
#         else:
#             markers = None
# 
#         def _encode(o):
#             try:
#                 import pandas as pd
#             except ImportError:
#                 pd = None
# 
#             if isinstance(o, (list, tuple, dict)):
#                 if markers is not None:
#                     marker_id = id(o)
#                     if marker_id in markers:
#                         if marker_id == root_id:
#                             return {"$ref": "#"}
#                         raise ValueError("Circular reference detected")
#                     markers[marker_id] = o
#                 try:
#                     if isinstance(o, dict):
#                         return {k: _encode(v) for k, v in o.items()}
#                     else:
#                         return [_encode(v) for v in o]
#                 finally:
#                     if markers is not None:
#                         del markers[marker_id]
# 
#             if isinstance(o, date):
#                 return {"$date": int(calendar.timegm(o.timetuple()) * 1000)}
#             if isinstance(o, datetime):
#                 return {"$date": int(calendar.timegm(o.utctimetuple()) * 1000)}
# 
#             if isinstance(o, Reference):
#                 # FIXME if reference is not saved, save it first here
#                 return {"$ref": o._uri}
# 
#             try:
#                 if pd and pd.api.types.is_integer(o):
#                     return int(o)
#             except AttributeError:
#                 # some versions of pandas may not have this API
#                 pass
# 
#             try:
#                 if pd and pd.api.types.is_float(o):
#                     return float(o)
#             except AttributeError:
#                 pass
# 
#             return o
# 
#         return JSONEncoder.encode(self, _encode(o))
# 
# Path: onecodex/exceptions.py
# class OneCodexException(Exception):
#     pass
# 
# class UploadException(Exception):
#     """An exception for when things go wrong with uploading."""
# 
#     pass
# 
# Path: onecodex/version.py



import atexit
import base64
import click
import concurrent.futures
import json
import logging
import os
import platform
import re
import requests
import sys
import sentry_sdk
        import OpenSSL  # noqa
        import ndg  # noqa
        import pyasn1  # noqa
    import pandas as pd
from functools import partial, wraps
    from StringIO import StringIO
    from io import StringIO  # noqa
    from urlparse import urlparse
    from urllib.parse import urlparse
from onecodex.vendored.potion_client.converter import PotionJSONEncoder
from onecodex.exceptions import OneCodexException, UploadException
from onecodex.version import __version__
    from IPython import get_ipython

try:
except ImportError:



log = logging.getLogger("onecodex")

OPTION_HELP = {
    "api_key": "Manually provide a One Codex API key",
    "no_pprint": "Do not pretty-print JSON responses",
    "threads": "Do not use multiple background threads to upload files",  # noqa
    "max_threads": "Specify a different max # of upload threads (defaults to 4)",  # noqa
    "verbose": "Log extra information to STDERR",
    "results": "Get a JSON array of the metagenomic classification results table",
    "readlevel": "Get the read-level data as a .tsv file",
    "readlevel_path": (
        "Output path or directory for a .tsv file with the raw "
        "read-level results. Defaults to original filename in "
        "the current working directory"
    ),
    "clean": (
        "Automatically clean up FASTX records during upload. This removes tabs from "
        "headers and converts U to T. If this isn't passed, these will cause errors."
    ),
    "interleave": (
        "Do not automatically interleave paired end files. Note this normally happens "
        "during the upload, does not require additional disk space, and does not change "
        "the files themselves."
    ),

# Path: onecodex/vendored/potion_client/converter.py
# class PotionJSONEncoder(JSONEncoder):
#     def encode(self, o):
#         root_id = id(o)
#         if self.check_circular:
#             markers = {}
#         else:
#             markers = None
# 
#         def _encode(o):
#             try:
#                 import pandas as pd
#             except ImportError:
#                 pd = None
# 
#             if isinstance(o, (list, tuple, dict)):
#                 if markers is not None:
#                     marker_id = id(o)
#                     if marker_id in markers:
#                         if marker_id == root_id:
#                             return {"$ref": "#"}
#                         raise ValueError("Circular reference detected")
#                     markers[marker_id] = o
#                 try:
#                     if isinstance(o, dict):
#                         return {k: _encode(v) for k, v in o.items()}
#                     else:
#                         return [_encode(v) for v in o]
#                 finally:
#                     if markers is not None:
#                         del markers[marker_id]
# 
#             if isinstance(o, date):
#                 return {"$date": int(calendar.timegm(o.timetuple()) * 1000)}
#             if isinstance(o, datetime):
#                 return {"$date": int(calendar.timegm(o.utctimetuple()) * 1000)}
# 
#             if isinstance(o, Reference):
#                 # FIXME if reference is not saved, save it first here
#                 return {"$ref": o._uri}
# 
#             try:
#                 if pd and pd.api.types.is_integer(o):
#                     return int(o)
#             except AttributeError:
#                 # some versions of pandas may not have this API
#                 pass
# 
#             try:
#                 if pd and pd.api.types.is_float(o):
#                     return float(o)
#             except AttributeError:
#                 pass
# 
#             return o
# 
#         return JSONEncoder.encode(self, _encode(o))
# 
# Path: onecodex/exceptions.py
# class OneCodexException(Exception):
#     pass
# 
# class UploadException(Exception):
#     """An exception for when things go wrong with uploading."""
# 
#     pass
# 
# Path: onecodex/version.py



# Path: onecodex/utils.py
import atexit
import base64
import click
import concurrent.futures
import json
import logging
import os
import platform
import re
import requests
import sys
import sentry_sdk
        import OpenSSL  # noqa
        import ndg  # noqa
        import pyasn1  # noqa
    import pandas as pd
from functools import partial, wraps
    from StringIO import StringIO
    from io import StringIO  # noqa
    from urlparse import urlparse
    from urllib.parse import urlparse
from onecodex.vendored.potion_client.converter import PotionJSONEncoder
from onecodex.exceptions import OneCodexException, UploadException
from onecodex.version import __version__
    from IPython import get_ipython


try:
except ImportError:



log = logging.getLogger("onecodex")

OPTION_HELP = {
    "api_key": "Manually provide a One Codex API key",
    "no_pprint": "Do not pretty-print JSON responses",
    "threads": "Do not use multiple background threads to upload files",  # noqa
    "max_threads": "Specify a different max # of upload threads (defaults to 4)",  # noqa
    "verbose": "Log extra information to STDERR",
    "results": "Get a JSON array of the metagenomic classification results table",
    "readlevel": "Get the read-level data as a .tsv file",
    "readlevel_path": (
        "Output path or directory for a .tsv file with the raw "
        "read-level results. Defaults to original filename in "
        "the current working directory"
    ),
    "clean": (
        "Automatically clean up FASTX records during upload. This removes tabs from "
        "headers and converts U to T. If this isn't passed, these will cause errors."
    ),
    "interleave": (
        "Do not automatically interleave paired end files. Note this normally happens "
        "during the upload, does not require additional disk space, and does not change "
        "the files themselves."
    ),

    "prompt": (