Skip to content

Commit

Permalink
Migrate from Flask to FastAPI with redis
Browse files Browse the repository at this point in the history
  • Loading branch information
S3L1M committed Aug 5, 2023
1 parent 2fced72 commit 45d2558
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 75 deletions.
2 changes: 1 addition & 1 deletion inventory-service/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ COPY . .
EXPOSE 7000

# Run the application
CMD ["python", "app.py"]
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7000"]
179 changes: 105 additions & 74 deletions inventory-service/app.py
Original file line number Diff line number Diff line change
@@ -1,103 +1,134 @@
from flask import Flask, jsonify, request
from flask_sqlalchemy import SQLAlchemy
from flask_caching import Cache
import lorem
import random

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:password@db2:5432/inventory_db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# Configure Redis caching
app.config['CACHE_TYPE'] = 'redis'
app.config['CACHE_REDIS_URL'] = 'redis://caching-db:6379/0'
cache = Cache(app)
cache.init_app(app)

db = SQLAlchemy(app)


class Product(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), unique=True)
price = db.Column(db.Float)
description = db.Column(db.String(500))

def __init__(self, name, price, description):
self.name = name
self.price = price
self.description = description


@cache.cached()
@app.route('/products', methods=['GET'])
def get_all_products():
products = Product.query.all()
from fastapi import FastAPI, Query, Depends, HTTPException
from sqlalchemy import create_engine, Column, Float, Integer, String
from sqlalchemy.orm import sessionmaker, declarative_base
from aioredis import create_redis_pool
import random, lorem, json

app = FastAPI()

# Database configuration
database_url = 'postgresql://postgres:password@db2:5432/inventory_db'
engine = create_engine(database_url)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()

# Redis caching configuration
redis_url = 'redis://caching-db:6379/0'
redis = None

# Dependency to get a database session
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()

# Product model
class Product(Base):
__tablename__ = 'products'

id = Column(Integer, primary_key=True)
name = Column(String(100), unique=True)
price = Column(Float)
description = Column(String(500))

# Create database tables
Base.metadata.create_all(bind=engine)

# Add dummy product data
db = SessionLocal()
for i in range(1, 101):
name = f'Product_{i}'
price = round(random.uniform(1.99, 999.99), 2)
description = lorem.get_sentence(count=2)
product = Product(name=name, price=price, description=description)
db.add(product)
db.commit()
db.close()

# Set up Redis connection
@app.on_event("startup")
async def startup_event():
global redis
redis = await create_redis_pool(redis_url)

# Shutdown Redis connection
@app.on_event("shutdown")
async def shutdown_event():
global redis
redis.close()
await redis.wait_closed()

# API endpoints
@app.get('/products')
async def get_all_products(db = Depends(get_db)):
products = await redis.get('products')
if products:
return json.loads(products)

products = db.query(Product).all()
result = []
for product in products:
result.append({
'name': product.name,
'price': product.price,
'description': product.description
})
return jsonify(result)
await redis.set('products', json.dumps(result))

return result

@cache.cached(timeout=50)
@app.route('/products/<name>', methods=['GET'])
def get_product_by_name(name):
product = Product.query.filter_by(name=name).first()
if product:
return jsonify({
'name': product.name,
'price': product.price,
'description': product.description
})
else:
return jsonify({'message': 'Product not found'}), 404

@app.get('/products/search')
async def search_product(keyword: str = Query(..., min_length=1), db = Depends(get_db)):
result = await redis.get(keyword)
if result:
return json.loads(result)

@app.route('/products/search', methods=['GET'])
def search_product():
keyword = request.args.get('keyword')
products = Product.query.filter(Product.name.ilike(f'%{keyword}%')).all()
products = db.query(Product).filter(Product.name.ilike(f'%{keyword}%')).all()
result = []
for product in products:
result.append({
'name': product.name,
'price': product.price,
'description': product.description
})
return jsonify(result)
await redis.set(keyword, json.dumps(result))

return result

@app.route('/products/price-range', methods=['GET'])
def get_products_by_price_range():
min_price = float(request.args.get('min_price'))
max_price = float(request.args.get('max_price'))
products = Product.query.filter(Product.price.between(min_price, max_price)).all()
@app.get('/products/price-range')
async def get_products_by_price_range(min_price: float = Query(...), max_price: float = Query(...), db = Depends(get_db)):
result = await redis.get(f'{min_price}_{max_price}')
if result:
return json.loads(result)

products = db.query(Product).filter(Product.price.between(min_price, max_price)).all()
result = []
for product in products:
result.append({
'name': product.name,
'price': product.price,
'description': product.description
})
return jsonify(result)

await redis.set(f'{min_price}_{max_price}', json.dumps(result))

if __name__ == '__main__':
# Create database tables
with app.app_context():
db.create_all()
return result

# Add dummy product data
for i in range(1, 101):
name = f'Product {i}'
price = round(random.uniform(1.99, 999.99), 2)
description = lorem.get_sentence(count=2)
product = Product(name, price, description)
db.session.add(product)
db.session.commit()
@app.get('/products/{name}')
async def get_product_by_name(name: str, db = Depends(get_db)):
product = await redis.get(name)
if product:
return json.loads(product)

app.run(host='0.0.0.0', port=7000)
product = db.query(Product).filter_by(name=name).first()
if product:
result = {
'name': product.name,
'price': product.price,
'description': product.description
}
await redis.set(name, json.dumps(result))
return result
else:
raise HTTPException(status_code=404, detail='Product not found')

0 comments on commit 45d2558

Please sign in to comment.