Skip to content

Commit

Permalink
IDV-Static-Liveness resource added
Browse files Browse the repository at this point in the history
  • Loading branch information
mehmet-yoti committed Dec 5, 2024
1 parent 5b8650f commit f7c41e6
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 8 deletions.
30 changes: 29 additions & 1 deletion examples/doc_scan/app.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import yoti_python_sdk
from flask import Flask, Response, render_template, request, session
from flask import Flask, Response, render_template, request, session, jsonify
from yoti_python_sdk.doc_scan import (
DocScanClient,
RequestedDocumentAuthenticityCheckBuilder,
Expand Down Expand Up @@ -133,6 +133,9 @@ def success():

try:
session_result = doc_scan_client.get_session(session_id)
resources = session_result.resources
print(resources)

except DocScanException as e:
return render_template("error.html", error=e.message)

Expand Down Expand Up @@ -173,6 +176,31 @@ def media():
retrieved_media.content, content_type=retrieved_media.mime_type, status=200
)

@app.route("/mediaShow")
def mediaShow():
media_id = request.args.get("mediaId", None)
session_id = request.args.get("sessionId", None)

if media_id is None:
return Response(status=404)

doc_scan_client = DocScanClient(YOTI_CLIENT_SDK_ID, YOTI_KEY_FILE_PATH)

#session_id = session.get("doc_scan_session_id", None)
if session_id is None:
return Response("No session ID available", status=404)

try:
retrieved_media = doc_scan_client.get_media_content(session_id, media_id)
except DocScanException as e:
return render_template("error.html", error=e.message)

if retrieved_media is None:
return Response("", status=204)

return Response(
retrieved_media.content, content_type=retrieved_media.mime_type, status=200
)

if __name__ == "__main__":
app.run()
52 changes: 51 additions & 1 deletion examples/doc_scan/templates/success.html
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,7 @@ <h3 class="mb-0">
{% for frame in liveness.frames %}
{% if frame.media is not none %}
<div class="card">
<img class="card-img-top" src="/media?mediaId={{ frame.media.id }}" />
<img class="card-img-top" src="/mediaShow?mediaId={{ frame.media.id }}&sessionId={{ session_result.session_id }}" />
<div class="card-body">
<h5 class="card-title">Frame</h5>
</div>
Expand All @@ -626,5 +626,55 @@ <h5 class="card-title">Frame</h5>
</div>
{% endfor %}
{% endwith %}

{% if session_result.resources.static_liveness_resources|length %}
<div class="row pt-4">
<div class="col">
<h2>Static Liveness Resources</h2>
</div>
</div>
{% endif %}

{% with liveness_num=0 %}
{% for liveness in session_result.resources.static_liveness_resources %}
{% set liveness_num = loop.index %}
<div class="row pt-4">
<div class="col">
<table class="table table-striped table-light">
<tbody>
<tr>
<td>ID</td>
<td>{{ liveness.id }}</td>
</tr>
</tbody>
</table>
<div class="accordion mt-3">
{% if liveness.image is not none %}
<div class="card">
<div class="card-header" id="liveness-{{ liveness_num }}-image">
<h3 class="mb-0">
<button class="btn btn-link" type="button" data-toggle="collapse"
data-target="#collapse-liveness-{{ liveness_num }}-image" aria-expanded="true"
aria-controls="collapse-liveness-{{ liveness_num }}-image">
Image
</button>
</h3>
</div>
<div id="collapse-liveness-{{ liveness_num }}-image" class="collapse" aria-labelledby="liveness-{{ liveness_num }}-image">
<div class="card">
<img class="card-img-top" src="/media?mediaId={{ liveness.image.media.id }}" />
<div class="card-body">
<h5 class="card-title">Static Liveness Image</h5>
</div>
</div>
</div>
</div>
{% endif %}
</div>

</div>
</div>
{% endfor %}
{% endwith %}
</div>
{% include "layout/footer.html" %}
6 changes: 3 additions & 3 deletions yoti_python_sdk/doc_scan/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ def get_session(self, session_id):
.build()
)
response = request.execute()

if response.status_code != 200:
raise DocScanException("Failed to retrieve session", response)

Expand Down Expand Up @@ -132,12 +131,13 @@ def get_media_content(self, session_id, media_id):
.with_get()
.with_pem_file(self.__key)
.with_base_url(self.__api_url)
.with_endpoint(Endpoint.get_media_content_path(session_id, media_id))
.with_endpoint(Endpoint.get_media_content_path(
session_id,media_id))
.with_param("sdkId", self.__sdk_id)
.build()

)
response = request.execute()

if response.status_code == 204:
return None

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,63 @@ def __init__(self, data=None):
if data is None:
data = dict()

ResourceResponse.__init__(self, data)

super().__init__(data)
self.__liveness_type = data.get("liveness_type", None)

@property
def liveness_type(self):
"""
Returns the type of liveness resource.
:return: liveness type
:rtype: str or None
"""
return self.__liveness_type

def to_zoom_liveness_resource(self):
"""
Converts this resource to a ZoomLivenessResourceResponse if applicable.
:return: ZoomLivenessResourceResponse or None
"""
if self.liveness_type == "zoom":
return ZoomLivenessResourceResponse(self._data)
return None

def to_static_liveness_resource(self):
"""
Converts this resource to a StaticLivenessResourceResponse if applicable.
:return: StaticLivenessResourceResponse or None
"""
if self.liveness_type == "static":
return StaticLivenessResourceResponse(self._data)
return None

@staticmethod
def filter_resources(resources, resource_type):
"""
Filters and converts resources to the specified type.
:param resources: List of raw resources
:type resources: list[dict]
:param resource_type: The target resource type ('zoom' or 'static')
:type resource_type: str
:return: List of resources converted to the specified type
:rtype: list[ZoomLivenessResourceResponse or StaticLivenessResourceResponse]
"""
filtered_resources = []
for resource in resources:
resource_obj = LivenessResourceResponse(resource)
if resource_type == "zoom":
zoom_resource = resource_obj.to_zoom_liveness_resource()
if zoom_resource:
filtered_resources.append(zoom_resource)
elif resource_type == "static":
static_resource = resource_obj.to_static_liveness_resource()
if static_resource:
filtered_resources.append(static_resource)
return filtered_resources

class ZoomLivenessResourceResponse(LivenessResourceResponse):
"""
Expand Down Expand Up @@ -65,3 +114,52 @@ def frames(self):
:rtype: list[FrameResponse]
"""
return self.__frames

class StaticLivenessResourceResponse(LivenessResourceResponse):
"""
Represents a Static Liveness resource for a given session
"""

def __init__(self, data=None):
"""
:param data: the data to parse
:type data: dict or None
"""
if data is None:
data = dict()

LivenessResourceResponse.__init__(self, data)

self.__image = FrameResponse(data["image"]) if "image" in data.keys() else None

@property
def image(self):
"""
Returns the associated image for the static liveness resource.
:return: the image
:rtype: MediaResponse or None
"""
return self.__image

@property
def facemap(self):
"""
Returns the associated facemap information for
the zoom liveness resource
:return: the facemap
:rtype: FaceMapResponse or None
"""
return self.__facemap

@property
def frames(self):
"""
Returns the list of associated frames for
the zoom liveness resource
:return: the frames
:rtype: list[FrameResponse]
"""
return self.__frames
19 changes: 18 additions & 1 deletion yoti_python_sdk/doc_scan/session/retrieve/resource_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from yoti_python_sdk.doc_scan.session.retrieve.liveness_resource_response import (
LivenessResourceResponse,
ZoomLivenessResourceResponse,
StaticLivenessResourceResponse
)


Expand Down Expand Up @@ -54,7 +55,9 @@ def __parse_liveness_capture(liveness_capture):
:return: the parsed liveness capture
:rtype: LivenessResourceResponse
"""
types = {"ZOOM": ZoomLivenessResourceResponse}
types = {"ZOOM": ZoomLivenessResourceResponse,
"STATIC": StaticLivenessResourceResponse,
}

clazz = types.get(
liveness_capture.get("liveness_type", None),
Expand Down Expand Up @@ -105,3 +108,17 @@ def zoom_liveness_resources(self):
for liveness in self.__liveness_capture
if isinstance(liveness, ZoomLivenessResourceResponse)
]

@property
def static_liveness_resources(self):
"""
Returns a filtered list of static liveness capture resources
:return: list of static liveness captures
:rtype: list[StaticLivenessResourceResponse]
"""
return [
liveness
for liveness in self.__liveness_capture
if isinstance(liveness, StaticLivenessResourceResponse)
]

0 comments on commit f7c41e6

Please sign in to comment.