Simon East
This Flask web app takes a Boston-area address or landmark and returns the nearest MBTA stop, including wheelchair accessibility and current temperature. It integrates Mapbox for geocoding, the MBTA v3 API for transit data, and the OpenWeather API for live weather conditions. A form-based interface, modular helper functions for external API calls, and a polished UI provide a clear, reliable, and user-friendly experience.
For this project I tried to treat it like a tiny real-world web app instead of a one-off script we usually do in class. I started by splitting the work into two layers: mbta_helper.py for all the API and data logic, and app.py for just handling requests, forms, and templates. Testing helper functions in isolation went surprisingly smoothly. For example, I used the main() block in mbta_helper.py to try locations like Boston Common and make sure I was actually getting back a latitude/longitude and a nearby station before I ever touched Flask. The tricky part was chaining three different APIs together and keeping the URLs and JSON straight – especially figuring out exactly where in the MBTA response the station name, distance, and accessibility info lived, and then reusing the station coordinates again for the OpenWeather call. I also had to think about stuff like "what if Mapbox returns no matches?" and make sure those turned into a clean error page instead of a long list of errors I was originally getting. If I did this again, I'd invest a bit more time up front in structured error handling and a couple of small tests around the helper functions so I wasn't relying so much on print debugging.
Since I worked alone, "teamwork" for me was really about how I divided the project into stages and kept myself organized. I tackled it in layers: first setting up environment variables with load_dotenv and making sure all the API keys were loaded, then getting each API working on its own (Mapbox for coordinates, MBTA for nearest stop, OpenWeather for current temperature), and only after that putting everything into the Flask routes and HTML. That rhythm helped a lot, because when something broke I usually knew what to blame. One thing I could have done better is treating my own work a bit more like a team project: for example, keeping a short to-do list like "better message when the user leaves the form blank," "differentiate MBTA errors from OpenWeather errors," or "tweak how accessibility is displayed," and checking those off as I went instead of keeping everything in my head.
I learned a lot about how APIs, JSON, and Flask actually fit together in a full request-response loop. Reading real JSON responses and pulling out only what I needed – like coordinates from Mapbox, station details from MBTA, and a single temperature value from OpenWeather in Fahrenheit – made the abstract idea of "working with APIs for a website functionality" feel much more concrete. On the Flask side, I saw why it's worth keeping routes thin: the form route just cleans up the user's input, calls one helper function to do the heavy lifting, and then either renders the station template or an error template. I leaned on ChatGPT to help with things like URL formatting, common mistakes with query parameters, and checking my errors. It was especially helpful when I needed to remember how certain libraries behave or why a particular JSON parsing approach was cleaner. At the same time, I noticed that AI suggestions sometimes assumed different libraries or a different project structure than the assignment, so I had to filter and adapt instead of copying directly. In hindsight, I wish I had used AI earlier for designing small tests and logging strategies, not just for debugging when something was already broken. Finally, and most importantly, I had ChatGPT design the webpages as I have very limited knowledge with HTML/CSS. (I asked it to make the webpage "prettier" as was done in class) from my barebones version to something that looks much cleaner, I think it did a pretty good job!
See the screenshots folder for the before and final looks!