<commit_before>from datetime import datetime
from flask import jsonify, abort, request
from flask import url_for as base_url_for
from sqlalchemy.exc import IntegrityError, DatabaseError

from . import main
from .. import db
from ..models import Service, ServiceArchive
from ..validation import validate_json_or_400, validate_updater_json_or_400


API_FETCH_PAGE_SIZE = 100


@main.route('/')
def index():
    """Entry point for the API, show the resources that are available."""
    return jsonify(links=[
        {
            "rel": "services.list",
            "href": url_for('.list_services', _external=True)
        }
    ]), 200


@main.route('/services', methods=['GET'])
def list_services():
    try:
        page = int(request.args.get('page', 1))
    except ValueError:
        abort(400, "Invalid page argument")

    supplier_id = request.args.get('supplier_id')

    services = Service.query
    if supplier_id is not None:
        try:
            supplier_id = int(supplier_id)
        except ValueError:
            abort(400, "Invalid supplier_id")
        services = services.filter(Service.supplier_id == supplier_id)

    services = services.paginate(page=page, per_page=API_FETCH_PAGE_SIZE,
                                 error_out=False)
    if request.args and not services.items:
        abort(404)
    return jsonify(
        services=list(map(jsonify_service, services.items)),
        links=pagination_links(services, '.list_services', request.args))


@main.route('/services-archive', methods=['GET'])
def list_archived_services_by_service_id():
    """
    Retrieves a list of services from the service_archive table
    for the supplied service_id
    :query_param service_id:
    :return: List[service]
    """

    try:
        service_id = int(request.args.get("service-id", "no service id"))
    except ValueError:
        abort(400, "Invalid service id supplied")

    try:
        page = int(request.args.get('page', 1))
    except ValueError:
        abort(400, "Invalid page argument")

    services = ServiceArchive.query.filter(Service.service_id == service_id)

    services = services.paginate(page=page, per_page=API_FETCH_PAGE_SIZE,
                                 error_out=False)

    if request.args and not services.items:
        abort(404)
    return jsonify(
        services=list(map(jsonify_service, services.items)),
        links=pagination_links(services, '.list_services', request.args))


@main.route('/services/<int:service_id>', methods=['POST'])
def update_service(service_id):
    """
        Update a service. Looks service up in DB, and updates the JSON listing.
        Uses existing JSON Parse routines for validation
    """
    service = Service.query.filter(
        Service.service_id == service_id
    ).first_or_404()

    service_to_archive = prepare_archived_service(service)
    update_json = get_json_from_request('update_details')['update_details']
    validate_updater_json_or_400(update_json)
    service_update = get_json_from_request('services')['services']

    data = dict(service.data.items())
    data.update(service_update)
    validate_json_or_400(data)

    now = datetime.now()
    service.data = data
    service.updated_at = now
    service.updated_by = update_json['updated_by']
    service.updated_reason = update_json['update_reason']

    db.session.add(service)
    db.session.add(service_to_archive)

    try:
        db.session.commit()
    except DatabaseError:
        db.session.rollback()
        abort(500, "Database error")

    return jsonify(message="done"), 200


@main.route('/services/<int:service_id>', methods=['PUT'])
def import_service(service_id):
    now = datetime.now()
    service = Service.query.filter(Service.service_id == service_id).first()

    if service is not None:
        abort(409, "Service already exists")

    service_data = drop_foreign_fields(
        get_json_from_request('services')['services']
    )

    update_json = get_json_from_request('update_details')['update_details']
    validate_updater_json_or_400(update_json)

    validate_json_or_400(service_data)

    if str(service_data['id']) != str(service_id):
        abort(400, "Invalid service ID provided")

    service = Service(service_id=service_id)
    service.data = service_data
    service.supplier_id = service_data['supplierId']
    service.updated_at = now
    service.created_at = now
    service.updated_by = update_json['updated_by']
    service.updated_reason = update_json['update_reason']

    db.session.add(service)

    try:
        db.session.commit()
    except IntegrityError:
        db.session.rollback()
        abort(400, "Unknown supplier ID provided")

    return "", 201


@main.route('/services/<int:service_id>', methods=['GET'])
def get_service(service_id):
    service = Service.query.filter(
        Service.service_id == service_id
    ).first_or_404()

    return jsonify(services=jsonify_service(service))


@main.route('/services-archive/<int:service_archive_id>', methods=['GET'])
def get_archived_service(service_archive_id):
    """
    Retrieves a service from the service_archive by PK
    :param service_archive_id:
    :return: service
    """

    try:
        int(service_archive_id)
    except ValueError:
        abort(400, "Invalid service id supplied")

    service = ServiceArchive.query.filter(
        ServiceArchive.id == service_archive_id
    ).first_or_404()

    return jsonify(services=jsonify_service(service))


def prepare_archived_service(service):
    """
    Makes a servicearchive instance based on this service
    :param Service:
    :return: ServiceArchive
    """
    return ServiceArchive(
        service_id=service.service_id,
        supplier_id=service.supplier_id,
        created_at=service.created_at,
        updated_at=service.updated_at,
        updated_by=service.updated_by,<commit_msg>Removed unnecessary ID check. As per @allait comment. Handled by route definition.<commit_after>from datetime import datetime
from flask import jsonify, abort, request
from flask import url_for as base_url_for
from sqlalchemy.exc import IntegrityError, DatabaseError

from . import main
from .. import db
from ..models import Service, ServiceArchive
from ..validation import validate_json_or_400, validate_updater_json_or_400


API_FETCH_PAGE_SIZE = 100


@main.route('/')
def index():
    """Entry point for the API, show the resources that are available."""
    return jsonify(links=[
        {
            "rel": "services.list",
            "href": url_for('.list_services', _external=True)
        }
    ]), 200


@main.route('/services', methods=['GET'])
def list_services():
    try:
        page = int(request.args.get('page', 1))
    except ValueError:
        abort(400, "Invalid page argument")

    supplier_id = request.args.get('supplier_id')

    services = Service.query
    if supplier_id is not None:
        try:
            supplier_id = int(supplier_id)
        except ValueError:
            abort(400, "Invalid supplier_id")
        services = services.filter(Service.supplier_id == supplier_id)

    services = services.paginate(page=page, per_page=API_FETCH_PAGE_SIZE,
                                 error_out=False)
    if request.args and not services.items:
        abort(404)
    return jsonify(
        services=list(map(jsonify_service, services.items)),
        links=pagination_links(services, '.list_services', request.args))


@main.route('/services-archive', methods=['GET'])
def list_archived_services_by_service_id():
    """
    Retrieves a list of services from the service_archive table
    for the supplied service_id
    :query_param service_id:
    :return: List[service]
    """

    try:
        service_id = int(request.args.get("service-id", "no service id"))
    except ValueError:
        abort(400, "Invalid service id supplied")

    try:
        page = int(request.args.get('page', 1))
    except ValueError:
        abort(400, "Invalid page argument")

    services = ServiceArchive.query.filter(Service.service_id == service_id)

    services = services.paginate(page=page, per_page=API_FETCH_PAGE_SIZE,
                                 error_out=False)

    if request.args and not services.items:
        abort(404)
    return jsonify(
        services=list(map(jsonify_service, services.items)),
        links=pagination_links(services, '.list_services', request.args))


@main.route('/services/<int:service_id>', methods=['POST'])
def update_service(service_id):
    """
        Update a service. Looks service up in DB, and updates the JSON listing.
        Uses existing JSON Parse routines for validation
    """
    service = Service.query.filter(
        Service.service_id == service_id
    ).first_or_404()

    service_to_archive = prepare_archived_service(service)
    update_json = get_json_from_request('update_details')['update_details']
    validate_updater_json_or_400(update_json)
    service_update = get_json_from_request('services')['services']

    data = dict(service.data.items())
    data.update(service_update)
    validate_json_or_400(data)

    now = datetime.now()
    service.data = data
    service.updated_at = now
    service.updated_by = update_json['updated_by']
    service.updated_reason = update_json['update_reason']

    db.session.add(service)
    db.session.add(service_to_archive)

    try:
        db.session.commit()
    except DatabaseError:
        db.session.rollback()
        abort(500, "Database error")

    return jsonify(message="done"), 200


@main.route('/services/<int:service_id>', methods=['PUT'])
def import_service(service_id):
    now = datetime.now()
    service = Service.query.filter(Service.service_id == service_id).first()

    if service is not None:
        abort(409, "Service already exists")

    service_data = drop_foreign_fields(
        get_json_from_request('services')['services']
    )

    update_json = get_json_from_request('update_details')['update_details']
    validate_updater_json_or_400(update_json)

    validate_json_or_400(service_data)

    if str(service_data['id']) != str(service_id):
        abort(400, "Invalid service ID provided")

    service = Service(service_id=service_id)
    service.data = service_data
    service.supplier_id = service_data['supplierId']
    service.updated_at = now
    service.created_at = now
    service.updated_by = update_json['updated_by']
    service.updated_reason = update_json['update_reason']

    db.session.add(service)

    try:
        db.session.commit()
    except IntegrityError:
        db.session.rollback()
        abort(400, "Unknown supplier ID provided")

    return "", 201


@main.route('/services/<int:service_id>', methods=['GET'])
def get_service(service_id):
    service = Service.query.filter(
        Service.service_id == service_id
    ).first_or_404()

    return jsonify(services=jsonify_service(service))


@main.route('/services-archive/<int:service_archive_id>', methods=['GET'])
def get_archived_service(service_archive_id):
    """
    Retrieves a service from the service_archive by PK
    :param service_archive_id:
    :return: service
    """

    service = ServiceArchive.query.filter(
        ServiceArchive.id == service_archive_id
    ).first_or_404()

    return jsonify(services=jsonify_service(service))


def prepare_archived_service(service):
    """
    Makes a servicearchive instance based on this service
    :param Service:
    :return: ServiceArchive
    """
    return ServiceArchive(
        service_id=service.service_id,
        supplier_id=service.supplier_id,
        created_at=service.created_at,
        updated_at=service.updated_at,
        updated_by=service.updated_by,
{'fraction_non_alphanumeric': 0.10832763337893297, 'fraction_numerical': 0.012397400820793434, 'mean_word_length': 3.4223062381852554, 'pattern_counts': {'":': 4, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1255575', 'n_tokens_mistral': 3604, 'n_tokens_neox': 3444, 'n_words': 727}