initial google-drive project

parents
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
media/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
data/
.idea
minio/
\ No newline at end of file
FROM python:3.10-slim-buster
RUN pip3 install --upgrade pip && pip3 install poetry
WORKDIR /app
COPY pyproject.toml poetry.lock /app/
RUN poetry config virtualenvs.create false \
&& poetry install --no-interaction --no-ansi
COPY . .
version: '3'
services:
core:
build:
context: .
dockerfile: Dockerfile
image: google_drive:1.0
restart: always
ports:
- "8000:8000"
env_file:
- .env
networks:
- googledrivenetwork
volumes:
- .:/app
command: bash -c "poetry run python3 src/app/main.py"
depends_on:
- postgres
postgres:
image: postgres:14-alpine
env_file:
- .env
ports:
- "5440:5432"
volumes:
- ./data/postgres:/var/lib/postgresql/data/
networks:
- googledrivenetwork
minio:
image: minio/minio
ports:
- "9000:9000"
- "9090:9090"
env_file:
- .env
command: server --console-address ":9090" /data
volumes:
- ./minio/data:/data
- ./minio/conf:/root/.minio
depends_on:
- postgres
- core
networks:
- googledrivenetwork
networks:
googledrivenetwork:
driver: bridge
This diff is collapsed.
[tool.poetry]
name = "google-drive"
version = "0.1.0"
description = ""
authors = ["beka <beka1990.30.10@gmail.com>"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.10"
fastapi = "^0.105.0"
uvicorn = "^0.24.0.post1"
tortoise-orm = {extras = ["asyncpg"], version = "^0.20.0"}
python-multipart = "^0.0.6"
miniopy-async = "^1.17"
asyncpg = "^0.29.0"
aerich = "^0.7.2"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
import io
import fastapi
from miniopy_async import Minio
import settings
class MinioClient(Minio):
def __init__(self, *args, **kwargs):
super().__init__(
*args,
endpoint=settings.minio_url,
access_key=settings.minio_root_user,
secret_key=settings.minio_root_password,
secure=False,
**kwargs,
)
async def upload_from_bytes(self, file: fastapi.UploadFile):
file_data = await file.read()
return await self.put_object(
bucket_name=settings.minio_bucket_name,
object_name=file.filename,
data=io.BytesIO(file_data),
length=len(file_data),
)
from fastapi import APIRouter
router = APIRouter(prefix='/api')
import os
from fastapi import FastAPI
from tortoise.contrib.fastapi import register_tortoise
TORTOISE_ORM = {
'connections': {'default': os.environ.get('DATABASE_URL')},
'apps': {
'models': {
'models': ['src.app.db.models', 'aerich.models'],
'default_connection': 'default',
},
},
}
def init_db(app: FastAPI) -> None:
register_tortoise(
app,
db_url=os.environ.get('DATABASE_URL'),
modules={"models": ["db.models"]},
generate_schemas=False,
add_exception_handlers=True,
)
class NotFoundException(Exception):
pass
class CreateException(Exception):
pass
class UpdateException(Exception):
pass
class DeleteException(Exception):
pass
import fastapi
import pydantic
from starlette import status
from fastapi.responses import JSONResponse
from .http import BaseHTTPException
async def query_params_exc_handler(
request: fastapi.Request, exc: pydantic.ValidationError,
) -> JSONResponse:
return JSONResponse(
{'detail': exc.errors()}, status.HTTP_422_UNPROCESSABLE_ENTITY,
)
async def request_exc_handler(
request: fastapi.Request, exc: BaseHTTPException,
) -> JSONResponse:
return JSONResponse(
{'detail': exc.detail}, exc.status_code,
)
async def internal_exc_handler(
request: fastapi.Request, exc: Exception,
) -> JSONResponse:
return JSONResponse(
{'detail': 'Internal Server Error'},
status.HTTP_500_INTERNAL_SERVER_ERROR,
)
from typing import Any, Dict
from fastapi.exceptions import HTTPException
from starlette import status
class BaseHTTPException(HTTPException):
pass
class HTTPBadRequestException(BaseHTTPException):
def __init__(
self, status_code: int = status.HTTP_400_BAD_REQUEST, detail: Any = None,
headers: Dict[str, str] | None = None
) -> None:
super().__init__(status_code, detail, headers)
class HTTPNotFoundException(BaseHTTPException):
def __init__(
self, status_code: int = status.HTTP_404_NOT_FOUND, detail: Any = None,
headers: Dict[str, str] | None = None
) -> None:
super().__init__(status_code, detail, headers)
import fastapi
import pydantic
from api.router import router
from exceptions import handlers as exc_handlers, http as http_exc
from db.conf import init_db
def setup():
app = fastapi.FastAPI()
app.include_router(router)
app.exception_handler(pydantic.ValidationError)(exc_handlers.query_params_exc_handler)
app.exception_handler(http_exc.BaseHTTPException)(exc_handlers.request_exc_handler)
app.exception_handler(500)(exc_handlers.internal_exc_handler)
return app
app = setup()
init_db(app)
if __name__ == '__main__':
import uvicorn
uvicorn.run('main:app', host='0.0.0.0', port=8000, reload=True)
import os
import pydantic
database_url = pydantic.PostgresDsn(os.getenv('DATABASE_URL'))
minio_root_user = os.getenv('MINIO_ROOT_USER')
minio_root_password = os.getenv('MINIO_ROOT_PASSWORD')
minio_url = os.getenv('MINIO_URL')
minio_bucket_name = os.getenv('MINIO_BUCKET_NAME')
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment