Skip to content

implement socket.io #66

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
6 changes: 3 additions & 3 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ services:
tty: true
networks:
- main_network
profiles:
- ui
# profiles:
# - ui

master-backend-api:
build:
Expand All @@ -41,7 +41,7 @@ services:
sh -c "
alembic upgrade head && \

uvicorn main:app --port=10000 --host=0.0.0.0 --workers 1 --reload --no-access-log
uvicorn main:get_application --factory --port=10000 --host=0.0.0.0 --workers 1 --reload --no-access-log
"
# uvicorn main:app --uds=/app/tmp_uds/master-backend.sock --workers 1 --reload --no-access-log &
#
Expand Down
9 changes: 6 additions & 3 deletions master_backend_api/app/dependencies/file_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,19 @@
MAX_FILE_SIZE = 5 * 1024 * 1024 # 5 MB


async def validate_image(mainImage: UploadFile = File(...)) -> File:

async def validate_image(mainImage: UploadFile = File(...)) -> UploadFile:
if mainImage.content_type not in ALLOWED_IMAGE_FILE_TYPES:
raise HTTPException(
status_code=400,
detail=f"Invalid file type: {mainImage.content_type}. "
f"Allowed types: {', '.join(ALLOWED_IMAGE_FILE_TYPES)}.",
)

file_size = len(await mainImage.read())
# Отримуємо розмір файлу без його повного зчитування
mainImage.file.seek(0, 2) # Переміщуємо курсор у кінець файлу
file_size = mainImage.file.tell() # Отримуємо поточну позицію (розмір у байтах)
mainImage.file.seek(0) # Повертаємо курсор на початок

if file_size > MAX_FILE_SIZE:
raise HTTPException(
status_code=400,
Expand Down
24 changes: 15 additions & 9 deletions master_backend_api/app/main.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from contextlib import asynccontextmanager
import socketio

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
Expand All @@ -10,6 +11,7 @@
from applications.users.router import router_users
from applications.payment.routers import router as payment_router
from services.redis_service import redis_service
from services.socketio_service import SocketIO, sio, NoPrefixNamespace # ?
from settings import settings
import sentry_sdk
from prometheus_fastapi_instrumentator import Instrumentator
Expand Down Expand Up @@ -80,17 +82,21 @@ def get_application() -> FastAPI:
add_sqladmin_interface(_app)

Instrumentator().instrument(_app).expose(_app)

_app = socketio.ASGIApp(SocketIO().get_sio_server(), _app, socketio_path="/api/socket.io")
# _app.mount("/api/socket.io", SocketIO().sio_app)

return _app


app = get_application()
# app = get_application()


@app.get("/")
async def index():
logging.debug("111111112222222222222")
logging.info("111111112222222222222")
logging.warning("111111112222222222222")
logging.error("111111112222222222222")
await redis_service.set_cache("hjhjhjhjhh55555555555555551111111", 45)
return {"status": "OK"}
# @app.get("/")
# async def index():
# logging.debug("111111112222222222222")
# logging.info("111111112222222222222")
# logging.warning("111111112222222222222")
# logging.error("111111112222222222222")
# await redis_service.set_cache("hjhjhjhjhh55555555555555551111111", 45)
# return {"status": "OK"}
33 changes: 33 additions & 0 deletions master_backend_api/app/services/socketio_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import socketio


class SocketIO:

def __init__(self):
self.sio_server = socketio.AsyncServer(
async_mode="asgi", cors_allowed_origins=["*"], transports=["websocket", "polling"]
)
self.sio_app = socketio.ASGIApp(
self.sio_server,
socketio_path="/api/socket.io/",
)

def get_sio_server(self):
return self.sio_server


sio = SocketIO().sio_server


class NoPrefixNamespace(socketio.AsyncNamespace):
# recheck this internet code
# how does it should works?
def on_connect(self, sid, environ):
print("connect ", sid)

async def on_message(self, sid, data):
print("message ", data)
await sio.emit("response", "hi " + data)

def on_disconnect(self, sid):
print("disconnect ", sid)
1 change: 0 additions & 1 deletion master_backend_api/app/storage/s3.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ async def get_s3_session(self) -> AsyncGenerator[aioboto3.Session.client, None]:

async def upload_file(self, file: UploadFile, object_name: str) -> str:
async for s3_client in self.get_s3_session():
file.file.seek(0) # because of validate_image - it has read file
try:
await s3_client.upload_fileobj(file, self.bucket_name, object_name)
return f"{settings.S3_PUBLIC_BUCKET_URL}/{object_name}"
Expand Down
85 changes: 84 additions & 1 deletion master_backend_api/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions master_backend_api/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ stripe = "^11.6.0"
flagsmith = "^3.8.0"
aioboto3 = "^14.1.0"
transliterate = "^1.10.2"
python-socketio = {extras = ["asyncio-client"], version = "^5.12.1"}

[tool.poetry.group.dev.dependencies]
flake8 = "^7.1.1"
Expand Down
51 changes: 33 additions & 18 deletions nginx/nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@ server {
server_tokens off;
charset utf-8;

# for dockerized minio
# location /storage/ {
# # https://min.io/docs/minio/linux/integrations/setup-nginx-proxy-with-minio.html
# # rewrite ^/storage(/.*)$ $1 break; -> do not enable it. This is caused because nginx will try to index the directory, and be blocked by itself.
# proxy_set_header Host $http_host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Forwarded-Proto $scheme;
# proxy_set_header X-NginX-Proxy true;
# real_ip_header X-Real-IP;
# proxy_connect_timeout 300;
# proxy_http_version 1.1;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection "upgrade";
# chunked_transfer_encoding off;
#
# proxy_pass http://s3:9000;
# }
# for dockerized minio
# location /storage/ {
# # https://min.io/docs/minio/linux/integrations/setup-nginx-proxy-with-minio.html
# # rewrite ^/storage(/.*)$ $1 break; -> do not enable it. This is caused because nginx will try to index the directory, and be blocked by itself.
# proxy_set_header Host $http_host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Forwarded-Proto $scheme;
# proxy_set_header X-NginX-Proxy true;
# real_ip_header X-Real-IP;
# proxy_connect_timeout 300;
# proxy_http_version 1.1;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection "upgrade";
# chunked_transfer_encoding off;
#
# proxy_pass http://s3:9000;
# }

location / {
proxy_set_header Host $http_host;
Expand All @@ -48,6 +48,21 @@ server {
send_timeout 60s;
}

# do we need it? it doesnt work without nginx to
location /api/socket.io/ {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

proxy_pass http://master-backend-api:10000/;
}


location /documentation/ {
proxy_pass http://mkdocs:8010/;
proxy_set_header Host $host;
Expand Down
Loading