# Path: sacred/commandline_options.py
# def cli_option(short_flag: str, long_flag: str, is_flag=False):
#     def wrapper(f: CLIFunction):
#         return CLIOption(f, short_flag, long_flag, is_flag)
# 
#     return wrapper
# 
# Path: sacred/dependencies.py
# def get_digest(filename):
#     """Compute the MD5 hash for a given file."""
#     h = hashlib.md5()
#     with open(filename, "rb") as f:
#         data = f.read(1 * MB)
#         while data:
#             h.update(data)
#             data = f.read(1 * MB)
#         return h.hexdigest()
# 
# Path: sacred/observers/base.py
# class RunObserver:
#     """Defines the interface for all run observers."""
# 
#     priority = 0
# 
#     def queued_event(
#         self, ex_info, command, host_info, queue_time, config, meta_info, _id
#     ):
#         pass
# 
#     def started_event(
#         self, ex_info, command, host_info, start_time, config, meta_info, _id
#     ):
#         pass
# 
#     def heartbeat_event(self, info, captured_out, beat_time, result):
#         pass
# 
#     def completed_event(self, stop_time, result):
#         pass
# 
#     def interrupted_event(self, interrupt_time, status):
#         pass
# 
#     def failed_event(self, fail_time, fail_trace):
#         pass
# 
#     def resource_event(self, filename):
#         pass
# 
#     def artifact_event(self, name, filename, metadata=None, content_type=None):
#         pass
# 
#     def log_metrics(self, metrics_by_name, info):
#         pass
# 
#     def join(self):
#         pass
# 
# Path: sacred/serializer.py
# def flatten(obj):
#     return _json.loads(json.encode(obj, keys=True))


import json
import os
import os.path
import re
import socket
        import boto3
        import boto3
from sacred.commandline_options import cli_option
from sacred.dependencies import get_digest
from sacred.observers.base import RunObserver
from sacred.serializer import flatten
        from botocore.errorfactory import ClientError
            "status": "RUNNING",
            "resources": [],
            "artifacts": [],
            "heartbeat": None,
        }
        self.config = config
        self.info = {}
        self.cout = ""
        self.cout_write_cursor = 0

        self.save_json(self.run_entry, "run.json")
        self.save_json(self.config, "config.json")
        self.save_cout()

        return _id

    def find_or_save(self, filename, store_dir):
        source_name, ext = os.path.splitext(os.path.basename(filename))
        md5sum = get_digest(filename)
        store_name = source_name + "_" + md5sum + ext
        store_path = s3_join(store_dir, store_name)
        if len(self._list_s3_subdirs(prefix=store_path)) == 0:
            self.save_file(filename, store_path)
        return store_path, md5sum

    def put_data(self, key, binary_data):
        self.s3.Object(self.bucket, key).put(Body=binary_data)

    def save_json(self, obj, filename):
        key = s3_join(self.dir, filename)

# Path: sacred/commandline_options.py
# def cli_option(short_flag: str, long_flag: str, is_flag=False):
#     def wrapper(f: CLIFunction):
#         return CLIOption(f, short_flag, long_flag, is_flag)
# 
#     return wrapper
# 
# Path: sacred/dependencies.py
# def get_digest(filename):
#     """Compute the MD5 hash for a given file."""
#     h = hashlib.md5()
#     with open(filename, "rb") as f:
#         data = f.read(1 * MB)
#         while data:
#             h.update(data)
#             data = f.read(1 * MB)
#         return h.hexdigest()
# 
# Path: sacred/observers/base.py
# class RunObserver:
#     """Defines the interface for all run observers."""
# 
#     priority = 0
# 
#     def queued_event(
#         self, ex_info, command, host_info, queue_time, config, meta_info, _id
#     ):
#         pass
# 
#     def started_event(
#         self, ex_info, command, host_info, start_time, config, meta_info, _id
#     ):
#         pass
# 
#     def heartbeat_event(self, info, captured_out, beat_time, result):
#         pass
# 
#     def completed_event(self, stop_time, result):
#         pass
# 
#     def interrupted_event(self, interrupt_time, status):
#         pass
# 
#     def failed_event(self, fail_time, fail_trace):
#         pass
# 
#     def resource_event(self, filename):
#         pass
# 
#     def artifact_event(self, name, filename, metadata=None, content_type=None):
#         pass
# 
#     def log_metrics(self, metrics_by_name, info):
#         pass
# 
#     def join(self):
#         pass
# 
# Path: sacred/serializer.py
# def flatten(obj):
#     return _json.loads(json.encode(obj, keys=True))


# Path: sacred/observers/s3_observer.py
import json
import os
import os.path
import re
import socket
        import boto3
        import boto3
from sacred.commandline_options import cli_option
from sacred.dependencies import get_digest
from sacred.observers.base import RunObserver
from sacred.serializer import flatten
        from botocore.errorfactory import ClientError

            "status": "RUNNING",
            "resources": [],
            "artifacts": [],
            "heartbeat": None,
        }
        self.config = config
        self.info = {}
        self.cout = ""
        self.cout_write_cursor = 0

        self.save_json(self.run_entry, "run.json")
        self.save_json(self.config, "config.json")
        self.save_cout()

        return _id

    def find_or_save(self, filename, store_dir):
        source_name, ext = os.path.splitext(os.path.basename(filename))
        md5sum = get_digest(filename)
        store_name = source_name + "_" + md5sum + ext
        store_path = s3_join(store_dir, store_name)
        if len(self._list_s3_subdirs(prefix=store_path)) == 0:
            self.save_file(filename, store_path)
        return store_path, md5sum

    def put_data(self, key, binary_data):
        self.s3.Object(self.bucket, key).put(Body=binary_data)

    def save_json(self, obj, filename):
        key = s3_join(self.dir, filename)

        self.put_data(key, json.dumps(flatten(obj), sort_keys=True, indent=2))