'Cast a vote on a thing.
`id` should be the fullname of the Link or Comment to vote on.
`dir` indicates the direction of the vote. Voting `1` is an upvote,
`-1` is a downvote, and `0` is equivalent to "un-voting" by clicking
again on a highlighted arrow.
**Note: votes must be cast by humans.** That is, API clients proxying a
human\'s action one-for-one are OK, but bots deciding how to vote on
content or amplifying a human\'s vote are not. See [the reddit
rules](/rules) for more details on what constitutes vote cheating.'

@require_oauth2_scope('vote')
@noresponse(VUser(), VModhash(), direction=VInt('dir', min=(-1), max=1, docs={'dir': 'vote    direction.    one    of    (1,    0,    -1)'}), thing=VByName('id'), rank=VInt('rank', min=1))
@api_doc(api_section.links_and_comments)
def POST_vote(self, direction, thing, rank):

    feature.is_enabled('persistent_vote_a_a')
    if ((not thing) or thing._deleted):
        return self.abort404()
    if (not thing.is_votable):
        abort(400, "That    type    of    thing    can't    be    voted    on.")
    hooks.get_hook('vote.validate').call(thing=thing)
    if (isinstance(thing, Link) and promote.is_promo(thing)):
        if (not promote.is_promoted(thing)):
            return abort(400, 'Bad    Request')
    if thing.archived_slow:
        return abort(400, 'This    thing    is    archived    and    may    no    longer    be    voted    on')
    VNotInTimeout().run(target=thing)
    if (direction == 1):
        direction = Vote.DIRECTIONS.up
    elif (direction == (-1)):
        direction = Vote.DIRECTIONS.down
    elif (direction == 0):
        direction = Vote.DIRECTIONS.unvote
    cast_vote(c.user, thing, direction, rank=rank)
