Ejemplo n.º 1
0
def create():
    data = parse_request(EntityCreateSchema)
    collection = get_db_collection(data['collection_id'], request.authz.WRITE)
    entity_id = create_entity(data, collection, sync=True)
    tag_request(entity_id=entity_id, collection_id=str(collection.id))
    entity = get_index_entity(entity_id, request.authz.READ)
    return EntitySerializer.jsonify(entity)
Ejemplo n.º 2
0
def suggest_property():
    prefix = request.args.get("prefix", "").lower().strip()
    tag_request(prefix=prefix)
    schema = request.args.get("schema", Entity.THING)
    matches = []
    for prop in model.get(schema).properties.values():
        match = not len(prefix)
        match = prefix in prop.name.lower()
        match = match or prefix in prop.label.lower()
        if match:
            matches.append({
                "id": prop.name,
                "quid": prop.name,
                "name": prop.label,
                "r:score": 100,
                "n:type": {
                    "id": "/properties/property",
                    "name": "Property"
                },
            })
    return jsonify({
        "code": "/api/status/ok",
        "status": "200 OK",
        "prefix": request.args.get("prefix", ""),
        "result": matches,
    })
Ejemplo n.º 3
0
def view(entity_id):
    """
    ---
    get:
      summary: Get an entity
      description: Return the entity with id `entity_id`
      parameters:
      - in: path
        name: entity_id
        required: true
        schema:
          type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Entity'
      tags:
      - Entity
    """
    enable_cache()
    excludes = ["text", "numeric.*"]
    entity = get_index_entity(entity_id, request.authz.READ, excludes=excludes)
    tag_request(collection_id=entity.get("collection_id"))
    proxy = model.get_proxy(entity)
    html = proxy.first("bodyHtml", quiet=True)
    source_url = proxy.first("sourceUrl", quiet=True)
    encoding = proxy.first("encoding", quiet=True)
    entity["safeHtml"] = sanitize_html(html, source_url, encoding=encoding)
    entity["shallow"] = False
    return EntitySerializer.jsonify(entity)
Ejemplo n.º 4
0
def delete(entity_id):
    """
    ---
    delete:
      summary: Delete an entity
      description: Delete the entity with id `entity_id`
      parameters:
      - in: path
        name: entity_id
        required: true
        schema:
          type: string
      responses:
        '204':
          description: No Content
      tags:
      - Entity
    """
    entity = get_index_entity(entity_id, request.authz.WRITE)
    collection = get_db_collection(entity.get('collection_id'),
                                   request.authz.WRITE)
    tag_request(collection_id=collection.id)
    delete_entity(collection, entity, sync=get_flag('sync', True))
    db.session.commit()
    return ('', 204)
Ejemplo n.º 5
0
def create():
    """Creates an alert for a given query string.
    ---
    post:
      summary: Create an alert
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AlertCreate'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Alert'
          description: OK
      tags:
        - Alert
    """
    require(request.authz.session_write)
    data = parse_request("AlertCreate")
    alert = Alert.create(data, request.authz.id)
    db.session.commit()
    tag_request(alert_id=alert.id)
    return AlertSerializer.jsonify(alert)
Ejemplo n.º 6
0
def delete(entity_id):
    """
    ---
    delete:
      summary: Delete an entity
      description: Delete the entity with id `entity_id`
      parameters:
      - in: path
        name: entity_id
        required: true
        schema:
          type: string
      responses:
        '204':
          description: No Content
      tags:
      - Entity
    """
    entity = get_index_entity(entity_id, request.authz.WRITE)
    collection = get_db_collection(entity.get("collection_id"),
                                   request.authz.WRITE)
    tag_request(collection_id=collection.id)
    sync = get_flag("sync", default=True)
    job_id = get_session_id()
    delete_entity(collection, entity, sync=sync, job_id=job_id)
    return ("", 204)
Ejemplo n.º 7
0
def export():
    """
    ---
    post:
      summary: Download the results of a search
      description: >-
        Downloads all the results of a search as a zip archive; upto a max of
        10,000 results. The returned file will contain an Excel document with
        structured data as well as the binary files from all matching
        documents.

        Supports the same query parameters as the search API.
      responses:
        '202':
          description: Accepted
      tags:
      - Entity
    """
    require(request.authz.logged_in)
    parser = SearchQueryParser(request.args, request.authz)
    tag_request(query=parser.text, prefix=parser.prefix)
    query = EntitiesQuery(parser)
    label = gettext("Search: %s") % query.to_text()
    export = create_export(
        operation=OP_EXPORT_SEARCH,
        role_id=request.authz.id,
        label=label,
        mime_type=ZIP,
        meta={"query": query.get_full_query()},
    )
    job_id = get_session_id()
    queue_task(None, OP_EXPORT_SEARCH, job_id=job_id, export_id=export.id)
    return ("", 202)
Ejemplo n.º 8
0
def create():
    require(request.authz.session_write)
    data = parse_request(AlertSchema)
    alert = Alert.create(data, request.authz.id)
    db.session.commit()
    tag_request(alert_id=alert.id)
    return AlertSerializer.jsonify(alert)
Ejemplo n.º 9
0
def suggest_property():
    prefix = request.args.get('prefix', '').lower().strip()
    tag_request(prefix=prefix)
    schema = request.args.get('schema', Entity.THING)
    matches = []
    for prop in model.get(schema).properties.values():
        match = not len(prefix)
        match = prefix in prop.name.lower()
        match = match or prefix in prop.label.lower()
        if match:
            matches.append({
                'id': prop.name,
                'quid': prop.name,
                'name': prop.label,
                'r:score': 100,
                'n:type': {
                    'id': '/properties/property',
                    'name': 'Property'
                }
            })
    return jsonify({
        "code": "/api/status/ok",
        "status": "200 OK",
        "prefix": request.args.get('prefix', ''),
        "result": matches
    })
Ejemplo n.º 10
0
def similar(entity_id):
    enable_cache()
    entity = get_index_entity(entity_id, request.authz.READ)
    tag_request(collection_id=entity.get('collection_id'))
    entity = model.get_proxy(entity)
    result = MatchQuery.handle(request, entity=entity)
    return EntitySerializer.jsonify_result(result)
Ejemplo n.º 11
0
def create():
    """
    ---
    post:
      summary: Create an entity in a collection
      description: >-
        Create an entity in a collection with a given schema and a set of given
        properties in the database. This is not the API you want to be using to
        load bulk data, but only for interactive entity manipulation in the UI.
        Always use the `bulk` API or for loading source datasets, no
        exceptions.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EntityCreate'
      responses:
        '200':
          description: Resturns the created entity
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Entity'
      tags:
        - Entity
    """
    data = parse_request('EntityCreate')
    collection = get_nested_collection(data, request.authz.WRITE)
    data.pop('id', None)
    validate = get_flag('validate', default=False)
    entity_id = upsert_entity(data, collection, sync=True, validate=validate)
    tag_request(entity_id=entity_id, collection_id=str(collection.id))
    entity = get_index_entity(entity_id, request.authz.READ)
    return EntitySerializer.jsonify(entity)
Ejemplo n.º 12
0
def view(entity_id):
    """
    ---
    get:
      summary: Get an entity
      description: Return the entity with id `entity_id`
      parameters:
      - in: path
        name: entity_id
        required: true
        schema:
          type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Entity'
      tags:
      - Entity
    """
    enable_cache()
    entity = get_index_entity(entity_id, request.authz.READ)
    tag_request(collection_id=entity.get('collection_id'))
    return EntitySerializer.jsonify(entity)
Ejemplo n.º 13
0
def tags(entity_id):
    """
    ---
    get:
      summary: Get entity tags
      description: >-
        Get tags for the entity with id `entity_id`.
      parameters:
      - in: path
        name: entity_id
        required: true
        schema:
          type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                allOf:
                - $ref: '#/components/schemas/QueryResponse'
                properties:
                  results:
                    type: array
                    items:
                      $ref: '#/components/schemas/EntityTag'
      tags:
      - Entity
    """
    enable_cache()
    entity = get_index_entity(entity_id, request.authz.READ)
    tag_request(collection_id=entity.get("collection_id"))
    results = entity_tags(model.get_proxy(entity), request.authz)
    return jsonify({"status": "ok", "total": len(results), "results": results})
Ejemplo n.º 14
0
def suggest_property():
    prefix = request.args.get('prefix', '').lower().strip()
    tag_request(prefix=prefix)
    schema = request.args.get('schema', Entity.THING)
    matches = []
    for prop in model.get(schema).properties.values():
        match = not len(prefix)
        match = prefix in prop.name.lower()
        match = match or prefix in prop.label.lower()
        if match:
            matches.append({
                'id': prop.name,
                'quid': prop.name,
                'name': prop.label,
                'r:score': 100,
                'n:type': {
                    'id': '/properties/property',
                    'name': 'Property'
                }
            })
    return jsonify({
        "code": "/api/status/ok",
        "status": "200 OK",
        "prefix": request.args.get('prefix', ''),
        "result": matches
    })
Ejemplo n.º 15
0
def entities_index(entityset_id):
    """Search entities in the entity set with id `entityset_id`.
    ---
    get:
      summary: Search entities in the entity set with id `entityset_id`
      description: >
        Supports all query filters and arguments present in the normal
        entity search API, but all resulting entities will be members of
        the set.
      parameters:
      - description: The entityset id.
        in: path
        name: entityset_id
        required: true
        schema:
          type: string
        example: 3a0d91ece2dce88ad3259594c7b642485235a048
      responses:
        '200':
          description: Resturns a list of entities in result
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EntitiesResponse'
      tags:
      - EntitySet
    """
    entityset = get_entityset(entityset_id, request.authz.READ)
    parser = SearchQueryParser(request.args, request.authz)
    tag_request(query=parser.text, prefix=parser.prefix)
    result = EntitySetItemsQuery.handle(request,
                                        parser=parser,
                                        entityset=entityset)
    return EntitySerializer.jsonify_result(result)
Ejemplo n.º 16
0
def create():
    require(settings.PASSWORD_LOGIN)
    require(not request.authz.in_maintenance)
    data = parse_request(RoleCreateSchema)
    try:
        email = Role.SIGNATURE.loads(data.get('code'),
                                     max_age=Role.SIGNATURE_MAX_AGE)
    except BadSignature:
        return jsonify({
            'status': 'error',
            'message': gettext('Invalid code')
        },
                       status=400)

    role = Role.by_email(email)
    if role is not None:
        return jsonify(
            {
                'status': 'error',
                'message': gettext('Email is already registered')
            },
            status=409)

    role = Role.load_or_create(foreign_id='password:{}'.format(email),
                               type=Role.USER,
                               name=data.get('name') or email,
                               email=email)
    role.set_password(data.get('password'))
    db.session.add(role)
    db.session.commit()
    update_role(role)
    # Let the serializer return more info about this user
    request.authz = Authz.from_role(role)
    tag_request(role_id=role.id)
    return RoleSerializer.jsonify(role, status=201)
Ejemplo n.º 17
0
def create():
    require(not request.authz.in_maintenance, settings.PASSWORD_LOGIN)
    data = parse_request(RoleCreateSchema)

    try:
        email = Role.SIGNATURE.loads(data.get('code'),
                                     max_age=Role.SIGNATURE_MAX_AGE)
    except BadSignature:
        return jsonify({
            'status': 'error',
            'message': gettext('Invalid code')
        }, status=400)

    role = Role.by_email(email)
    if role is not None:
        return jsonify({
            'status': 'error',
            'message': gettext('Email is already registered')
        }, status=409)

    role = Role.load_or_create(
        foreign_id='password:{}'.format(email),
        type=Role.USER,
        name=data.get('name') or email,
        email=email
    )
    role.set_password(data.get('password'))
    db.session.add(role)
    db.session.commit()
    update_role(role)
    # Let the serializer return more info about this user
    request.authz.id = role.id
    tag_request(role_id=role.id)
    return RoleSerializer.jsonify(role, status=201)
Ejemplo n.º 18
0
def export():
    """
    ---
    get:
      summary: Download the results of a search
      description: >-
        Downloads all the results of a search as a zip archive; upto a max of
        10,000 results. The returned file will contain an Excel document with
        structured data as well as the binary files from all matching
        documents.

        Supports the same query parameters as the search API.
      responses:
        '200':
          content:
            application/zip:
              schema:
                format: binary
                type: string
          description: OK
      tags:
      - Entity
    """
    require(request.authz.logged_in)
    parser = SearchQueryParser(request.args, request.authz)
    parser.limit = MAX_PAGE
    tag_request(query=parser.text, prefix=parser.prefix)
    result = EntitiesQuery.handle(request, parser=parser)
    stream = export_entities(request, result)
    response = Response(stream, mimetype='application/zip')
    disposition = 'attachment; filename={}'.format('Query_export.zip')
    response.headers['Content-Disposition'] = disposition
    return response
Ejemplo n.º 19
0
def update(entity_id):
    """
    ---
    post:
      summary: Update an entity
      description: >
        Update the entity with id `entity_id`. This only applies to
        entities which are backed by a database row, i.e. not any
        entities resulting from a mapping or bulk load.
      parameters:
      - in: path
        name: entity_id
        required: true
        schema:
          type: string
          format: entity_id
      - in: query
        name: sign
        description: Sign entity IDs referenced in nested properties.
        required: false
        schema:
          type: boolean
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EntityUpdate'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Entity'
      tags:
      - Entity
    """
    data = parse_request("EntityUpdate")
    try:
        entity = get_index_entity(entity_id, request.authz.WRITE)
        require(check_write_entity(entity, request.authz))
        collection = get_db_collection(entity.get("collection_id"),
                                       request.authz.WRITE)
    except NotFound:
        collection = get_nested_collection(data, request.authz.WRITE)
    tag_request(collection_id=collection.id)
    data["id"] = entity_id
    if get_flag("validate", default=False):
        validate_entity(data)
    entity_id = upsert_entity(
        data,
        collection,
        authz=request.authz,
        sync=get_flag("sync", default=True),
        sign=get_flag("sign", default=False),
        job_id=get_session_id(),
    )
    db.session.commit()
    return view(entity_id)
Ejemplo n.º 20
0
def match():
    entity = parse_request(EntityUpdateSchema)
    entity = model.get_proxy(entity)
    tag_request(schema=entity.schema.name, caption=entity.caption)
    collection_ids = request.args.getlist('collection_ids')
    result = MatchQuery.handle(request, entity=entity,
                               collection_ids=collection_ids)
    return EntitySerializer.jsonify_result(result)
Ejemplo n.º 21
0
def similar(entity_id):
    enable_cache()
    entity = get_index_entity(entity_id, request.authz.READ)
    tag_request(collection_id=entity.get('collection_id'))
    entity = model.get_proxy(entity)
    record_audit(Audit.ACT_ENTITY, id=entity_id)
    result = MatchQuery.handle(request, entity=entity)
    return EntitySerializer.jsonify_result(result)
Ejemplo n.º 22
0
def match():
    entity = parse_request(EntityUpdateSchema)
    record_audit(Audit.ACT_MATCH, entity=entity)
    entity = model.get_proxy(entity)
    tag_request(schema=entity.schema.name, caption=entity.caption)
    collection_ids = request.args.getlist('collection_ids')
    result = MatchQuery.handle(request, entity=entity,
                               collection_ids=collection_ids)
    return EntitySerializer.jsonify_result(result)
Ejemplo n.º 23
0
def similar(profile_id):
    """
    ---
    get:
      summary: Get similar entities
      description: >
        Get a list of similar entities to the profile with id `profile_id`
      parameters:
      - in: path
        name: profile_id
        required: true
        schema:
          type: string
      - in: query
        name: 'filter:schema'
        schema:
          items:
            type: string
          type: array
      - in: query
        name: 'filter:schemata'
        schema:
          items:
            type: string
          type: array
      responses:
        '200':
          description: Returns a list of entities
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EntitiesResponse'
      tags:
      - Profile
    """
    # enable_cache()
    profile = obj_or_404(get_profile(profile_id, authz=request.authz))
    require(request.authz.can(profile.get("collection_id"),
                              request.authz.READ))
    tag_request(collection_id=profile.get("collection_id"))
    exclude = [item["entity_id"] for item in profile["items"]]
    result = MatchQuery.handle(request,
                               entity=profile["merged"],
                               exclude=exclude)
    entities = list(result.results)
    result.results = []
    for obj in entities:
        item = {
            "score": compare(model, profile["merged"], obj),
            "judgement": Judgement.NO_JUDGEMENT,
            "collection_id": profile.get("collection_id"),
            "entity": obj,
        }
        result.results.append(item)
    return SimilarSerializer.jsonify_result(result)
Ejemplo n.º 24
0
def update(entity_id):
    entity = get_db_entity(entity_id, request.authz.WRITE)
    tag_request(collection_id=entity.collection_id)
    data = parse_request(EntityUpdateSchema)
    if get_flag('merge'):
        props = merge_data(data.get('properties'), entity.data)
        data['properties'] = props
    entity.update(data)
    db.session.commit()
    data = update_entity(entity, sync=get_flag('sync', True))
    return EntitySerializer.jsonify(data)
Ejemplo n.º 25
0
def export(format):
    require(request.authz.logged_in)
    parser = SearchQueryParser(request.args, request.authz)
    parser.limit = EXPORT_MAX
    tag_request(query=parser.text, prefix=parser.prefix)
    result = EntitiesQuery.handle(request, parser=parser)
    stream = export_entities(request, result, format)
    response = Response(stream, mimetype='application/zip')
    disposition = 'attachment; filename={}'.format('Query_export.zip')
    response.headers['Content-Disposition'] = disposition
    return response
Ejemplo n.º 26
0
def update(entity_id):
    entity = get_db_entity(entity_id, request.authz.WRITE)
    tag_request(collection_id=entity.collection_id)
    data = parse_request(EntityUpdateSchema)
    if get_flag('merge'):
        props = merge_data(data.get('properties'), entity.data)
        data['properties'] = props
    entity.update(data)
    db.session.commit()
    data = update_entity(entity, sync=get_flag('sync', True))
    return EntitySerializer.jsonify(data)
Ejemplo n.º 27
0
def export(format):
    require(request.authz.logged_in)
    parser = SearchQueryParser(request.args, request.authz)
    parser.limit = EXPORT_MAX
    tag_request(query=parser.text, prefix=parser.prefix)
    result = EntitiesQuery.handle(request, parser=parser)
    stream = export_entities(request, result, format)
    response = Response(stream, mimetype='application/zip')
    disposition = 'attachment; filename={}'.format('Query_export.zip')
    response.headers['Content-Disposition'] = disposition
    return response
Ejemplo n.º 28
0
def references(entity_id):
    enable_cache()
    entity = get_index_entity(entity_id, request.authz.READ)
    tag_request(collection_id=entity.get('collection_id'))
    results = []
    for prop, total in entity_references(entity, request.authz):
        results.append({
            'count': total,
            'property': prop,
            'schema': prop.schema.name,
        })
    return jsonify({'status': 'ok', 'total': len(results), 'results': results})
Ejemplo n.º 29
0
def similar(entity_id):
    """
    ---
    get:
      summary: Get similar entities
      description: >
        Get a list of similar entities to the entity with id `entity_id`
      parameters:
      - in: path
        name: entity_id
        required: true
        schema:
          type: string
      - in: query
        name: 'filter:schema'
        schema:
          items:
            type: string
          type: array
      - in: query
        name: 'filter:schemata'
        schema:
          items:
            type: string
          type: array
      responses:
        '200':
          description: Returns a list of scored and judged entities
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SimilarResponse'
      tags:
      - Entity
    """
    # enable_cache()
    entity = get_index_entity(entity_id, request.authz.READ)
    tag_request(collection_id=entity.get("collection_id"))
    proxy = model.get_proxy(entity)
    result = MatchQuery.handle(request, entity=proxy)
    entities = list(result.results)
    pairs = [(entity_id, s.get("id")) for s in entities]
    judgements = pairwise_judgements(pairs, entity.get("collection_id"))
    result.results = []
    for obj in entities:
        item = {
            "score": compare(model, proxy, obj),
            "judgement": judgements.get((entity_id, obj.get("id"))),
            "collection_id": entity.get("collection_id"),
            "entity": obj,
        }
        result.results.append(item)
    return SimilarSerializer.jsonify_result(result)
Ejemplo n.º 30
0
def index():
    # enable_cache(vary_user=True)
    parser = SearchQueryParser(request.args, request.authz)
    tag_request(query=parser.text, prefix=parser.prefix)
    result = EntitiesQuery.handle(request, parser=parser)
    links = {}
    if request.authz.logged_in and result.total <= EXPORT_MAX:
        query = list(request.args.items(multi=True))
        links['export'] = url_for('entities_api.export',
                                  format='excel',
                                  _authorize=True,
                                  _query=query)
    return EntitySerializer.jsonify_result(result, extra={'links': links})
Ejemplo n.º 31
0
def index():
    # enable_cache(vary_user=True)
    parser = SearchQueryParser(request.args, request.authz)
    tag_request(query=parser.text, prefix=parser.prefix)
    result = EntitiesQuery.handle(request, parser=parser)
    links = {}
    if request.authz.logged_in and result.total <= EXPORT_MAX:
        query = list(request.args.items(multi=True))
        links['export'] = url_for('entities_api.export',
                                  format='excel',
                                  _authorize=True,
                                  _query=query)
    return EntitySerializer.jsonify_result(result, extra={'links': links})
Ejemplo n.º 32
0
def content(entity_id):
    """
    ---
    get:
      summary: Get the content of an entity
      description: >
        Return the text and/or html content of the entity with id `entity_id`
      parameters:
      - in: path
        name: entity_id
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                properties:
                  headers:
                    type: object
                  html:
                    type: string
                  text:
                    type: string
                type: object
          description: OK
        '404':
          description: Not Found
      tags:
      - Entity
    """
    enable_cache()
    entity = get_index_entity(entity_id, request.authz.READ)
    tag_request(collection_id=entity.get('collection_id'))
    for entity in entities_by_ids([entity_id],
                                  schemata=entity.get('schema'),
                                  excludes=['text']):
        proxy = model.get_proxy(entity)
        html = proxy.first('bodyHtml', quiet=True)
        source_url = proxy.first('sourceUrl', quiet=True)
        encoding = proxy.first('encoding', quiet=True)
        html = sanitize_html(html, source_url, encoding=encoding)
        headers = proxy.first('headers', quiet=True)
        headers = registry.json.unpack(headers)
        return jsonify({
            'headers': headers,
            'text': proxy.first('bodyText', quiet=True),
            'html': html
        })
    return ('', 404)
Ejemplo n.º 33
0
def tags(entity_id):
    """
    ---
    get:
      summary: Get entity tags
      description: >-
        Get tags for the entity with id `entity_id`. Tags include the query
        string to make a search by that particular tag.
      parameters:
      - in: path
        name: entity_id
        required: true
        schema:
          type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                allOf:
                - $ref: '#/components/schemas/QueryResponse'
                properties:
                  results:
                    type: array
                    items:
                      $ref: '#/components/schemas/EntityTag'
      tags:
      - Entity
    """
    enable_cache()
    entity = get_index_entity(entity_id, request.authz.READ)
    tag_request(collection_id=entity.get('collection_id'))
    results = []
    for (field, value, total) in entity_tags(entity, request.authz):
        qvalue = quote(value.encode('utf-8'))
        key = ('filter:%s' % field, qvalue)
        results.append({
            'id': query_string([key]),
            'value': value,
            'field': field,
            'count': total,
        })

    results.sort(key=lambda p: p['count'], reverse=True)
    return jsonify({
        'status': 'ok',
        'total': len(results),
        'results': results
    })
Ejemplo n.º 34
0
def create():
    """
    ---
    post:
      summary: Create an entity in a collection
      description: >-
        Create an entity in a collection with a given schema and a set of given
        properties in the database. This is not the API you want to be using to
        load bulk data, but only for interactive entity manipulation in the UI.
        Always use the `bulk` API or for loading source datasets, no
        exceptions.
      parameters:
      - in: query
        name: sign
        description: Sign entity IDs referenced in nested properties.
        required: false
        schema:
          type: boolean
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EntityCreate'
      responses:
        '200':
          description: Resturns the created entity
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Entity'
      tags:
        - Entity
    """
    data = parse_request("EntityCreate")
    collection = get_nested_collection(data, request.authz.WRITE)
    data.pop("id", None)
    if get_flag("validate", default=False):
        validate_entity(data)
    entity_id = upsert_entity(
        data,
        collection,
        authz=request.authz,
        sync=True,
        sign=get_flag("sign", default=False),
        job_id=get_session_id(),
    )
    db.session.commit()
    tag_request(entity_id=entity_id, collection_id=collection.id)
    entity = get_index_entity(entity_id, request.authz.READ)
    return EntitySerializer.jsonify(entity)
Ejemplo n.º 35
0
def retrieve():
    """Downloads a binary blob from the blob storage archive.
    ---
    get:
      summary: Download a blob from the archive
      parameters:
      - description: Authorization token for an archive blob
        in: query
        name: claim
        schema:
          type: string
          description: A signed JWT with the object hash.
      responses:
        '200':
          description: OK
          content:
            '*/*': {}
        '404':
          description: Object does not exist.
      tags:
      - Archive
    """
    token = request.args.get("token")
    token = jwt.decode(token, key=settings.SECRET_KEY, verify=True)
    content_hash = token.get("c")
    file_name = token.get("f")
    mime_type = token.get("m")
    expire = datetime.utcfromtimestamp(token["exp"])
    tag_request(content_hash=content_hash, file_name=file_name)
    url = archive.generate_url(
        content_hash,
        file_name=file_name,
        mime_type=mime_type,
        expire=expire,
    )
    if url is not None:
        return redirect(url)
    try:
        local_path = archive.load_file(content_hash)
        if local_path is None:
            return Response(status=404)
        return send_file(
            str(local_path),
            as_attachment=True,
            conditional=True,
            attachment_filename=file_name,
            mimetype=mime_type,
        )
    finally:
        archive.cleanup_file(content_hash)
Ejemplo n.º 36
0
def create():
    """Create a user role.
    ---
    post:
      summary: Create a user account
      description: >
        Create a user role by supplying the required account details.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RoleCreate'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Role'
      tags:
      - Role
    """
    require(settings.PASSWORD_LOGIN)
    require(not request.authz.in_maintenance)
    data = parse_request("RoleCreate")
    try:
        email = Role.SIGNATURE.loads(data.get("code"),
                                     max_age=Role.SIGNATURE_MAX_AGE)
    except BadSignature:
        return jsonify({
            "status": "error",
            "message": gettext("Invalid code")
        },
                       status=400)

    role = Role.by_email(email)
    if role is not None:
        return jsonify(
            {
                "status": "error",
                "message": gettext("Email is already registered")
            },
            status=409,
        )

    role = create_user(email, data.get("name"), data.get("password"))
    # Let the serializer return more info about this user
    request.authz = Authz.from_role(role)
    tag_request(role_id=role.id)
    return RoleSerializer.jsonify(role, status=201)
Ejemplo n.º 37
0
def index():
    # enable_cache(vary_user=True)
    parser = SearchQueryParser(request.args, request.authz)
    if parser.text:
        QueryLog.save(request.authz.id, request._session_id, parser.text)
        db.session.commit()
    tag_request(query=parser.text, prefix=parser.prefix)
    result = EntitiesQuery.handle(request, parser=parser)
    links = {}
    if request.authz.logged_in and result.total <= MAX_PAGE:
        query = list(request.args.items(multi=True))
        links['export'] = url_for('entities_api.export',
                                  _authorize=True,
                                  _query=query)
    return EntitySerializer.jsonify_result(result, extra={'links': links})
Ejemplo n.º 38
0
def merge(entity_id, other_id):
    entity = get_db_entity(entity_id, request.authz.WRITE)
    other = get_db_entity(other_id, request.authz.WRITE)
    tag_request(collection_id=entity.collection_id)

    try:
        entity.merge(other)
    except ValueError as ve:
        raise BadRequest(ve.message)

    db.session.commit()
    sync = get_flag('sync', True)
    data = update_entity(entity, sync=sync)
    update_entity(other, sync=sync)
    return EntitySerializer.jsonify(data)
Ejemplo n.º 39
0
def merge(entity_id, other_id):
    entity = get_db_entity(entity_id, request.authz.WRITE)
    other = get_db_entity(other_id, request.authz.WRITE)
    tag_request(collection_id=entity.collection_id)

    try:
        entity.merge(other)
    except ValueError as ve:
        raise BadRequest(ve.message)

    db.session.commit()
    sync = get_flag('sync', True)
    data = update_entity(entity, sync=sync)
    update_entity(other, sync=sync)
    return EntitySerializer.jsonify(data)
Ejemplo n.º 40
0
def suggest_type():
    prefix = request.args.get('prefix', '').lower().strip()
    tag_request(prefix=prefix)
    matches = []
    for schema in model:
        match = not len(prefix)
        match = match or prefix in schema.name.lower()
        match = match or prefix in schema.label.lower()
        if match and schema.matchable:
            matches.append(get_freebase_type(schema))
    return jsonify({
        "code": "/api/status/ok",
        "status": "200 OK",
        "prefix": request.args.get('prefix', ''),
        "result": matches
    })
Ejemplo n.º 41
0
def references(entity_id):
    enable_cache()
    entity = get_index_entity(entity_id, request.authz.READ)
    tag_request(collection_id=entity.get('collection_id'))
    record_audit(Audit.ACT_ENTITY, id=entity_id)
    results = []
    for prop, total in entity_references(entity, request.authz):
        results.append({
            'count': total,
            'property': prop,
            'schema': prop.schema.name,
        })
    return jsonify({
        'status': 'ok',
        'total': len(results),
        'results': results
    })
Ejemplo n.º 42
0
def content(entity_id):
    enable_cache()
    entity = get_index_entity(entity_id, request.authz.READ)
    tag_request(collection_id=entity.get('collection_id'))
    for entity in entities_by_ids([entity_id],
                                  schemata=entity.get('schema'),
                                  excludes=['text']):
        proxy = model.get_proxy(entity)
        record_audit(Audit.ACT_ENTITY, id=entity_id)
        html = sanitize_html(proxy.first('bodyHtml', quiet=True),
                             proxy.first('sourceUrl', quiet=True))
        headers = proxy.first('headers', quiet=True)
        headers = registry.json.unpack(headers)
        return jsonify({
            'headers': headers,
            'text': proxy.first('bodyText', quiet=True),
            'html': html
        })
    return ('', 404)
Ejemplo n.º 43
0
def suggest_entity():
    """Suggest API, emulates Google Refine API."""
    prefix = request.args.get('prefix', '')
    tag_request(prefix=prefix)
    types = request.args.getlist('type') or Entity.THING
    args = {
        'prefix': prefix,
        'filter:schemata': types,
        'filter:collection_id': request.args.getlist('filter:collection_id')
    }
    parser = SearchQueryParser(args, request.authz)
    query = EntitiesQuery(parser)
    result = query.search()
    matches = list(entity_matches(result))
    return jsonify({
        "code": "/api/status/ok",
        "status": "200 OK",
        "prefix": prefix,
        "result": matches
    })
Ejemplo n.º 44
0
def retrieve():
    claim = request.args.get('claim')
    role_id, content_hash, file_name, mime_type = archive_claim(claim)
    require(request.authz.id == role_id)
    record_audit(Audit.ACT_ARCHIVE, content_hash=content_hash)
    tag_request(content_hash=content_hash, file_name=file_name)
    url = archive.generate_url(content_hash,
                               file_name=file_name,
                               mime_type=mime_type)
    if url is not None:
        return redirect(url)
    try:
        local_path = archive.load_file(content_hash)
        if local_path is None:
            return Response(status=404)
        return send_file(local_path,
                         as_attachment=True,
                         conditional=True,
                         attachment_filename=file_name,
                         mimetype=mime_type)
    finally:
        archive.cleanup_file(content_hash)
Ejemplo n.º 45
0
def tags(entity_id):
    enable_cache()
    entity = get_index_entity(entity_id, request.authz.READ)
    tag_request(collection_id=entity.get('collection_id'))
    record_audit(Audit.ACT_ENTITY, id=entity_id)
    results = []
    for (field, value, total) in entity_tags(entity, request.authz):
        qvalue = quote(value.encode('utf-8'))
        key = ('filter:%s' % field, qvalue)
        results.append({
            'id': query_string([key]),
            'value': value,
            'field': field,
            'count': total,
        })

    results.sort(key=lambda p: p['count'], reverse=True)
    return jsonify({
        'status': 'ok',
        'total': len(results),
        'results': results
    })
Ejemplo n.º 46
0
def delete(entity_id):
    entity = get_db_entity(entity_id, request.authz.WRITE)
    tag_request(collection_id=entity.collection_id)
    delete_entity(entity, sync=True)
    db.session.commit()
    return ('', 204)
Ejemplo n.º 47
0
def create():
    data = parse_request(EntityCreateSchema)
    collection = get_db_collection(data['collection_id'], request.authz.WRITE)
    data = create_entity(data, collection, sync=get_flag('sync', True))
    tag_request(entity_id=data.get('id'), collection_id=str(collection.id))
    return EntitySerializer.jsonify(data)
Ejemplo n.º 48
0
def view(entity_id):
    enable_cache()
    entity = get_index_entity(entity_id, request.authz.READ)
    record_audit(Audit.ACT_ENTITY, id=entity_id)
    tag_request(collection_id=entity.get('collection_id'))
    return EntitySerializer.jsonify(entity)