(20241010) Almost ready for deployment.
This commit is contained in:
@@ -11,7 +11,7 @@
|
|||||||
OBJECTIVE:
|
OBJECTIVE:
|
||||||
|
|
||||||
To provide an easy way to assess images for blurriness.
|
To provide an easy way to assess images for blurriness.
|
||||||
Tried and implemented using HuggingFace models.
|
Tried and implemented using HuggingFace behaviour_models.
|
||||||
|
|
||||||
REFERENCES:
|
REFERENCES:
|
||||||
|
|
||||||
@@ -193,7 +193,7 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
image = r"/home/developer/Downloads/low-res-check.png"
|
image = r"/home/developer/Downloads/low-res-check.png"
|
||||||
assessor = AssessImageBlur(model = r"/home/developer/PycharmProjects/utils/data/ai/models/hugging_face/image_classification/BlurOrBokeh")
|
assessor = AssessImageBlur(model = r"/home/developer/PycharmProjects/utils/data/ai/behaviour_models/hugging_face/image_classification/BlurOrBokeh")
|
||||||
usable = await assessor.is_ok(image)
|
usable = await assessor.is_ok(image)
|
||||||
classes = await assessor.classify(image)
|
classes = await assessor.classify(image)
|
||||||
print("IS OKAY:", usable)
|
print("IS OKAY:", usable)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
OBJECTIVE:
|
OBJECTIVE:
|
||||||
|
|
||||||
To provide an easy way to assess images for adult content.
|
To provide an easy way to assess images for adult content.
|
||||||
Tried and implemented using HuggingFace models.
|
Tried and implemented using HuggingFace behaviour_models.
|
||||||
|
|
||||||
REFERENCES:
|
REFERENCES:
|
||||||
|
|
||||||
|
|||||||
@@ -13,12 +13,12 @@
|
|||||||
To provide an easy way to get masks from dichotomous image segmentation.
|
To provide an easy way to get masks from dichotomous image segmentation.
|
||||||
|
|
||||||
This code uses a very specific model from HuggingFace: "ZhengPeng7/BiRefNet-portrait".
|
This code uses a very specific model from HuggingFace: "ZhengPeng7/BiRefNet-portrait".
|
||||||
You may experiment with other models too, but make sure that model is made for "dichotomous" behaviour. This
|
You may experiment with other behaviour_models too, but make sure that model is made for "dichotomous" behaviour. This
|
||||||
means that the model should have only two classes like "foreground", and "background". The specified model was
|
means that the model should have only two classes like "foreground", and "background". The specified model was
|
||||||
trained for implementing portrait mode style blurring of backgrounds.
|
trained for implementing portrait mode style blurring of backgrounds.
|
||||||
|
|
||||||
The originally tested model has an MIT license as per their GitHub page. The code in this file may or may not
|
The originally tested model has an MIT license as per their GitHub page. The code in this file may or may not
|
||||||
support drop-in replacement for other models, please be aware about this.
|
support drop-in replacement for other behaviour_models, please be aware about this.
|
||||||
|
|
||||||
REFERENCES:
|
REFERENCES:
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
OBJECTIVE:
|
OBJECTIVE:
|
||||||
|
|
||||||
To provide a class to detect objects in images using YOLO models.
|
To provide a class to detect objects in images using YOLO behaviour_models.
|
||||||
|
|
||||||
REFERENCES:
|
REFERENCES:
|
||||||
|
|
||||||
@@ -166,7 +166,7 @@ class YoloDetect:
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
# model_file_path = os.path.join(constants.PROJECT_DIRECTORY, "ai", "yolo", "models", "yolov8x.pt")
|
# model_file_path = os.path.join(constants.PROJECT_DIRECTORY, "ai", "yolo", "behaviour_models", "yolov8x.pt")
|
||||||
model_file_path = r"/home/developer/PycharmProjects/utils/data/ai/models/hugging_face/object_detection/YOLOv10-Document-Layout-Analysis/yolov10x_best.pt"
|
model_file_path = r"/home/developer/PycharmProjects/utils/data/ai/models/hugging_face/object_detection/YOLOv10-Document-Layout-Analysis/yolov10x_best.pt"
|
||||||
# sample_image_path = r"/home/developer/Downloads/2_cats.jpg"
|
# sample_image_path = r"/home/developer/Downloads/2_cats.jpg"
|
||||||
sample_image_path = r"/home/developer/Downloads/flattened_image.jpg"
|
sample_image_path = r"/home/developer/Downloads/flattened_image.jpg"
|
||||||
|
|||||||
Binary file not shown.
@@ -55,8 +55,12 @@ import datetime
|
|||||||
|
|
||||||
# System-level activities:
|
# System-level activities:
|
||||||
import io
|
import io
|
||||||
|
<<<<<<< HEAD
|
||||||
|
=======
|
||||||
|
import os
|
||||||
|
>>>>>>> 0450b2a445509ef536ccf8598ab31a0e4ba09f18
|
||||||
|
|
||||||
# For Pydantic data-models:
|
# For Pydantic data-behaviour_models:
|
||||||
import pydantic
|
import pydantic
|
||||||
|
|
||||||
# For hashing and shortening the hash:
|
# For hashing and shortening the hash:
|
||||||
@@ -700,7 +704,9 @@ def should_not_be_under_maintenance(attr_name):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
Use this decorator to reject a request when the app is being marked as "under-maintenance". You will need to create
|
Use this decorator to reject a request when the app is being marked as "under-maintenance". You will need to create
|
||||||
a boolean variable within the scope of the 'current_app' for this to work.
|
a boolean variable within the scope of the 'current_app' for this to work. An alternate to this is to set the value
|
||||||
|
in an environment variable named 'IS_UNDER_MAINTENANCE' to a string value of either 'True' or 'False' for
|
||||||
|
multi-worker deployments.
|
||||||
:param attr_name: The name of the boolean variable that will hold the information about the app being under
|
:param attr_name: The name of the boolean variable that will hold the information about the app being under
|
||||||
maintenance. If its value is True at the time of checking, the incoming request will be rejected.
|
maintenance. If its value is True at the time of checking, the incoming request will be rejected.
|
||||||
:return: The decorator factory.
|
:return: The decorator factory.
|
||||||
@@ -717,7 +723,9 @@ def should_not_be_under_maintenance(attr_name):
|
|||||||
# Get the attribute and check if it indicates that the app is under maintenance,
|
# Get the attribute and check if it indicates that the app is under maintenance,
|
||||||
# call the wrapped function if not under maintenance:
|
# call the wrapped function if not under maintenance:
|
||||||
app_attr = getattr(current_app, attr_name)
|
app_attr = getattr(current_app, attr_name)
|
||||||
if app_attr: response = ResponseModel(status_code = StatusCodes.DOWN_FOR_MAINTENANCE).for_quart()
|
env_attr = True if os.environ.get("IS_UNDER_MAINTENANCE", "False").lower() == "true" else False
|
||||||
|
if app_attr or env_attr:
|
||||||
|
response = ResponseModel(status_code = StatusCodes.DOWN_FOR_MAINTENANCE).for_quart()
|
||||||
else:
|
else:
|
||||||
response = await func(*args, **kwargs)
|
response = await func(*args, **kwargs)
|
||||||
kwargs["decorator_count"] -= 1
|
kwargs["decorator_count"] -= 1
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Vendored
+46
@@ -123,6 +123,52 @@ def cache_it(cache = None, expiry = 120):
|
|||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
def cache_class_methods(attr_name, expiry = 120):
|
||||||
|
|
||||||
|
"""
|
||||||
|
This decorator factory takes an instance of the async caching class 'AsyncRedisCache' and holds your data there.
|
||||||
|
If a subsequent call is made to the same decorated function with the same inputs, the result is fetched from the
|
||||||
|
cache instead of going through the whole function again.
|
||||||
|
:param attr_name: The name of the variable that has an instance of "AsyncRedisCache".
|
||||||
|
:param expiry: The time in seconds after which the cached data must be cleared.
|
||||||
|
:return: The decorator that automatically caches your data.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def decorator(func):
|
||||||
|
|
||||||
|
@wraps(func)
|
||||||
|
async def wrapper(self, *args, **kwargs):
|
||||||
|
|
||||||
|
# Get the cache object first:
|
||||||
|
cache_obj = getattr(self, attr_name)
|
||||||
|
|
||||||
|
# We first use the name of the function and the inputs given to it to generate a key for Redis with the
|
||||||
|
# simple hashing and shortening by way of base64 strings:
|
||||||
|
inputs_given = func.__name__ + str([_ for _ in args]) + str(kwargs)
|
||||||
|
sha256_hash = hashlib.sha256()
|
||||||
|
sha256_hash.update(inputs_given.encode("utf-8"))
|
||||||
|
hashed_key = sha256_hash.digest()
|
||||||
|
base64_key = base64.b64encode(hashed_key).decode("utf-8")
|
||||||
|
|
||||||
|
# Now we check if we have the value in cache:
|
||||||
|
try: response = await cache_obj.get(base64_key, raise_exception = True)
|
||||||
|
|
||||||
|
# If the key doesn't exist, we pass through the function and store the results.
|
||||||
|
except:
|
||||||
|
response = await func(self, *args, **kwargs)
|
||||||
|
await cache_obj.set(key = base64_key, value = response, expiry = expiry)
|
||||||
|
|
||||||
|
# Return the response from the wrapped function.
|
||||||
|
return response
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
# *****************************************************************************************************************
|
# *****************************************************************************************************************
|
||||||
# ***** ****
|
# ***** ****
|
||||||
# *** CLASSES ***
|
# *** CLASSES ***
|
||||||
|
|||||||
Binary file not shown.
@@ -96,7 +96,8 @@ class AsyncMySQL:
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
A class to work with SQL-based databases. Originally meant to only invoke stored procedures and retrieve them as
|
A class to work with SQL-based databases. Originally meant to only invoke stored procedures and retrieve them as
|
||||||
JSON-like structures (list or dict).
|
JSON-like structures (list or dict). The format for the results was very specific to our use case for serving
|
||||||
|
Bicree's requirement. This may not serve your requirement at all.
|
||||||
:param pool_size: The number of connections to maintain n a pool.
|
:param pool_size: The number of connections to maintain n a pool.
|
||||||
:param args: Any arguments to pass. Not used.
|
:param args: Any arguments to pass. Not used.
|
||||||
:param kwargs: Pass the connection configuration from here.
|
:param kwargs: Pass the connection configuration from here.
|
||||||
@@ -207,8 +208,6 @@ class AsyncMySQL:
|
|||||||
await asyncio.sleep(backoff_seconds)
|
await asyncio.sleep(backoff_seconds)
|
||||||
backoff_seconds = backoff_seconds * backoff_multiplier
|
backoff_seconds = backoff_seconds * backoff_multiplier
|
||||||
|
|
||||||
print("LEN:", len(results))
|
|
||||||
|
|
||||||
# If the results are blank:
|
# If the results are blank:
|
||||||
if len(results) == 0: return {
|
if len(results) == 0: return {
|
||||||
"status": results[0][0]["status"],
|
"status": results[0][0]["status"],
|
||||||
@@ -238,9 +237,6 @@ class AsyncMySQL:
|
|||||||
formatted_results["seconds"] = time.perf_counter() - start_ts
|
formatted_results["seconds"] = time.perf_counter() - start_ts
|
||||||
|
|
||||||
# Done here:
|
# Done here:
|
||||||
print(f"{procedure_name}:")
|
|
||||||
print(json.to_string(formatted_results))
|
|
||||||
print("\n")
|
|
||||||
if return_exception: return formatted_results, exception
|
if return_exception: return formatted_results, exception
|
||||||
else: return formatted_results
|
else: return formatted_results
|
||||||
|
|
||||||
@@ -274,12 +270,20 @@ if __name__ == "__main__":
|
|||||||
:return: None.
|
:return: None.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# cred_json = {
|
||||||
|
# "host": "del.ditscentre.in",
|
||||||
|
# "user": "bicree",
|
||||||
|
# "port": 3306,
|
||||||
|
# "password": "9c3b2808a4aa281129d399fe09e69b53",
|
||||||
|
# "database": "bicree"
|
||||||
|
# }
|
||||||
|
|
||||||
cred_json = {
|
cred_json = {
|
||||||
"host": "del.ditscentre.in",
|
"host": "del.ditscentre.in",
|
||||||
"user": "bicree",
|
"user": "caOffice",
|
||||||
"port": 3306,
|
"port": 3306,
|
||||||
"password": "9c3b2808a4aa281129d399fe09e69b53",
|
"password": "jstArchon",
|
||||||
"database": "bicree"
|
"database": "caOffice"
|
||||||
}
|
}
|
||||||
|
|
||||||
db_conn = AsyncMySQL(
|
db_conn = AsyncMySQL(
|
||||||
@@ -299,10 +303,16 @@ if __name__ == "__main__":
|
|||||||
# )
|
# )
|
||||||
# )
|
# )
|
||||||
|
|
||||||
|
# result = await db_conn.call_procedure_and_get_json(
|
||||||
|
# procedure_name = "listSummary",
|
||||||
|
# procedure_args = ("bd7a6e53-1345-11ef-940c-0cc47a84a0bb",)
|
||||||
|
# )
|
||||||
|
|
||||||
result = await db_conn.call_procedure_and_get_json(
|
result = await db_conn.call_procedure_and_get_json(
|
||||||
procedure_name = "listSummary",
|
procedure_name = "campaign_activity_report",
|
||||||
procedure_args = ("bd7a6e53-1345-11ef-940c-0cc47a84a0bb",)
|
procedure_args = (10000000,)
|
||||||
)
|
)
|
||||||
|
print("RESULT:", json.to_string(result, default = str))
|
||||||
|
|
||||||
|
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
|
|||||||
@@ -387,7 +387,7 @@ if __name__ == "__main__":
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
my_scanner = DocumentScanner(
|
my_scanner = DocumentScanner(
|
||||||
layout_detection_yolo = r"/home/developer/PycharmProjects/utils/data/ai/models/hugging_face/object_detection/YOLOv10-Document-Layout-Analysis/yolov10x_best.pt",
|
layout_detection_yolo = r"/home/developer/PycharmProjects/utils/data/ai/behaviour_models/hugging_face/object_detection/YOLOv10-Document-Layout-Analysis/yolov10x_best.pt",
|
||||||
whitelisted_yolo_classes = [0, 1, 3, 4, 5, 7, 9, 10],
|
whitelisted_yolo_classes = [0, 1, 3, 4, 5, 7, 9, 10],
|
||||||
# whitelisted_yolo_classes = [0, 1, 3, 4, 5, 6, 7, 8, 9, 10],
|
# whitelisted_yolo_classes = [0, 1, 3, 4, 5, 6, 7, 8, 9, 10],
|
||||||
ocr_languages = ["en"]
|
ocr_languages = ["en"]
|
||||||
|
|||||||
@@ -353,7 +353,7 @@ if __name__ == "__main__":
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
my_scanner = DocumentScanner(
|
my_scanner = DocumentScanner(
|
||||||
layout_detection_yolo = r"/home/developer/PycharmProjects/utils/data/ai/models/hugging_face/object_detection/YOLOv10-Document-Layout-Analysis/yolov10x_best.pt",
|
layout_detection_yolo = r"/home/developer/PycharmProjects/utils/data/ai/behaviour_models/hugging_face/object_detection/YOLOv10-Document-Layout-Analysis/yolov10x_best.pt",
|
||||||
whitelisted_yolo_classes = [0, 1, 3, 4, 5, 7, 9, 10],
|
whitelisted_yolo_classes = [0, 1, 3, 4, 5, 7, 9, 10],
|
||||||
# whitelisted_yolo_classes = [0, 1, 3, 4, 5, 6, 7, 8, 9, 10],
|
# whitelisted_yolo_classes = [0, 1, 3, 4, 5, 6, 7, 8, 9, 10],
|
||||||
ocr_languages = ["en"]
|
ocr_languages = ["en"]
|
||||||
|
|||||||
Reference in New Issue
Block a user