Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Fixes #23 Add support for configs and flex databases
  • Loading branch information
EliuX committed Mar 13, 2020
commit b94a95f5a916219a9e9bbbb0474d9f76b4f83eba
2 changes: 1 addition & 1 deletion tests/projects/projects_namespace_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ def test_list_should_return_nothing(client):
assert 200 == response.status_code

json_data = json.loads(response.data)
assert [] == json_data
assert [] == json_data
Empty file added tests/time_entries/__init__.py
Empty file.
10 changes: 10 additions & 0 deletions tests/time_entries/time_enties_namespace_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from flask import json

def test_list_should_return_empty_array(client):
"""Should return an empty array"""
response = client.get("/time-entries", follow_redirects=True)

assert 200 == response.status_code

json_data = json.loads(response.data)
assert [] == json_data
25 changes: 24 additions & 1 deletion time_tracker_api/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,37 @@
import os
from flask import Flask


def create_app():
def create_app(config_path='time_tracker_api.config.WhateverDevelopConfig',
config_data=None):
flask_app = Flask(__name__)

init_app_config(flask_app, config_path, config_data)
init_app(flask_app)

return flask_app


def init_app_config(app, config_path, config_data=None):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we have type hints here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure

if config_path:
app.config.from_object(config_path)
else:
# ensure the instance folder exists
try:
os.makedirs(app.instance_path)
except OSError:
pass

# Located in `/instance`
app.config.from_pyfile('config.py', silent=True)

if config_data:
app.config.update(config_data)


def init_app(app: Flask):
from .database import init_app as init_database
init_database(app)

from .api import api
api.init_app(app)
9 changes: 9 additions & 0 deletions time_tracker_api/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class Config:
DEBUG = False


class WhateverDevelopConfig(Config):
DEBUG = True
FLASK_DEBUG = True
FLASK_ENV = "develop"
DATABASE = "whatever"
28 changes: 28 additions & 0 deletions time_tracker_api/database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""
Agnostic database assets
Put here your utils and class independent of
the database solution
"""
from flask import Flask

RepositoryModel = None


def init_app(app: Flask) -> None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not call this function 'init_database' directly ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is some sort of standard that some objects like the APIs in flask Restplus have a function called init_app so they take the Flask app as a parameter and they do whatever initialization logic they need to be ready to be used by that app. So whatever module or package you add if you want to make it like pluggable to Flask this is pretty much the way to go

"""Make the app ready to use the database"""
database_strategy_name = app.config['DATABASE']
with app.app_context():
module = globals()["use_%s" % database_strategy_name]()
global RepositoryModel
RepositoryModel = module.repository_model


def create(model_name: str):
"""Creates the repository instance for the chosen database"""
return RepositoryModel(model_name)


def use_whatever():
from time_tracker_api import whatever_repository
return whatever_repository
5 changes: 4 additions & 1 deletion time_tracker_api/time_entries/time_entries_namespace.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from flask_restplus import fields, Resource, Namespace
from time_tracker_api.api import audit_fields
from time_tracker_api import database

ns = Namespace('time-entries', description='API for time entries')

Expand Down Expand Up @@ -61,13 +62,15 @@
)


model = database.create('time-entries')

@ns.route('')
class TimeEntries(Resource):
@ns.doc('list_time_entries')
@ns.marshal_list_with(time_entry_response, code=200)
def get(self):
"""List all available time entries"""
return []
return model.find_all()

@ns.doc('create_time_entry')
@ns.expect(time_entry)
Expand Down
10 changes: 10 additions & 0 deletions time_tracker_api/whatever_repository.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class WhateverRepository():
def __init__(self, model_name):
self.model_name = model_name

def find_all(self):
print('Fetching all entries from {0}'.format(self.model_name))
return []


repository_model = WhateverRepository