Python implementation of a Secret Santa generator that notifies participants by email of whom they have to gift. Allows for defining restrictions between participants to prevent somebody from gifting specific people.
Enjoy it and have fun š I'll be happy to know if you use it, so don't hesitate to contact me!
This package provides the following functionalities:
- 100% free Secret Santa generator: generate with very few lines of code the pairings for your yearly family Secret Santa! You only need to specify the participants.
- Specify avoid rules: easily specify which participants should avoid whom and let the algorithm work its magic! If you provide too many rules and the scenario cannot be solved, you will be rapidly alerted.
- Communication via email: communicate each participant by email whom they have to gift. You can send the emails using any account that you own.
- Email body customisation: provide your own email template for the automatically generated emails.
- Dry run mode: test your rules in a safe environment that prevents emails from being sent.
This software has been packaged and uploaded to PyPi, the Python Package Index. To install it, simply run the following command:
pip install secret-santa-bpguasch
You can now review the usage instructions.
AWS Lambda is a serverless compute service that lets you run code without provisioning or managing servers. This Python package is provided as well as an AWS Lambda Layer for you to use in your functions. Follow these steps to add the Secret Santa Lambda Layer to your AWS Lambda function:
- From this repository, download the python.zip file
- Navigate to the AWS Lambda section in the AWS Console, and select Layers under Additional resources
- Select Create layer, give it a name and upload the file you recently downloaded
- Open the Lambda function in which you would like to use the layer
- Scroll to the bottom of the page and select Add a layer
- Select Custom layers and choose the layer you just created
In your Python script, start by importing the package:
from secret_santa_bpguasch import *
The application will email each participant whom they have to gift. For this reason, you have to provide some configuration parameters to send emails using one of your accounts:
email_config = EmailServer(
host="smtp.gmail.com",
port=465,
username='',
password=''
)
Most likely you will need to create a dedicated App password to log into your email account programmatically. Taking Gmail as an example, you can learn more about it here. As the username field, you should specify your email address.
Next, define some configuration parameters for the Secret Santa Generator:
game_config = Game(
name="Smith Secret Santa",
budget=30,
subject="Smith's family Secret Santa 2022"
)
The game name will appear as the email sender identity (name). The subject represents the email subject and the budget value is used to compose the default email body. By default, each participant will receive and email with the following body:
Ā”Hello, giver_name! You are receiver_name's Secret Santa this year. Remember that the maximum budget is $budget. Happy shopping and merry Christmas :)
Optionally, you can define in the game configuration a method that generates the email body for a pairing of giver-receiver. Said method must receive a list as an argument and return a string. You can use this feature to customise the email as you want with HTML. To provide your generator method, you can do the following:
def my_custom_email_body_generator(pairing: list) -> str:
return 'The giver is {} and the receiver is {}'.format(pairing[0], pairing[1])
Then, you can include your method in the configuration as follows:
game_config = Game(
name="Smith Secret Santa",
budget=30,
subject="Smith's family Secret Santa 2022",
body_generator_func=my_custom_email_body_generator
)
By doing this, your method will be automatically invoked whenever an email has to be sent to the giver.
Next, you need to supply the participants in the form of a dictionary:
participants = {
'borja': {
"email": "borja@secretsanta.com",
"avoidGiftingTo": ["mark"]
},
'john': {
"email": "john@secretsanta.com",
"avoidGiftingTo": []
},
'mark': {
"email": "mark@secretsanta.com",
"avoidGiftingTo": []
}
}
Finally, you can create an instance of SecretSanta to generate the pairings:
secret_santa = SecretSanta(
game_config,
email_config,
participants
)
# Call the method dry run to run tests and verify your configuration.
# When you generate pairings in dry run mode, no emails are sent.
secret_santa.dry_run()
# When you are confident about the configuration, you can call the play method
#secret_santa.play()
The whole script together would look as follows:
from secret_santa_bpguasch import *
def my_custom_email_body_generator(pairing: list) -> str:
return 'The giver is {} and the receiver is {}'.format(pairing[0], pairing[1])
if __name__ == '__main__':
email_config = EmailServer(
host="smtp.gmail.com",
port=465,
username='',
password=''
)
game_config = Game(
name="Smith Secret Santa",
budget=30,
subject="Smith's family Secret Santa 2022",
body_generator_func=my_custom_email_body_generator
)
participants = {
'borja': {
"email": "borja@secretsanta.com",
"avoidGiftingTo": ["mark"]
},
'john': {
"email": "john@secretsanta.com",
"avoidGiftingTo": []
},
'mark': {
"email": "mark@secretsanta.com",
"avoidGiftingTo": []
}
}
secret_santa = SecretSanta(
game_config,
email_config,
participants
)
secret_santa.dry_run()
The secret-santa-bpguasch Python package is organised in different modules. An overview of the classes contained in each module that can be worked with is provided below. Check the docstring for a detailed description of each method parameter:
A module with classes that encapsulate configuration attributes.
Click to show package contents
Exception subclass that represents an invalid configuration, either because the data is wrong formatted or because the scenario cannot be solved given the specified restrictions.
Class that encapsulates email server configuration parameters
EmailServer(host: str, port: int, username: str, password: str)
Parameters:
Name | Type | Description |
---|---|---|
host | str |
Email server host |
port | int |
Email server port |
username | str |
Email server username |
password | str |
Email server password |
Class that encapsulates game configuration parameters
Game(name: str, budget: float, subject: str, body_generator_func=None)
Parameters:
Name | Type | Description |
---|---|---|
name | str |
Game name. Will appear as the sender identity (name) |
budget | float |
Budget for the present. Will appear in the default email body |
subject | str |
Subject of the email that each participant receives |
body_generator_func | descriptor |
Descriptor of a method used to generate a custom email body for a given pairing |
A module with the class that implements the Secret Santa algorithm.
Click to show package contents
Class that implements the Secret Santa algorithm and participants notification
SecretSanta(game_config: Game, email_config: EmailServer, participants: dict)
Parameters:
Name | Type | Description |
---|---|---|
game_config | Game |
Game configuration attributes |
email_config | EmailServer |
Email server configuration attributes |
participants | dict |
Game participants |
The constructor will raise an InvalidConfigurationException
exception if the validation of the participants argument fails. The validation will fail if the structure does not have the expected fields and field types or if the scenario cannot be solved due to the specified restrictions.
Signature | Description | Return | Throws |
---|---|---|---|
dry_run() | Creates giver-receiver pairings applying the specified participant restrictions. Doesn't send any email communication. Use this method to test your scenario configuration. The first element of the returned value represents the giver and the second the receiver. | list |
- |
play() | Creates giver-receiver pairings applying the specified participant restrictions. Sends individual emails to participants to let them know whom they have to gift. The first element of the returned value represents the giver and the second the receiver. | list |
- |