Just Another Web Framework - streamlining flask application development
Project description
Jawf
Just Another Web Framework - streamlining flask application development
Setup
$git clone https://github.com/codemation/Jawf.git
$ sudo ./setup.py install
$ jawf --help
Basic Usage
Initialize a JAWF Project directory
$ jawf --init <projName>
$ jawf --init Project1
Not inside existing jawf project
Succesfully created jawf project: Project1
Add an app to project
Usage: jawf --add-app <app-name> [--route <urlpattern> default: /app-name]
$ jawf --add-app myfirstapp
$ jawf --add-app homepage --route /
$ jawf --add-app myfirstapp
Not inside existing jawf project
--add-app
must be used within an existing project directory
or combined with --project <project-path>
$ cd Project1/
/Project1 $ jawf --add-app myfirstapp
Detected Existing project:Project1
app myfirstapp was created successfully within /home/josh/python/mysql/Project1/
This creates an application which is immedietly wired up to the project. Can be tested right away.
/Project1$ python3 server.py
* Serving Flask app "server" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://0.0.0.0:8080/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 144-714-176
$ curl http://0.0.0.0:8080/myfirstapp
<h1>Hello myfirstapp World</h1>
A closer look at the skeleton of the application created.
Project1/apps/myfirstapp/myfirstapp.py
# myfirstapp
def run(server):
# Add import libraries here, run only once, when server is started
@server.route('/myfirstapp')
def myfirstapp_func():
# Add repeatable logic here, run as often as endpoint is called.
print("Hello myfirstapp World")
return "<h1>Hello myfirstapp World</h1>", 200
If you are familiar with flask routing, this is exactly the same. The work of wiring together multiple endpoints to a primary server app is done for you.
Add an DB to project
JAWF makes it easy to add new databaes, tables to a project as well as accessing the data in combination with [pyql]https://github.com/codemation/pyql
Supported database types: sqlite3, mysql
jawf --add-db <db-name> [--type mysql default: sqlite3]
jawf --add-db finance --type mysql
jawf --add-db stocks
sqlite3 is a builtin library with python3 and creates light-weight databases in place for storing / retreiving data.
sqlite3
Project1$ jawf --add-db stocks
Detected Existing project:Project1
db stocks created successfully
This does not immedietly create a database until a table is added, and server is started.
Lets have a look at the DB file created at Project1/dbs/stocks/
stocks_db.py
# stocks - type sqlite3
def run(server):
import sys, os
@server.route('/stocks_attach')
def stocks_attach():
config=dict()
with open('.cmddir', 'r') as projDir:
for projectPath in projDir:
config['database'] = f'{projectPath}dbs/stocks/stocks'
#USE ENV PATH for PYQL library or /pyql/
sys.path.append('/pyql/' if os.getenv('PYQL_PATH') == None else os.getenv('PYQL_PATH'))
try:
import data, sqlite3
from . import setup
server.data['stocks'] = data.database(sqlite3.connect, **config)
setup.attach_tables(server)
return {"status": 200, "message": "stocks attached successfully"}, 200
except Exception as e:
return {"status": 200, "message": repr(e)}, 500
stocks_attach()
Whats happening here:
Similar to app's there is an endpoint created to allow app developers control on when the web-server will attempt to access the DB This becomes more useful with remote-db's or in micro-service deployments, when a DB server may not be ready as soon as the APP server.
# stocks - type sqlite3
def run(server):
import sys, os
@server.route('/stocks_attach')
def stocks_attach():
config=dict()
Here we are first checking the project relative directory, as this is important wth sqlite3 databases which are always locally existing within the server. By default, mysqlite Db will exist within dbs/db-name/db
with open('.cmddir', 'r') as projDir:
for projectPath in projDir:
config['database'] = f'{projectPath}dbs/stocks/stocks'
PYQL is a dependency. If not directly install int a venv, this can be accessed using a ENV Variable PYQL_PATH or default /pyql/ system path.
#USE ENV PATH for PYQL library or /pyql/
sys.path.append('/pyql/' if os.getenv('PYQL_PATH') == None else os.getenv('PYQL_PATH'))
Finally PYQL libraryies are imported, and DB connector is attached to the server object (available in all JAWF apps), then tables are attached, and configured if not existing.
try:
import data, sqlite3
from . import setup
server.data['stocks'] = data.database(sqlite3.connect, **config)
setup.attach_tables(server)
return {"status": 200, "message": "stocks attached successfully"}, 200
except Exception as e:
return {"status": 200, "message": repr(e)}, 500
mysql
Project1$$ jawf --add-db trades --type mysql
Detected Existing project:Project1
db trades created successfully
Databases must be created already within the mysql instance, as well as appropiate user / permissions for accessing the DB, creating tables.
trades.py
# trades - type mysql
def run(server):
import sys, os
@server.route('/trades_attach')
def trades_attach():
config=dict()
env = ['DB_USER','DB_PASSWORD','DB_HOST', 'DB_PORT']
conf = ['user','password','database','host','port']
try:
config = {cnfVal: os.getenv(dbVal).rstrip() for dbVal,cnfVal in zip(env,conf)}
except Exception as e:
print('Missing an environment variable')
config= {cnfVal: os.getenv(dbVal) for dbVal,cnfVal in zip(env,conf)}
print(config)
return {
"status": 500,
"message": "Missing environment variable(s)",
"env-vars": config
}, 500
#USE ENV PATH for PYQL library or /pyql/
sys.path.append('/pyql/' if os.getenv('PYQL_PATH') == None else os.getenv('PYQL_PATH'))
try:
import data, mysql
from . import setup
server.data['trades'] = data.database(mysql.connector.connect, **config)
setup.attach_tables(server)
return {"status": 200, "message": "trades attached successfully"}, 200
except Exception as e:
return {"status": 200, "message": repr(e)}, 500
trades_attach()
Much of the same logic is shared with SQLITE3 databases, but the most important different is the DB connector requirements. As this is not always a DB locally existing(it could be), we need to know a few more details on how to access the database.
Here we are looking for 4 different ENV vars. These can be set in a number of different ways or passed into the /DB_NAME_attach endpoint via a POST request, passing in a JSON key-value pair for 'user','password','database','host','port'
env = ['DB_USER','DB_PASSWORD','DB_HOST', 'DB_PORT', DB_NAME]
conf = ['user','password','host','port', database]
try:
config = {cnfVal: os.getenv(dbVal).rstrip() for dbVal,cnfVal in zip(env,conf)}
except Exception as e:
print('Missing an environment variable')
config= {cnfVal: os.getenv(dbVal) for dbVal,cnfVal in zip(env,conf)}
print(config)
return {
"status": 500,
"message": "Missing environment variable(s)",
"env-vars": config
}, 500
Add a Table to a DB
Databases are comprised of tables, so we need to configure the schema for each of the tables we want the JAWF project to create. PYQL will automatically discover tables which already exist and be made accessible via the server.data['databaseName'].tables['tableName']
jawf --add-db-table <db-name> --table <table-name>
jawf --add-db-table finance --table purchaseOrders
$ jawf --add-db-table trades --table daytrades
Detected Existing project:Project1
table daytrades config created within db trades
This creates a daytrades table within the tables dir of the trades database.
def db_attach(server):
db = server.data['trades']
# Example
# db.create_table(
# 'users', # table-name
# [
# ('userid', int, 'AUTOINCREMENT'),
# ('username', str, 'UNIQUE NOT NULL'),
# ('email', str, 'NOT NULL'),
# ('join_date', str),
# ('last_login', str),
# ],
# 'userid' # Primary Key
# )
#UNCOMMENT Below to create
#
#db.create_table(
# 'daytrades', [
# (),
# (),
# ()
#)
pass # Enter db.create_table statement here
See PYQL docs for more information Table SCHEMA usage, but the above template gets you started.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
File details
Details for the file Jawf-0.3-py3-none-any.whl
.
File metadata
- Download URL: Jawf-0.3-py3-none-any.whl
- Upload date:
- Size: 11.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/2.0.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.6.0 requests-toolbelt/0.9.1 tqdm/4.38.0 CPython/3.6.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | c3b40b6f2bcdd845df122db21c0d700f26b7fb98ea139b7e527751910638934f |
|
MD5 | b3fd95584c3f3f636ff50961cdeed83b |
|
BLAKE2b-256 | b0ab74fe7877613537c88271b57b8ef473a3f79003756b36bf26ae35fb225d06 |