Manish Gupta commited on
Commit
ac621a7
·
1 Parent(s): 38a75a9

First Commit.

Browse files
Files changed (4) hide show
  1. __pycache__/aws_utils.cpython-310.pyc +0 -0
  2. app.py +150 -0
  3. aws_utils.py +136 -0
  4. requirements.txt +1 -0
__pycache__/aws_utils.cpython-310.pyc ADDED
Binary file (3.92 kB). View file
 
app.py ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import io
3
+ from PIL import Image
4
+ import gradio as gr
5
+
6
+ import aws_utils
7
+
8
+ AWS_BUCKET = os.getenv("AWS_BUCKET")
9
+ os.environ["AWS_ACCESS_KEY_ID"] = os.getenv("AWS_ACCESS_KEY_ID")
10
+ os.environ["AWS_SECRET_ACCESS_KEY"] = os.getenv("AWS_SECRET_ACCESS_KEY")
11
+ os.environ["S3_BUCKET_NAME"] = os.getenv("AWS_BUCKET")
12
+
13
+
14
+ def load_text_data(characters: list, current_index: int):
15
+ curr_char = characters[current_index]
16
+ return (
17
+ curr_char["name"],
18
+ curr_char["age"],
19
+ curr_char["gender"],
20
+ curr_char["description"],
21
+ )
22
+
23
+
24
+ def load_data(character_data: list, current_index: int):
25
+ if current_index < len(character_data) - 1:
26
+ current_index += 1
27
+ else:
28
+ return [], *load_text_data(character_data, current_index)
29
+
30
+ images = []
31
+ name = character_data[current_index]["name"]
32
+ for idx in range(1, 5):
33
+ url = f"s3://{AWS_BUCKET}/{comic_id}/character_compositions/{name}/"
34
+ data = aws_utils.fetch_from_s3(url)
35
+ images.append(Image.open(io.BytesIO(data)))
36
+
37
+ return images, *load_text_data(character_data, current_index)
38
+
39
+
40
+ def load_data_once(comic_id: str, current_index: int):
41
+ # Logic to load and return character images based on comic_id
42
+ # You can replace this with actual image paths or generation logic
43
+ print(f"Getting characters for comic id: {comic_id}")
44
+ characters = []
45
+ data = eval(
46
+ aws_utils.fetch_from_s3(
47
+ source=f"s3://{AWS_BUCKET}/{comic_id}/characters.json"
48
+ ).decode("utf-8")
49
+ )
50
+ for _, profile in data.items():
51
+ characters.append(profile)
52
+
53
+ images = []
54
+ # Loading the 0th frame of 0th scene in 0th episode.
55
+ name = characters[current_index]["name"]
56
+ for idx in range(1, 5):
57
+ url = f"s3://{AWS_BUCKET}/{comic_id}/character_compositions/{name}/"
58
+ data = aws_utils.fetch_from_s3(url)
59
+ images.append(Image.open(io.BytesIO(data)))
60
+
61
+ return images, *load_text_data(characters, current_index)
62
+
63
+
64
+ def save_image(
65
+ selected_image,
66
+ comic_id: str,
67
+ character_data: list,
68
+ current_index: int,
69
+ ):
70
+ # Implement your AWS S3 save logic here
71
+ print(f"Saving image: {selected_image}")
72
+ name = character_data[current_index]["name"]
73
+ with Image.open(selected_image[0]) as img:
74
+ # Convert and save as JPG
75
+ img_bytes = io.BytesIO()
76
+ img.convert("RGB").save(img_bytes, "JPEG")
77
+ img_bytes.seek(0)
78
+
79
+ aws_utils.save_to_s3(
80
+ AWS_BUCKET,
81
+ f"{comic_id}/characters",
82
+ img_bytes,
83
+ f"{name}.jpg",
84
+ )
85
+ print("Image saved successfully!")
86
+
87
+
88
+ # Function to handle image selection and enable the save button
89
+ def select_image(selected_image_index, images):
90
+ # Get the selected image from its index
91
+ selected_image = images[selected_image_index]
92
+ return gr.update(interactive=True), selected_image
93
+
94
+
95
+ with gr.Blocks() as demo:
96
+ selected_image = gr.State(None)
97
+ current_index = gr.State(0)
98
+ character_data = gr.State([])
99
+
100
+ with gr.Row():
101
+ comic_id = gr.Textbox(label="Enter Comic ID:", placeholder="Enter Comic ID")
102
+ load_button = gr.Button("Load Data")
103
+
104
+ images = gr.Gallery(
105
+ label="Select an Image", elem_id="image_select", columns=4, height=300
106
+ )
107
+
108
+ # Display information about current Character
109
+ with gr.Row():
110
+ name = gr.Textbox(label="Name", interactive=False)
111
+ age = gr.Textbox(label="Age", interactive=False)
112
+ gender = gr.Textbox(label="Gender", interactive=False)
113
+ description = gr.Textbox(label="description", interactive=False)
114
+
115
+ # buttons to interact with the data
116
+ with gr.Row():
117
+ save_button = gr.Button("Save Image")
118
+ next_button = gr.Button("Next Image")
119
+
120
+ load_button.click(
121
+ load_data_once,
122
+ inputs=[comic_id, current_index],
123
+ outputs=[images, character_data, current_index, name, age, gender, description],
124
+ )
125
+
126
+ # When an image is clicked
127
+ images.select(
128
+ select_image,
129
+ inputs=[gr.Number(), images],
130
+ outputs=[save_button, selected_image],
131
+ )
132
+
133
+ save_button.click(
134
+ save_image,
135
+ inputs=[
136
+ selected_image,
137
+ comic_id,
138
+ character_data,
139
+ current_index,
140
+ ],
141
+ outputs=[],
142
+ )
143
+
144
+ next_button.click(
145
+ load_data,
146
+ inputs=[character_data, current_index],
147
+ outputs=[images, character_data, current_index, name, age, gender, description],
148
+ )
149
+
150
+ demo.launch()
aws_utils.py ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+ from io import BytesIO
4
+ from typing import Union
5
+ from urllib.parse import urlparse
6
+
7
+ import boto3
8
+ from botocore.client import Config
9
+ from botocore.exceptions import NoCredentialsError
10
+
11
+ AWS_REGION = os.getenv("AWS_REGION")
12
+
13
+ # Initialize the S3 client
14
+ S3_CLIENT = boto3.client(
15
+ "s3", region_name=AWS_REGION, config=Config(signature_version="s3v4")
16
+ )
17
+
18
+
19
+ def save_to_s3(
20
+ bucket_name: str,
21
+ folder_name: str,
22
+ content: Union[str, dict, BytesIO],
23
+ file_name: str,
24
+ ) -> str:
25
+ """
26
+ Save a file to an S3 bucket, determining the content type based on the input type.
27
+
28
+ Args:
29
+ bucket_name (str): The name of the S3 bucket.
30
+ folder_name (str): The folder path in the S3 bucket.
31
+ content (Union[str, dict, BytesIO]): The content to save, can be a string, dictionary, or BytesIO.
32
+ file_name (str): The file name under which the content should be saved.
33
+
34
+ Returns:
35
+ str: The S3 URL of the uploaded file, or an error message if credentials are not available.
36
+ """
37
+ # Ensure the folder name ends with a '/'
38
+ # if not folder_name.endswith('/'):
39
+ # folder_name += '/'
40
+ # Determine file name and content type based on the input
41
+ if isinstance(content, str):
42
+ file_content = content
43
+ content_type = "text/plain"
44
+ elif isinstance(content, dict):
45
+ file_content = json.dumps(content)
46
+ content_type = "application/json"
47
+ elif isinstance(content, BytesIO):
48
+ file_content = content
49
+ content_type = "image/jpeg"
50
+ else:
51
+ print(
52
+ "Invalid content type. Content must be a string, dictionary, or BytesIO."
53
+ )
54
+ raise ValueError("Content must be either a string, dictionary, or BytesIO.")
55
+
56
+ # Ensure the folder name ends with a '/'
57
+ s3_file_path = f"{folder_name.rstrip('/')}/{file_name}"
58
+
59
+ try:
60
+ # Upload the file to S3
61
+ S3_CLIENT.put_object(
62
+ Bucket=bucket_name,
63
+ Key=s3_file_path,
64
+ Body=file_content,
65
+ ContentType=content_type,
66
+ )
67
+ s3_url = f"s3://{bucket_name}/{s3_file_path}"
68
+ print(f"File successfully uploaded to {s3_url}")
69
+ return s3_url
70
+
71
+ except NoCredentialsError:
72
+ print("AWS credentials not available.")
73
+ return "Error: AWS credentials not available."
74
+
75
+
76
+ def fetch_from_s3(source: Union[str, dict], region_name: str = "ap-south-1") -> bytes:
77
+ """
78
+ Fetch a file's content from S3 given a source URL or dictionary with bucket and key.
79
+
80
+ Args:
81
+ source (Union[str, dict]): The source S3 URL or a dictionary with 'bucket_name' and 'file_key'.
82
+ region_name (str): The AWS region name for the S3 client (default is 'ap-south-1').
83
+
84
+ Returns:
85
+ bytes: The content of the file fetched from S3.
86
+ """
87
+ print(f"Fetching file from S3. Source: {source}")
88
+ s3_client = boto3.client("s3", region_name=region_name)
89
+
90
+ # Parse the source depending on its type
91
+ if isinstance(source, str):
92
+ parsed_url = urlparse(source)
93
+ bucket_name = parsed_url.netloc.split(".")[0]
94
+ file_path = parsed_url.path.lstrip("/")
95
+ elif isinstance(source, dict):
96
+ bucket_name = source.get("bucket_name")
97
+ file_path = source.get("file_key")
98
+ if not bucket_name or not file_path:
99
+ print("Dictionary input must contain 'bucket_name' and 'file_key'.")
100
+ raise ValueError(
101
+ "Dictionary input must contain 'bucket_name' and 'file_key'."
102
+ )
103
+ else:
104
+ print("Source must be a string URL or a dictionary.")
105
+ raise ValueError("Source must be a string URL or a dictionary.")
106
+
107
+ print(f"Attempting to download from bucket: {bucket_name}, path: {file_path}")
108
+ try:
109
+ response = s3_client.get_object(Bucket=bucket_name, Key=file_path)
110
+ file_content = response["Body"].read()
111
+ print(f"File fetched successfully from {bucket_name}/{file_path}")
112
+ return file_content
113
+ except Exception as e:
114
+ print(f"Failed to fetch file from S3: {e}")
115
+ raise
116
+
117
+
118
+ def list_s3_objects(bucket_name: str, folder_path: str = "") -> list:
119
+ """
120
+ Lists a content of the given a directory URL.
121
+
122
+ Args:
123
+ bucket_name (str): The name of the S3 bucket.
124
+ folder_name (str): The folder path in the S3 bucket.
125
+
126
+ Returns:
127
+ list: The list of files found inside the given directory URL.
128
+ """
129
+ response = S3_CLIENT.list_objects_v2(Bucket=bucket_name, Prefix=folder_path)
130
+ # Check if the bucket contains objects
131
+ objects = []
132
+ if "Contents" in response:
133
+ for obj in response["Contents"]:
134
+ objects.append(obj["Key"])
135
+
136
+ return objects
requirements.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ boto3==1.35.41