def post(self):
        """**Create a Quest entry**

        **Example Request:**

        .. sourcecode:: http

            POST /api/v1/quests HTTP/1.1
            Host: localhost
            Content-Type: application/json
            {
                "fateId": 1,
                "creator": "johnny",
                "targetTime": timestamp,
                "description": "This is a quest almighty",
                "hostnames": [],
                "hostQuery": "tag=value"
            }

        **Example response:**

        .. sourcecode:: http

            HTTP/1.1 201 OK
            Location: /api/v1/hosts/example

            {
                "status": "created",
                "id": 1,
                "href": "/api/v1/quests/1",
                "creator": "johnny",
                "embarkTime": timestamp,
                "targetTime": timestamp,
                "completionTime": timestamp,
                "description": "This is a quest almighty",
                "labors": [],
            }

        :reqjson int eventTypeId: the ID of the EventType to for the Events that will be thrown in the creation of this Quest
        :regjson string creator: the user creating this Quest
        :regjson array hostnames: the array of hostnames that will be part of this Quest
        :regjson string hostQuery: the query to send to the plugin to come up with the list of hostnames that will be part of this Quest
        :regjson string description: The human readable description this Quest
        :regjson timestamp targetTime: (*optional*) The target date for the completion of this Quest

        :reqheader Content-Type: The server expects a json body specified with
                                 this header.

        :resheader Location: URL to the created resource.

        :statuscode 201: The Quest was successfully created.
        :statuscode 400: The request was malformed.
        :statuscode 401: The request was made without being logged in.
        :statuscode 409: There was a conflict with another resource.

        """

        tx = id_generator()

        log.info("QUEST [{}]: Creating a new quest".format(tx))

        try:
            fate_id = self.jbody["fateId"]
            creator = self.jbody["creator"]
            if not EMAIL_REGEX.match(creator):
                creator += "@" + self.domain
            description = self.jbody["description"]
            hostnames = self.jbody.get("hostnames") or []

            if "targetTime" in self.jbody:
                target_time = parser.parse(
                    self.jbody["targetTime"]
                )
                target_time = target_time.replace(tzinfo=None)
                if target_time <= datetime.utcnow():
                    raise exc.BadRequest(
                        "Quest target date must be in future"
                    )
            else:
                target_time = None
        except KeyError as err:
            raise exc.BadRequest(
                "Missing Required Argument: {}".format(err.message)
            )
        except ValueError as err:
            raise exc.BadRequest(err.message)

        log.info(
            "QUEST [{}]: {} creating quest with fate {} for hosts {}".format(
                tx, creator, fate_id, ", ".join(hostnames)
            )
        )

        fate = (
            self.session.query(Fate).get(fate_id)
        )

        if fate is None:
            self.write_error(400, message="Bad fate id {}".format(fate_id))
            return

        # If a host query was specified, we need to talk to the external
        # query server to resolve this into a list of hostnames
        if self.jbody in "hostQuery":
            query = self.jbody["hostQuery"]
            response = PluginHelper.request_get(params={"query": query})
            if response.json()["status"] == "ok":
                hostnames.extend(response.json()["results"])
                log.info(
                    "QUEST [{}]: Hostnames after query: {}".format(
                        tx, ", ".join(hostnames)
                    )
                )

        # We need to create a list of hostnames that don't have a Host record
        new_hosts_needed = list(hostnames)
        hosts = (
            self.session.query(Host).filter(Host.hostname.in_(hostnames)).all()
        )
        for host in hosts:
            new_hosts_needed.remove(str(host.hostname))

        # if we need to create hosts, do them all at once
        if new_hosts_needed:
            Host.create_many(self.session, new_hosts_needed)
            hosts = (
                self.session.query(Host).filter(
                    Host.hostname.in_(hostnames)
                ).all()
            )

        log.info("QUEST [{}]: Working with {} hosts".format(tx, len(hosts)))

        if len(hosts) == 0:
            raise exc.BadRequest("No hosts found with given list")

        try:
            quest = Quest.create(
                self.session, creator, hosts, target_time, fate_id=fate_id,
                description=description
            )
        except IntegrityError as err:
            raise exc.Conflict(err.orig.message)
        except exc.ValidationError as err:
            raise exc.BadRequest(err.message)

        self.session.flush()
        self.session.commit()

        json = quest.to_dict(self.href_prefix)

        json["labors"] = (
            [labor.to_dict(self.href_prefix)
             for labor in quest.get_open_labors()]
        )

        self.created("/api/v1/quests/{}".format(quest.id), json)

        log.info(
            "QUEST [{}]: Created quest {}".format(tx, quest.id)
        )
dataset/ETHPy150Open dropbox/hermes/hermes/handlers/api.py/QuestsHandler.post/swapped operands of `in`