This is a Proof of Concept (PoC) Flask application of an “Image Annotation Service” where users can perform all the basic actions in order to upload an image and have it annotated.
The Entity Relationship Diagram (ERD) provided below illustrates the structure of the database schema used in the application. It outlines the relationships between different entities such as User, Image, Comment, Annotation, and ImageSummary. The ERD serves as a visual representation of how data is organized and related within the database.
---
title: Entity Relationship Diagram
---
erDiagram
User {
id UUID PK
username VARCHAR
email VARCHAR
password_hash VARCHAR
created_at DATETIME
updated_at DATETIME
deleted_at DATETIME
}
Image {
id UUID PK
filename VARCHAR
user_id UUID FK
annotation_status ENUM
created_at DATETIME
updated_at DATETIME
deleted_at DATETIME
}
Comment {
id UUID PK
body TEXT
user_id UUID FK
image_id UUID FK
created_at DATETIME
updated_at DATETIME
deleted_at DATETIME
}
Annotation {
id UUID PK
name VARCHAR
created_at DATETIME
updated_at DATETIME
deleted_at DATETIME
}
ImageSummary {
id UUID PK
image_id UUID FK
comment_summary TEXT
comment_count INTEGER
average_comment_length INTEGER
users_commented_count INTEGER
sentiment_score INTEGER
created_at DATETIME
updated_at DATETIME
deleted_at DATETIME
}
User ||--o{ Comment : "writes"
User ||--o{ Image : "uploads"
Image ||--o{ Comment : "has"
Image }o--o{ Annotation : "has"
Image ||--|| ImageSummary : "has"
Swagger has been integrated into the application to provide a comprehensive documentation of the available endpoints and their functionalities. Swagger is a powerful tool for designing, building, and documenting APIs with ease.
When the application is running, Swagger documentation can be accessed at the following endpoint:
http://localhost:5000/apidocs/
Flask is a lightweight WSGI web application framework in Python, offering tools, libraries, and patterns for building scalable web applications.
SQLAlchemy is an open-source SQL toolkit and Object-Relational Mapping (ORM) library for Python. It provides a comprehensive suite of enterprise-level persistence patterns and an efficient SQL expression language.
JSON Web Tokens (JWT) are utilized for authentication and authorization purposes in the application. Custom decorators encapsulate JWT processing logic, enhancing code readability and maintainability by separating authentication concerns from endpoint implementations.
Marshmallow is employed for data serialization, validation, and security. It ensures proper formatting, validation, and sanitization of data exchanged between the application and clients, enhancing robustness and security.
PostgreSQL is a powerful open-source object-relational database system known for its reliability, robustness, and support for advanced features such as multi-version concurrency control (MVCC) and table inheritance.
Docker and Docker Compose simplify deployment and orchestration by containerizing the Flask application and PostgreSQL database. The Docker Compose file automates the setup of the entire system, streamlining deployment and ensuring convenient orchestration of services.
Alembic is used for database migrations in conjunction with SQLAlchemy, facilitating the creation and management of database schema changes over time.
NLTK and TextBlob are Python libraries for natural language processing tasks such as tokenization, part-of-speech tagging, sentiment analysis, and more, enhancing the application's text processing capabilities.
Pytest is a powerful Python testing tool used for writing and executing automated tests. It promotes test-driven development practices, ensuring the reliability and quality of the application's codebase.
Mermaid, a Markdown-like script language, was utilized for creating the Entity Relationship Diagram (ERD). Mermaid offers a simple syntax for generating diagrams directly within Markdown documents, facilitating the visualization of complex data structures and relationships with ease.
Swagger has been integrated into the application to provide a comprehensive documentation of the available endpoints and their functionalities. It allows developers to visualize, interact with, and test the API endpoints directly from the Swagger UI. This facilitates better understanding and utilization of the API, enhancing the overall development and testing process.
The Repository Pattern is used as an abstraction layer that separates the logic that retrieves data from the database from the business logic in the application. This pattern ensures that only the repositories perform operations on the ORM models and handle the database session, preventing direct manipulation of the database session outside the repository. This separation of concerns enhances maintainability, testability, and scalability of the application.
The Singleton Pattern is employed for common services and utility methods, ensuring that all parts of the application can access and use the same resources correctly configured anywhere in the codebase. By enforcing a single instance of these resources throughout the application, this pattern promotes consistency, reduces resource consumption, and simplifies resource management.
JSON Web Token (JWT) is utilized to secure the endpoints of the application. JWT is a stateless authentication mechanism that generates tokens containing user claims, which are then used to authenticate and authorize requests. By leveraging JWT, the application ensures secure communication between clients and the server, mitigating risks associated with traditional session-based authentication methods.
Ensure that Docker and Docker Compose are installed on your system.
-
Clone the repository to your local machine:
git clone <repository_url> -
Navigate to the project directory:
cd <project_directory>
- Run Docker Compose to set up the application:
docker-compose up
-
Docker Compose will initialize PostgreSQL, create the required database, and start the Flask application.
-
During initialization, the Flask application downloads necessary NLP models, establishes connections, initializes services, and creates an admin user in the database.
-
If the database is empty, two dummy annotations are automatically added to seed the database.
-
Once the setup is complete, you can start using the endpoints or visit the Swagger documentation page to explore the available endpoints and their functionalities.
To perform any action on the application, you need to obtain a token by visiting the following endpoint:
http://127.0.0.1:5000/user/login
Provide the following credentials to obtain a bearer token:
username: admin
password: password
After providing the credentials, you will receive a bearer token, which you must use in all your requests to authenticate. For example to use the token with Postman, follow these steps:
- Open Postman and create a new request for the desired endpoint of the Flask application.
- In the request headers, add an authorization header with the value "Bearer ", replacing "" with the token obtained from the previous step.
- Send the request to the Flask application endpoint. The application will authenticate the request using the provided token and respond accordingly.
For more information on how to use Postman, you can visit the Postman website.
A Continuous Integration (CI) pipeline has been set up using GitHub Actions. This pipeline automates the execution of unit and integration tests whenever changes are pushed to the repository.
The CI pipeline ensures that all tests, including unit tests and integration tests, are automatically run to validate the integrity and functionality of the application. Any failures or issues are reported back to the developers for prompt resolution.
The GitHub pipeline also generates a workflow status badge, which reflects the current status of the application based on the outcome of the tests. This badge provides visibility into the health and stability of the application directly from the GitHub repository page.