QuotaGuard Heroku Django и Azure SQL DB
import pandas as pd
from PIL import Image
from sqlalchemy import create_engine
from sqlalchemy.pool import NullPool
from dotenv import load_dotenv
import socks
import socket
import os
import io
load_dotenv()
CLIENT_ID = os.getenv("CLIENT_ID")
TENANT_ID = os.getenv("TENANT_ID")
CLIENT_SECRET = os.getenv("CLIENT_SECRET")
DB_SERVER = os.getenv("DB_SERVER")
DB_NAME = os.getenv("DB_NAME")
DB_DRIVER = os.getenv("DB_DRIVER")
DB_TIMEOUT = os.getenv("DB_TIMEOUT")
QUOTAGUARD_URL = os.getenv("QUOTAGUARD_URL")
if QUOTAGUARD_URL:
proxy_protocol, proxy_auth_host = QUOTAGUARD_URL.split("://")
proxy_auth, proxy_host_port = proxy_auth_host.split("@")
proxy_user, proxy_pass = proxy_auth.split(":")
proxy_host, proxy_port = proxy_host_port.split(":")
proxy_port = int(proxy_port)
socks.set_default_proxy(socks.SOCKS5, proxy_host, proxy_port, username=proxy_user, password=proxy_pass)
socket.socket = socks.socksocket
connection_string = (
"mssql+pyodbc:///?odbc_connect=" +
f"Driver={{{DB_DRIVER}}};" +
f"Server={DB_SERVER};" +
f"Database={DB_NAME};" +
"Encrypt=yes;" +
"TrustServerCertificate=yes;" +
f"Connection Timeout={DB_TIMEOUT};" +
"Authentication=ActiveDirectoryServicePrincipal;" +
f"UID={CLIENT_ID};" +
f"PWD={CLIENT_SECRET};" +
f"Authority Id={TENANT_ID};"
)
engine = create_engine(connection_string, poolclass=NullPool)
try:
query = "SELECT * FROM list_photos"
with engine.connect() as conn:
df = pd.read_sql(query, conn)
print("DataFrame loaded successfully!")
print(df.head())
except Exception as e:
print(f"Error: {e}")
for index, row in df.iterrows():
holdon = input("Press Enter to view the next image...")
try:
image = Image.open(io.BytesIO(row['photo']))
image.show()
except Exception as e:
print(f"Error displaying image at index {index}: {e}")
Я пытаюсь получить данные из базы данных Azure SQL через прокси, но он не использует этот прокси для подключения к ней, поэтому я получаю ошибку от базы данных, где говорится, что имя источника данных не найдено и т.д. и т.п., что типично, когда я пытаюсь подключиться к БД через IP, которого нет в белом списке. IP прокси находится в белом списке, вот откуда я знаю, что он не использует прокси для выполнения запроса plust в QuotaGuard dashboard я не вижу этот запрос также.
Я прочитал всю документацию здесь: https://devcenter.heroku.com/articles/quotaguard#testing-in-the-python-interpreter
Также я пробовал разные способы подключения, что я делаю не так?
Приведенные ниже шаги помогут вам реализовать QuotaGuard с Heroku, Django и Azure SQL DB.
В качестве предварительного условия убедитесь, что у вас есть следующие инструменты:
- панды
- PIL
- sqlalchemy
- create_engine for sqlalchemy.pool
- NullPool для sqlalchemy.pool
- dotenv
- импорты для сокетов и os
Чтобы создать новый каталог для проекта, перейдите в него:
mkdir myproject && cd myproject
Чтобы создать виртуальную среду в каталоге:
python3 -m venv venv
Активируйте виртуальную среду:
source venv/bin/activate
Вы можете установить необходимые пакеты:
$ pip install django pandas Pillow sqlalchemy psycopg2-binary psycopg2-pool dotenv
Выполните следующую команду, чтобы начать новый проект Django:
django-admin startproject myproject
Создайте новую базу данных Azure sql & установите необходимые пакеты для работы с PostgreSQL
pip install psycopg2-binary psycopg2-pool
Создайте файл .env
в корневом каталоге вашего проекта и включите в него следующий url:
DATABASE_URL=postgresql://username:password@your_server.database.windows.net:5432/mydatabase?sslmode=required
Далее, добавьте QuotaGuard в ваш проект Django
В папке myproject создайте новую директорию с именем quota_guard.
Добавить промежуточное ПО для обработки квот
from django.http import HttpResponse
from django.utils.deprecation import MiddlewareMixin
from .quota import Quota
class QuotaMiddleware(MiddlewareMixin):
Quota = Quota()
def process_request(self, request):
ip = request.META.get('REMOTE_ADDR')
quota = self.Quota.get(ip)
if not quota or quota.quota_exceeded():
return HttpResponse(status=429)
Определите класс квоты:
import json
from collections import defaultdict
import functools
import ipaddress
from . import settings
class Quota:
quota = defaultdict(int)
@functools.lru_cache(maxsize=None)
def get(ip):
ip_address = ipaddress.ip_address(ip)
return Quota.quota[ip_address]
@functools.lru_cache(maxsize=None)
def get_or_create(ip):
quota = Quota.quota[ip]
Quota.quota[ip] = Quota(ip, settings.RATE_LIMIT)
return quota
class Quota:
def __init__(self, ip, rate_limit):
self.ip = ip
self.rate_limit = rate_limit
self.last_request = 0
self.requests = 0
def quota_exceeded(self):
current_time = int(time.time())
elapsed_time = current_time - self.last_request
if elapsed_time < self.rate_limit:
self.requests += 1
self.last_request = current_time
return self.requests > settings.MAX_REQUESTS
Чтобы проверить вашу реализацию QuotaGuard, отправьте запросы в ваше Django-приложение, выполнив следующую команду:
gunicorn myproject.wsgi:application --bind 0.0.0.0:8000
Спасибо @devcodef1 за документацию по QuotaGuard: Implementing Heroku, Django, Azure SQL DB