Instruction:
Can you generate the documentation for the following Python 3 function
async def run(self):

        # Once everything is ready, we can add an event handler.
        #
        # Events are an abstraction over Telegram's "Updates" and
        # are much easier to use.
        self.add_event_handler(self.message_handler, events.NewMessage)

        # Enter a while loop to chat as long as the user wants
        while True:
            # Retrieve the top dialogs. You can set the limit to None to
            # retrieve all of them if you wish, but beware that may take
            # a long time if you have hundreds of them.
            dialog_count = 15

            # Entities represent the user, chat or channel
            # corresponding to the dialog on the same index.
            dialogs = await self.get_dialogs(limit=dialog_count)

            i = None
            while i is None:
                print_title('Dialogs window')

                # Display them so the user can choose
                for i, dialog in enumerate(dialogs, start=1):
                    sprint('{}. {}'.format(i, get_display_name(dialog.entity)))

                # Let the user decide who they want to talk to
                print()
                print('> Who do you want to send messages to?')
                print('> Available commands:')
                print('  !q: Quits the dialogs window and exits.')
                print('  !l: Logs out, terminating this session.')
                print()
                i = await async_input('Enter dialog ID or a command: ')
                if i == '!q':
                    return
                if i == '!l':
                    # Logging out will cause the user to need to reenter the
                    # code next time they want to use the library, and will
                    # also delete the *.session file off the filesystem.
                    #
                    # This is not the same as simply calling .disconnect(),
                    # which simply shuts down everything gracefully.
                    await self.log_out()
                    return

                try:
                    i = int(i if i else 0) - 1
                    # Ensure it is inside the bounds, otherwise retry
                    if not 0 <= i < dialog_count:
                        i = None
                except ValueError:
                    i = None

            # Retrieve the selected user (or chat, or channel)
            entity = dialogs[i].entity

            # Show some information
            print_title('Chat with "{}"'.format(get_display_name(entity)))
            print('Available commands:')
            print('  !q:  Quits the current chat.')
            print('  !Q:  Quits the current chat and exits.')
            print('  !h:  prints the latest messages (message History).')
            print('  !up  <path>: Uploads and sends the Photo from path.')
            print('  !uf  <path>: Uploads and sends the File from path.')
            print('  !d   <msg-id>: Deletes a message by its id')
            print('  !dm  <msg-id>: Downloads the given message Media (if any).')
            print('  !dp: Downloads the current dialog Profile picture.')
            print('  !i:  Prints information about this chat..')
            print()

            # And start a while loop to chat
            while True:
                msg = await async_input('Enter a message: ')
                # Quit
                if msg == '!q':
                    break
                elif msg == '!Q':
                    return

                # History
                elif msg == '!h':
                    # First retrieve the messages and some information
                    messages = await self.get_messages(entity, limit=10)

                    # Iterate over all (in reverse order so the latest appear
                    # the last in the console) and print them with format:
                    # "[hh:mm] Sender: Message"
                    for msg in reversed(messages):
                        # Note how we access .sender here. Since we made an
                        # API call using the self client, it will always have
                        # information about the sender. This is different to
                        # events, where Telegram may not always send the user.
                        name = get_display_name(msg.sender)

                        # Format the message content
                        if getattr(msg, 'media', None):
                            self.found_media[msg.id] = msg
                            content = '<{}> {}'.format(
                                type(msg.media).__name__, msg.message)

                        elif hasattr(msg, 'message'):
                            content = msg.message
                        elif hasattr(msg, 'action'):
                            content = str(msg.action)
                        else:
                            # Unknown message, simply print its class name
                            content = type(msg).__name__

                        # And print it to the user
                        sprint('[{}:{}] (ID={}) {}: {}'.format(
                            msg.date.hour, msg.date.minute, msg.id, name, content))

                # Send photo
                elif msg.startswith('!up '):
                    # Slice the message to get the path
                    path = msg[len('!up '):]
                    await self.send_photo(path=path, entity=entity)

                # Send file (document)
                elif msg.startswith('!uf '):
                    # Slice the message to get the path
                    path = msg[len('!uf '):]
                    await self.send_document(path=path, entity=entity)

                # Delete messages
                elif msg.startswith('!d '):
                    # Slice the message to get message ID
                    msg = msg[len('!d '):]
                    deleted_msg = await self.delete_messages(entity, msg)
                    print('Deleted {}'.format(deleted_msg))

                # Download media
                elif msg.startswith('!dm '):
                    # Slice the message to get message ID
                    await self.download_media_by_id(msg[len('!dm '):])

                # Download profile photo
                elif msg == '!dp':
                    print('Downloading profile picture to usermedia/...')
                    os.makedirs('usermedia', exist_ok=True)
                    output = await self.download_profile_photo(entity,
                                                               'usermedia')
                    if output:
                        print('Profile picture downloaded to', output)
                    else:
                        print('No profile picture found for this user!')

                elif msg == '!i':
                    attributes = list(entity.to_dict().items())
                    pad = max(len(x) for x, _ in attributes)
                    for name, val in attributes:
                        print("{:<{width}} : {}".format(name, val, width=pad))

                # Send chat message (if any)
                elif msg:
                    await self.send_message(entity, msg, link_preview=False)

Response: This function is the main loop of the Telegram client. It will wait for the user to enter a new message and send it to the user.


Instruction:
Explain what the following Python 3 code does
async def send_photo(self, path, entity):
        await self.send_file(
            entity, path,
            progress_callback=self.upload_progress_callback
        )
        print('Photo sent!')

Response: Sends the file located at path to the desired entity as a photo


Instruction:
Write a Python 3 function for
sending the file located at path to the desired entity as a document

Response:
async def send_document(self, path, entity):
        """Sends the file located at path to the desired entity as a document"""
        await self.send_file(
            entity, path,
            force_document=True,
            progress_callback=self.upload_progress_callback
        )
        print('Document sent!')


Instruction:
Here you have a function in Python 3, explain what it does
async def download_media_by_id(self, media_id):
        try:
            msg = self.found_media[int(media_id)]
        except (ValueError, KeyError):
            # ValueError when parsing, KeyError when accessing dictionary
            print('Invalid media ID given or message not found!')
            return

        print('Downloading media to usermedia/...')
        os.makedirs('usermedia', exist_ok=True)
        output = await self.download_media(
            msg.media,
            file='usermedia/',
            progress_callback=self.download_progress_callback
        )
        print('Media downloaded to {}!'.format(output))

Response:
Given a message ID finds the media this message contained and
           downloads it.


Instruction:
Write a Python 3 script to
return the file name of the given object.

Response:
def _get_file_name(tlobject):
    """``ClassName -> class_name.html``."""
    name = tlobject.name if isinstance(tlobject, TLObject) else tlobject
    # Courtesy of http://stackoverflow.com/a/1176023/4759433
    s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
    result = re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()
    return '{}.html'.format(result)


Instruction:
Implement a function in Python 3 to
return the code to import a TLObject.

Response:
def get_import_code(tlobject):
    """``TLObject -> from ... import ...``."""
    kind = 'functions' if tlobject.is_function else 'types'
    ns = '.' + tlobject.namespace if tlobject.namespace else ''
    return 'from telethon.tl.{}{} import {}'\
        .format(kind, ns, tlobject.class_name)


Instruction:
Make a summary of the following Python 3 code
def _get_path_for(root, tlobject):
    out_dir = root / ('methods' if tlobject.is_function else 'constructors')
    if tlobject.namespace:
        out_dir /= tlobject.namespace

    return out_dir / _get_file_name(tlobject)

Response: Creates and returns the path for the given TLObject at root.


Instruction:
Create a Python 3 function for
finding the <title > for the given HTML file or ( Unknown ) if no title is found.

Response:
def _find_title(html_file):
    """Finds the <title> for the given HTML file, or (Unknown)."""
    # TODO Is it necessary to read files like this?
    with html_file.open() as f:
        for line in f:
            if '<title>' in line:
                # + 7 to skip len('<title>')
                return line[line.index('<title>') + 7:line.index('</title>')]

    return '(Unknown)'


Instruction:
Implement a function in Python 3 to
build the menu used for the current document writer.

Response:
def _build_menu(docs):
    """
    Builds the menu used for the current ``DocumentWriter``.
    """

    paths = []
    current = docs.filename
    while current != docs.root:
        current = current.parent
        paths.append(current)

    for path in reversed(paths):
        docs.add_menu(path.stem.title(), link=path / 'index.html')

    if docs.filename.stem != 'index':
        docs.add_menu(docs.title, link=docs.filename)

    docs.end_menu()


Instruction:
Implement a function in Python 3 to
generate the index. html file for the specified folder.

Response:
def _generate_index(root, folder, paths,
                    bots_index=False, bots_index_paths=()):
    """Generates the index file for the specified folder"""
    # Determine the namespaces listed here (as sub folders)
    # and the files (.html files) that we should link to
    namespaces = []
    files = []
    INDEX = 'index.html'
    BOT_INDEX = 'botindex.html'

    for item in (bots_index_paths or folder.iterdir()):
        if item.is_dir():
            namespaces.append(item)
        elif item.name not in (INDEX, BOT_INDEX):
            files.append(item)

    # Now that everything is setup, write the index.html file
    filename = folder / (BOT_INDEX if bots_index else INDEX)
    with DocsWriter(root, filename, _get_path_for_type) as docs:
        # Title should be the current folder name
        docs.write_head(str(folder).replace(os.path.sep, '/').title(),
                        css_path=paths['css'],
                        default_css=paths['default_css'])

        docs.set_menu_separator(paths['arrow'])
        _build_menu(docs)
        docs.write_title(str(filename.parent.relative_to(root))
                         .replace(os.path.sep, '/').title())

        if bots_index:
            docs.write_text('These are the methods that you may be able to '
                            'use as a bot. Click here to '
                            'view them all.'.format(INDEX))
        else:
            docs.write_text('Click here to view the methods '
                            'that you can use as a bot.'.format(BOT_INDEX))
        if namespaces:
            docs.write_title('Namespaces', level=3)
            docs.begin_table(4)
            namespaces.sort()
            for namespace in namespaces:
                # For every namespace, also write the index of it
                namespace_paths = []
                if bots_index:
                    for item in bots_index_paths:
                        if item.parent == namespace:
                            namespace_paths.append(item)

                _generate_index(root, namespace, paths,
                                bots_index, namespace_paths)

                docs.add_row(
                    namespace.stem.title(),
                    link=namespace / (BOT_INDEX if bots_index else INDEX))

            docs.end_table()

        docs.write_title('Available items')
        docs.begin_table(2)

        files = [(f, _find_title(f)) for f in files]
        files.sort(key=lambda t: t[1])

        for file, title in files:
            docs.add_row(title, link=file)

        docs.end_table()
        docs.end_body()


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _get_description(arg):
    desc = []
    otherwise = False
    if arg.can_be_inferred:
        desc.append('If left unspecified, it will be inferred automatically.')
        otherwise = True
    elif arg.is_flag:
        desc.append('This argument defaults to '
                    'None and can be omitted.')
        otherwise = True

    if arg.type in {'InputPeer', 'InputUser', 'InputChannel',
                    'InputNotifyPeer', 'InputDialogPeer'}:
        desc.append(
            'Anything entity-like will work if the library can find its '
            'Input version (e.g., usernames, Peer, '
            'User or Channel objects, etc.).'
        )

    if arg.is_vector:
        if arg.is_generic:
            desc.append('A list of other Requests must be supplied.')
        else:
            desc.append('A list must be supplied.')
    elif arg.is_generic:
        desc.append('A different Request must be supplied for this argument.')
    else:
        otherwise = False  # Always reset to false if no other text is added

    if otherwise:
        desc.insert(1, 'Otherwise,')
        desc[-1] = desc[-1][:1].lower() + desc[-1][1:]

    return ' '.join(desc).replace(
        'list',
        'list'
    )

Response: Generates a proper description for the given argument.


Instruction:
Can you generate the documentation for the following Python 3 function
def _copy_replace(src, dst, replacements):
    with src.open() as infile, dst.open('w') as outfile:
        outfile.write(re.sub(
            '|'.join(re.escape(k) for k in replacements),
            lambda m: str(replacements[m.group(0)]),
            infile.read()
        ))

Response: Copies the src file into dst applying the replacements dict


Instruction:
Write a Python 3 script to
generate the documentation HTML files from scheme. tl methods and constructors and layer.

Response:
def _write_html_pages(root, tlobjects, methods, layer, input_res):
    """
    Generates the documentation HTML files from from ``scheme.tl``
    to ``/methods`` and ``/constructors``, etc.
    """
    # Save 'Type: [Constructors]' for use in both:
    # * Seeing the return type or constructors belonging to the same type.
    # * Generating the types documentation, showing available constructors.
    paths = {k: root / v for k, v in (
        ('css', 'css'),
        ('arrow', 'img/arrow.svg'),
        ('search.js', 'js/search.js'),
        ('404', '404.html'),
        ('index_all', 'index.html'),
        ('bot_index', 'botindex.html'),
        ('index_types', 'types/index.html'),
        ('index_methods', 'methods/index.html'),
        ('index_constructors', 'constructors/index.html')
    )}
    paths['default_css'] = 'light'  # docs.<name>.css, local path
    type_to_constructors = defaultdict(list)
    type_to_functions = defaultdict(list)
    for tlobject in tlobjects:
        d = type_to_functions if tlobject.is_function else type_to_constructors
        d[tlobject.result].append(tlobject)

    for t, cs in type_to_constructors.items():
        type_to_constructors[t] = list(sorted(cs, key=lambda c: c.name))

    methods = {m.name: m for m in methods}

    # Since the output directory is needed everywhere partially apply it now
    create_path_for = functools.partial(_get_path_for, root)
    path_for_type = lambda t: root / _get_path_for_type(t)
    bot_docs_paths = []

    for tlobject in tlobjects:
        filename = create_path_for(tlobject)
        with DocsWriter(root, filename, path_for_type) as docs:
            docs.write_head(title=tlobject.class_name,
                            css_path=paths['css'],
                            default_css=paths['default_css'])

            # Create the menu (path to the current TLObject)
            docs.set_menu_separator(paths['arrow'])
            _build_menu(docs)

            # Create the page title
            docs.write_title(tlobject.class_name)

            if tlobject.is_function:
                if tlobject.usability == Usability.USER:
                    start = '<strong>Only users</strong> can'
                elif tlobject.usability == Usability.BOT:
                    bot_docs_paths.append(filename)
                    start = '<strong>Only bots</strong> can'
                elif tlobject.usability == Usability.BOTH:
                    bot_docs_paths.append(filename)
                    start = '<strong>Both users and bots</strong> can'
                else:
                    bot_docs_paths.append(filename)
                    start = \
                        'Both users and bots <strong>may</strong> be able to'

                docs.write_text('{} use this method. <a href="#examples">'
                                'See code examples.</a>'.format(start))

            # Write the code definition for this TLObject
            docs.write_code(tlobject)
            docs.write_copy_button('Copy import to the clipboard',
                                   get_import_code(tlobject))

            # Write the return type (or constructors belonging to the same type)
            docs.write_title('Returns' if tlobject.is_function
                             else 'Belongs to', level=3)

            generic_arg = next((arg.name for arg in tlobject.args
                                if arg.generic_definition), None)

            if tlobject.result == generic_arg:
                # We assume it's a function returning a generic type
                generic_arg = next((arg.name for arg in tlobject.args
                                    if arg.is_generic))
                docs.write_text('This function returns the result of whatever '
                                'the result from invoking the request passed '
                                'through <i>{}</i> is.'.format(generic_arg))
            else:
                if re.search('^vector<', tlobject.result, re.IGNORECASE):
                    docs.write_text('A list of the following type is returned.')
                    _, inner = tlobject.result.split('<')
                    inner = inner.strip('>')
                else:
                    inner = tlobject.result

                docs.begin_table(column_count=1)
                docs.add_row(inner, link=path_for_type(inner))
                docs.end_table()

                cs = type_to_constructors.get(inner, [])
                if not cs:
                    docs.write_text('This type has no instances available.')
                elif len(cs) == 1:
                    docs.write_text('This type can only be an instance of:')
                else:
                    docs.write_text('This type can be an instance of either:')

                docs.begin_table(column_count=2)
                for constructor in cs:
                    link = create_path_for(constructor)
                    docs.add_row(constructor.class_name, link=link)
                docs.end_table()

            # Return (or similar types) written. Now parameters/members
            docs.write_title(
                'Parameters' if tlobject.is_function else 'Members', level=3
            )

            # Sort the arguments in the same way they're sorted
            # on the generated code (flags go last)
            args = [
                a for a in tlobject.sorted_args()
                if not a.flag_indicator and not a.generic_definition
            ]

            if args:
                # Writing parameters
                docs.begin_table(column_count=3)

                for arg in args:
                    # Name row
                    docs.add_row(arg.name,
                                 bold=True)

                    # Type row
                    friendly_type = 'flag' if arg.type == 'true' else arg.type
                    if arg.is_generic:
                        docs.add_row('!' + friendly_type, align='center')
                    else:
                        docs.add_row(
                            friendly_type, align='center',
                            link=path_for_type(arg.type)
                         )

                    # Add a description for this argument
                    docs.add_row(_get_description(arg))

                docs.end_table()
            else:
                if tlobject.is_function:
                    docs.write_text('This request takes no input parameters.')
                else:
                    docs.write_text('This type has no members.')

            if tlobject.is_function:
                docs.write_title('Known RPC errors')
                method_info = methods.get(tlobject.fullname)
                errors = method_info and method_info.errors
                if not errors:
                    docs.write_text("This request can't cause any RPC error "
                                    "as far as we know.")
                else:
                    docs.write_text(
                        'This request can cause {} known error{}:'.format(
                            len(errors), '' if len(errors) == 1 else 's'
                    ))
                    docs.begin_table(column_count=2)
                    for error in errors:
                        docs.add_row('<code>{}</code>'.format(error.name))
                        docs.add_row('{}.'.format(error.description))
                    docs.end_table()
                    docs.write_text('You can import these from '
                                    '<code>telethon.errors</code>.')

                docs.write_title('Example', id='examples')
                docs.write('''<pre>\
<strong>from</strong> telethon.sync <strong>import</strong> TelegramClient
<strong>from</strong> telethon <strong>import</strong> functions, types

<strong>with</strong> TelegramClient(name, api_id, api_hash) <strong>as</strong> client:
    result = client(''')
                tlobject.as_example(docs, indent=1)
                docs.write(')\n')
                if tlobject.result.startswith('Vector'):
                    docs.write('''\
    <strong>for</strong> x <strong>in</strong> result:
        print(x''')
                else:
                    docs.write('    print(result')
                    if tlobject.result != 'Bool' \
                            and not tlobject.result.startswith('Vector'):
                        docs.write('.stringify()')

                docs.write(')</pre>')

            depth = '../' * (2 if tlobject.namespace else 1)
            docs.add_script(src='prependPath = "{}";'.format(depth))
            docs.add_script(path=paths['search.js'])
            docs.end_body()

    # Find all the available types (which are not the same as the constructors)
    # Each type has a list of constructors associated to it, hence is a map
    for t, cs in type_to_constructors.items():
        filename = path_for_type(t)
        out_dir = filename.parent
        if out_dir:
            out_dir.mkdir(parents=True, exist_ok=True)

        # Since we don't have access to the full TLObject, split the type
        if '.' in t:
            namespace, name = t.split('.')
        else:
            namespace, name = None, t

        with DocsWriter(root, filename, path_for_type) as docs:
            docs.write_head(title=snake_to_camel_case(name),
                            css_path=paths['css'],
                            default_css=paths['default_css'])

            docs.set_menu_separator(paths['arrow'])
            _build_menu(docs)

            # Main file title
            docs.write_title(snake_to_camel_case(name))

            # List available constructors for this type
            docs.write_title('Available constructors', level=3)
            if not cs:
                docs.write_text('This type has no constructors available.')
            elif len(cs) == 1:
                docs.write_text('This type has one constructor available.')
            else:
                docs.write_text('This type has %d constructors available.' %
                                len(cs))

            docs.begin_table(2)
            for constructor in cs:
                # Constructor full name
                link = create_path_for(constructor)
                docs.add_row(constructor.class_name, link=link)
            docs.end_table()

            # List all the methods which return this type
            docs.write_title('Methods returning this type', level=3)
            functions = type_to_functions.get(t, [])
            if not functions:
                docs.write_text('No method returns this type.')
            elif len(functions) == 1:
                docs.write_text('Only the following method returns this type.')
            else:
                docs.write_text(
                    'The following %d methods return this type as a result.' %
                    len(functions)
                )

            docs.begin_table(2)
            for func in functions:
                link = create_path_for(func)
                docs.add_row(func.class_name, link=link)
            docs.end_table()

            # List all the methods which take this type as input
            docs.write_title('Methods accepting this type as input', level=3)
            other_methods = sorted(
                (u for u in tlobjects
                 if any(a.type == t for a in u.args) and u.is_function),
                key=lambda u: u.name
            )
            if not other_methods:
                docs.write_text(
                    'No methods accept this type as an input parameter.')
            elif len(other_methods) == 1:
                docs.write_text(
                    'Only this method has a parameter with this type.')
            else:
                docs.write_text(
                    'The following %d methods accept this type as an input '
                    'parameter.' % len(other_methods))

            docs.begin_table(2)
            for ot in other_methods:
                link = create_path_for(ot)
                docs.add_row(ot.class_name, link=link)
            docs.end_table()

            # List every other type which has this type as a member
            docs.write_title('Other types containing this type', level=3)
            other_types = sorted(
                (u for u in tlobjects
                 if any(a.type == t for a in u.args) and not u.is_function),
                key=lambda u: u.name
            )

            if not other_types:
                docs.write_text(
                    'No other types have a member of this type.')
            elif len(other_types) == 1:
                docs.write_text(
                    'You can find this type as a member of this other type.')
            else:
                docs.write_text(
                    'You can find this type as a member of any of '
                    'the following %d types.' % len(other_types))

            docs.begin_table(2)
            for ot in other_types:
                link = create_path_for(ot)
                docs.add_row(ot.class_name, link=link)
            docs.end_table()
            docs.end_body()

    # After everything's been written, generate an index.html per folder.
    # This will be done automatically and not taking into account any extra
    # information that we have available, simply a file listing all the others
    # accessible by clicking on their title
    for folder in ['types', 'methods', 'constructors']:
        _generate_index(root, root / folder, paths)

    _generate_index(root, root / 'methods', paths, True,
                    bot_docs_paths)

    # Write the final core index, the main index for the rest of files
    types = set()
    methods = []
    cs = []
    for tlobject in tlobjects:
        if tlobject.is_function:
            methods.append(tlobject)
        else:
            cs.append(tlobject)

        if not tlobject.result.lower() in CORE_TYPES:
            if re.search('^vector<', tlobject.result, re.IGNORECASE):
                types.add(tlobject.result.split('<')[1].strip('>'))
            else:
                types.add(tlobject.result)

    types = sorted(types)
    methods = sorted(methods, key=lambda m: m.name)
    cs = sorted(cs, key=lambda c: c.name)

    shutil.copy(str(input_res / '404.html'), str(paths['404']))
    _copy_replace(input_res / 'core.html', paths['index_all'], {
        '{type_count}': len(types),
        '{method_count}': len(methods),
        '{constructor_count}': len(tlobjects) - len(methods),
        '{layer}': layer,
    })

    def fmt(xs):
        zs = {}  # create a dict to hold those which have duplicated keys
        for x in xs:
            zs[x.class_name] = x.class_name in zs
        return ', '.join(
            '"{}.{}"'.format(x.namespace, x.class_name)
            if zs[x.class_name] and x.namespace
            else '"{}"'.format(x.class_name) for x in xs
        )

    request_names = fmt(methods)
    constructor_names = fmt(cs)

    def fmt(xs, formatter):
        return ', '.join('"{}"'.format(
            formatter(x)).replace(os.path.sep, '/') for x in xs)

    type_names = fmt(types, formatter=lambda x: x)

    # Local URLs shouldn't rely on the output's root, so set empty root
    get_path_for = functools.partial(_get_path_for, Path())

    request_urls = fmt(methods, get_path_for)
    type_urls = fmt(types, _get_path_for_type)
    constructor_urls = fmt(cs, get_path_for)

    paths['search.js'].parent.mkdir(parents=True, exist_ok=True)
    _copy_replace(input_res / 'js/search.js', paths['search.js'], {
        '{request_names}': request_names,
        '{type_names}': type_names,
        '{constructor_names}': constructor_names,
        '{request_urls}': request_urls,
        '{type_urls}': type_urls,
        '{constructor_urls}': constructor_urls
    })


Instruction:
Here you have a function in Python 3, explain what it does
def _create_structure(tlobjects, output_dir):
    types_ns = set()
    method_ns = set()
    for obj in tlobjects:
        if obj.namespace:
            if obj.is_function:
                method_ns.add(obj.namespace)
            else:
                types_ns.add(obj.namespace)

    output_dir.mkdir(exist_ok=True)

    type_dir = output_dir / 'types'
    type_dir.mkdir(exist_ok=True)

    cons_dir = output_dir / 'constructors'
    cons_dir.mkdir(exist_ok=True)
    for ns in types_ns:
        (type_dir / ns).mkdir(exist_ok=True)
        (cons_dir / ns).mkdir(exist_ok=True)

    meth_dir = output_dir / 'methods'
    meth_dir.mkdir(exist_ok=True)
    for ns in types_ns:
        (meth_dir / ns).mkdir(exist_ok=True)

Response:
Create the required directory structure
    in output_dir for the input objects.


Instruction:
Make a summary of the following Python 3 code
def create_connection(self, *args, **kwargs):

        args = list(args)
        if len(args) == 0:  # kazoo 2.6.0 slightly changed the way how it calls create_connection method
            kwargs['timeout'] = max(self._connect_timeout, kwargs.get('timeout', self._connect_timeout*10)/10.0)
        elif len(args) == 1:
            args.append(self._connect_timeout)
        else:
            args[1] = max(self._connect_timeout, args[1]/10.0)
        return super(PatroniSequentialThreadingHandler, self).create_connection(*args, **kwargs)

Response: This method is used to establish a connection with one of the zookeeper nodes.


Instruction:
Write a Python 3 script to
set the ttl of the current session.

Response:
def set_ttl(self, ttl):
        """It is not possible to change ttl (session_timeout) in zookeeper without
        destroying old session and creating the new one. This method returns `!True`
        if session_timeout has been changed (`restart()` has been called)."""
        if self._client._session_timeout != ttl:
            self._client._session_timeout = ttl
            self._client.restart()
            return True


Instruction:
Implement a Python 3 function for
translating scope name to service name which can be used in dns.

Response:
def service_name_from_scope_name(scope_name):
    """Translate scope name to service name which can be used in dns.

    230 = 253 - len('replica.') - len('.service.consul')
    """

    def replace_char(match):
        c = match.group(0)
        return '-' if c in '. _' else "u{:04d}".format(ord(c))

    service_name = re.sub(r'[^a-z0-9\-]', replace_char, scope_name.lower())
    return service_name[0:230]


Instruction:
Given the following Python 3 function, write the documentation
def _do_refresh_session(self):
        if self._session and self._last_session_refresh + self._loop_wait > time.time():
            return False

        if self._session:
            try:
                self._client.session.renew(self._session)
            except NotFound:
                self._session = None
        ret = not self._session
        if ret:
            try:
                self._session = self._client.session.create(name=self._scope + '-' + self._name,
                                                            checks=self.__session_checks,
                                                            lock_delay=0.001, behavior='delete')
            except InvalidSessionTTL:
                logger.exception('session.create')
                self.adjust_ttl()
                raise

        self._last_session_refresh = time.time()
        return ret

Response: Refreshes the session if it had to create new session


Instruction:
Create a Python 3 function to
read and parses postmaster. pid from the data directory

Response:
def _read_postmaster_pidfile(data_dir):
        """Reads and parses postmaster.pid from the data directory

        :returns dictionary of values if successful, empty dictionary otherwise
        """
        pid_line_names = ['pid', 'data_dir', 'start_time', 'port', 'socket_dir', 'listen_addr', 'shmem_key']
        try:
            with open(os.path.join(data_dir, 'postmaster.pid')) as f:
                return {name: line.rstrip('\n') for name, line in zip(pid_line_names, f)}
        except IOError:
            return {}


Instruction:
Here you have a function in Python 3, explain what it does
def signal_stop(self, mode):
        if self.is_single_user:
            logger.warning("Cannot stop server; single-user server is running (PID: {0})".format(self.pid))
            return False
        try:
            self.send_signal(STOP_SIGNALS[mode])
        except psutil.NoSuchProcess:
            return True
        except psutil.AccessDenied as e:
            logger.warning("Could not send stop signal to PostgreSQL (error: {0})".format(e))
            return False

        return None

Response: Signal postmaster process to stop the server.


Instruction:
Write a Python 3 function that can
return a human readable string representation of the size of a resource.

Response:
def repr_size(n_bytes):
    """
    >>> repr_size(1000)
    '1000 Bytes'
    >>> repr_size(8257332324597)
    '7.5 TiB'
    """
    if n_bytes < 1024:
        return '{0} Bytes'.format(n_bytes)
    i = -1
    while n_bytes > 1023:
        n_bytes /= 1024.0
        i += 1
    return '{0} {1}iB'.format(round(n_bytes, 1), si_prefixes[i])


Instruction:
Write a Python 3 script to
return the size in bytes for the given prefix.

Response:
def size_as_bytes(size_, prefix):
    """
    >>> size_as_bytes(7.5, 'T')
    8246337208320
    """
    prefix = prefix.upper()

    assert prefix in si_prefixes

    exponent = si_prefixes.index(prefix) + 1

    return int(size_ * (1024.0 ** exponent))


Instruction:
Write a Python 3 script for
running the WAL - E backup process.

Response:
def run(self):
        """
        Creates a new replica using WAL-E

        Returns
        -------
        ExitCode
            0 = Success
            1 = Error, try again
            2 = Error, don't try again

        """
        if self.init_error:
            logger.error('init error: %r did not exist at initialization time',
                         self.wal_e.env_dir)
            return ExitCode.FAIL

        try:
            should_use_s3 = self.should_use_s3_to_create_replica()
            if should_use_s3 is None:  # Need to retry
                return ExitCode.RETRY_LATER
            elif should_use_s3:
                return self.create_replica_with_s3()
            elif not should_use_s3:
                return ExitCode.FAIL
        except Exception:
            logger.exception("Unhandled exception when running WAL-E restore")
        return ExitCode.FAIL


Instruction:
Create a Python 3 function to
determine whether it makes sense to use S3 and not pg_basebackup.

Response:
def should_use_s3_to_create_replica(self):
        """ determine whether it makes sense to use S3 and not pg_basebackup """

        threshold_megabytes = self.wal_e.threshold_mb
        threshold_percent = self.wal_e.threshold_pct

        try:
            cmd = self.wal_e.cmd + ['backup-list', '--detail', 'LATEST']

            logger.debug('calling %r', cmd)
            wale_output = subprocess.check_output(cmd)

            reader = csv.DictReader(wale_output.decode('utf-8').splitlines(),
                                    dialect='excel-tab')
            rows = list(reader)
            if not len(rows):
                logger.warning('wal-e did not find any backups')
                return False

            # This check might not add much, it was performed in the previous
            # version of this code. since the old version rolled CSV parsing the
            # check may have been part of the CSV parsing.
            if len(rows) > 1:
                logger.warning(
                    'wal-e returned more than one row of backups: %r',
                    rows)
                return False

            backup_info = rows[0]
        except subprocess.CalledProcessError:
            logger.exception("could not query wal-e latest backup")
            return None

        try:
            backup_size = int(backup_info['expanded_size_bytes'])
            backup_start_segment = backup_info['wal_segment_backup_start']
            backup_start_offset = backup_info['wal_segment_offset_backup_start']
        except KeyError:
            logger.exception("unable to get some of WALE backup parameters")
            return None

        # WAL filename is XXXXXXXXYYYYYYYY000000ZZ, where X - timeline, Y - LSN logical log file,
        # ZZ - 2 high digits of LSN offset. The rest of the offset is the provided decimal offset,
        # that we have to convert to hex and 'prepend' to the high offset digits.

        lsn_segment = backup_start_segment[8:16]
        # first 2 characters of the result are 0x and the last one is L
        lsn_offset = hex((int(backup_start_segment[16:32], 16) << 24) + int(backup_start_offset))[2:-1]

        # construct the LSN from the segment and offset
        backup_start_lsn = '{0}/{1}'.format(lsn_segment, lsn_offset)

        diff_in_bytes = backup_size
        attempts_no = 0
        while True:
            if self.master_connection:
                try:
                    # get the difference in bytes between the current WAL location and the backup start offset
                    with psycopg2.connect(self.master_connection) as con:
                        if con.server_version >= 100000:
                            wal_name = 'wal'
                            lsn_name = 'lsn'
                        else:
                            wal_name = 'xlog'
                            lsn_name = 'location'
                        con.autocommit = True
                        with con.cursor() as cur:
                            cur.execute(("SELECT CASE WHEN pg_catalog.pg_is_in_recovery()"
                                         " THEN GREATEST(pg_catalog.pg_{0}_{1}_diff(COALESCE("
                                         "pg_last_{0}_receive_{1}(), '0/0'), %s)::bigint, "
                                         "pg_catalog.pg_{0}_{1}_diff(pg_catalog.pg_last_{0}_replay_{1}(), %s)::bigint)"
                                         " ELSE pg_catalog.pg_{0}_{1}_diff(pg_catalog.pg_current_{0}_{1}(), %s)::bigint"
                                         " END").format(wal_name, lsn_name),
                                        (backup_start_lsn, backup_start_lsn, backup_start_lsn))

                            diff_in_bytes = int(cur.fetchone()[0])
                except psycopg2.Error:
                    logger.exception('could not determine difference with the master location')
                    if attempts_no < self.retries:  # retry in case of a temporarily connection issue
                        attempts_no = attempts_no + 1
                        time.sleep(RETRY_SLEEP_INTERVAL)
                        continue
                    else:
                        if not self.no_master:
                            return False  # do no more retries on the outer level
                        logger.info("continue with base backup from S3 since master is not available")
                        diff_in_bytes = 0
                        break
            else:
                # always try to use WAL-E if master connection string is not available
                diff_in_bytes = 0
            break

        # if the size of the accumulated WAL segments is more than a certan percentage of the backup size
        # or exceeds the pre-determined size - pg_basebackup is chosen instead.
        is_size_thresh_ok = diff_in_bytes < int(threshold_megabytes) * 1048576
        threshold_pct_bytes = backup_size * threshold_percent / 100.0
        is_percentage_thresh_ok = float(diff_in_bytes) < int(threshold_pct_bytes)
        are_thresholds_ok = is_size_thresh_ok and is_percentage_thresh_ok

        class Size(object):
            def __init__(self, n_bytes, prefix=None):
                self.n_bytes = n_bytes
                self.prefix = prefix

            def __repr__(self):
                if self.prefix is not None:
                    n_bytes = size_as_bytes(self.n_bytes, self.prefix)
                else:
                    n_bytes = self.n_bytes
                return repr_size(n_bytes)

        class HumanContext(object):
            def __init__(self, items):
                self.items = items

            def __repr__(self):
                return ', '.join('{}={!r}'.format(key, value)
                                 for key, value in self.items)

        human_context = repr(HumanContext([
            ('threshold_size', Size(threshold_megabytes, 'M')),
            ('threshold_percent', threshold_percent),
            ('threshold_percent_size', Size(threshold_pct_bytes)),
            ('backup_size', Size(backup_size)),
            ('backup_diff', Size(diff_in_bytes)),
            ('is_size_thresh_ok', is_size_thresh_ok),
            ('is_percentage_thresh_ok', is_percentage_thresh_ok),
        ]))

        if not are_thresholds_ok:
            logger.info('wal-e backup size diff is over threshold, falling back '
                        'to other means of restore: %s', human_context)
        else:
            logger.info('Thresholds are OK, using wal-e basebackup: %s', human_context)
        return are_thresholds_ok


Instruction:
Here you have a function in Python 3, explain what it does
def watching(w, watch, max_count=None, clear=True):

    if w and not watch:
        watch = 2
    if watch and clear:
        click.clear()
    yield 0

    if max_count is not None and max_count < 1:
        return

    counter = 1
    while watch and counter <= (max_count or counter):
        time.sleep(watch)
        counter += 1
        if clear:
            click.clear()
        yield 0

Response: Yields the list of items that are watching w.


Instruction:
Given the following Python 3 function, write the documentation
def _do_failover_or_switchover(obj, action, cluster_name, master, candidate, force, scheduled=None):

    dcs = get_dcs(obj, cluster_name)
    cluster = dcs.get_cluster()

    if action == 'switchover' and cluster.leader is None:
        raise PatroniCtlException('This cluster has no master')

    if master is None:
        if force or action == 'failover':
            master = cluster.leader and cluster.leader.name
        else:
            master = click.prompt('Master', type=str, default=cluster.leader.member.name)

    if master is not None and cluster.leader and cluster.leader.member.name != master:
        raise PatroniCtlException('Member {0} is not the leader of cluster {1}'.format(master, cluster_name))

    # excluding members with nofailover tag
    candidate_names = [str(m.name) for m in cluster.members if m.name != master and not m.nofailover]
    # We sort the names for consistent output to the client
    candidate_names.sort()

    if not candidate_names:
        raise PatroniCtlException('No candidates found to {0} to'.format(action))

    if candidate is None and not force:
        candidate = click.prompt('Candidate ' + str(candidate_names), type=str, default='')

    if action == 'failover' and not candidate:
        raise PatroniCtlException('Failover could be performed only to a specific candidate')

    if candidate == master:
        raise PatroniCtlException(action.title() + ' target and source are the same.')

    if candidate and candidate not in candidate_names:
        raise PatroniCtlException('Member {0} does not exist in cluster {1}'.format(candidate, cluster_name))

    scheduled_at_str = None
    scheduled_at = None

    if action == 'switchover':
        if scheduled is None and not force:
            scheduled = click.prompt('When should the switchover take place (e.g. 2015-10-01T14:30) ',
                                     type=str, default='now')

        scheduled_at = parse_scheduled(scheduled)
        if scheduled_at:
            if cluster.is_paused():
                raise PatroniCtlException("Can't schedule switchover in the paused state")
            scheduled_at_str = scheduled_at.isoformat()

    failover_value = {'leader': master, 'candidate': candidate, 'scheduled_at': scheduled_at_str}

    logging.debug(failover_value)

    # By now we have established that the leader exists and the candidate exists
    click.echo('Current cluster topology')
    output_members(dcs.get_cluster(), cluster_name)

    if not force:
        demote_msg = ', demoting current master ' + master if master else ''

        if not click.confirm('Are you sure you want to {0} cluster {1}{2}?'.format(action, cluster_name, demote_msg)):
            raise PatroniCtlException('Aborting ' + action)

    r = None
    try:
        member = cluster.leader.member if cluster.leader else cluster.get_member(candidate, False)

        r = request_patroni(member, 'post', action, failover_value, auth_header(obj))

        # probably old patroni, which doesn't support switchover yet
        if r.status_code == 501 and action == 'switchover' and 'Server does not support this operation' in r.text:
            r = request_patroni(member, 'post', 'failover', failover_value, auth_header(obj))

        if r.status_code in (200, 202):
            logging.debug(r)
            cluster = dcs.get_cluster()
            logging.debug(cluster)
            click.echo('{0} {1}'.format(timestamp(), r.text))
        else:
            click.echo('{0} failed, details: {1}, {2}'.format(action.title(), r.status_code, r.text))
            return
    except Exception:
        logging.exception(r)
        logging.warning('Failing over to DCS')
        click.echo('{0} Could not {1} using Patroni api, falling back to DCS'.format(timestamp(), action))
        dcs.manual_failover(master, candidate, scheduled_at=scheduled_at)

    output_members(cluster, cluster_name)

Response: Internal helper function to perform failover or switchover actions.


Instruction:
How would you code a function in Python 3 to
rip - off of the ha. touch_member without inter - class dependencies

Response:
def touch_member(config, dcs):
    ''' Rip-off of the ha.touch_member without inter-class dependencies '''
    p = Postgresql(config['postgresql'])
    p.set_state('running')
    p.set_role('master')

    def restapi_connection_string(config):
        protocol = 'https' if config.get('certfile') else 'http'
        connect_address = config.get('connect_address')
        listen = config['listen']
        return '{0}://{1}/patroni'.format(protocol, connect_address or listen)

    data = {
        'conn_url': p.connection_string,
        'api_url': restapi_connection_string(config['restapi']),
        'state': p.state,
        'role': p.role
    }

    return dcs.touch_member(data, permanent=True)


Instruction:
Write a Python 3 script for
filling - in some basic configuration parameters if config file is not set

Response:
def set_defaults(config, cluster_name):
    """fill-in some basic configuration parameters if config file is not set """
    config['postgresql'].setdefault('name', cluster_name)
    config['postgresql'].setdefault('scope', cluster_name)
    config['postgresql'].setdefault('listen', '127.0.0.1')
    config['postgresql']['authentication'] = {'replication': None}
    config['restapi']['listen'] = ':' in config['restapi']['listen'] and config['restapi']['listen'] or '127.0.0.1:8008'


Instruction:
Implement a Python 3 function for
creating a temporary file with specified contents that persists for the context.

Response:
def temporary_file(contents, suffix='', prefix='tmp'):
    """Creates a temporary file with specified contents that persists for the context.

    :param contents: binary string that will be written to the file.
    :param prefix: will be prefixed to the filename.
    :param suffix: will be appended to the filename.
    :returns path of the created file.
    """
    tmp = tempfile.NamedTemporaryFile(suffix=suffix, prefix=prefix, delete=False)
    with tmp:
        tmp.write(contents)

    try:
        yield tmp.name
    finally:
        os.unlink(tmp.name)


Instruction:
How would you implement a function in Python 3 that
shows a diff between two strings.

Response:
def show_diff(before_editing, after_editing):
    """Shows a diff between two strings.

    If the output is to a tty the diff will be colored. Inputs are expected to be unicode strings.
    """
    def listify(string):
        return [l+'\n' for l in string.rstrip('\n').split('\n')]

    unified_diff = difflib.unified_diff(listify(before_editing), listify(after_editing))

    if sys.stdout.isatty():
        buf = io.StringIO()
        for line in unified_diff:
            # Force cast to unicode as difflib on Python 2.7 returns a mix of unicode and str.
            buf.write(text_type(line))
        buf.seek(0)

        class opts:
            side_by_side = False
            width = 80
            tab_width = 8
        cdiff.markup_to_pager(cdiff.PatchStream(buf), opts)
    else:
        for line in unified_diff:
            click.echo(line.rstrip('\n'))


Instruction:
Here you have a function in Python 3, explain what it does
def format_config_for_editing(data):
    return yaml.safe_dump(data, default_flow_style=False, encoding=None, allow_unicode=True)

Response: Formats the configuration as YAML for human consumption.


Instruction:
Make a summary of the following Python 3 code
def apply_config_changes(before_editing, data, kvpairs):
    changed_data = copy.deepcopy(data)

    def set_path_value(config, path, value, prefix=()):
        # Postgresql GUCs can't be nested, but can contain dots so we re-flatten the structure for this case
        if prefix == ('postgresql', 'parameters'):
            path = ['.'.join(path)]

        key = path[0]
        if len(path) == 1:
            if value is None:
                config.pop(key, None)
            else:
                config[key] = value
        else:
            if not isinstance(config.get(key), dict):
                config[key] = {}
            set_path_value(config[key], path[1:], value, prefix + (key,))
            if config[key] == {}:
                del config[key]

    for pair in kvpairs:
        if not pair or "=" not in pair:
            raise PatroniCtlException("Invalid parameter setting {0}".format(pair))
        key_path, value = pair.split("=", 1)
        set_path_value(changed_data, key_path.strip().split("."), yaml.safe_load(value))

    return format_config_for_editing(changed_data), changed_data

Response: Applies config changes specified as a list of key - value pairs.


Instruction:
How would you implement a function in Python 3 that
applies changes from a YAML file to the configuration datastructure

Response:
def apply_yaml_file(data, filename):
    """Applies changes from a YAML file to configuration

    :param data: configuration datastructure
    :param filename: name of the YAML file, - is taken to mean standard input
    :returns tuple of human readable and parsed datastructure after changes
    """
    changed_data = copy.deepcopy(data)

    if filename == '-':
        new_options = yaml.safe_load(sys.stdin)
    else:
        with open(filename) as fd:
            new_options = yaml.safe_load(fd)

    patch_config(changed_data, new_options)

    return format_config_for_editing(changed_data), changed_data


Instruction:
Can you write a function in Python 3 where it
invokes editor command to edit configuration in human readable format

Response:
def invoke_editor(before_editing, cluster_name):
    """Starts editor command to edit configuration in human readable format

    :param before_editing: human representation before editing
    :returns tuple of human readable and parsed datastructure after changes
    """
    editor_cmd = os.environ.get('EDITOR')
    if not editor_cmd:
        raise PatroniCtlException('EDITOR environment variable is not set')

    with temporary_file(contents=before_editing.encode('utf-8'),
                        suffix='.yaml',
                        prefix='{0}-config-'.format(cluster_name)) as tmpfile:
        ret = subprocess.call([editor_cmd, tmpfile])
        if ret:
            raise PatroniCtlException("Editor exited with return code {0}".format(ret))

        with codecs.open(tmpfile, encoding='utf-8') as fd:
            after_editing = fd.read()

        return after_editing, yaml.safe_load(after_editing)


Instruction:
Explain what the following Python 3 code does
def _tag_ebs(self, conn, role):
        tags = {'Name': 'spilo_' + self.cluster_name, 'Role': role, 'Instance': self.instance_id}
        volumes = conn.get_all_volumes(filters={'attachment.instance-id': self.instance_id})
        conn.create_tags([v.id for v in volumes], tags)

Response: set tags for the EBS storage


Instruction:
Can you generate the documentation for the following Python 3 function
def _tag_ec2(self, conn, role):
        tags = {'Role': role}
        conn.create_tags([self.instance_id], tags)

Response: tag the current EC2 instance with a cluster role


Instruction:
Can you generate the documentation for the following Python 3 function
def failover_limitation(self):
        if not self.reachable:
            return 'not reachable'
        if self.tags.get('nofailover', False):
            return 'not allowed to promote'
        if self.watchdog_failed:
            return 'not watchdog capable'
        return None

Response: Returns a string describing what the node can promote or None if everything is ok.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_effective_tags(self):
        tags = self.patroni.tags.copy()
        # _disable_sync could be modified concurrently, but we don't care as attribute get and set are atomic.
        if self._disable_sync > 0:
            tags['nosync'] = True
        return tags

Response: Return configuration tags merged with dynamically applied tags.


Instruction:
Can you generate the documentation for the following Python 3 function
def process_sync_replication(self):
        if self.is_synchronous_mode():
            current = self.cluster.sync.leader and self.cluster.sync.sync_standby
            picked, allow_promote = self.state_handler.pick_synchronous_standby(self.cluster)
            if picked != current:
                # We need to revoke privilege from current before replacing it in the config
                if current:
                    logger.info("Removing synchronous privilege from %s", current)
                    if not self.dcs.write_sync_state(self.state_handler.name, None, index=self.cluster.sync.index):
                        logger.info('Synchronous replication key updated by someone else.')
                        return

                if self.is_synchronous_mode_strict() and picked is None:
                    picked = '*'
                    logger.warning("No standbys available!")

                logger.info("Assigning synchronous standby status to %s", picked)
                self.state_handler.set_synchronous_standby(picked)

                if picked and picked != '*' and not allow_promote:
                    # Wait for PostgreSQL to enable synchronous mode and see if we can immediately set sync_standby
                    time.sleep(2)
                    picked, allow_promote = self.state_handler.pick_synchronous_standby(self.cluster)
                if allow_promote:
                    try:
                        cluster = self.dcs.get_cluster()
                    except DCSError:
                        return logger.warning("Could not get cluster state from DCS during process_sync_replication()")
                    if cluster.sync.leader and cluster.sync.leader != self.state_handler.name:
                        logger.info("Synchronous replication key updated by someone else")
                        return
                    if not self.dcs.write_sync_state(self.state_handler.name, picked, index=cluster.sync.index):
                        logger.info("Synchronous replication key updated by someone else")
                        return
                    logger.info("Synchronous standby status assigned to %s", picked)
        else:
            if self.cluster.sync.leader and self.dcs.delete_sync_state(index=self.cluster.sync.index):
                logger.info("Disabled synchronous replication")
            self.state_handler.set_synchronous_standby(None)

Response: Process synchronous standby and update the sync_standby state.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def while_not_sync_standby(self, func):

        if not self.is_synchronous_mode() or self.patroni.nosync:
            return func()

        with self._member_state_lock:
            self._disable_sync += 1
        try:
            if self.touch_member():
                # Master should notice the updated value during the next cycle. We will wait double that, if master
                # hasn't noticed the value by then not disabling sync replication is not likely to matter.
                for _ in polling_loop(timeout=self.dcs.loop_wait*2, interval=2):
                    try:
                        if not self.is_sync_standby(self.dcs.get_cluster()):
                            break
                    except DCSError:
                        logger.warning("Could not get cluster state, skipping synchronous standby disable")
                        break
                    logger.info("Waiting for master to release us from synchronous standby")
            else:
                logger.warning("Updating member state failed, skipping synchronous standby disable")

            return func()
        finally:
            with self._member_state_lock:
                self._disable_sync -= 1

Response: Runs specified action while the node is not assigned synchronous standby status.


Instruction:
Write a Python 3 function that can
return True if instance with an wal should be unhealthy due to replication lag.

Response:
def is_lagging(self, wal_position):
        """Returns if instance with an wal should consider itself unhealthy to be promoted due to replication lag.

        :param wal_position: Current wal position.
        :returns True when node is lagging
        """
        lag = (self.cluster.last_leader_operation or 0) - wal_position
        return lag > self.patroni.config.get('maximum_lag_on_failover', 0)


Instruction:
How would you code a function in Python 3 to
demote PostgreSQL running as master.

Response:
def demote(self, mode):
        """Demote PostgreSQL running as master.

        :param mode: One of offline, graceful or immediate.
            offline is used when connection to DCS is not available.
            graceful is used when failing over to another node due to user request. May only be called running async.
            immediate is used when we determine that we are not suitable for master and want to failover quickly
                without regard for data durability. May only be called synchronously.
            immediate-nolock is used when find out that we have lost the lock to be master. Need to bring down
                PostgreSQL as quickly as possible without regard for data durability. May only be called synchronously.
        """
        mode_control = {
            'offline':          dict(stop='fast', checkpoint=False, release=False, offline=True, async_req=False),
            'graceful':         dict(stop='fast', checkpoint=True, release=True, offline=False, async_req=False),
            'immediate':        dict(stop='immediate', checkpoint=False, release=True, offline=False, async_req=True),
            'immediate-nolock': dict(stop='immediate', checkpoint=False, release=False, offline=False, async_req=True),
        }[mode]

        self.state_handler.trigger_check_diverged_lsn()
        self.state_handler.stop(mode_control['stop'], checkpoint=mode_control['checkpoint'],
                                on_safepoint=self.watchdog.disable if self.watchdog.is_running else None)
        self.state_handler.set_role('demoted')
        self.set_is_leader(False)

        if mode_control['release']:
            with self._async_executor:
                self.release_leader_key_voluntarily()
            time.sleep(2)  # Give a time to somebody to take the leader lock
        if mode_control['offline']:
            node_to_follow, leader = None, None
        else:
            cluster = self.dcs.get_cluster()
            node_to_follow, leader = self._get_node_to_follow(cluster), cluster.leader

        # FIXME: with mode offline called from DCS exception handler and handle_long_action_in_progress
        # there could be an async action already running, calling follow from here will lead
        # to racy state handler state updates.
        if mode_control['async_req']:
            self._async_executor.schedule('starting after demotion')
            self._async_executor.run_async(self.state_handler.follow, (node_to_follow,))
        else:
            if self.is_synchronous_mode():
                self.state_handler.set_synchronous_standby(None)
            if self.state_handler.rewind_or_reinitialize_needed_and_possible(leader):
                return False  # do not start postgres, but run pg_rewind on the next iteration
            self.state_handler.follow(node_to_follow)


Instruction:
Can you tell what is the following Python 3 function doing
def process_manual_failover_from_leader(self):
        failover = self.cluster.failover
        if not failover or (self.is_paused() and not self.state_handler.is_leader()):
            return

        if (failover.scheduled_at and not
            self.should_run_scheduled_action("failover", failover.scheduled_at, lambda:
                                             self.dcs.manual_failover('', '', index=failover.index))):
            return

        if not failover.leader or failover.leader == self.state_handler.name:
            if not failover.candidate or failover.candidate != self.state_handler.name:
                if not failover.candidate and self.is_paused():
                    logger.warning('Failover is possible only to a specific candidate in a paused state')
                else:
                    if self.is_synchronous_mode():
                        if failover.candidate and not self.cluster.sync.matches(failover.candidate):
                            logger.warning('Failover candidate=%s does not match with sync_standby=%s',
                                           failover.candidate, self.cluster.sync.sync_standby)
                            members = []
                        else:
                            members = [m for m in self.cluster.members if self.cluster.sync.matches(m.name)]
                    else:
                        members = [m for m in self.cluster.members
                                   if not failover.candidate or m.name == failover.candidate]
                    if self.is_failover_possible(members):  # check that there are healthy members
                        self._async_executor.schedule('manual failover: demote')
                        self._async_executor.run_async(self.demote, ('graceful',))
                        return 'manual failover: demoting myself'
                    else:
                        logger.warning('manual failover: no healthy members found, failover is not possible')
            else:
                logger.warning('manual failover: I am already the leader, no need to failover')
        else:
            logger.warning('manual failover: leader name does not match: %s != %s',
                           failover.leader, self.state_handler.name)

        logger.info('Cleaning up failover key')
        self.dcs.manual_failover('', '', index=failover.index)

Response: Checks if manual failover is requested and takes action if appropriate.


Instruction:
Can you write a function in Python 3 where it
clusters has no leader key

Response:
def process_unhealthy_cluster(self):
        """Cluster has no leader key"""

        if self.is_healthiest_node():
            if self.acquire_lock():
                failover = self.cluster.failover
                if failover:
                    if self.is_paused() and failover.leader and failover.candidate:
                        logger.info('Updating failover key after acquiring leader lock...')
                        self.dcs.manual_failover('', failover.candidate, failover.scheduled_at, failover.index)
                    else:
                        logger.info('Cleaning up failover key after acquiring leader lock...')
                        self.dcs.manual_failover('', '')
                self.load_cluster_from_dcs()

                if self.is_standby_cluster():
                    # standby leader disappeared, and this is a healthiest
                    # replica, so it should become a new standby leader.
                    # This imply that we need to start following a remote master
                    msg = 'promoted self to a standby leader by acquiring session lock'
                    return self.enforce_follow_remote_master(msg)
                else:
                    return self.enforce_master_role(
                        'acquired session lock as a leader',
                        'promoted self to leader by acquiring session lock'
                    )
            else:
                return self.follow('demoted self after trying and failing to obtain lock',
                                   'following new leader after trying and failing to obtain lock')
        else:
            # when we are doing manual failover there is no guaranty that new leader is ahead of any other node
            # node tagged as nofailover can be ahead of the new leader either, but it is always excluded from elections
            if bool(self.cluster.failover) or self.patroni.nofailover:
                self.state_handler.trigger_check_diverged_lsn()
                time.sleep(2)  # Give a time to somebody to take the leader lock

            if self.patroni.nofailover:
                return self.follow('demoting self because I am not allowed to become master',
                                   'following a different leader because I am not allowed to promote')
            return self.follow('demoting self because i am not the healthiest node',
                               'following a different leader because i am not the healthiest node')


Instruction:
Make a summary of the following Python 3 code
def restart(self, restart_data, run_async=False):
        assert isinstance(restart_data, dict)

        if (not self.restart_matches(restart_data.get('role'),
                                     restart_data.get('postgres_version'),
                                     ('restart_pending' in restart_data))):
            return (False, "restart conditions are not satisfied")

        with self._async_executor:
            prev = self._async_executor.schedule('restart')
            if prev is not None:
                return (False, prev + ' already in progress')

            # Make the main loop to think that we were recovering dead postgres. If we fail
            # to start postgres after a specified timeout (see below), we need to remove
            # leader key (if it belong to us) rather than trying to start postgres once again.
            self.recovering = True

        # Now that restart is scheduled we can set timeout for startup, it will get reset
        # once async executor runs and main loop notices PostgreSQL as up.
        timeout = restart_data.get('timeout', self.patroni.config['master_start_timeout'])
        self.set_start_timeout(timeout)

        # For non async cases we want to wait for restart to complete or timeout before returning.
        do_restart = functools.partial(self.state_handler.restart, timeout, self._async_executor.critical_task)
        if self.is_synchronous_mode() and not self.has_lock():
            do_restart = functools.partial(self.while_not_sync_standby, do_restart)

        if run_async:
            self._async_executor.run_async(do_restart)
            return (True, 'restart initiated')
        else:
            res = self._async_executor.run(do_restart)
            if res:
                return (True, 'restarted successfully')
            elif res is None:
                return (False, 'postgres is still starting')
            else:
                return (False, 'restart failed')

Response: Restart the dead postgres.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def handle_starting_instance(self):

        # Check if we are in startup, when paused defer to main loop for manual failovers.
        if not self.state_handler.check_for_startup() or self.is_paused():
            self.set_start_timeout(None)
            if self.is_paused():
                self.state_handler.set_state(self.state_handler.is_running() and 'running' or 'stopped')
            return None

        # state_handler.state == 'starting' here
        if self.has_lock():
            if not self.update_lock():
                logger.info("Lost lock while starting up. Demoting self.")
                self.demote('immediate-nolock')
                return 'stopped PostgreSQL while starting up because leader key was lost'

            timeout = self._start_timeout or self.patroni.config['master_start_timeout']
            time_left = timeout - self.state_handler.time_in_state()

            if time_left <= 0:
                if self.is_failover_possible(self.cluster.members):
                    logger.info("Demoting self because master startup is taking too long")
                    self.demote('immediate')
                    return 'stopped PostgreSQL because of startup timeout'
                else:
                    return 'master start has timed out, but continuing to wait because failover is not possible'
            else:
                msg = self.process_manual_failover_from_leader()
                if msg is not None:
                    return msg

                return 'PostgreSQL is still starting up, {0:.0f} seconds until timeout'.format(time_left)
        else:
            # Use normal processing for standbys
            logger.info("Still starting up as a standby.")
            return None

Response: This method handles the starting instance of a PostgreSQL instance.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_remote_member(self, member=None):
        cluster_params = self.get_standby_cluster_config()

        if cluster_params:
            name = member.name if member else 'remote_master:{}'.format(uuid.uuid1())

            data = {k: v for k, v in cluster_params.items() if k in RemoteMember.allowed_keys()}
            data['no_replication_slot'] = 'primary_slot_name' not in cluster_params
            conn_kwargs = member.conn_kwargs() if member else \
                {k: cluster_params[k] for k in ('host', 'port') if k in cluster_params}
            if conn_kwargs:
                data['conn_kwargs'] = conn_kwargs

            return RemoteMember(name, data)

Response: Returns RemoteMember object for given member.


Instruction:
Given the following Python 3 function, write the documentation
def _get_machines_cache_from_srv(self, srv):

        ret = []
        for r in ['-client-ssl', '-client', '-ssl', '', '-server-ssl', '-server']:
            protocol = 'https' if '-ssl' in r else 'http'
            endpoint = '/members' if '-server' in r else ''
            for host, port in self.get_srv_record('_etcd{0}._tcp.{1}'.format(r, srv)):
                url = uri(protocol, host, port, endpoint)
                if endpoint:
                    try:
                        response = requests.get(url, timeout=self.read_timeout, verify=False)
                        if response.ok:
                            for member in response.json():
                                ret.extend(member['clientURLs'])
                            break
                    except RequestException:
                        logger.exception('GET %s', url)
                else:
                    ret.append(url)
            if ret:
                self._protocol = protocol
                break
        else:
            logger.warning('Can not resolve SRV for %s', srv)
        return list(set(ret))

Response: Fetch list of machines cache entries by resolving _etcd - server. _tcp. SRV record.


Instruction:
Create a Python 3 function for
getting a list of machines cache entries from a DNS host and port.

Response:
def _get_machines_cache_from_dns(self, host, port):
        """One host might be resolved into multiple ip addresses. We will make list out of it"""
        if self.protocol == 'http':
            ret = []
            for af, _, _, _, sa in self._dns_resolver.resolve(host, port):
                host, port = sa[:2]
                if af == socket.AF_INET6:
                    host = '[{0}]'.format(host)
                ret.append(uri(self.protocol, host, port))
            if ret:
                return list(set(ret))
        return [uri(self.protocol, host, port)]


Instruction:
Implement a Python 3 function for
building and executes pg_ctl command

Response:
def pg_ctl(self, cmd, *args, **kwargs):
        """Builds and executes pg_ctl command

        :returns: `!True` when return_code == 0, otherwise `!False`"""

        pg_ctl = [self._pgcommand('pg_ctl'), cmd]
        return subprocess.call(pg_ctl + ['-D', self._data_dir] + list(args), **kwargs) == 0


Instruction:
Explain what the following Python 3 code does
def pg_isready(self):

        cmd = [self._pgcommand('pg_isready'), '-p', self._local_address['port'], '-d', self._database]

        # Host is not set if we are connecting via default unix socket
        if 'host' in self._local_address:
            cmd.extend(['-h', self._local_address['host']])

        # We only need the username because pg_isready does not try to authenticate
        if 'username' in self._superuser:
            cmd.extend(['-U', self._superuser['username']])

        ret = subprocess.call(cmd)
        return_codes = {0: STATE_RUNNING,
                        1: STATE_REJECT,
                        2: STATE_NO_RESPONSE,
                        3: STATE_UNKNOWN}
        return return_codes.get(ret, STATE_UNKNOWN)

Response: Runs pg_isready to see if PostgreSQL is accepting connections.


Instruction:
Make a summary of the following Python 3 code
def can_rewind(self):
        # low-hanging fruit: check if pg_rewind configuration is there
        if not self.config.get('use_pg_rewind'):
            return False

        cmd = [self._pgcommand('pg_rewind'), '--help']
        try:
            ret = subprocess.call(cmd, stdout=open(os.devnull, 'w'), stderr=subprocess.STDOUT)
            if ret != 0:  # pg_rewind is not there, close up the shop and go home
                return False
        except OSError:
            return False
        return self.configuration_allows_rewind(self.controldata())

Response:
check if pg_rewind executable is there and that wal_log_hints and checksums turned on
            return True if it is possible to revert the archive


Instruction:
How would you implement a function in Python 3 that
executes a query and return the cursor.

Response:
def _query(self, sql, *params):
        """We are always using the same cursor, therefore this method is not thread-safe!!!
        You can call it from different threads only if you are holding explicit `AsyncExecutor` lock,
        because the main thread is always holding this lock when running HA cycle."""
        cursor = None
        try:
            cursor = self._cursor()
            cursor.execute(sql, params)
            return cursor
        except psycopg2.Error as e:
            if cursor and cursor.connection.closed == 0:
                # When connected via unix socket, psycopg2 can't recoginze 'connection lost'
                # and leaves `_cursor_holder.connection.closed == 0`, but psycopg2.OperationalError
                # is still raised (what is correct). It doesn't make sense to continiue with existing
                # connection and we will close it, to avoid its reuse by the `_cursor` method.
                if isinstance(e, psycopg2.OperationalError):
                    self.close_connection()
                else:
                    raise e
            if self.state == 'restarting':
                raise RetryFailedError('cluster is being restarted')
            raise PostgresConnectionException('connection problems')


Instruction:
Explain what the following Python 3 code does
def run_bootstrap_post_init(self, config):
        cmd = config.get('post_bootstrap') or config.get('post_init')
        if cmd:
            r = self._local_connect_kwargs

            if 'host' in r:
                # '/tmp' => '%2Ftmp' for unix socket path
                host = quote_plus(r['host']) if r['host'].startswith('/') else r['host']
            else:
                host = ''

                # https://www.postgresql.org/docs/current/static/libpq-pgpass.html
                # A host name of localhost matches both TCP (host name localhost) and Unix domain socket
                # (pghost empty or the default socket directory) connections coming from the local machine.
                r['host'] = 'localhost'  # set it to localhost to write into pgpass

            if 'user' in r:
                user = r['user'] + '@'
            else:
                user = ''
                if 'password' in r:
                    import getpass
                    r.setdefault('user', os.environ.get('PGUSER', getpass.getuser()))

            connstring = 'postgres://{0}{1}:{2}/{3}'.format(user, host, r['port'], r['database'])
            env = self.write_pgpass(r) if 'password' in r else None

            try:
                ret = self.cancellable_subprocess_call(shlex.split(cmd) + [connstring], env=env)
            except OSError:
                logger.error('post_init script %s failed', cmd)
                return False
            if ret != 0:
                logger.error('post_init script %s returned non-zero code %d', cmd, ret)
                return False
        return True

Response: Runs a script after initdb or custom bootstrap script is called and waits until completion.


Instruction:
How would you code a function in Python 3 to
return True if there is one that does not require a replication connection.

Response:
def can_create_replica_without_replication_connection(self):
        """ go through the replication methods to see if there are ones
            that does not require a working replication connection.
        """
        replica_methods = self._create_replica_methods
        return any(self.replica_method_can_work_without_replication_connection(method) for method in replica_methods)


Instruction:
Explain what the following Python 3 code does
def create_replica(self, clone_member):

        self.set_state('creating replica')
        self._sysid = None

        is_remote_master = isinstance(clone_member, RemoteMember)
        create_replica_methods = is_remote_master and clone_member.create_replica_methods

        # get list of replica methods either from clone member or from
        # the config. If there is no configuration key, or no value is
        # specified, use basebackup
        replica_methods = (
            create_replica_methods
            or self._create_replica_methods
            or ['basebackup']
        )

        if clone_member and clone_member.conn_url:
            r = clone_member.conn_kwargs(self._replication)
            connstring = 'postgres://{user}@{host}:{port}/{database}'.format(**r)
            # add the credentials to connect to the replica origin to pgpass.
            env = self.write_pgpass(r)
        else:
            connstring = ''
            env = os.environ.copy()
            # if we don't have any source, leave only replica methods that work without it
            replica_methods = \
                [r for r in replica_methods if self.replica_method_can_work_without_replication_connection(r)]

        # go through them in priority order
        ret = 1
        for replica_method in replica_methods:
            with self._cancellable_lock:
                if self._is_cancelled:
                    break
            # if the method is basebackup, then use the built-in
            if replica_method == "basebackup":
                ret = self.basebackup(connstring, env, self.config.get(replica_method, {}))
                if ret == 0:
                    logger.info("replica has been created using basebackup")
                    # if basebackup succeeds, exit with success
                    break
            else:
                if not self.data_directory_empty():
                    if self.config.get(replica_method, {}).get('keep_data', False):
                        logger.info('Leaving data directory uncleaned')
                    else:
                        self.remove_data_directory()

                cmd = replica_method
                method_config = {}
                # user-defined method; check for configuration
                # not required, actually
                if self.config.get(replica_method, {}):
                    method_config = self.config[replica_method].copy()
                    # look to see if the user has supplied a full command path
                    # if not, use the method name as the command
                    cmd = method_config.pop('command', cmd)

                # add the default parameters
                if not method_config.get('no_params', False):
                    method_config.update({"scope": self.scope,
                                          "role": "replica",
                                          "datadir": self._data_dir,
                                          "connstring": connstring})
                else:
                    for param in ('no_params', 'no_master', 'keep_data'):
                        method_config.pop(param, None)
                params = ["--{0}={1}".format(arg, val) for arg, val in method_config.items()]
                try:
                    # call script with the full set of parameters
                    ret = self.cancellable_subprocess_call(shlex.split(cmd) + params, env=env)
                    # if we succeeded, stop
                    if ret == 0:
                        logger.info('replica has been created using %s', replica_method)
                        break
                    else:
                        logger.error('Error creating replica using method %s: %s exited with code=%s',
                                     replica_method, cmd, ret)
                except Exception:
                    logger.exception('Error creating replica using method %s', replica_method)
                    ret = 1

        self.set_state('stopped')
        return ret

Response: create the replica according to the replica_method_can_work_without_replication_connection method.


Instruction:
How would you explain what the following Python 3 function does
def is_running(self):
        if self._postmaster_proc:
            if self._postmaster_proc.is_running():
                return self._postmaster_proc
            self._postmaster_proc = None

        # we noticed that postgres was restarted, force syncing of replication
        self._schedule_load_slots = self.use_slots

        self._postmaster_proc = PostmasterProcess.from_pidfile(self._data_dir)
        return self._postmaster_proc

Response:
Returns the most recently seen process
        if one is running or None. If no process is running updates the cached process based on pid file.


Instruction:
Write a Python 3 function that can
call a callback command without waiting for it to finish

Response:
def call_nowait(self, cb_name):
        """ pick a callback command and call it without waiting for it to finish """
        if self.bootstrapping:
            return
        if cb_name in (ACTION_ON_START, ACTION_ON_STOP, ACTION_ON_RESTART, ACTION_ON_ROLE_CHANGE):
            self.__cb_called = True

        if self.callback and cb_name in self.callback:
            cmd = self.callback[cb_name]
            try:
                cmd = shlex.split(self.callback[cb_name]) + [cb_name, self.role, self.scope]
                self._callback_executor.call(cmd)
            except Exception:
                logger.exception('callback %s %s %s %s failed', cmd, cb_name, self.role, self.scope)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def wait_for_port_open(self, postmaster, timeout):
        for _ in polling_loop(timeout):
            with self._cancellable_lock:
                if self._is_cancelled:
                    return False

            if not postmaster.is_running():
                logger.error('postmaster is not running')
                self.set_state('start failed')
                return False

            isready = self.pg_isready()
            if isready != STATE_NO_RESPONSE:
                if isready not in [STATE_REJECT, STATE_RUNNING]:
                    logger.warning("Can't determine PostgreSQL startup status, assuming running")
                return True

        logger.warning("Timed out waiting for PostgreSQL to start")
        return False

Response: Waits until PostgreSQL opens ports. Returns True if successful False otherwise.


Instruction:
Write a Python 3 function for
building the effective configuration dictionary from the server parameters and controldata.

Response:
def _build_effective_configuration(self):
        """It might happen that the current value of one (or more) below parameters stored in
        the controldata is higher than the value stored in the global cluster configuration.

        Example: max_connections in global configuration is 100, but in controldata
        `Current max_connections setting: 200`. If we try to start postgres with
        max_connections=100, it will immediately exit.
        As a workaround we will start it with the values from controldata and set `pending_restart`
        to true as an indicator that current values of parameters are not matching expectations."""

        OPTIONS_MAPPING = {
            'max_connections': 'max_connections setting',
            'max_prepared_transactions': 'max_prepared_xacts setting',
            'max_locks_per_transaction': 'max_locks_per_xact setting'
        }

        if self._major_version >= 90400:
            OPTIONS_MAPPING['max_worker_processes'] = 'max_worker_processes setting'

        data = self.controldata()
        effective_configuration = self._server_parameters.copy()

        for name, cname in OPTIONS_MAPPING.items():
            value = parse_int(effective_configuration[name])
            cvalue = parse_int(data[cname])
            if cvalue > value:
                effective_configuration[name] = cvalue
                self._pending_restart = True
        return effective_configuration


Instruction:
Implement a Python 3 function for
starting a PostgreSQL server.

Response:
def start(self, timeout=None, task=None, block_callbacks=False, role=None):
        """Start PostgreSQL

        Waits for postmaster to open ports or terminate so pg_isready can be used to check startup completion
        or failure.

        :returns: True if start was initiated and postmaster ports are open, False if start failed"""
        # make sure we close all connections established against
        # the former node, otherwise, we might get a stalled one
        # after kill -9, which would report incorrect data to
        # patroni.
        self.close_connection()

        if self.is_running():
            logger.error('Cannot start PostgreSQL because one is already running.')
            self.set_state('starting')
            return True

        if not block_callbacks:
            self.__cb_pending = ACTION_ON_START

        self.set_role(role or self.get_postgres_role_from_data_directory())

        self.set_state('starting')
        self._pending_restart = False

        configuration = self._server_parameters if self.role == 'master' else self._build_effective_configuration()
        self._write_postgresql_conf(configuration)
        self.resolve_connection_addresses()
        self._replace_pg_hba()
        self._replace_pg_ident()

        options = ['--{0}={1}'.format(p, configuration[p]) for p in self.CMDLINE_OPTIONS
                   if p in configuration and p != 'wal_keep_segments']

        with self._cancellable_lock:
            if self._is_cancelled:
                return False

        with task or null_context():
            if task and task.is_cancelled:
                logger.info("PostgreSQL start cancelled.")
                return False

            self._postmaster_proc = PostmasterProcess.start(self._pgcommand('postgres'),
                                                            self._data_dir,
                                                            self._postgresql_conf,
                                                            options)

            if task:
                task.complete(self._postmaster_proc)

        start_timeout = timeout
        if not start_timeout:
            try:
                start_timeout = float(self.config.get('pg_ctl_timeout', 60))
            except ValueError:
                start_timeout = 60

        # We want postmaster to open ports before we continue
        if not self._postmaster_proc or not self.wait_for_port_open(self._postmaster_proc, start_timeout):
            return False

        ret = self.wait_for_startup(start_timeout)
        if ret is not None:
            return ret
        elif timeout is not None:
            return False
        else:
            return None


Instruction:
How would you implement a function in Python 3 that
stops the PostgreSQL node.

Response:
def stop(self, mode='fast', block_callbacks=False, checkpoint=None, on_safepoint=None):
        """Stop PostgreSQL

        Supports a callback when a safepoint is reached. A safepoint is when no user backend can return a successful
        commit to users. Currently this means we wait for user backends to close. But in the future alternate mechanisms
        could be added.

        :param on_safepoint: This callback is called when no user backends are running.
        """
        if checkpoint is None:
            checkpoint = False if mode == 'immediate' else True

        success, pg_signaled = self._do_stop(mode, block_callbacks, checkpoint, on_safepoint)
        if success:
            # block_callbacks is used during restart to avoid
            # running start/stop callbacks in addition to restart ones
            if not block_callbacks:
                self.set_state('stopped')
                if pg_signaled:
                    self.call_nowait(ACTION_ON_STOP)
        else:
            logger.warning('pg_ctl stop failed')
            self.set_state('stop failed')
        return success


Instruction:
Explain what the following Python 3 code does
def check_startup_state_changed(self):
        ready = self.pg_isready()

        if ready == STATE_REJECT:
            return False
        elif ready == STATE_NO_RESPONSE:
            self.set_state('start failed')
            self._schedule_load_slots = False  # TODO: can remove this?
            if not self._running_custom_bootstrap:
                self.save_configuration_files()  # TODO: maybe remove this?
            return True
        else:
            if ready != STATE_RUNNING:
                # Bad configuration or unexpected OS error. No idea of PostgreSQL status.
                # Let the main loop of run cycle clean up the mess.
                logger.warning("%s status returned from pg_isready",
                               "Unknown" if ready == STATE_UNKNOWN else "Invalid")
            self.set_state('running')
            self._schedule_load_slots = self.use_slots
            if not self._running_custom_bootstrap:
                self.save_configuration_files()
            # TODO: __cb_pending can be None here after PostgreSQL restarts on its own. Do we want to call the callback?
            # Previously we didn't even notice.
            action = self.__cb_pending or ACTION_ON_START
            self.call_nowait(action)
            self.__cb_pending = None

            return True

Response: Checks if PostgreSQL has completed starting up or failed or still starting. Returns True if state was changed from starting False otherwise.


Instruction:
How would you code a function in Python 3 to
wait for PostgreSQL startup to complete or fail.

Response:
def wait_for_startup(self, timeout=None):
        """Waits for PostgreSQL startup to complete or fail.

        :returns: True if start was successful, False otherwise"""
        if not self.is_starting():
            # Should not happen
            logger.warning("wait_for_startup() called when not in starting state")

        while not self.check_startup_state_changed():
            with self._cancellable_lock:
                if self._is_cancelled:
                    return None
            if timeout and self.time_in_state() > timeout:
                return None
            time.sleep(1)

        return self.state == 'running'


Instruction:
How would you explain what the following Python 3 function does
def restart(self, timeout=None, task=None, block_callbacks=False, role=None):
        self.set_state('restarting')
        if not block_callbacks:
            self.__cb_pending = ACTION_ON_RESTART
        ret = self.stop(block_callbacks=True) and self.start(timeout, task, True, role)
        if not ret and not self.is_starting():
            self.set_state('restart failed ({0})'.format(self.state))
        return ret

Response: Restarts the PostgreSQL instance.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _replace_pg_hba(self):

        # when we are doing custom bootstrap we assume that we don't know superuser password
        # and in order to be able to change it, we are opening trust access from a certain address
        if self._running_custom_bootstrap:
            addresses = {'': 'local'}
            if 'host' in self._local_address and not self._local_address['host'].startswith('/'):
                for _, _, _, _, sa in socket.getaddrinfo(self._local_address['host'], self._local_address['port'],
                                                         0, socket.SOCK_STREAM, socket.IPPROTO_TCP):
                    addresses[sa[0] + '/32'] = 'host'

            with open(self._pg_hba_conf, 'w') as f:
                f.write(self._CONFIG_WARNING_HEADER)
                for address, t in addresses.items():
                    f.write((
                        '{0}\treplication\t{1}\t{3}\ttrust\n'
                        '{0}\tall\t{2}\t{3}\ttrust\n'
                    ).format(t, self._replication['username'], self._superuser.get('username') or 'all', address))
        elif not self._server_parameters.get('hba_file') and self.config.get('pg_hba'):
            with open(self._pg_hba_conf, 'w') as f:
                f.write(self._CONFIG_WARNING_HEADER)
                for line in self.config['pg_hba']:
                    f.write('{0}\n'.format(line))
            return True

Response: Replace pg_hba. conf content in PGDATA if pg_hba. conf is not defined in the postgresql. parameters section and pg_hba is defined in the postgresql. parameters section.