Issue: SSL and peewee
Author: ra-esmith
State: closed
Created: 2019-03-04 16:06:52

Hello,

Not sure if this is something peewee can help with.

I have been using peewee for a few years now, works great.  Oddly this morning I am getting lots of errors from heroku related to SSL

The docs from heroku suggest that I should say "sslmode='require' in my connection to the database.  As heroku says SSL required for all connections.  https://devcenter.heroku.com/articles/heroku-postgresql#heroku-postgres-ssl


Something like

import os
import psycopg2
DATABASE_URL = os.environ['DATABASE_URL']
conn = psycopg2.connect(DATABASE_URL, sslmode='require')


Where in my python code does peewee make a DB connection, and how can I tell peewee to use ssl ... and what do I need to do for that to work.

Thanks!
Evan

From the [docs](http://docs.peewee-orm.com/en/latest/peewee/database.html):

> The Database initialization method expects the name of the database as the first parameter. Subsequent keyword arguments are passed to the underlying database driver when establishing the connection, allowing you to pass vendor-specific parameters easily.

```python
db = PostgresqlDatabase('my_db', sslmode='require', ...etc...)
```

I am using Flask, see below.  I am unsure how to pass in the sslmode require into my configuration.  Does not seem the call above is something I can do.  Also I tried using SSLify ... but that does not seem to be putting sqlmode require on for postgres.



----------------
# here is my app code to startup ...

from __future__ import print_function

import json
import logging
import os

from flask import Flask
from flask_caching import Cache
from flask_peewee.db import Database
from flask_sslify import SSLify
from flask_htmlmin import HTMLMIN

from peewee import PostgresqlDatabase

try:
    theapp_app = Flask(__name__)
    theapp_app.config['MINIFY_PAGE'] = True
    htmlmin = HTMLMIN(theapp_app)
    
    theapp_app.logger.setLevel(logging.ERROR)
    # theapp_app.logger.setLevel(logging.INFO)
    theapp_app.debug = False
    sslify = SSLify(theapp_app)
    theapp_app.jinja_env.globals.update(len=len, dumps=json.dumps)
    if 'ON_HEROKU' in os.environ:
        theapp_app.config.from_object('theapp_config.ProductionConfig')
        cache = Cache(theapp_app, config={'CACHE_TYPE': 'filesystem', 'CACHE_DIR': 'cache'})
    else:
        theapp_app.config.from_object('theapp_config.DevelopmentConfig')
        cache = Cache(theapp_app, config={'CACHE_TYPE': 'simple'})
    db = Database(theapp_app)
    # TODO: how to pass sslmode into the current setup above ... 
    # sslmode='require' as an option ... for heroku
    # Example: but how to use flask theapp_app above
    # db = PostgresqlDatabase('my_app', user='postgres', password='secret', host='10.1.0.9', port=5432)

except Exception as e:
    print("Exception: " + str(e))

So I am trying the following, as I am on heroku which binds the environment variable DATABASE_URL
if is_running_on_heroku():
    class ProductionConfig(BaseConfig):
        def __init__(self):
            pass

        urlparse.uses_netloc.append('postgres')
        url = urlparse.urlparse(os.environ['DATABASE_URL'])
        DATABASE = {
            'name': url.path[1:],
            'user': url.username,
            'password': url.password,
            'host': url.hostname,
            'port': url.port,
            'engine': 'peewee.PostgresqlDatabase',
            'sslmode':'require' # see if we can get sslmode for heroku on
        }
        DEBUG = False


    base_url = ra_config["base_url"]
else:
    base_url = ra_config["ra"]["local_base_url"]


and I think that as password and other args are somehow passed into the database that I can also put sslmode here and it will float along in also ...

Yes. If you look at the code you can see that parameters from the database config dict are passed to the Peewee database constructor.