Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
5 changes: 4 additions & 1 deletion .env.template
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
ADS_PORT=7676
DISCOUNTS_PORT=2814
AUTH_PORT=7578
DBM_PORT=7595
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
DD_API_KEY=
Expand Down Expand Up @@ -48,4 +49,6 @@ NEXT_PUBLIC_DD_SERVICE="frontend"
NEXT_PUBLIC_DD_VERSION="1.0.0"
NEXT_PUBLIC_DD_ENV="development"
NEXT_PUBLIC_AUTH_ROUTE="http://localhost"
NEXT_PUBLIC_AUTH_PORT="7578"
NEXT_PUBLIC_AUTH_PORT="7578"
NEXT_PUBLIC_DBM_ROUTE="http://localhost"
NEXT_PUBLIC_DBM_PORT="7595"
26 changes: 26 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,32 @@ services:
- "${AUTH_PORT}:${AUTH_PORT}"
networks:
- storedog-net
dbm:
depends_on:
- postgres
profiles:
- dbm
environment:
- FLASK_APP=dbm.py
- FLASK_DEBUG=1
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_HOST=postgres
- DD_SERVICE=storedog-dbm
- DD_AGENT_HOST=dd-agent
- DD_LOGS_INJECTION=true
- DD_TRACE_ANALYTICS_ENABLED=true
- DD_PROFILING_ENABLED=true
- DD_APPSEC_ENABLED=true
build:
context: ./services/dbm
command: gunicorn --bind 0.0.0.0:${DBM_PORT} dbm:app # If using any other port besides the default 8282, overriding the CMD is required
volumes:
- "./services/dbm:/app"
ports:
- "${DBM_PORT}:${DBM_PORT}"
networks:
- storedog-net
dd-agent:
image: gcr.io/datadoghq/agent:latest
environment:
Expand Down
Copy link
Collaborator

Choose a reason for hiding this comment

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

is this a temp file or something?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Honestly not sure, wasn't going to commit it but then noticed that there was a ton of these files. I'm not exactly sure what they're for and if we even need them (in the repo at least).

Copy link
Collaborator

Choose a reason for hiding this comment

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

Oh yea, I see what you mean. Maybe we should try deleting them, restarting the app locally, and see if it blows up or if the backend will auto-generate them. And then add that /storage dir to .gitignore

We try that separately from this PR, doesn't have to happen here

Binary file not shown.
37 changes: 37 additions & 0 deletions services/dbm/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Version control
.git

# Compiled Python bytecode
**/__pycache__
**/*.pyc
**/*.pyo

# Compiled extensions
**/*.pyd
**/*.so

# coverage.py
.coverage
.coverage.*
htmlcov

# Cached files
.cache
.mypy_cache
.hypothesis
.pytest_cache

# Virtualenvs and builds
build/
dist/
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Docker
Dockerfile*
.dockerignore
27 changes: 27 additions & 0 deletions services/dbm/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# syntax = docker/dockerfile:1.2
# ^ This enables the new BuildKit stable syntax which can be
# run with the DOCKER_BUILDKIT=1 environment variable in your
# docker build command (see build.sh)
FROM python:3.9.6-slim-buster

# Update, upgrade, and cleanup debian packages
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
apt-get upgrade --yes && \
apt-get install --yes build-essential libpq-dev && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

# Copy over app
WORKDIR /app
COPY . .

# Install dependencies via pip and avoid caching build artifacts
RUN pip install --no-cache-dir -r requirements.txt

# Set default Flask app and development environment
ENV FLASK_APP=dbm.py

# Start the app using ddtrace so we have profiling and tracing
ENTRYPOINT ["ddtrace-run"]
CMD gunicorn --bind 0.0.0.0:7578 dbm:app
40 changes: 40 additions & 0 deletions services/dbm/bootstrap.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from flask import Flask
from models import Items, db
from faker import Faker
import random
import os

fake = Faker()
DB_USERNAME = os.environ['POSTGRES_USER']
DB_PASSWORD = os.environ['POSTGRES_PASSWORD']
DB_HOST = os.environ['POSTGRES_HOST']


def create_app():
"""Create a Flask application"""
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://' + \
DB_USERNAME + ':' + DB_PASSWORD + '@' + DB_HOST + '/' + DB_USERNAME
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db.init_app(app)
initialize_database(app, db)
return app


def initialize_database(app, db):
"""Drop and restore database in a consistent state"""
app.logger.info('Running DB Init for DBM')
with app.app_context():
db.drop_all()
db.create_all()
for i in range(15000):
newItem = Items(
fake.sentence(),
random.randint(1, 7000),
fake.image_url(),
random.randint(1, 10)
)
db.session.add(newItem)
i+1
db.session.commit()
50 changes: 50 additions & 0 deletions services/dbm/dbm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from flask import jsonify
from flask_cors import CORS
from bootstrap import create_app
from models import db
import random
import os

DB_USERNAME = os.environ['POSTGRES_USER']
DB_PASSWORD = os.environ['POSTGRES_PASSWORD']
DB_HOST = os.environ['POSTGRES_HOST']

DB_URL = 'postgresql://' + \
DB_USERNAME + ':' + DB_PASSWORD + '@' + DB_HOST + '/' + DB_USERNAME

app = create_app()
app.config.update(
DEBUG=True,
SECRET_KEY="secret_sauce",
)

CORS(app)
engine = db.create_engine(DB_URL)

@app.route("/get-item", methods=["GET"])
def product_ticker():
query = db.text(f'SELECT * FROM items WHERE order_count::int > {random.randint(1, 7000)};')
app.logger.info(engine)
try:
app.logger.info('Connecting to db')
with engine.begin() as conn:
results = conn.execute(query).fetchall()
if results:
app.logger.info('Results found, parsing single item')
result = random.choice(results)
item_response = {
'id': result.id,
'description': result.description,
'last_hour': result.last_hour,
'order_count': result.order_count,
'image_url': result.image_url
}
return jsonify(item_response)
except:
app.logger.error("An error occurred while getting items.")
err = jsonify({'error': 'Internal Server Error'})
err.status_code = 500
return err

if __name__ == "__main__":
app.run(debug=True)
27 changes: 27 additions & 0 deletions services/dbm/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()


class Items(db.Model):
__tablename__ = 'items'
id = db.Column(db.Integer, primary_key=True)
description = db.Column(db.String(128))
order_count = db.Column(db.String(64))
last_hour = db.Column(db.String(64))
image_url = db.Column(db.String(64))

def __init__(self, description, order_count, image_url, last_hour):
self.description = description
self.order_count = order_count
self.last_hour = last_hour
self.image_url = image_url

def serialize(self):
return {
'id': self.id,
'description': self.description,
'order_count': self.order_count,
'last_hour': self.last_hour,
'image_url': self.image_url
}
25 changes: 25 additions & 0 deletions services/dbm/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
certifi==2020.11.8
chardet==3.0.4
click==8.0
ddtrace==1.7.2
Flask==2.2.2
Flask-Login==0.6.2
Flask-WTF==1.0.1
Flask-Cors==3.0.10
Flask-SQLAlchemy==3.0.2
idna==2.10
intervaltree==3.1.0
itsdangerous==2.0
Jinja2==3.0
MarkupSafe==2.1.1
nose==1.3.7
protobuf==3.14.0
requests==2.25.1
six==1.15.0
sortedcontainers==2.3.0
SQLAlchemy==1.4.42
psycopg2-binary
tenacity==6.2.0
urllib3==1.26.5
gunicorn==20.1.0
Faker==18.3.2