Skip to main content

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.

Release files for Jawf 0.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for Jawf 0.3
File Interpreter ABI Platform
Jawf-0.3-py3-none-any.whl Python 3 none any Details

Release files / Jawf-0.3-py3-none-any.whl

Download URL Jawf-0.3-py3-none-any.whl
Size 11.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c3b40b6f2bcdd845df122db21c0d700f26b7fb98ea139b7e527751910638934f
BLAKE2b-256 checksum
How to use checksums
b0ab74fe7877613537c88271b57b8ef473a3f79003756b36bf26ae35fb225d06
Upload date
Uploaded using Trusted Publishing?
What is 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

Release history Release notifications | RSS feed

This release

0.3 This release

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page