# Path: quantrocket/houston.py
# CANNOT_CONNECT_TO_HOUSTON_ERROR_LOCAL = """{error}
# 
# Could not connect to houston at {scheme}://{netloc}
# 
# Please verify that houston is running and bound to port {port} by checking the output of:
# 
#     docker ps
# 
# The output should resemble:
# 
#     quantrocket/houston ... 0.0.0.0:{port}->80/tcp ... quantrocket_houston_1
#     ...
# 
# If not running you can deploy it with:
# 
#     docker-compose -p quantrocket up -d
# """
# CANNOT_CONNECT_TO_HOUSTON_ERROR_CLOUD = """{error}
# 
# Could not connect to houston at {scheme}://{netloc}
# 
# Please verify that the URL is correct and houston is running.
# """
#     DEFAULT_TIMEOUT = 120
# def _get_force_timeout():
#     def __init__(self):
#     def base_url(self):
#     def _set_base_url(self):
#     def request(self, method, url, *args, **kwargs):
#     def raise_for_status_with_json(response):
# def ping():
# def _cli_ping():
# class Houston(requests.Session):
# 
# Path: quantrocket/cli/utils/output.py
# def json_to_cli(func, *args, **kwargs):
#     """
#     Converts a JSON response to a more appropriate CLI response.
# 
#     If JSON is preferred, the response will be returned as-is. Otherwise:
# 
#     - If the JSON is a list of scalars, the output will be simplified to a
#     string of newline-separated values suitable for the command line (unless
#     simplify_lists is False).
# 
#     - If the JSON is empty, nothing will be returned.
# 
#     - YAML will be returned.
#     """
#     exit_code = 0
#     simplify_list = kwargs.pop("simplify_list", True)
#     try:
#         json_response = func(*args, **kwargs)
#     except requests.exceptions.HTTPError as e:
#         # use json response from service, if available
#         json_response = getattr(e, "json_response", {}) or {"status": "error", "msg": repr(e)}
#         exit_code = 1
#     if not json_response:
#         return None, exit_code
#     if os.environ.get("QUANTROCKET_CLI_OUTPUT_FORMAT", "").lower() == "json":
#         return json.dumps(json_response), exit_code
#     if simplify_list and isinstance(json_response, list) and not any([
#         isinstance(item, (dict, list, tuple, set)) for item in json_response]):
#         return "\n".join([str(item) for item in json_response]), exit_code
#     return yaml.safe_dump(json_response, default_flow_style=False).strip(), exit_code
# 
# Path: quantrocket/cli/utils/stream.py
# def to_bytes(f):
#     """
#     Yields the file line-by-line, converting str to bytes.
#     """
#     for line in f:
#         if six.PY3 and isinstance(line, six.string_types):
#             line = line.encode("utf-8")
#         yield line
# 
# Path: quantrocket/cli/utils/files.py
# def write_response_to_filepath_or_buffer(filepath_or_buffer, response):
#     """
#     Writes the response content to the filepath or buffer.
#     """
#     if hasattr(filepath_or_buffer, "write"):
#         if six.PY3 and filepath_or_buffer is sys.stdout:
#             # Write bytes to stdout (https://stackoverflow.com/a/23932488)
#             filepath_or_buffer = filepath_or_buffer.buffer
#         mode = getattr(filepath_or_buffer, "mode", "w")
#         for chunk in response.iter_content(chunk_size=1024):
#             if chunk:
#                 if "b" not in mode and six.PY3:
#                     chunk = chunk.decode("utf-8")
#                 filepath_or_buffer.write(chunk)
#         if filepath_or_buffer.seekable():
#             filepath_or_buffer.seek(0)
#     else:
#         with open(filepath_or_buffer, "wb") as f:
#             for chunk in response.iter_content(chunk_size=1024):
#                 if chunk:
#                     f.write(chunk)
# 
# Path: quantrocket/exceptions.py
# class ParameterError(ValueError):
#     pass
# 
# class NoMasterData(NoData):
#     pass


import sys
import six
import json
import requests
        import pandas as pd
        import pandas as pd
        import pandas as pd
        import pandas as pd
        import pandas as pd
from quantrocket.houston import houston
from quantrocket.cli.utils.output import json_to_cli
from quantrocket.cli.utils.stream import to_bytes
from quantrocket.cli.utils.files import write_response_to_filepath_or_buffer
from quantrocket.exceptions import ParameterError, NoMasterData
    if not response.content:
        return {}
    return response.json()

def _cli_load_or_show_rollrules(filename=None):
    if filename:
        return json_to_cli(load_rollrules_config, filename)
    else:
        return json_to_cli(get_rollrules_config)

def collect_ibkr_calendar(exchanges=None):
    """
    Collect upcoming trading hours from IBKR for exchanges and save to
    securities master database.

    Parameters
    ----------
    exchanges : list of str, optional
        limit to these exchanges

    Returns
    -------
    dict
        status message
    """
    params = {}
    if exchanges:
        params["exchanges"] = exchanges

    response = houston.post("/master/calendar/ibkr", params=params)

# Path: quantrocket/houston.py
# CANNOT_CONNECT_TO_HOUSTON_ERROR_LOCAL = """{error}
# 
# Could not connect to houston at {scheme}://{netloc}
# 
# Please verify that houston is running and bound to port {port} by checking the output of:
# 
#     docker ps
# 
# The output should resemble:
# 
#     quantrocket/houston ... 0.0.0.0:{port}->80/tcp ... quantrocket_houston_1
#     ...
# 
# If not running you can deploy it with:
# 
#     docker-compose -p quantrocket up -d
# """
# CANNOT_CONNECT_TO_HOUSTON_ERROR_CLOUD = """{error}
# 
# Could not connect to houston at {scheme}://{netloc}
# 
# Please verify that the URL is correct and houston is running.
# """
#     DEFAULT_TIMEOUT = 120
# def _get_force_timeout():
#     def __init__(self):
#     def base_url(self):
#     def _set_base_url(self):
#     def request(self, method, url, *args, **kwargs):
#     def raise_for_status_with_json(response):
# def ping():
# def _cli_ping():
# class Houston(requests.Session):
# 
# Path: quantrocket/cli/utils/output.py
# def json_to_cli(func, *args, **kwargs):
#     """
#     Converts a JSON response to a more appropriate CLI response.
# 
#     If JSON is preferred, the response will be returned as-is. Otherwise:
# 
#     - If the JSON is a list of scalars, the output will be simplified to a
#     string of newline-separated values suitable for the command line (unless
#     simplify_lists is False).
# 
#     - If the JSON is empty, nothing will be returned.
# 
#     - YAML will be returned.
#     """
#     exit_code = 0
#     simplify_list = kwargs.pop("simplify_list", True)
#     try:
#         json_response = func(*args, **kwargs)
#     except requests.exceptions.HTTPError as e:
#         # use json response from service, if available
#         json_response = getattr(e, "json_response", {}) or {"status": "error", "msg": repr(e)}
#         exit_code = 1
#     if not json_response:
#         return None, exit_code
#     if os.environ.get("QUANTROCKET_CLI_OUTPUT_FORMAT", "").lower() == "json":
#         return json.dumps(json_response), exit_code
#     if simplify_list and isinstance(json_response, list) and not any([
#         isinstance(item, (dict, list, tuple, set)) for item in json_response]):
#         return "\n".join([str(item) for item in json_response]), exit_code
#     return yaml.safe_dump(json_response, default_flow_style=False).strip(), exit_code
# 
# Path: quantrocket/cli/utils/stream.py
# def to_bytes(f):
#     """
#     Yields the file line-by-line, converting str to bytes.
#     """
#     for line in f:
#         if six.PY3 and isinstance(line, six.string_types):
#             line = line.encode("utf-8")
#         yield line
# 
# Path: quantrocket/cli/utils/files.py
# def write_response_to_filepath_or_buffer(filepath_or_buffer, response):
#     """
#     Writes the response content to the filepath or buffer.
#     """
#     if hasattr(filepath_or_buffer, "write"):
#         if six.PY3 and filepath_or_buffer is sys.stdout:
#             # Write bytes to stdout (https://stackoverflow.com/a/23932488)
#             filepath_or_buffer = filepath_or_buffer.buffer
#         mode = getattr(filepath_or_buffer, "mode", "w")
#         for chunk in response.iter_content(chunk_size=1024):
#             if chunk:
#                 if "b" not in mode and six.PY3:
#                     chunk = chunk.decode("utf-8")
#                 filepath_or_buffer.write(chunk)
#         if filepath_or_buffer.seekable():
#             filepath_or_buffer.seek(0)
#     else:
#         with open(filepath_or_buffer, "wb") as f:
#             for chunk in response.iter_content(chunk_size=1024):
#                 if chunk:
#                     f.write(chunk)
# 
# Path: quantrocket/exceptions.py
# class ParameterError(ValueError):
#     pass
# 
# class NoMasterData(NoData):
#     pass


# Path: quantrocket/master.py
import sys
import six
import json
import requests
        import pandas as pd
        import pandas as pd
        import pandas as pd
        import pandas as pd
        import pandas as pd
from quantrocket.houston import houston
from quantrocket.cli.utils.output import json_to_cli
from quantrocket.cli.utils.stream import to_bytes
from quantrocket.cli.utils.files import write_response_to_filepath_or_buffer
from quantrocket.exceptions import ParameterError, NoMasterData

    if not response.content:
        return {}
    return response.json()

def _cli_load_or_show_rollrules(filename=None):
    if filename:
        return json_to_cli(load_rollrules_config, filename)
    else:
        return json_to_cli(get_rollrules_config)

def collect_ibkr_calendar(exchanges=None):
    """
    Collect upcoming trading hours from IBKR for exchanges and save to
    securities master database.

    Parameters
    ----------
    exchanges : list of str, optional
        limit to these exchanges

    Returns
    -------
    dict
        status message
    """
    params = {}
    if exchanges:
        params["exchanges"] = exchanges

    response = houston.post("/master/calendar/ibkr", params=params)

    houston.raise_for_status_with_json(response)