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
Extract DAL from time_tracker_api #50
  • Loading branch information
EliuX committed Apr 7, 2020
commit 0bb037198cbc5b42914c41eaef690600b7eaf611
7 changes: 5 additions & 2 deletions .env.template
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Package where the app is located
# API
## Package where the app is located
export FLASK_APP=time_tracker_api

# The database connection URI. Check out the README.md for more details

# Common attributes
## The database connection URI. Check out the README.md for more details
DATABASE_URI=mssql+pyodbc://<user>:<password>@time-tracker-srv.database.windows.net/<database>?driver\=ODBC Driver 17 for SQL Server
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ ENV FLASK_APP time_tracker_api

EXPOSE 5000

CMD ["gunicorn", "-b 0.0.0.0:5000", "run:app"]
CMD ["gunicorn", "-b 0.0.0.0:5000", "api:app"]
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# time-tracker-api

The API of the TSheets killer app.
This is the mono-repository for the backend services and common codebase

## Getting started
Follow the following instructions to get the project ready to use ASAP.
Expand Down Expand Up @@ -30,10 +30,16 @@ automatically [pip](https://pip.pypa.io/en/stable/) as well.

- Install the requirements:
```
python3 -m pip install -r requirements/<stage>.txt
python3 -m pip install -r requirements/<app>/<stage>.txt
```

The `stage` can be `dev` or `prod`.
Where <app> is one of the executable app namespace, e.g. `time_tracker_api`.
The `stage` can be

* `dev`: Used for working locally
* `prod`: For anything deployed


Remember to do it with Python 3.


Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
12 changes: 12 additions & 0 deletions requirements/sql_db_serverless.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# requirements/sql_db_serverless.txt

# For SQL database serverless (MS SQL)


# SQL Server driver
pyodbc==4.0.30

# ORM
SQLAlchemy==1.3.15
SQLAlchemy-Utils==0.36.3
flask_sqlalchemy==2.4.1
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# requirements/dev.txt
# requirements/time_tracker_api/dev.txt

# Include the prod resources
-r prod.txt

# For development
Expand Down
12 changes: 5 additions & 7 deletions requirements/prod.txt → requirements/time_tracker_api/prod.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# requirements/prod.txt
# requirements/time_tracker_api/prod.txt

# Dependencies
-r ../sql_db_serverless.txt


# For production releases

Expand All @@ -21,12 +25,6 @@ Faker==4.0.2
#CLI support
Flask-Script==2.0.6

# SQL database (MS SQL)
pyodbc==4.0.30
SQLAlchemy==1.3.15
SQLAlchemy-Utils==0.36.3
flask_sqlalchemy==2.4.1

# Handling requests
requests==2.23.0

Expand Down
Empty file added tests/commons/__init__.py
Empty file.
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from time_tracker_api.sql_repository import db, AuditedSQLModel
from commons.data_access_layer.azure.sql_repository import db, AuditedSQLModel

from sqlalchemy_utils import UUIDType
import uuid
Expand Down
22 changes: 11 additions & 11 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import pytest
from _pytest.fixtures import FixtureRequest
from flask import Flask
from flask.testing import FlaskClient

from time_tracker_api import create_app


@pytest.fixture(scope='session')
def app(request: FixtureRequest) -> Flask:
def app() -> Flask:
return create_app("time_tracker_api.config.TestConfig")


Expand All @@ -18,15 +17,16 @@ def client(app: Flask) -> FlaskClient:


@pytest.fixture(scope="module")
def sql_repository():
from .resources import PersonSQLModel
from time_tracker_api.sql_repository import db
def sql_repository(app: Flask):
with app.test_client():
from tests.commons.data_access_layer.azure.resources import PersonSQLModel
from commons.data_access_layer.azure.sql_repository import db

db.metadata.create_all(bind=db.engine, tables=[PersonSQLModel.__table__])
print("Test models created!")
db.metadata.create_all(bind=db.engine, tables=[PersonSQLModel.__table__])
print("Test models created!")

from time_tracker_api.sql_repository import SQLRepository
yield SQLRepository(PersonSQLModel)
from commons.data_access_layer.azure.sql_repository import SQLRepository
yield SQLRepository(PersonSQLModel)

db.metadata.drop_all(bind=db.engine, tables=[PersonSQLModel.__table__])
print("Test models removed!")
db.metadata.drop_all(bind=db.engine, tables=[PersonSQLModel.__table__])
print("Test models removed!")
Empty file.
Empty file.
Empty file.
File renamed without changes.
Empty file.
4 changes: 2 additions & 2 deletions time_tracker_api/activities/activities_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ class ActivityDao(CRUDDao):


def create_dao() -> ActivityDao:
from time_tracker_api.sql_repository import db
from time_tracker_api.sql_repository import SQLCRUDDao
from sqlalchemy_utils import UUIDType
import uuid
from commons.data_access_layer.azure.sql_repository import db
from commons.data_access_layer.azure.sql_repository import SQLCRUDDao

class ActivitySQLModel(db.Model):
__tablename__ = 'activity'
Expand Down
5 changes: 3 additions & 2 deletions time_tracker_api/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ class DevelopmentConfig(Config):


class SQLConfig(Config):
SQLALCHEMY_DATABASE_URI = Config.DATABASE_URI
SQLALCHEMY_COMMIT_ON_TEARDOWN = True
SQLALCHEMY_TRACK_MODIFICATIONS = False
DATABASE_URI = os.environ.get('DATABASE_URI')
SQLALCHEMY_DATABASE_URI = DATABASE_URI


class TestConfig(SQLConfig):
Expand All @@ -41,7 +42,7 @@ class ProductionConfig(Config):


class AzureConfig(SQLConfig):
DATABASE_URI = os.environ.get('DATABASE_URI', os.environ.get('SQLAZURECONNSTR_DATABASE_URI'))
DATABASE_URI = os.environ.get('SQLAZURECONNSTR_DATABASE_URI', SQLConfig.DATABASE_URI)
SQLALCHEMY_DATABASE_URI = DATABASE_URI


Expand Down
2 changes: 1 addition & 1 deletion time_tracker_api/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def __call__(self, *args, **kwargs):


def init_app(app: Flask) -> None:
from time_tracker_api.sql_repository import init_app, SQLSeeder
from commons.data_access_layer.azure.sql_repository import init_app, SQLSeeder
init_app(app)
global seeder
seeder = SQLSeeder()
3 changes: 2 additions & 1 deletion time_tracker_api/projects/projects_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ class ProjectDao(CRUDDao):


def create_dao() -> ProjectDao:
from time_tracker_api.sql_repository import db
from commons.data_access_layer.azure.sql_repository import db
from time_tracker_api.database import COMMENTS_MAX_LENGTH
from time_tracker_api.sql_repository import SQLCRUDDao
from sqlalchemy_utils import UUIDType
import uuid
from commons.data_access_layer.azure.sql_repository import SQLCRUDDao, AuditedSQLModel

class ProjectSQLModel(db.Model):
__tablename__ = 'project'
Expand Down
4 changes: 2 additions & 2 deletions time_tracker_api/time_entries/time_entries_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ class TimeEntriesDao(CRUDDao):


def create_dao() -> TimeEntriesDao:
from time_tracker_api.sql_repository import db
from commons.data_access_layer.azure.sql_repository import db
from time_tracker_api.database import COMMENTS_MAX_LENGTH
from time_tracker_api.sql_repository import SQLCRUDDao
from sqlalchemy_utils import UUIDType
import uuid
from commons.data_access_layer.azure.sql_repository import SQLCRUDDao

class TimeEntrySQLModel(db.Model):
__tablename__ = 'time_entry'
Expand Down