A Python library to obtain dining hours and menus at Swarthmore College.
Copyright 2021–2022 Bill Dengler
Licensed under the Apache License, Version 2.0 (the "Licence"); you may not use this library except in compliance with the Licence.
Unless required by applicable law or agreed to in writing, software distributed under the Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the Licence for the specific language governing permissions and limitations under the Licence. If the terms of the licence pose a serious obstacle for your use, please contact the author.
>>> import marys
>>> m=marys.Menu() # Fetch latest menus from The Dash
Menu
objects make the full json API available, so programs that rely on it can start using Marys immediately.
>>> m["sharples"][0]["title"]
'Breakfast'
>>> m["sharples"][0]["enddate"]
'2022-02-14 09:30:00'
>>> m["sharples"][0]["description"]
"Soup Island: Oatmeal with Raisins, Craisins & Cinnamon Sugar Main: Eggs to Order, Bacon, Chicken Sausage, Hashbrown Potatoes Phoenixes - Egg & Cheese Sandwiches Chef's Choice of Waffles, French Toast or Pancakes Fresh Fruit, Selection of Bread, Bagels & Spreads Yogurt, Granola & Cereal Dessert: Baker's Choice of Pastry or Donuts"
Marys adds extra features on top of the base API to ease access to the menu.
While the original description
is provided for backwards compatibility with the original JSON API, there is also a cleaned_description
more suitable for use inside applications, with resolved HTML entities and cleaned-up formatting.
>>> m["sharples"][0]["cleaned_description"]
"Soup Island: Oatmeal with Raisins, Craisins & Cinnamon Sugar Main: Eggs to Order, Bacon, Chicken Sausage, Hashbrown Potatoes Phoenixes - Egg & Cheese Sandwiches Chef's Choice of Waffles, French Toast or Pancakes Fresh Fruit, Selection of Bread, Bagels & Spreads Yogurt, Granola & Cereal Dessert: Baker's Choice of Pastry or Donuts"
Menu
objects contain special breakfast
, lunch
, dinner
, and now
keys for accessing breakfast, lunch, dinner, or currently available meals respectively. Lunch automatically resolves to brunch when necessary.
>>> m["breakfast"]
{'sharples': Sharples Dining Hall [Sharples Dining Hall Breakfast {'title': 'Breakfast', 'startdate': '2022-02-14 07:30:00', 'enddate': '2022-02-14 09:30:00', 'short_time': '7:30am - 9:30am', 'description': "Soup Island: Oatmeal with Raisins, Craisins & Cinnamon Sugar Main: Eggs to Order, Bacon, Chicken Sausage, Hashbrown Potatoes Phoenixes - Egg & Cheese Sandwiches Chef's Choice of Waffles, French Toast or Pancakes Fresh Fruit, Selection of Bread, Bagels & Spreads Yogurt, Granola & Cereal Dessert: Baker's Choice of Pastry or Donuts", 'html_description': "<strong>Soup Island:</strong> Oatmeal with Raisins, Craisins & Cinnamon Sugar<br /><strong>Main:</strong> Eggs to Order, Bacon, Chicken Sausage, Hashbrown Potatoes<br />Phoenixes - Egg & Cheese Sandwiches<br />Chef's Choice of Waffles, French Toast or Pancakes<br />Fresh Fruit, Selection of Bread, Bagels & Spreads<br />Yogurt, Granola & Cereal<br /><strong>Dessert:</strong> Baker's Choice of Pastry or Donuts", 'cleaned_description': "Soup Island: Oatmeal with Raisins, Craisins & Cinnamon Sugar Main: Eggs to Order, Bacon, Chicken Sausage, Hashbrown Potatoes Phoenixes - Egg & Cheese Sandwiches Chef's Choice of Waffles, French Toast or Pancakes Fresh Fruit, Selection of Bread, Bagels & Spreads Yogurt, Granola & Cereal Dessert: Baker's Choice of Pastry or Donuts"}, Sharples Dining Hall Continental Breakfast {'title': 'Continental Breakfast', 'startdate': '2022-02-14 09:30:00', 'enddate': '2022-02-14 10:30:00', 'short_time': '9:30am - 10:30am', 'description': 'Served by the Fireplace - Includes Selection of Breads & Bagels, Spreads, Yogurt & Granola, Cereal, Fresh Bakery Special or Donuts, Full Beverage Station with Coffee', 'html_description': 'Served by the Fireplace - Includes Selection of Breads & Bagels, Spreads, Yogurt & Granola, Cereal, Fresh Bakery Special or Donuts, Full Beverage Station with Coffee', 'cleaned_description': 'Served by the Fireplace - Includes Selection of Breads & Bagels, Spreads, Yogurt & Granola, Cereal, Fresh Bakery Special or Donuts, Full Beverage Station with Coffee'}]}
>>> m["lunch"]
{'sharples': Sharples Dining Hall [Sharples Dining Hall Lunch {'title': 'Lunch', 'startdate': '2022-02-14 10:30:00', 'enddate': '2022-02-14 13:30:00', 'short_time': '10:30am - 1:30pm', 'description': "Chicken Fingers and Fries Homestyle Tofu with Green Beans ::vegan::, Vegetable Lo Mein Cheesesteak Bar, with Vegan, Beef, and Chicken Options, and Toppings Corn, Peas Soups: Vegetable ::vegan::, Tomato Dessert: Hope's Homestyle Cookies, Homemade Vegan Cookies", 'html_description': "<ul><li>Chicken Fingers and Fries</li><li>Homestyle Tofu with Green Beans ::vegan::, Vegetable Lo Mein</li><li>Cheesesteak Bar, with Vegan, Beef, and Chicken Options, and Toppings</li><li>Corn, Peas</li><li>Soups: Vegetable ::vegan::, Tomato</li><li>Dessert: Hope's Homestyle Cookies, Homemade Vegan Cookies</li></ul>", 'cleaned_description': "Chicken Fingers and Fries Homestyle Tofu with Green Beans ::vegan::, Vegetable Lo Mein Cheesesteak Bar, with Vegan, Beef, and Chicken Options, and Toppings Corn, Peas Soups: Vegetable ::vegan::, Tomato Dessert: Hope's Homestyle Cookies, Homemade Vegan Cookies"}, Sharples Dining Hall Lite Lunch {'title': 'Lite Lunch', 'startdate': '2022-02-14 13:30:00', 'enddate': '2022-02-14 16:00:00', 'short_time': '1:30pm - 4:00pm', 'description': 'Includes Salad Bar and Deli with Selection of Breads & Wraps, Soups of the Day, Cereal & Granola, Ice Cream & Frozen Yogurt, Fresh Fruit, Full Beverage Station with Coffee', 'html_description': 'Includes Salad Bar and Deli with Selection of Breads & Wraps, Soups of the Day, Cereal & Granola, Ice Cream & Frozen Yogurt, Fresh Fruit, Full Beverage Station with Coffee', 'cleaned_description': 'Includes Salad Bar and Deli with Selection of Breads & Wraps, Soups of the Day, Cereal & Granola, Ice Cream & Frozen Yogurt, Fresh Fruit, Full Beverage Station with Coffee'}], 'kohlberg': Kohlberg coffee bar [Kohlberg coffee bar Grab & Go Lunch {'title': 'Grab & Go Lunch', 'startdate': '2022-02-14 11:30:00', 'enddate': '2022-02-14 13:30:00', 'short_time': '11:30am - 1:30pm', 'description': "Grilled Chicken & Pesto Sandwich on Ciabatta ::halal:: Hummus & Olive Sandwich ::vegan:: Chocolate Sesame Butter & Jam on Multigrain ::vegan:: Chicken Caesar Salad ::halal:: Chef's Salad with Ham, Turkey and Cheese", 'html_description': "<html-blob><u></u>Grilled Chicken & Pesto Sandwich on Ciabatta ::halal:: <br>Hummus & Olive Sandwich ::vegan:: <br>Chocolate Sesame Butter & Jam on Multigrain ::vegan:: <br>Chicken Caesar Salad ::halal:: <br>Chef's Salad with Ham, Turkey and Cheese <u></u></html-blob>", 'cleaned_description': "Grilled Chicken & Pesto Sandwich on Ciabatta ::halal:: Hummus & Olive Sandwich ::vegan:: Chocolate Sesame Butter & Jam on Multigrain ::vegan:: Chicken Caesar Salad ::halal:: Chef's Salad with Ham, Turkey and Cheese"}]}
>>> m["dinner"]
{'sharples': Sharples Dining Hall [Sharples Dining Hall Dinner {'title': 'Dinner', 'startdate': '2022-02-14 16:00:00', 'enddate': '2022-02-14 20:00:00', 'short_time': '4:00pm - 8:00pm', 'description': 'Tilapia with Seafood Sauce, Rice Pilaf Butternut and Sage Orzo ::vegan::, Seitan Chimichurri ::vegan:: Tortilla Soup Bar, with Chips, Chicken, Rice, Black Beans, Corn, Jalapenos, Cheese, and Choice of Chicken or Vegan Broth Pennsylvania Blend, Cauliflower Soups: Vegetable ::vegan::, Tomato Dessert: Cupcakes', 'html_description': '<ul><li>Tilapia with Seafood Sauce, Rice Pilaf</li><li>Butternut and Sage Orzo ::vegan::, Seitan Chimichurri ::vegan::</li><li>Tortilla Soup Bar, with Chips, Chicken, Rice, Black Beans, Corn, Jalapenos, Cheese, and Choice of Chicken or Vegan Broth</li><li>Pennsylvania Blend, Cauliflower</li><li>Soups: Vegetable ::vegan::, Tomato</li><li>Dessert: Cupcakes</li></ul>', 'cleaned_description': 'Tilapia with Seafood Sauce, Rice Pilaf Butternut and Sage Orzo ::vegan::, Seitan Chimichurri ::vegan:: Tortilla Soup Bar, with Chips, Chicken, Rice, Black Beans, Corn, Jalapenos, Cheese, and Choice of Chicken or Vegan Broth Pennsylvania Blend, Cauliflower Soups: Vegetable ::vegan::, Tomato Dessert: Cupcakes'}]}
>>> m["now"]
{'sharples': Sharples Dining Hall [Sharples Dining Hall Dinner {'title': 'Dinner', 'startdate': '2022-02-14 16:00:00', 'enddate': '2022-02-14 20:00:00', 'short_time': '4:00pm - 8:00pm', 'description': 'Tilapia with Seafood Sauce, Rice Pilaf Butternut and Sage Orzo ::vegan::, Seitan Chimichurri ::vegan:: Tortilla Soup Bar, with Chips, Chicken, Rice, Black Beans, Corn, Jalapenos, Cheese, and Choice of Chicken or Vegan Broth Pennsylvania Blend, Cauliflower Soups: Vegetable ::vegan::, Tomato Dessert: Cupcakes', 'html_description': '<ul><li>Tilapia with Seafood Sauce, Rice Pilaf</li><li>Butternut and Sage Orzo ::vegan::, Seitan Chimichurri ::vegan::</li><li>Tortilla Soup Bar, with Chips, Chicken, Rice, Black Beans, Corn, Jalapenos, Cheese, and Choice of Chicken or Vegan Broth</li><li>Pennsylvania Blend, Cauliflower</li><li>Soups: Vegetable ::vegan::, Tomato</li><li>Dessert: Cupcakes</li></ul>', 'cleaned_description': 'Tilapia with Seafood Sauce, Rice Pilaf Butternut and Sage Orzo ::vegan::, Seitan Chimichurri ::vegan:: Tortilla Soup Bar, with Chips, Chicken, Rice, Black Beans, Corn, Jalapenos, Cheese, and Choice of Chicken or Vegan Broth Pennsylvania Blend, Cauliflower Soups: Vegetable ::vegan::, Tomato Dessert: Cupcakes'}], 'essies': Essie Mae's [Essie Mae's Essie Mae's Open {'title': "Essie Mae's Open", 'startdate': '2022-02-14 08:00:00', 'enddate': '2022-02-14 22:30:00', 'short_time': '8:00am - 10:30pm', 'description': "Here to serve you Breakfast, lunch and Dinner Today's Lunch Special South of the Border Burger- Beef patty, pepper jack cheese, bacon and pico de gallo with French fries and a choice of drink. Todays Soup Lobster Bisque Late Night Meal Plan is available 4pm till 10pm and tonight's local food vendor is Yangzi from Media. Please be aware that the Grill close's nightly at 9:30pm.", 'html_description': "<html-blob><u></u><u></u>Here to serve you Breakfast, lunch and Dinner <br><b>Today's Lunch Special </b><u></u><br><u></u>South of the Border Burger- Beef patty, pepper jack cheese, bacon and pico de gallo with French fries and a choice of drink. <br><b>Todays Soup </b></html-blob><br><html-blob>Lobster Bisque <br>Late Night Meal Plan is available 4pm till 10pm and tonight's local food vendor is Yangzi from Media. <br>Please be aware that the Grill close's nightly at 9:30pm.<u></u><u></u></html-blob>", 'cleaned_description': "Here to serve you Breakfast, lunch and Dinner Today's Lunch Special South of the Border Burger- Beef patty, pepper jack cheese, bacon and pico de gallo with French fries and a choice of drink. Todays Soup Lobster Bisque Late Night Meal Plan is available 4pm till 10pm and tonight's local food vendor is Yangzi from Media. Please be aware that the Grill close's nightly at 9:30pm."}], 'science_center': Science Center coffee bar [Science Center coffee bar Science Center Open {'title': 'Science Center Open', 'startdate': '2022-02-14 08:00:00', 'enddate': '2022-02-15 00:00:00', 'short_time': '8:00am - 12:00am', 'description': "We are here to serve you coffee and specialty drinks. We also have a variety of pastries and snacks available. Our local food vendor Yangzi will be here daily for lunch serving Chinese and Sushi. Late Night Meal Plan is available 10pm till midnight. Tonight's local food vendor is Shere Punjab from Media.", 'html_description': "<html-blob>We are here to serve you coffee and specialty drinks. We also have a variety of pastries and snacks available. <br>Our local food vendor Yangzi will be here daily for lunch serving Chinese and Sushi. <br>Late Night Meal Plan is available 10pm till midnight. <br>Tonight's local food vendor is Shere Punjab from Media. </html-blob>", 'cleaned_description': "We are here to serve you coffee and specialty drinks. We also have a variety of pastries and snacks available. Our local food vendor Yangzi will be here daily for lunch serving Chinese and Sushi. Late Night Meal Plan is available 10pm till midnight. Tonight's local food vendor is Shere Punjab from Media."}]}
Marys objects have an open
property which states whether this object or descendants is open.
>>> m.open # Is anything open?
True
>>> m["sharples"].open # Is Sharples open for any meal?
True
>>> m["sharples"][1]["title"]
'Continental Breakfast'
>>> m["sharples"][1].open # Is continental breakfast available right now?
False
>>> m["dinner"].open # Is dinner available anywhere right now?
True
Marys objects have a complete string representation.
>>> str(m["tomorrow"])
"At Sharples Dining Hall\nBreakfast (07:30–09:30)\nSoup Island: Oatmeal with Raisins, Craisins and Cinnamon Sugar Main: Eggs to Order, Bacon, Chicken Sausage, Hashbrown Potatoes Phoenixes - Egg and Cheese Sandwiches Chef's Choice of Waffles, French Toast or Pancakes Fresh Fruit, Selection of Bread, Bagels and Spreads Yogurt, Granola and Cereal Dessert: Baker's Choice of Pastry or Donuts\nContinental Breakfast (09:30–10:30)\nServed by the Fireplace - Includes Selection of Breads and Bagels, Spreads, Yogurt and Granola, Cereal, Fresh Bakery Special or Donuts, Full Beverage Station with Coffee\nLunch (10:30–13:30)\nCuban Sandwiches and Yucca Fries Empanadas, Black Beans, Rice, and Island Slaw Kale and Edamame Salad (vegan), Lentil Stew (vegan) Broccoli Soups: Thai Vegetable, New England Clam Chowder Dessert: Brownies\nLite Lunch (13:30–16:00)\nIncludes Salad Bar and Deli with Selection of Breads and Wraps, Soups of the Day, Cereal and Granola, Ice Cream and Frozen Yogurt, Fresh Fruit, Full Beverage Station with Coffee\nDinner (16:00–20:00)\nBaked Chicken (halal) with Macaroni and Cheese Spanish Chickpea Stew (vegan), Mushroom Ragout with Buttered Noodles Potato Bar, with Baked Idaho's and Sweets, Onion Rings, Potato Skins, and All of the Toppings Lima Succotash, Greens Soups: Thai Vegetable, New England Clam Chowder Dessert: Pumpkin Cake\n\nAt Essie Mae's\nEssie Mae's Open (08:00–22:30)\nHere to serve you Breakfast, Lunch and Dinner. We also offer a large variety of snacks and grocery items. Today's Lunch Special Pork Carnita wrap- sauteed onions and peppers and cilantro mayonnaise served with French fries and a choice of drink. Todays Soup Broccoli Cheddar Late Night Meal Plan is available 4pm till 10pm and tonight's local food vendor is Dos Gringo's from Media. Please be aware that the Grill close's nightly at 9:30pm.\n\nAt Kohlberg coffee bar\nKohlberg Open (08:00–16:30)\nWe are open and ready to provide you with you Coffee and specialty drink needs. We also have a selection of Sandwiches, Salads and pastries. Hot food will be provided by Shere Punjab available from 11 am. Today's Soup -Classic beef Stew\nGrab & Go Lunch (11:30–13:30)\nRoast Turkey Sandwich on Ciabatta Tempeh Tomato and Lettuce on Multigrain Bread (vegan) Sunbutter and Jam on Multigrain Bread (vegan) Chicken Caesar Salad (halal) Chef's Salad with Ham, Turkey and Cheese\n\nAt Science Center coffee bar\nScience Center Open (08:00–00:00)\nWe are here to serve you coffee and specialty drinks. We also have a variety of pastries and snacks available. Our local food vendor Yangzi will be here daily for lunch serving Chinese and Sushi. Late Night Meal Plan is available 10pm till midnight. Tonight's local food vendor is Dos Gringo's from Media.\n\n"
>>> str(m["essies"][0])
"Essie Mae's Open (08:00–22:30)\nHere to serve you Breakfast, lunch and Dinner Today's Lunch Special South of the Border Burger- Beef patty, pepper jack cheese, bacon and pico de gallo with French fries and a choice of drink. Todays Soup Lobster Bisque Late Night Meal Plan is available 4pm till 10pm and tonight's local food vendor is Yangzi from Media. Please be aware that the Grill close's nightly at 9:30pm."
Marys objects can be rendered as Speech Synthesis Markup Language for voice assistants and speech systems.
>>> m["dinner"].ssml()
'At Sharples Dining Hall<break strength="weak"/>Dinner (from 4:00pm to 8:00pm) <break strength="weak"/>Tilapia with Seafood Sauce, Rice Pilaf<break strength="weak"/>Butternut and Sage Orzo ::vegan::, Seitan Chimichurri ::vegan::<break strength="weak"/>Tortilla Soup Bar, with Chips, Chicken, Rice, Black Beans, Corn, Jalapenos, Cheese, and Choice of Chicken or Vegan Broth<break strength="weak"/>Pennsylvania Blend, Cauliflower<break strength="weak"/>Soups: Vegetable ::vegan::, Tomato<break strength="weak"/>Dessert: Cupcakes<break strength="weak"/>'
If using this library with Amazon Alexa, Alexa emotions are supported.
>>> marys.Menu(data={})["breakfast"].ssml(dialect=marys.SSMLDialect.AMAZON)
'<amazon:emotion name="disappointed" intensity="medium">Dining is currently unavailable at this time!</amazon:emotion>'
Similarly to ssml
, Marys objects can be represented as a card (object with title and content). These are useful for creating dialog boxes in graphical programs or textual responses for voice assistants like Alexa and Google Assistant.
>>> m["sharples"].card()
Card(title='At Sharples Dining Hall', content="Breakfast (07:30–09:30)\nSoup Island: Oatmeal with Raisins, Craisins and Cinnamon Sugar Main: Eggs to Order, Bacon, Chicken Sausage, Hashbrown Potatoes Phoenixes - Egg and Cheese Sandwiches Chef's Choice of Waffles, French Toast or Pancakes Fresh Fruit, Selection of Bread, Bagels and Spreads Yogurt, Granola and Cereal Dessert: Baker's Choice of Pastry or Donuts\nContinental Breakfast (09:30–10:30)\nServed by the Fireplace - Includes Selection of Breads and Bagels, Spreads, Yogurt and Granola, Cereal, Fresh Bakery Special or Donuts, Full Beverage Station with Coffee\nLunch (10:30–13:30)\nChicken Fingers and Fries Homestyle Tofu with Green Beans (vegan), Vegetable Lo Mein Cheesesteak Bar, with Vegan, Beef, and Chicken Options, and Toppings Corn, Peas Soups: Vegetable (vegan), Tomato Dessert: Hope's Homestyle Cookies, Homemade Vegan Cookies\nLite Lunch (13:30–16:00)\nIncludes Salad Bar and Deli with Selection of Breads and Wraps, Soups of the Day, Cereal and Granola, Ice Cream and Frozen Yogurt, Fresh Fruit, Full Beverage Station with Coffee\nDinner (16:00–20:00)\nTilapia with Seafood Sauce, Rice Pilaf Butternut and Sage Orzo (vegan), Seitan Chimichurri (vegan) Tortilla Soup Bar, with Chips, Chicken, Rice, Black Beans, Corn, Jalapenos, Cheese, and Choice of Chicken or Vegan Broth Pennsylvania Blend, Cauliflower Soups: Vegetable (vegan), Tomato Dessert: Cupcakes\n")
>>> m["sharples"].card().title
'At Sharples Dining Hall'
For programs using Python's coroutine (async
/await
) syntax, a coroutine is provided to asynchronously construct a Menu
object. If your programs do not use the async
or await
keywords, you don't need to use this.
For example, Marys can be added to a discord.py bot with something like the following (which uses old-style commands, but could easily be adapted for slash commands).
import discord
import marys
from discord.ext import commands
class Marys(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.command()
async def marys(self, ctx, query="current"):
"""Request Swarthmore dining menus"""
m = await marys.Menu.asynchronous()
resp = await ctx.send(str(m[query]))
# Then, in the entry point/main function of your bot,
# import the Marys class defined earlier, then
await bot.add_cog(Marys(bot))
This library was named after Mary Kassab, a Sharples manager who often assisted me, a totally blind student, in navigating the dining hall.