<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:

def job_list():
    '''List all jobs.

    :param _limit: maximum number of jobs to show (default 100)
    :type _limit: int
    :param _offset: how many jobs to skip before showin the first one (default 0)
    :type _offset: int
    :param _status: filter jobs by status (complete, error)
    :type _status: string

    Also, you can filter the jobs by their metadata. Use the metadata key
    as parameter key and the value as value.

    :rtype: A list of job ids
    '''
    args = dict((key, value) for key, value in flask.request.args.items())
    limit = args.pop('_limit', 100)
    offset = args.pop('_offset', 0)

    select = sql.select(
        [db.JOBS_TABLE.c.job_id],
        from_obj=[db.JOBS_TABLE.outerjoin(
            db.METADATA_TABLE,
            db.JOBS_TABLE.c.job_id == db.METADATA_TABLE.c.job_id)
        ]).\
        group_by(db.JOBS_TABLE.c.job_id).\
        order_by(db.JOBS_TABLE.c.requested_timestamp.desc()).\
        limit(limit).offset(offset)

    status = args.pop('_status', None)
    if status:
        select = select.where(db.JOBS_TABLE.c.status == status)

    ors = []
    for key, value in args.iteritems():
        # Turn strings into unicode to stop SQLAlchemy
        # "Unicode type received non-unicode bind param value" warnings.
        key = unicode(key)

        ors.append(sql.and_(db.METADATA_TABLE.c.key == key,
                   db.METADATA_TABLE.c.value == value))

    if ors:
        select = select.where(sql.or_(*ors))
        select = select.having(
            sql.func.count(db.JOBS_TABLE.c.job_id) == len(ors)
        )

    result = db.ENGINE.execute(select)
    listing = []
    for (job_id,) in result:
        listing.append(flask.url_for('job_status', job_id=job_id))

    return flask.jsonify(list=listing)