A Movie Theatre Ticket Booking System Build in Python Using FastAPI.
LoadBalancerURL: http://ticketlymain-1835126091.ap-south-1.elb.amazonaws.com:8477/docs#/
QR Code(Tryit on Your Phone):
- TicketSlot : A logical entity which defines movieslot (could be extended to documentaries, concerts etc - Hence the name
TicketSlot
and not justMovieSlot
). It is defined as following:
{
"slotName": "Skyfall",
"slotDescription": "An ex-MI6 agent steals a hard drive with top secret information to carry out a vendetta on Bond's overseer, M. Bond must face his past in a bid to try and save M.",
"startTime": "2020-11-01 12:22",
"endTime": "2020-11-01 15:22",
"slotType": "Movie",
"genre": "Action"
}
Same movie can have many diffrent TicketSlot
s if the movie is scheduled at many different timings.
- Ticket : A logical entity which defines a ticket object at a point in time. Tickets are
Booked
at the time of booking and the state changes toExpired
,Canceled
,Archived
according toTicket
s lifecycle which is controled by theTicketController
.
{
"ticketStatus": "Booked",
"ticketSlotId": "713396",
"ticketId": "TKT331086",
"userId": "U385985"
}
- User : A logical entity which defines a user object. Example:
{
"userId": "U385985",
"userName": "Anuranjan",
"phoneNumber": "7906543416"
}
Click To Expand Sample Requests
{
"userName": "John",
"userPhoneNumber": "9653864514",
"movieName": "Avatar",
"movieStartTime":"2020-11-01 12:22",
"numTickets": "3"
}
{
"ticketId": "TKT437664",
"newMovie": "Avatar",
"newStartTime": "2020-11-01 12:22"
}
{
"movieName": "Inception",
"movieStartTime": "2020-11-01 12:22"
}
{
"ticketId": "TKT437664"
}
{
"ticketId": "TKT437664"
}
{
"slotName": "Skyfall",
"slotDescription": "An ex-MI6 agent steals a hard drive with top secret information to carry out a vendetta on Bond's overseer, M. Bond must face his past in a bid to try and save M.",
"startTime": "2020-11-01 12:22",
"endTime": "2020-11-01 15:22",
"slotType": "Movie",
"genre": "Action"
}
{
"genre": "Action"
}
- Atomicity of Transactions (Transaction as a whole is rolled back if something goes wrong)
- Immutability - Tickets cannot be recycled, a new ticket is generated at updation which saves a lot of trouble.
- Cloud Enabled & Horizontally Scalable Service Oriented Architecture (AWS Support)
- Object Oriented Design
- Fast: Very high performance, on par with NodeJS and Go (thanks to FastAPI)
- Automated Ticket Invalidation via
cron
- The cron jobs setup to run on ec2 automatically triggersexpireTickets
API to invalidate tickets after 8 hours
Since this seems like a system which might need code volution, new features to be added in future, I decided to closely follow the OOPS paradigm. UML also makes it easy to think through and handle corner cases.
The architecture of the application involves back-facing and a client-facing parts. I decided to use AWS for the backend of the application. The application is configured to use ec2, however, the instances are throttled and managed according to the scaling policies defined using AWS AutoScaling Groups. This is all configured behind an Application Load Balancer (ALB) which hides all the complexity from the user.
When the ALB receives a request, it is automatically routed to one of the ec2 instances within the target group.
For static content, we could leverage AWS Amplify and S3. For tables in particular, I decided to use DynamoDB for two reasons:
- NoSQL Databases allow a code-first strategy. This allows easy integration with ORMs and thus, faster development. The schema is loosely coupled with code, and thus can evolve over time.
- Faster read through.
As shown below, even witha simulated load test, the DynamoDB database can handle sub-millisecond latency for scans. (Note that this does not include GET operations where hash_key is involved, which are O(logn)
)
I chose to define a two-fold scaling mechanism. New nodes (ec2-instances) are spawned automatically if:
- The ALB health-check (runs every 300 sec) marks the node unhealthy (disk failure / disaster etc)
- The network load as observed by the nodes is higher than specified threadshold.
This could also be configured using CloudWatch logs. But because of limited time, I didn't get a chance to do it
AWS allows SNS alarms (Simple Notification Service) to be set up if there is an unusually high amount of load on the database
pytest is used as the testing framework:
Build with
- FastAPI
- Pydantic
git clone https://github.com/almique/Movie_Ticket_Booking.git
uvicorn main:app --reload
Just install pytest and in the terminal type:
pytest