Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setup MongoDB and S3 clients #4 #10

Merged
merged 10 commits into from
Sep 23, 2024
File renamed without changes.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
.vscode/
mongodb/data/*
!mongodb/data/.keep
minio/data/*
!minio/data/.keep
object_storage_api/logging.ini
/keys/jwt-key.pub
/mongodb/keys/rs_keyfile
Expand Down
41 changes: 28 additions & 13 deletions README.md

Large diffs are not rendered by default.

30 changes: 28 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,38 @@ services:

mongo-db:
image: mongo:7.0-jammy
container_name: mongodb_container
container_name: object_storage_api_mongodb_container
volumes:
- ./mongodb/data:/data/db
restart: always
ports:
- 27017:27017
- 27018:27017
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example

minio:
image: minio/minio:RELEASE.2024-09-13T20-26-02Z
command: minio server /data
volumes:
- ./minio/data:/data
ports:
- 9000:9000
- 9001:9001
environment:
MINIO_ROOT_USER: root
MINIO_ROOT_PASSWORD: example_password
MINIO_ADDRESS: ":9000"
MINIO_CONSOLE_ADDRESS: ":9001"

# From https://stackoverflow.com/questions/66412289/minio-add-a-public-bucket-with-docker-compose
minio_create_buckets:
image: minio/mc
depends_on:
- minio
entrypoint: >
/bin/sh -c "
/usr/bin/mc alias set object-storage http://minio:9000 root example_password;
/usr/bin/mc mb object-storage/object-storage;
exit 0;
"
Empty file added minio/data/.keep
Empty file.
Empty file added mongodb/data/.keep
Empty file.
11 changes: 10 additions & 1 deletion object_storage_api/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,13 @@ API__ROOT_PATH=
# The allowed headers, origins, and methods for cross-origin requests.
API__ALLOWED_CORS_HEADERS=["*"]
API__ALLOWED_CORS_ORIGINS=["*"]
API__ALLOWED_CORS_METHODS=["*"]
API__ALLOWED_CORS_METHODS=["*"]
DATABASE__PROTOCOL=mongodb
DATABASE__USERNAME=root
DATABASE__PASSWORD=example
DATABASE__HOST_AND_OPTIONS="localhost:27018/?authMechanism=SCRAM-SHA-256&authSource=admin"
DATABASE__NAME=object-storage
OBJECT_STORAGE__ENDPOINT_URL="http://minio:9000"
OBJECT_STORAGE__ACCESS_KEY=root
OBJECT_STORAGE__SECRET_ACCESS_KEY=example_password
OBJECT_STORAGE__BUCKET_NAME=object-storage
37 changes: 33 additions & 4 deletions object_storage_api/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from pathlib import Path
from typing import List

from pydantic import BaseModel
from pydantic import BaseModel, ConfigDict, SecretStr
from pydantic_settings import BaseSettings, SettingsConfigDict


Expand All @@ -22,16 +22,45 @@ class APIConfig(BaseModel):
allowed_cors_methods: List[str]


class DatabaseConfig(BaseModel):
"""
Configuration model for the database.
"""

protocol: SecretStr
username: SecretStr
password: SecretStr
host_and_options: SecretStr
name: SecretStr

model_config = ConfigDict(hide_input_in_errors=True)


class ObjectStorageConfig(BaseModel):
"""
Configuration model for the S3 object storage.
"""

endpoint_url: SecretStr
access_key: SecretStr
secret_access_key: SecretStr
bucket_name: SecretStr

model_config = ConfigDict(hide_input_in_errors=True)


class Config(BaseSettings):
"""
Overall configuration model for the application.

It includes attributes for the API, authentication, and Object Storage server configurations. The class inherits
from `BaseSettings` and automatically reads environment variables. If values are not passed in form of system
environment variables at runtime, it will attempt to read them from the .env file.
It includes attributes for the API, authentication, database, and object storage configurations. The class
inherits from `BaseSettings` and automatically reads environment variables. If values are not passed in form of
system environment variables at runtime, it will attempt to read them from the .env file.
"""

api: APIConfig
database: DatabaseConfig
object_storage: ObjectStorageConfig

model_config = SettingsConfigDict(
env_file=Path(__file__).parent.parent / ".env",
Expand Down
31 changes: 31 additions & 0 deletions object_storage_api/core/database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""
Module for connecting to a MongoDB database.
"""

from typing import Annotated

from fastapi import Depends
from pymongo import MongoClient
from pymongo.database import Database

from object_storage_api.core.config import config

db_config = config.database
mongodb_client = MongoClient(
f"{db_config.protocol.get_secret_value()}://"
f"{db_config.username.get_secret_value()}:{db_config.password.get_secret_value()}@"
f"{db_config.host_and_options.get_secret_value()}",
tz_aware=True,
)


def get_database() -> Database:
"""
Connects to a MongoDB database and returns the specified database.

:return: The MongoDB database object.
"""
return mongodb_client[db_config.name.get_secret_value()]


DatabaseDep = Annotated[Database, Depends(get_database)]
15 changes: 15 additions & 0 deletions object_storage_api/core/object_store.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""
Module for connecting to an S3 object store.
"""

import boto3

from object_storage_api.core.config import config

object_storage_config = config.object_storage
s3_client = boto3.client(
"s3",
endpoint_url=object_storage_config.endpoint_url.get_secret_value(),
aws_access_key_id=object_storage_config.access_key.get_secret_value(),
aws_secret_access_key=object_storage_config.secret_access_key.get_secret_value(),
)
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ dependencies = [
"fastapi[all]",
"PyJWT",
"pymongo",
"boto3"
]

[project.urls]
Expand Down
10 changes: 10 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
annotated-types==0.7.0
anyio==4.5.0
boto3==1.35.22
botocore==1.35.22
certifi==2024.8.30
cffi==1.17.1
click==8.1.7
cryptography==43.0.1
dnspython==2.6.1
email_validator==2.2.0
fastapi==0.115.0
Expand All @@ -13,27 +17,33 @@ httpx==0.27.2
idna==3.10
itsdangerous==2.2.0
Jinja2==3.1.4
jmespath==1.0.1
markdown-it-py==3.0.0
MarkupSafe==2.1.5
mdurl==0.1.2
orjson==3.10.7
pycparser==2.22
pydantic==2.9.2
pydantic-extra-types==2.9.0
pydantic-settings==2.5.2
pydantic_core==2.23.4
Pygments==2.18.0
PyJWT==2.9.0
pymongo==4.9.1
python-dateutil==2.9.0.post0
python-dotenv==1.0.1
python-multipart==0.0.9
PyYAML==6.0.2
rich==13.8.1
s3transfer==0.10.2
shellingham==1.5.4
six==1.16.0
sniffio==1.3.1
starlette==0.38.5
typer==0.12.5
typing_extensions==4.12.2
ujson==5.10.0
urllib3==2.2.3
uvicorn==0.30.6
uvloop==0.20.0
watchfiles==0.24.0
Expand Down