Spaces:
Build error
Build error
Commit ·
aa26805
1
Parent(s): 0565e38
Single docker
Browse files
Dockerfile
CHANGED
|
@@ -1,11 +1,26 @@
|
|
| 1 |
-
# Use
|
| 2 |
-
FROM
|
| 3 |
|
| 4 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
ENV MYSQL_ROOT_PASSWORD=rootpassword
|
| 6 |
ENV MYSQL_DATABASE=mydatabase
|
| 7 |
ENV MYSQL_USER=myuser
|
| 8 |
ENV MYSQL_PASSWORD=mypassword
|
| 9 |
|
| 10 |
-
# Expose port
|
| 11 |
-
EXPOSE 3306
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Use a base image with Python
|
| 2 |
+
FROM python:3.9
|
| 3 |
|
| 4 |
+
# Install MySQL
|
| 5 |
+
RUN apt-get update && apt-get install -y mysql-server && apt-get clean
|
| 6 |
+
|
| 7 |
+
# Set the working directory
|
| 8 |
+
WORKDIR /app
|
| 9 |
+
|
| 10 |
+
# Copy the current directory contents into the container at /app
|
| 11 |
+
COPY . /app
|
| 12 |
+
|
| 13 |
+
# Install any needed packages specified in requirements.txt
|
| 14 |
+
RUN pip install --no-cache-dir -r requirements.txt
|
| 15 |
+
|
| 16 |
+
# Set environment variables for MySQL
|
| 17 |
ENV MYSQL_ROOT_PASSWORD=rootpassword
|
| 18 |
ENV MYSQL_DATABASE=mydatabase
|
| 19 |
ENV MYSQL_USER=myuser
|
| 20 |
ENV MYSQL_PASSWORD=mypassword
|
| 21 |
|
| 22 |
+
# Expose port 80 for the FastAPI app and 3306 for MySQL
|
| 23 |
+
EXPOSE 7860 3306
|
| 24 |
+
|
| 25 |
+
# Initialize MySQL and run FastAPI
|
| 26 |
+
CMD service mysql start && mysql -e "CREATE DATABASE IF NOT EXISTS ${MYSQL_DATABASE}; GRANT ALL ON ${MYSQL_DATABASE}.* TO '${MYSQL_USER}'@'localhost' IDENTIFIED BY '${MYSQL_PASSWORD}'; FLUSH PRIVILEGES;" && uvicorn main:app --host 0.0.0.0 --port 7860
|
db.py
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import asyncio, contextlib, os
|
| 2 |
+
from dotenv import load_dotenv
|
| 3 |
+
from sqlalchemy.ext.asyncio import (
|
| 4 |
+
AsyncSession,
|
| 5 |
+
async_sessionmaker,
|
| 6 |
+
create_async_engine
|
| 7 |
+
)
|
| 8 |
+
from sqlalchemy.orm import sessionmaker
|
| 9 |
+
|
| 10 |
+
from models import Base
|
| 11 |
+
from typing import AsyncIterator, Any, Dict, List, Optional, Tuple, Type, Union
|
| 12 |
+
load_dotenv()
|
| 13 |
+
|
| 14 |
+
# Define the MySQL connection details
|
| 15 |
+
DATABASE_URL = os.getenv('DATABASE_URL')
|
| 16 |
+
|
| 17 |
+
# Create an engine to connect to the MySQL server
|
| 18 |
+
engine = create_async_engine(DATABASE_URL, echo=True, future=True)
|
| 19 |
+
|
| 20 |
+
async_session = async_sessionmaker(
|
| 21 |
+
bind=engine,
|
| 22 |
+
expire_on_commit=False
|
| 23 |
+
)
|
| 24 |
+
|
| 25 |
+
async def create_async_db():
|
| 26 |
+
async with engine.begin() as conn:
|
| 27 |
+
await conn.run_sync(Base.metadata.create_all)
|
| 28 |
+
|
| 29 |
+
class DatabaseSessionManager:
|
| 30 |
+
def __init__(self, sessionmaker, engine):
|
| 31 |
+
self.sessionmaker = sessionmaker
|
| 32 |
+
self.engine = engine
|
| 33 |
+
|
| 34 |
+
async def close(self):
|
| 35 |
+
if self.engine:
|
| 36 |
+
await self.engine.dispose()
|
| 37 |
+
|
| 38 |
+
@contextlib.asynccontextmanager
|
| 39 |
+
async def create_session(self) -> AsyncIterator[AsyncSession]:
|
| 40 |
+
session = self.sessionmaker()
|
| 41 |
+
try:
|
| 42 |
+
yield session
|
| 43 |
+
except Exception:
|
| 44 |
+
await session.rollback()
|
| 45 |
+
raise
|
| 46 |
+
finally:
|
| 47 |
+
await session.close()
|
| 48 |
+
|
| 49 |
+
session_manager = DatabaseSessionManager(async_session, engine)
|
| 50 |
+
|
| 51 |
+
async def get_async_db():
|
| 52 |
+
async with session_manager.create_session() as session:
|
| 53 |
+
try:
|
| 54 |
+
yield session
|
| 55 |
+
finally:
|
| 56 |
+
await session.close()
|
main.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from fastapi import FastAPI, Depends
|
| 2 |
+
from sqlalchemy.ext.asyncio import AsyncSession
|
| 3 |
+
from sqlalchemy.future import select
|
| 4 |
+
from typing import List
|
| 5 |
+
|
| 6 |
+
from models import User
|
| 7 |
+
from db import get_async_db, create_async_db
|
| 8 |
+
|
| 9 |
+
app = FastAPI()
|
| 10 |
+
|
| 11 |
+
@app.on_event("startup")
|
| 12 |
+
async def on_startup():
|
| 13 |
+
await create_async_db()
|
| 14 |
+
|
| 15 |
+
@app.get("/users/", response_model=List[User])
|
| 16 |
+
async def read_users(skip: int = 0, limit: int = 10, db: AsyncSession = Depends(get_async_db)):
|
| 17 |
+
async with db as session:
|
| 18 |
+
result = await session.execute(select(User).offset(skip).limit(limit))
|
| 19 |
+
users = result.scalars().all()
|
| 20 |
+
return users
|
models.py
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sqlalchemy import Column, Integer, String
|
| 2 |
+
from sqlalchemy.orm import declarative_base
|
| 3 |
+
|
| 4 |
+
Base = declarative_base()
|
| 5 |
+
|
| 6 |
+
class User(Base):
|
| 7 |
+
__tablename__ = 'users'
|
| 8 |
+
id = Column(Integer, primary_key=True, index=True)
|
| 9 |
+
name = Column(String, index=True)
|
| 10 |
+
email = Column(String, unique=True, index=True)
|
my.cnf
DELETED
|
@@ -1,2 +0,0 @@
|
|
| 1 |
-
[mysqld]
|
| 2 |
-
bind-address = 0.0.0.0
|
|
|
|
|
|
|
|
|
start.sh
DELETED
|
@@ -1,13 +0,0 @@
|
|
| 1 |
-
#!/bin/bash
|
| 2 |
-
|
| 3 |
-
# Start MySQL server
|
| 4 |
-
docker-entrypoint.sh mysqld &
|
| 5 |
-
|
| 6 |
-
# Wait for MySQL server to start
|
| 7 |
-
sleep 10
|
| 8 |
-
|
| 9 |
-
# Grant remote access to MySQL user
|
| 10 |
-
mysql -uroot -prootpassword -e "GRANT ALL PRIVILEGES ON *.* TO 'myuser'@'%' IDENTIFIED BY 'mypassword'; FLUSH PRIVILEGES;"
|
| 11 |
-
|
| 12 |
-
# Keep the container running
|
| 13 |
-
tail -f /dev/null
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|