Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions commons/data_access_layer/file_stream.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import os
from azure.storage.blob.blockblobservice import BlockBlobService

ACCOUNT_KEY = os.environ.get('AZURE_STORAGE_ACCOUNT_KEY')

class FileStream:
def __init__(self, account_name:str, container_name:str):
"""
Initialize the FileStream object. which is used to get the file stream from Azure Blob Storage.
`account_name`: The name of the Azure Storage account.
`container_name`: The name of the Azure Storage container.
"""
self.account_name = account_name
self.container_name = container_name
self.blob_service = BlockBlobService(account_name=self.account_name, account_key=ACCOUNT_KEY)

def get_file_stream(self, filename:str):
import tempfile
try:
local_file = tempfile.NamedTemporaryFile()
self.blob_service.get_blob_to_stream(self.container_name, filename, stream=local_file)

local_file.seek(0)
return local_file
except Exception as e:
print(e)
return None
5 changes: 4 additions & 1 deletion requirements/time_tracker_api/dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,7 @@ coverage==4.5.1
# CLI tools
PyInquirer==1.0.3
pyfiglet==0.7
factory_boy==3.2.0
factory_boy==3.2.0

# azure blob storage
azure-storage-blob==2.1.0
15 changes: 15 additions & 0 deletions tests/commons/data_access_layer/file_stream_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import json

from commons.data_access_layer.file_stream import FileStream

fs = FileStream("storageaccounteystr82c5","tt-common-files")

def test_get_file_stream_return_file_when_enter_file_name():
result = fs.get_file_stream("activity_test.json")

assert len(json.load(result)) == 15

def test_get_file_stream_return_None_when_not_enter_file_name_or_incorrect_name():
result = fs.get_file_stream("")

assert result == None
12 changes: 12 additions & 0 deletions tests/time_tracker_api/activities/activities_model_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,15 @@ def test_create_activity_should_add_active_status(
activity_repository_create_mock.assert_called_with(
data=expect_argument, event_context=ANY
)

def test_find_all_from_blob_storage(
event_context: EventContext,
activity_repository: ActivityCosmosDBRepository,
):
activity_repository.container = Mock()

result = activity_repository.find_all_from_blob_storage(
event_context=event_context,
file_name="activity_test.json"
)
assert len(result) == 15
13 changes: 11 additions & 2 deletions tests/time_tracker_api/activities/activities_namespace_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from flask import json
from flask.testing import FlaskClient
from flask_restplus._http import HTTPStatus
import pytest
from pytest_mock import MockFixture

from utils.enums.status import Status
Expand All @@ -18,6 +19,14 @@

fake_activity = ({"id": fake.random_int(1, 9999)}).update(valid_activity_data)

def test_get_all_activities_return_list_activities_when_send_get_request(
client: FlaskClient, valid_header: dict
):
response = client.get(
"/activities", headers=valid_header, follow_redirects=True
)

assert HTTPStatus.OK == response.status_code

def test_create_activity_should_succeed_with_valid_request(
client: FlaskClient, mocker: MockFixture, valid_header: dict
Expand Down Expand Up @@ -55,7 +64,7 @@ def test_create_activity_should_reject_bad_request(
assert HTTPStatus.BAD_REQUEST == response.status_code
repository_create_mock.assert_not_called()


@pytest.mark.skip(reason="There is currently no way to test this. Getting the value of the azure blob storage")
def test_list_all_active(
client: FlaskClient, mocker: MockFixture, valid_header: dict
):
Expand All @@ -81,7 +90,7 @@ def test_list_all_active(
max_count=ANY,
)


@pytest.mark.skip(reason="There is currently no way to test this. Getting the value of the azure blob storage")
def test_list_all_active_activities(
client: FlaskClient, mocker: MockFixture, valid_header: dict
):
Expand Down
24 changes: 22 additions & 2 deletions time_tracker_api/activities/activities_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from commons.data_access_layer.database import EventContext
from utils.enums.status import Status
from utils.query_builder import CosmosDBQueryBuilder

from commons.data_access_layer.file_stream import FileStream

class ActivityDao(CRUDDao):
pass
Expand Down Expand Up @@ -113,6 +113,21 @@ def find_all(
function_mapper = self.get_mapper_or_dict(mapper)
return list(map(function_mapper, result))

def find_all_from_blob_storage(
self,
event_context: EventContext,
mapper: Callable = None,
file_name: str = "activity.json",
):
tenant_id_value = self.find_partition_key_value(event_context)
function_mapper = self.get_mapper_or_dict(mapper)
if tenant_id_value is None:
return []

import json
fs = FileStream("storageaccounteystr82c5","tt-common-files")
result = fs.get_file_stream(file_name)
return list(map(function_mapper, json.load(result))) if result is not None else []

class ActivityCosmosDBDao(APICosmosDBDao, ActivityDao):
def __init__(self, repository):
Expand All @@ -128,7 +143,7 @@ def get_all_with_id_in_list(
activity_ids,
)

def get_all(
def get_all_old(
self,
conditions: dict = None,
activities_id: List = None,
Expand All @@ -147,6 +162,11 @@ def get_all(
)
return activities

def get_all(self, conditions: dict = None) -> list:
event_ctx = self.create_event_context("read-many")
activities = self.repository.find_all_from_blob_storage(event_context=event_ctx)
return activities

def create(self, activity_payload: dict):
event_ctx = self.create_event_context('create')
activity_payload['status'] = Status.ACTIVE.value
Expand Down