Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions backend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
data/
env/
19 changes: 10 additions & 9 deletions backend/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
REQUEST_ARG_POST_ID = 'postId'
REQUEST_ARG_IMAGE_URL = 'imageUrl'


def posts(request: Request) -> Response:
"""Return data related to posts.

Expand All @@ -34,24 +35,24 @@ def posts(request: Request) -> Response:
'Content-Length': len(posts_json)
}
response = make_response((posts_json, status, headers))
except GetPostQueryException:
error_body = {
'errorCode': 'unknown',
'message': 'An unknown server error occured. Try again later.'
}
response = make_response((error_body, 500))
except UnknownPostIdException:
error_body = {
'errorCode': 'unknownPostId',
'message': 'The provided post does not exist.'
}
response = make_response((error_body, 404))
except GetPostException:
error_body = {
'errorCode': 'unknown',
'message': 'An unknown server error occurred. Try again later.'
}
response = make_response((error_body, 500))
except:
response = _generate_server_error()
elif request.method === 'POST':
elif request.method == 'POST':
try:
imageUrl = request.args.get(REQUEST_ARG_IMAGE_URL)
if imageUrl is None or imageUrl == ''
image_url = request.args.get(REQUEST_ARG_IMAGE_URL)
if image_url is None or image_url == '':
add_post_metadata = AddPostMetadata()
# TODO: Handle uploads
except CreatePostException:
Expand Down
55 changes: 55 additions & 0 deletions backend/ml/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
from typing import List


class HashtagPrediction:
"""A single prediction for a hashtag; a mapping of a hashtag to its confidence.

Attributes:
hashtag (str): A possibly relevant hashtag for a piece of content
confidence (float): The probability that the hashtag is relevant
"""

def __init__(self, hashtag: str, confidence: float):
self.hashtag = hashtag
self.confidence = confidence


class ClassPrediction:
"""A single prediction for an object's class; a mapping of a class to its confidence.

Attributes:
object_class (str): The category of
confidence (float): The probability that the hashtag is relevant
"""

def __init__(self, object_class: str, confidence: float):
self.object_class = object_class
self.confidence = confidence


class TextPostPredictionResult:
def __init__(self, hashtags: List[HashtagPrediction], entities: List[str]):
pass


class ImagePostPredictionResult:
"""
Attributes:
hashtags (List[HashtagPrediction]): A list of eight relevant hashtags
classes (List[str])
"""

def __init__(self, hashtags: List[HashtagPrediction], classes: List[str]):
pass


class PredictionSuggestion:
"""A suggestion to re-tag a data point.

Attributes:
prediction_id (str):
new_value (dict): A json payload containing new data
"""

def __init__(self, prediction_id: str, new_value: dict):
pass
5 changes: 2 additions & 3 deletions backend/posts/intelligence.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import os
import base64
from typing import List
from models import PostMetadata

API_BASE = 'https://api.imagga.com/v2'

Expand Down Expand Up @@ -45,11 +44,11 @@ def generate_image_metadata(image_url: str) -> List[PostPredictionData]:
Returns:
A list of PostPredictionData containing results from hashtag generation.
"""
result_json = _get_imagga_data(imageUrl)
result_json = _get_imagga_data(image_url)
predictions = []
for json_object in result_json.result.tags:
tag = json_object['tag']['en']
confidence = json_object['confidence']
prediction = PostPredictionData(confidence, tag)
predictions.add(prediction)
predictions.append(prediction)
return predictions
50 changes: 45 additions & 5 deletions backend/posts/models.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,59 @@
"""Domain-layer abstractions for data models that the client will accept."""

class PostMetadata:
from typing import List, Dict, Tuple


class ImagePost:
"""A data container for post attributes.

This is used to store post data after being generated using
machine learning.

Attributes:
uid (str): A unique identifier for this post
image_url (str): The downloadable location
hashtags (List[Dict[str, int]]): A list of hashtags and their confidence ratings
captions (List[Dict[str, int]]): A list of captions and their confidence ratings
"""

def __init__(self, id: str, image_url: str, hashtags: list, caption: str):
self.id = id
def __init__(self, uid: str, image_url: str, hashtags: List[Dict[str, int]],
captions: List[Dict[str, int]], upload_timestamp: int, segments: List[Tuple[int, int]]):
self.uid = uid
self.image_url = image_url
self.hashtags = hashtags
self.caption = caption
self.captions = captions
self.upload_timestamp = upload_timestamp


class TextPost:
"""A data container for text post attributes."""

def __init__(self, uid: str, content: str, hashtags: List[Dict[str, int]],
captions: List[Dict[str, int]], upload_timestamp: int):
self.uid = uid
self.content = content
self.hashtags = hashtags
self.captions = captions
self.upload_timestamp = upload_timestamp


class AddPostMetadata:
class AddTextPostMetadata:
"""Metadata needed to upload a new text post to the backend.

Attributes:
text (str): The contents of the post
"""

def __init__(self, text: str):
self.text = text


class AddImagePostMetadata:
"""Metadata needed to upload a new image post to the database.

Attributes:
image_url (str): A URL to this image stored in Cloud Storage
"""

def ___init__(self, image_url: str):
self.image_url = image_url
5 changes: 3 additions & 2 deletions backend/posts/posts.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,13 @@ def get_post_by_id(post_id: str) -> PostMetadata:
A PostMetadata object containing post data.
"""
try:
doc = db.collection(COLLECTION_POSTS) \
posts = db.collection(COLLECTION_POSTS) \
.document(post_id) \
.get()
# TODO: Validate that this post is text
if len(posts) < 1:
raise UnknownPostIdException()
return
return posts[0]
except NotFound:
raise UnknownPostIdException()
except:
Expand Down