Skip to content

Commit b1a3975

Browse files
Initial commit
0 parents  commit b1a3975

33 files changed

+460
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.idea
2+
venv
3+
*.log

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
## api
2+
3+
### Project Setup
4+
5+
1. `pip install -r requirements.txt`
6+
2. `chmod +x unit-tests.sh`
7+
3. `./unit-tests.sh`

app/__init__.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import click
2+
from werkzeug.middleware.proxy_fix import ProxyFix
3+
4+
from .factory import Factory
5+
6+
7+
def create_app(environment='development'):
8+
f = Factory(environment)
9+
f.set_flask()
10+
f.set_db()
11+
f.set_migration()
12+
f.set_api()
13+
14+
# from models import Example
15+
16+
app = f.flask
17+
18+
from .views import sample_page
19+
20+
app.register_blueprint(sample_page, url_prefix='/views')
21+
22+
if app.config['TESTING']: # pragma: no cover
23+
# Setup app for testing
24+
@app.before_first_request
25+
def initialize_app():
26+
pass
27+
28+
@app.after_request
29+
def after_request(response):
30+
response.headers.add('Access-Control-Allow-Origin', '*')
31+
response.headers.add('Access-Control-Allow-Headers',
32+
'Content-Type,Authorization')
33+
response.headers.add('Access-Control-Allow-Methods',
34+
'GET,PUT,POST,DELETE')
35+
36+
return response
37+
38+
app.wsgi_app = ProxyFix(app.wsgi_app)
39+
40+
@app.cli.command()
41+
@click.argument('command')
42+
def setup(command):
43+
pass
44+
45+
return app
46+

app/config.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import os
2+
3+
4+
class Config:
5+
ERROR_404_HELP = False
6+
7+
SECRET_KEY = os.getenv('APP_SECRET', 'secret key')
8+
9+
SQLALCHEMY_DATABASE_URI = 'sqlite:///tutorial.db'
10+
SQLALCHEMY_TRACK_MODIFICATIONS = False
11+
12+
DOC_USERNAME = 'api'
13+
DOC_PASSWORD = 'password'
14+
15+
16+
class DevConfig(Config):
17+
DEBUG = True
18+
19+
20+
class TestConfig(Config):
21+
SQLALCHEMY_DATABASE_URI = 'sqlite://'
22+
TESTING = True
23+
DEBUG = True
24+
25+
26+
class ProdConfig(Config):
27+
DEBUG = False
28+
29+
30+
config = {
31+
'development': DevConfig,
32+
'testing': TestConfig,
33+
'production': ProdConfig
34+
}

app/factory.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import logging
2+
import os
3+
import sys
4+
from logging.handlers import RotatingFileHandler
5+
6+
from flask import Flask
7+
8+
from .config import config
9+
10+
11+
class Factory:
12+
13+
def __init__(self, environment='development'):
14+
self._environment = os.environ.get('APP_ENVIRONMENT', environment)
15+
self.flask = None
16+
17+
@property
18+
def environment(self):
19+
return self._environment
20+
21+
@environment.setter
22+
def environment(self, env):
23+
self._environment = env
24+
25+
def set_flask(self, **kwargs):
26+
self.flask = Flask(__name__, **kwargs)
27+
self.flask.config.from_object(config[self._environment])
28+
# setup logging
29+
file_handler = RotatingFileHandler('api.log', maxBytes=10000, backupCount=1)
30+
file_handler.setLevel(logging.INFO)
31+
self.flask.logger.addHandler(file_handler)
32+
stdout = logging.StreamHandler(sys.stdout)
33+
stdout.setLevel(logging.DEBUG)
34+
self.flask.logger.addHandler(stdout)
35+
36+
return self.flask
37+
38+
def set_db(self):
39+
from .models.database import db
40+
db.init_app(self.flask)
41+
42+
def set_migration(self):
43+
from .models.database import db, migrate
44+
migrate.init_app(self.flask, db)
45+
46+
def set_api(self):
47+
from .resources import api
48+
api.init_app(self.flask, version='1.0.0', title='api')

app/models/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .base import Example

app/models/base.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from sqlalchemy import Column, DateTime, func, Integer, String
2+
3+
from .database import db
4+
5+
6+
class Base(db.Model):
7+
__abstract__ = True
8+
9+
id = Column(Integer, primary_key=True)
10+
created_at = Column(DateTime, default=func.now())
11+
updated_at = Column(DateTime, onupdate=func.now())
12+
13+
14+
class Example(Base):
15+
name = Column(String)

app/models/database.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from flask_migrate import Migrate
2+
from flask_sqlalchemy import SQLAlchemy
3+
4+
db = SQLAlchemy()
5+
migrate = Migrate()

app/models/datastore.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from abc import ABC
2+
3+
from .base import Example
4+
5+
6+
class Datastore(ABC):
7+
8+
def __init__(self, _db=None):
9+
self.session = None
10+
if _db:
11+
self.session = _db.session
12+
13+
14+
class ExampleDatastore(Datastore):
15+
16+
def __init__(self, _db):
17+
super().__init__(_db)
18+
19+
def create_example(self, name):
20+
ex = Example(name=name)
21+
self.session.add(ex)
22+
self.session.commit()

app/resources/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from .example import ns as example_ns
2+
from ..utils import PatchedApi
3+
4+
api = PatchedApi()
5+
6+
api.add_namespace(example_ns)

0 commit comments

Comments
 (0)