Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
303 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
localhost.sqlite | ||
*.sqlite | ||
*.db | ||
|
||
# Byte-compiled / optimized / DLL files | ||
__pycache__/ | ||
*.py[cod] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# This file specifies files that are *not* uploaded to Google Cloud Platform | ||
# using gcloud. It follows the same syntax as .gitignore, with the addition of | ||
# "#!include" directives (which insert the entries of the given .gitignore-style | ||
# file at that point). | ||
# | ||
# For more information, run: | ||
# $ gcloud topic gcloudignore | ||
# | ||
.gcloudignore | ||
# If you would like to upload your .git directory, .gitignore file or files | ||
# from your .gitignore file, remove the corresponding line | ||
# below: | ||
.git | ||
.gitignore | ||
|
||
# Python pycache: | ||
__pycache__/ | ||
# Ignored by the build system | ||
/setup.cfg | ||
|
||
# custom | ||
env.yaml | ||
WEB-INF/ | ||
.pytest_cache/ | ||
venv/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
# Datastore Emulator | ||
WEB-INF/ | ||
env.yaml | ||
localhost.sqlite | ||
|
||
# Byte-compiled / optimized / DLL files | ||
__pycache__/ | ||
*.py[cod] | ||
*$py.class | ||
|
||
# C extensions | ||
*.so | ||
|
||
# Distribution / packaging | ||
.Python | ||
build/ | ||
develop-eggs/ | ||
dist/ | ||
downloads/ | ||
eggs/ | ||
.eggs/ | ||
lib/ | ||
lib64/ | ||
parts/ | ||
sdist/ | ||
var/ | ||
wheels/ | ||
pip-wheel-metadata/ | ||
share/python-wheels/ | ||
*.egg-info/ | ||
.installed.cfg | ||
*.egg | ||
MANIFEST | ||
|
||
# PyInstaller | ||
# Usually these files are written by a python script from a template | ||
# before PyInstaller builds the exe, so as to inject date/other infos into it. | ||
*.manifest | ||
*.spec | ||
|
||
# Installer logs | ||
pip-log.txt | ||
pip-delete-this-directory.txt | ||
|
||
# Unit test / coverage reports | ||
htmlcov/ | ||
.tox/ | ||
.nox/ | ||
.coverage | ||
.coverage.* | ||
.cache | ||
nosetests.xml | ||
coverage.xml | ||
*.cover | ||
.hypothesis/ | ||
.pytest_cache/ | ||
|
||
# Translations | ||
*.mo | ||
*.pot | ||
|
||
# Django stuff: | ||
*.log | ||
local_settings.py | ||
db.sqlite3 | ||
db.sqlite3-journal | ||
|
||
# Flask stuff: | ||
instance/ | ||
.webassets-cache | ||
|
||
# Scrapy stuff: | ||
.scrapy | ||
|
||
# Sphinx documentation | ||
docs/_build/ | ||
|
||
# PyBuilder | ||
target/ | ||
|
||
# Jupyter Notebook | ||
.ipynb_checkpoints | ||
|
||
# IPython | ||
profile_default/ | ||
ipython_config.py | ||
|
||
# pyenv | ||
.python-version | ||
|
||
# pipenv | ||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. | ||
# However, in case of collaboration, if having platform-specific dependencies or dependencies | ||
# having no cross-platform support, pipenv may install dependencies that don't work, or not | ||
# install all needed dependencies. | ||
#Pipfile.lock | ||
|
||
# celery beat schedule file | ||
celerybeat-schedule | ||
|
||
# SageMath parsed files | ||
*.sage.py | ||
|
||
# Environments | ||
.env | ||
.venv | ||
env/ | ||
venv/ | ||
ENV/ | ||
env.bak/ | ||
venv.bak/ | ||
|
||
# Spyder project settings | ||
.spyderproject | ||
.spyproject | ||
|
||
# Rope project settings | ||
.ropeproject | ||
|
||
# mkdocs documentation | ||
/site | ||
|
||
# mypy | ||
.mypy_cache/ | ||
.dmypy.json | ||
dmypy.json | ||
|
||
# Pyre type checker | ||
.pyre/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# Simple GAE app with an SQL database | ||
|
||
A simple 2nd generation GAE web app made with Python 3 and Flask using an SQL database. | ||
|
||
## Preview | ||
|
||
![](static/img/preview.png) | ||
|
||
## Requirements | ||
|
||
Install the necessary libraries using this command: | ||
|
||
pip install -r requirements.txt | ||
|
||
Using a virtual environment is strongly encouraged! | ||
|
||
## Run the web app | ||
|
||
> Assuming you use the PyCharm IDE. | ||
Right-click on `run.py` and select `Run 'run'`. Your web app will now be accessible via `localhost:8080`. | ||
|
||
Every time you'll change a Python file, your web app will auto-reload. But it won't auto-reload on non-Python files | ||
changes. In that case just make a minor edit (like adding a space) in some Python file to force auto-reload. | ||
|
||
## Shut down the web app | ||
|
||
To **shut down** the web app click the **red square icon** below the reload button. | ||
|
||
## Deployment to GAE | ||
|
||
See [these instructions](https://github.com/smartninja/gae-2nd-gen-examples#deployment-to-google-app-engine). | ||
|
||
## Useful links | ||
|
||
- [Using Cloud SQL on GAE with Python 3](https://cloud.google.com/appengine/docs/standard/python3/using-cloud-sql) | ||
|
||
## Issues | ||
|
||
Please [create a new issue](https://github.com/smartninja/gae-2nd-gen-examples/issues/new) in case there's some bug or | ||
something should be improved. | ||
|
||
Happy to receive pull requests, too! :) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
runtime: python37 | ||
|
||
handlers: | ||
- url: /static | ||
static_dir: static | ||
- url: /.* | ||
script: auto |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import os | ||
from flask import Flask, render_template, request | ||
from flask_sqlalchemy import SQLAlchemy | ||
|
||
app = Flask(__name__) | ||
|
||
# determine the database URL | ||
db_user = os.environ.get('CLOUD_SQL_USERNAME') | ||
db_password = os.environ.get('CLOUD_SQL_PASSWORD') | ||
db_name = os.environ.get('CLOUD_SQL_DATABASE_NAME') | ||
db_connection_name = os.environ.get('CLOUD_SQL_CONNECTION_NAME') | ||
|
||
if db_user and db_password and db_name and db_connection_name: # if on google cloud, connect to PostgreSQL | ||
sqla_db_uri = f"postgresql://{db_user}:{db_password}@/{db_name}?host=/cloudsql/{db_connection_name}" | ||
else: # if on localhost, use SQLite | ||
sqla_db_uri = "sqlite:///localhost.sqlite" | ||
|
||
app.config['SQLALCHEMY_DATABASE_URI'] = sqla_db_uri | ||
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False | ||
db = SQLAlchemy(app) | ||
|
||
|
||
class Message(db.Model): | ||
id = db.Column(db.Integer, primary_key=True) | ||
text = db.Column(db.Text, nullable=False) | ||
|
||
def __repr__(self): | ||
return '<Message %r>' % self.title | ||
|
||
|
||
# create all tables in the database | ||
db.create_all() | ||
|
||
|
||
@app.route("/", methods=["GET", "POST"]) | ||
def index(): | ||
# get all messages from the db | ||
messages = db.session.query(Message).all() | ||
|
||
if request.method == "POST": | ||
# create a new message | ||
message = Message(text=request.form.get("message")) | ||
db.session.add(message) | ||
db.session.commit() | ||
|
||
return render_template("index.html", messages=messages) | ||
|
||
|
||
if __name__ == '__main__': | ||
if os.getenv('GAE_ENV', '').startswith('standard'): | ||
app.run() # production | ||
else: | ||
app.run(port=8080, host="localhost") # localhost |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Flask | ||
Flask-SQLAlchemy |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import os | ||
|
||
main_command = "export FLASK_APP=main.py && flask run --host localhost --port 8080 --reload" | ||
|
||
# Run the main command, which is either the web app, or pytest | ||
run_main_command = os.popen(main_command) | ||
|
||
# Print process output in the Terminal | ||
print(run_main_command.read()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.red { | ||
color: red; | ||
} |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<title>Simple GAE app with SQL example</title> | ||
|
||
<link rel="stylesheet" href="/static/css/style.css"> | ||
</head> | ||
<body> | ||
<h1>Simple GAE app with SQL example</h1> | ||
|
||
<p> | ||
Enter your message: | ||
|
||
<form method="post" action="/"> | ||
<input type="text" name="message"> | ||
<button type="submit">Submit</button> | ||
</form> | ||
</p> | ||
|
||
{% for item in messages %} | ||
<p>{{ item.text }} <small><em>(message ID: {{item.id}})</em></small></p> | ||
{% endfor %} | ||
|
||
</body> | ||
</html> |