Python/Django backend dasturlash
15 subscribers
260 photos
74 videos
109 files
322 links
Anything personal
Download Telegram
FastAPI SQLAlchemy 2.0 bilan (Type-Annotated, ya'ni Mapped va mapped_column) sintaksisida relationshiplarni ko'rib chiqamiz: 👇
1. One-to-Many (Birga ko'p) va Foreign KeyMantiq: Bir foydalanuvchi (User) ko'plab maqolalar (Post) yozishi mumkin.


from typing import List
from sqlalchemy import ForeignKey, String
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship

class Base(DeclarativeBase):
pass

# 1. USER (Bir)
class User(Base):
__tablename__ = "users"

id: Mapped[int] = mapped_column(primary_key=True)
username: Mapped[str] = mapped_column(String(50))

# Python darajasidagi bog'lanish (Ko'p bo'lgani uchun List olinadi)
posts: Mapped[List["Post"]] = relationship(back_populates="author")

# 2. POST (Ko'p)
class Post(Base):
__tablename__ = "posts"

id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str] = mapped_column(String(100))

# Baza darajasida bog'lanish (Foreign Key)
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"))

# Python darajasidagi bog'lanish (Faqat bitta obyekt)
author: Mapped["User"] = relationship(back_populates="posts")
2. One-to-One (Birga bir)Mantiq: Har bir foydalanuvchining (User) faqat bitta profili (Profile) bo'ladi.SQLAlchemy 2.0 da One-to-One qilish uchun ForeignKey qo'yilgan ustunni unikal (unique=True) qilish va munosabat turini to'g'ri ko'rsatish kifoya.


class Profile(Base):
__tablename__ = "profiles"

id: Mapped[int] = mapped_column(primary_key=True)
bio: Mapped[str] = mapped_column(String(255))

# Foreign Key unikal (unique=True) bo'lishi shart!
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), unique=True)

# Har ikki tomonda ham List ishlatilmaydi, chunki munosabat 1:1
user: Mapped["User"] = relationship(back_populates="profile")

# 💡 Diqqat: Yuqoridagi User modeliga quyidagi qatorni qo'shib qo'yish kerak:
# profile: Mapped["Profile"] = relationship(back_populates="user")
3. Many-to-Many (Ko'pga ko'p) va Oddiy Oraliq TableMantiq: Maqola (Post) ko'plab teglarga (Tag) ega bo'lishi mumkin. Ustunlar faqat ID-lardan iborat bo'lgani uchun Table obyektidan foydalanamiz.


from sqlalchemy import Table, Column

# 1. ORALIQ JADVAL (Faqat ID'larni saqlaydi)
post_tag_m2m = Table(
"post_tag_association",
Base.metadata,
Column("post_id", ForeignKey("posts.id"), primary_key=True),
Column("tag_id", ForeignKey("tags.id"), primary_key=True),
)

# 2. TAG JADVALI
class Tag(Base):
__tablename__ = "tags"

id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(50))

# secondary orqali oraliq jadval ko'rsatiladi
posts: Mapped[List["Post"]] = relationship(secondary=post_tag_m2m, back_populates="tags")

# 3. POST JADVALI (Yuqoridagi Post modelini kengaytiramiz)
class Post(Base):
__tablename__ = "posts"

id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str] = mapped_column(String(100))
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
author: Mapped["User"] = relationship(back_populates="posts")

# Teglar bilan Many-to-Many bog'lanish
tags: Mapped[List[Tag]] = relationship(secondary=post_tag_m2m, back_populates="posts")
4. Many-to-Many orqali qo'shimcha ma'lumot saqlash (Association Object)Mantiq: Talaba (Student) va Kurs (Course). Biz talaba kursga qachon yozilganini (enrolled_at) ham saqlamoqchimiz.Bunda oraliq jadval to'laqonli modelga (Base klasiga) aylanadi va ikkita One-to-Many munosabati kabi yoziladi.


from datetime import datetime
from sqlalchemy import func

# 1. KENGAYTIRILGAN ORALIQ MODEL
class Enrollment(Base):
__tablename__ = "enrollments"

student_id: Mapped[int] = mapped_column(ForeignKey("students.id"), primary_key=True)
course_id: Mapped[int] = mapped_column(ForeignKey("courses.id"), primary_key=True)

# Qo'shimcha ustun (Masalan: yozilgan vaqti)
enrolled_at: Mapped[datetime] = mapped_column(default=func.now())

# Har ikki modelga munosabat (relationship)
student: Mapped["Student"] = relationship(back_populates="course_associations")
course: Mapped["Course"] = relationship(back_populates="student_associations")

# 2. STUDENT MODELI
class Student(Base):
__tablename__ = "students"

id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(100))

# Kurslarga oraliq model orqali boriladi
course_associations: Mapped[List["Enrollment"]] = relationship(back_populates="student")

# 3. COURSE MODELI
class Course(Base):
__tablename__ = "courses"

id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str] = mapped_column(String(100))

# Talabalarga oraliq model orqali boriladi
student_associations: Mapped[List["Enrollment"]] = relationship(back_populates="course")
💡 FastAPI uchun muhim eslatma (N+1 muammosi)FastAPI asinxron (asyncio) ishlaganda, munosabatlarni chaqirishda xatolik (MissingGreenlet) bermasligi uchun query yozayotganda ma'lumotlarni srazi qo'shib yuklab olish lozim (lazy="selectin" yoki selectinload yordamida)💡️


from sqlalchemy.orm import selectinload
from sqlalchemy.future import select

# API endpoint ichida ishlatilishi:
stmt = select(Post).options(selectinload(Post.author)).where(Post.id == 1)
result = await db.execute(stmt)
post = result.scalar_one()
print(post.author.username) # Muammosiz ishlaydi
alembic init qilingandan keyin agar database asinxron bo'lsa alembic migration qilishda xatolik bo'lmasligi uchun alembic/env.pyni asinxronga o'tkazish:


from __future__ import annotations
import asyncio
from logging.config import fileConfig
from alembic import context
from sqlalchemy import pool
from sqlalchemy.ext.asyncio import create_async_engine
from database import Base
# Import all model modules so metadata is populated before autogenerate.
# Replace this import with your project package if needed.
import models # noqa: F401

config = context.config

if config.config_file_name is not None:
fileConfig(config.config_file_name)

target_metadata = Base.metadata

def run_migrations_offline() -> None:
"""Run migrations without DB connection."""
url = config.get_main_option("sqlalchemy.url")
context.configure(
url=url,
target_metadata=target_metadata,
literal_binds=True,
dialect_opts={"paramstyle": "named"},
compare_type=True,
compare_server_default=True,
)

with context.begin_transaction():
context.run_migrations()

def do_run_migrations(connection) -> None:
context.configure(
connection=connection,
target_metadata=target_metadata,
compare_type=True,
compare_server_default=True,
)

with context.begin_transaction():
context.run_migrations()

async def run_migrations_online() -> None:
"""Run migrations through async engine, but execute Alembic sync core via run_sync."""
connectable = create_async_engine(
config.get_main_option("sqlalchemy.url"),
poolclass=pool.NullPool,
)

try:
async with connectable.connect() as connection:
await connection.run_sync(do_run_migrations)
finally:
await connectable.dispose()

if context.is_offline_mode():
run_migrations_offline()
else:
asyncio.run(run_migrations_online())


alembic.ini faylida ham postgresql+asyncpg ishlatiladi
FastAPI da xuddi djangodagidek Choice yozish uchun quyidagidek yozish kerak:

class RoleChoice(str, Enum):
# (backend_value, frontend_label)
ADMIN = ("admin", "Admin Administrator")
EDITOR = ("editor", "Redaktor / Muharrir")
USER = ("user", "Oddiy foydalanuvchi")

def __new__(cls, value, label):
obj = str.__new__(cls, value)
obj._value_ = value
obj.label = label
return obj


Shunda masalan admin <- bu dbga yoziladigani Admin Adminstrator esa frontendda ko'rsatiladigan sifatida ishlatish mumkin bo'ladi.

# Frontend barcha ro'yxatni ("choices") olmoqchi bo'lsa:
@app.get("/roles")
async def get_roles():
return [
{"value": role.value, "label": role.label}
for role in RoleChoice
]
https://fastapicloud.com/
Fastapi loyihani terminalda bitta command bilan deploy qilsa bo'ladigan website

uv run fastapi deploy
😯 FastAPI Cloud вышел в публичную бету

Деплой существующего FastAPI-приложения:

uv run fastapi deploy


Новое приложение:

uvx fastapi-new
uv run fastapi deploy


🚀 Что включено из коробки
— HTTPS по умолчанию — автоматические TLS-сертификаты
— Автоскейлинг — растёт с трафиком, scale to zero в разработке
— Zero-downtime деплои — новые версии раскатываются постепенно
— Авто-верификация — если что-то сломалось, остаётся последняя рабочая версия
— GitHub интеграция — push в main = автодеплой, без CI-конфигов
— БД из коробки — Neon (Postgres), Redis Cloud, Supabase в пару кликов
— Логи, метрики, переменные окружения, кастомные домены
— VS Code расширение


⚙️ GitHub Actions если нужно


fastapi cloud setup-ci


Команда сама создаёт deploy tokens, прописывает их как GitHub secrets и генерирует workflow файл.

🤖 Про агентов

CLI спроектирован так чтобы AI-агенты могли работать с ним из терминала — деплоить, читать логи, обновлять переменные, дебажить — без кастомных интеграций. Поддержка JSON-вывода, явные параметры.

Вместо стен YAML — одна команда fastapi deploy. Это и есть deployment surface для агентов.

Ссылка на сайт

📍 Навигация: ВакансииЗадачиСобесы

Библиотека питониста

#буст
Forwarded from Вайб-кодинг
This media is not supported in your browser
VIEW IN TELEGRAM
Сохраняем: постоянно обновляемый список на 100% бесплатных API для LLM, которые остаются бесплатными навсегда.

В список входят Google AI Studio, Groq, Cerebras, OpenRouter, NVIDIA NIM, Mistral и десятки других сервисов с точными лимитами запросов и поддержкой OpenAI SDK в одном месте.

Уже 25 тыс. звёзд на GitHub. Просто вставьте любой endpoint в Cursor или Claude Code и начинайте разработку 😎
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Прогер
Claude Code может стать дешевле на 90% благодаря этому коду на GitHub

Суть простая: код встраивается между агентом и терминалом и сжимает вывод команд еще до того, как он попадет в контекст. Это помогает экономить до 90% токенов на каждом запуске. Claude Code, Cursor, Copilot и Gemini видят не длинные логи, а только суть. Поэтому расходы заметно снижаются

подписаться#полезно
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from [PYTHON:TODAY]
Media is too big
VIEW IN TELEGRAM
🖥 Unlimited-OCR — новая open-source модель, которая умеет анализировать десятки страниц документа за один запуск, без разбиения на отдельные изображения. Проект построен на новой архитектуре R-SWA, благодаря которой скорость практически не падает даже на очень длинных документах.

Что умеет?
📚 Обрабатывает целые книги, PDF, научные статьи, инструкции и большие документы одним проходом.
🖼 Работает не только с PDF, но и с отдельными изображениями, сканами и фотографиями документов.
🌍 Поддерживает множество языков.
📄 Сохраняет структуру документа и корректно извлекает длинные тексты.
✂️ Не требует разрезать PDF на десятки частей — модель рассчитана на длинные последовательности и может распознавать десятки страниц за один запуск.

Подходит для:
* обучения по электронным книгам;
* оцифровки архивов;
* подготовки данных для RAG;
* поиска информации в больших PDF;
* создания собственных AI-баз знаний.

⚙️ Установка

Клонируем проект:
git clone https://github.com/baidu/Unlimited-OCR
cd Unlimited-OCR


Устанавливаем зависимости:
pip install torch torchvision transformers pymupdf pillow matplotlib einops addict easydict psutil


▶️ Пример использования

from transformers import AutoModel, AutoTokenizer

model = AutoModel.from_pretrained(
"baidu/Unlimited-OCR",
trust_remote_code=True
)


Простой пример распознавания PDF:
model.infer_multi(
tokenizer,
prompt='<image>Multi page parsing.',
image_files=pdf_to_images('your_doc.pdf', dpi=300),
output_path='your/output/dir',
image_size=1024,
max_length=32768,
no_repeat_ngram_size=35, ngram_window=1024,
save_results=True,
)


💬 Если вы работаете с огромными PDF, учебниками, исследованиями или строите AI-системы поверх документов, Unlimited-OCR выглядит одним из самых интересных открытых OCR-проектов.

Ключевая особенность — возможность обрабатывать длинные документы целиком без традиционного разбиения на страницы, что упрощает конвейер обработки и ускоряет работу с большими объемами данных.

♎️ GitHub/Инструкция

#python #soft #github
Please open Telegram to view this post
VIEW IN TELEGRAM