Async release

This commit is contained in:
Carlos Mesquita
2024-07-23 08:40:35 +01:00
parent a4caecdb4f
commit 3cf9fa5cba
116 changed files with 5609 additions and 30630 deletions

View File

@@ -0,0 +1,8 @@
from .document_stores import *
from .firebase import FirebaseStorage
__all__ = [
"FirebaseStorage"
]
__all__.extend(document_stores.__all__)

View File

@@ -0,0 +1,7 @@
from .firestore import Firestore
#from .mongo import MongoDB
__all__ = [
"Firestore",
#"MongoDB"
]

View File

@@ -0,0 +1,38 @@
import logging
from google.cloud.firestore_v1.async_client import AsyncClient
from google.cloud.firestore_v1.async_collection import AsyncCollectionReference
from google.cloud.firestore_v1.async_document import AsyncDocumentReference
from app.repositories.abc import IDocumentStore
class Firestore(IDocumentStore):
def __init__(self, client: AsyncClient):
self._client = client
self._logger = logging.getLogger(__name__)
async def save_to_db(self, collection: str, item):
collection_ref: AsyncCollectionReference = self._client.collection(collection)
update_time, document_ref = await collection_ref.add(item)
if document_ref:
self._logger.info(f"Document added with ID: {document_ref.id}")
return True, document_ref.id
else:
return False, None
async def save_to_db_with_id(self, collection: str, item, id: str):
collection_ref: AsyncCollectionReference = self._client.collection(collection)
document_ref: AsyncDocumentReference = collection_ref.document(id)
await document_ref.set(item)
doc_snapshot = await document_ref.get()
if doc_snapshot.exists:
self._logger.info(f"Document added with ID: {document_ref.id}")
return True, document_ref.id
else:
return False, None
async def get_all(self, collection: str):
collection_ref: AsyncCollectionReference = self._client.collection(collection)
docs = []
async for doc in collection_ref.stream():
docs.append(doc.to_dict())
return docs

View File

@@ -0,0 +1,36 @@
"""import logging
from pymongo import MongoClient
from app.repositories.abc import IDocumentStore
class MongoDB(IDocumentStore):
def __init__(self, client: MongoClient):
self._client = client
self._logger = logging.getLogger(__name__)
def save_to_db(self, collection: str, item):
collection_ref = self._client[collection]
result = collection_ref.insert_one(item)
if result.inserted_id:
self._logger.info(f"Document added with ID: {result.inserted_id}")
return True, str(result.inserted_id)
else:
return False, None
def save_to_db_with_id(self, collection: str, item, doc_id: str):
collection_ref = self._client[collection]
item['_id'] = doc_id
result = collection_ref.replace_one({'_id': id}, item, upsert=True)
if result.upserted_id or result.matched_count:
self._logger.info(f"Document added with ID: {doc_id}")
return True, doc_id
else:
return False, None
def get_all(self, collection: str):
collection_ref = self._client[collection]
all_documents = list(collection_ref.find())
return all_documents
"""

View File

@@ -0,0 +1,83 @@
import logging
from typing import Optional
import aiofiles
from httpx import AsyncClient
from app.repositories.abc import IFileStorage
class FirebaseStorage(IFileStorage):
def __init__(self, client: AsyncClient, token: str, bucket: str):
self._httpx_client = client
self._token = token
self._storage_url = f'https://firebasestorage.googleapis.com/v0/b/{bucket}'
self._logger = logging.getLogger(__name__)
async def download_firebase_file(self, source_blob_name: str, destination_file_name: str) -> Optional[str]:
source_blob_name = source_blob_name.replace('/', '%2F')
download_url = f"{self._storage_url}/o/{source_blob_name}?alt=media"
response = await self._httpx_client.get(
download_url,
headers={'Authorization': f'Firebase {self._token}'}
)
if response.status_code == 200:
async with aiofiles.open(destination_file_name, 'wb') as file:
await file.write(response.content)
self._logger.info(f"File downloaded to {destination_file_name}")
return destination_file_name
else:
self._logger.error(f"Failed to download blob {source_blob_name}. {response.status_code} - {response.content}")
return None
async def upload_file_firebase_get_url(self, destination_blob_name: str, source_file_name: str) -> Optional[str]:
destination_blob_name = destination_blob_name.replace('/', '%2F')
upload_url = f"{self._storage_url}/o/{destination_blob_name}"
async with aiofiles.open(source_file_name, 'rb') as file:
file_bytes = await file.read()
response = await self._httpx_client.post(
upload_url,
headers={
'Authorization': f'Firebase {self._token}',
"X-Goog-Upload-Protocol": "multipart"
},
files={
'metadata': (None, '{"metadata":{"test":"testMetadata"}}', 'application/json'),
'file': file_bytes
}
)
if response.status_code == 200:
self._logger.info(f"File {source_file_name} uploaded to {self._storage_url}/o/{destination_blob_name}.")
# TODO: Test this
#await self.make_public(destination_blob_name)
file_url = f"{self._storage_url}/o/{destination_blob_name}"
return file_url
else:
self._logger.error(f"Failed to upload file {source_file_name}. Error: {response.status_code} - {str(response.content)}")
return None
async def make_public(self, destination_blob_name: str):
acl_url = f"{self._storage_url}/o/{destination_blob_name}/acl"
acl = {'entity': 'allUsers', 'role': 'READER'}
response = await self._httpx_client.post(
acl_url,
headers={
'Authorization': f'Bearer {self._token}',
'Content-Type': 'application/json'
},
json=acl
)
if response.status_code == 200:
self._logger.info(f"Blob {destination_blob_name} is now public.")
else:
self._logger.error(f"Failed to make blob {destination_blob_name} public. {response.status_code} - {response.content}")