Fweather
The name is a portmanteau of fun and weather! Pronounced fwe-ther This was made using Django, world weather online api, giphy api, gmail api, and sqlite.
TODO: heroku demo link
Subscribing an email in Washington, DC
Receiving an email for subscriber in Woburn, MA after verification.
Requirements
- pipenv - setup environment vars
- pyenv or python 3 - cause python 2 will die soon
- npm - to install js / css dependencies
- Sign up for the world weather online api to get historical weather for free for 60 days
- Sign up for the giphy api to get gifs
- Sign up for the gmail api to send emails
- Purposely didn't use Klaviyo or MailChimp because that would make the app WAY too easy ;)
- Insert tokens in the
.envfile to keep sensitive information stored as environment variables.envis committed so do not upload a personal one by mistake. Run the command below to ignore local changes.git update-index --assume-unchanged .env
Quick start
Dependencies
python 3.6
pyenv install 3.6.5
pyenv local 3.6.5
pip dependencies
pipenv install
sqlite database schema
python manage.py makemigrations fweather
python manage.py migrate --run-syncdb
js and css
npm i
python manage.py collectstatic
Run
python manage.py runserver --noreload
Note: The --noreload is important as it will prevent the app from running the overriden ready() function twice. The app gets the gmail refresh token on django start.
In production environments, it's better to run it using gunicorn.
gunicorn fweather.wsgi
It's also runable in docker if using ECS or Docker Swarm / Kubernetes to deploy.
# build
docker build -t fweather .
# run daemonized
docker run -p 8000:8000 -d fweather
Admin panel
Register
python manage.py createsuperuser
Login on http://localhost:8000/admin
Management commands
python manage.py send
--email EMAIL Send to a particular email
--email-all Send to all emails in database
TODO
Essential
- read info from .env file
- django skeleton
- sign up to get giphy api
- sign up to get openweathermap api
- sign up page with email and
countryzip code - sign up form submittal using jquery to hit api
- api checks for email that's already signed
- api sanitizes input
- api upserts tiny db with email and country
- ui always looks like the submission works so no one can see who signed up
- admin interface
- foreign key constraint on email
- admin interface allows editing foreign key
- use the gmail api to send email
- get gmail token on boot and check if the token exists already
- email is sent asynchronously
- use weather api to get weather for a location
- verify subscriber using email and
uuid.v4() - django management command to send out email to every person
- email contains current weather from the location provided
- use giphy api to get a related weather gif
- email contains a gif
- prompt "are you sure?" before sending email to everyone on the list
- Replace
printstatements withlogging
Extra
-
[deploy] heroku
- research postgresql integration since heroku does not persist sqlite dbs
- installed whitenoise middleware to deliver static files while
debug=True
-
[feature] unsubscribe - would have to generate another temp id that only gets sent in emails
-
[feature] email can be written in markdown template
-
[feature] email contains fahrenheit and celsius
-
[feature] email forecasts the week
-
[feature] email is sexy using zurb
-
[feature] curses
-
[sec] recaptcha on subscribe
-
[sec] encrypt email data in database and store key in file or separate database
-
[maint] django tests
-
[doc] sphinx autodoc
Notes
Security
- Zip codes and emails are validated
- Only zip codes converted to city, state are returned and printed client side
- Always returned a successful message (unless bad zip or email) in case someone is guessing at the database for who's already using my fun weather email service
- Validated emails that subscribed before sending them emails
- To increase security more, I could add a recaptcha, encrypt email data (or offload emails to mailchimp / klaviyo), and add additional security headers using securityheaders.io as a reference
Re-inventing the wheel
- I used zipcodes and email_validator instead of recreating my own validation
- I used bootstrap to make the sign up page formatted and look more appealing
I could have...
- used MailChimp / klaviyo
- used API to add the email addresses (less than 2000 are free) and custom text field like zip code or location
- used API again to send the emails using the custom django manage command
- e.g. http://eepurl.com/dsmv2P
- Used flask (soooo much easier) instead of django but then I wouldn't have learned django
- The above steps would remove the overhead of the database, input injection, PII / GPDR, styles, javascript... so much stuff
Usability
- Sign up page is using bootstrap so everything looks OK
- Additional things to add would be a background, maybe a nice navbar at the top, a form rounded edge border
Learned
- Django basics such as setting up a project, creating a database
- Django admin section is pretty cool
- Debugging django in pycharm
Other
-
I could not sign up for Weather Underground because they have a bug on their sign up page
-
I thought if I provided a location for weather it would be too easy for users to fake their location with a simple dropdown. Instead I used zip codes.
For convenience, here are some sample zip codes
Location Zip Anchorage, AK 99501 Austin, TX 73301 Boston, MA 02111 Seattle, WA 98101 Washington, DC 20001

