Skip to main content

O'zbekcha to'liq asinxron web framework - FastAPI + Tortoise ORM + Flask-style

Project description

🚀 ProWeb - O'zbekcha To'liq Asinxron Web Framework

ProWeb - bu FastAPI, Tortoise ORM va Flask-style kodlash usulini birlashtirgan, to'liq o'zbekcha dokumentatsiyali, zamonaviy asinxron web framework.

✨ Asosiy Xususiyatlar

  • 🔥 FastAPI asosida - yuqori tezlikda ishlovchi API
  • 🐢 Tortoise ORM - to'liq asinxron ORM (Django-style)
  • 🌶️ Flask-style kodlash - oddiy va tushunarli sintaksis
  • 🎨 Jinja2 templates - osonlashtirilgan shablonlar
  • 🛠️ Avtomatik Admin Panel - Django kabi tayyor admin
  • 📦 Django-style CLI - tanish komandalar
  • 🇺🇿 O'zbekcha dokumentatsiya - to'liq o'zbek tilida
  • 100% Asinxron - barcha operatsiyalar async/await

📥 O'rnatish

pip install proweb

Yoki GitHub'dan:

git clone https://github.com/proweb/proweb.git
cd proweb
pip install -e .

🎯 Tezkor Boshlash

1. Yangi loyiha yaratish

proweb createproject mening_saytim
cd mening_saytim
pip install -r requirements.txt

2. Yangi ilova yaratish

proweb createapp blog

3. Model yaratish

apps/blog/models.py:

from proweb import Model, fields

class Maqola(Model):
    sarlavha = fields.CharField(max_length=200)
    matn = fields.TextField()
    muallif = fields.CharField(max_length=100)
    yaratilgan = fields.DatetimeField(auto_now_add=True)
    
    class Meta:
        table = "maqolalar"
    
    def __str__(self):
        return self.sarlavha

4. Migratsiya qilish

proweb makemigrations
proweb migrate

5. View yaratish

apps/blog/views.py:

from proweb import ProWeb
from proweb.templates import render_template
from .models import Maqola

async def maqolalar_royxati():
    """Barcha maqolalar ro'yxati"""
    maqolalar = await Maqola.barchasini_olish()
    return await render_template(
        "blog/list.html",
        maqolalar=maqolalar
    )

async def maqola_detali(id: int):
    """Bitta maqola batafsil"""
    maqola = await Maqola.olish(id=id)
    return await render_template(
        "blog/detail.html",
        maqola=maqola
    )

6. URL routing

main.py:

from proweb import ProWeb
from apps.blog import views

app = ProWeb(__name__)

# Flask-style routing
@app.get("/")
async def bosh_sahifa():
    return {"xabar": "Salom Dunyo!"}

@app.get("/maqolalar")
async def maqolalar():
    return await views.maqolalar_royxati()

@app.get("/maqolalar/{id}")
async def maqola_detali(id: int):
    return await views.maqola_detali(id)

# API endpoint
@app.post("/api/maqola/")
async def maqola_yaratish(sarlavha: str, matn: str):
    maqola = await Maqola.yaratish(
        sarlavha=sarlavha,
        matn=matn
    )
    return {"id": maqola.id, "xabar": "Muvaffaqiyatli yaratildi"}

7. Admin panel sozlash

apps/blog/admin.py:

from proweb.admin import admin_site, ModelAdmin
from .models import Maqola

class MaqolaAdmin(ModelAdmin):
    list_display = ['id', 'sarlavha', 'muallif', 'yaratilgan']
    search_fields = ['sarlavha', 'matn']
    list_filter = ['yaratilgan']

admin_site.register(Maqola, MaqolaAdmin)

8. Serverni ishga tushirish

proweb runserver

Endi quyidagi manzillar ochiladi:

📚 To'liq Misol

Complete CRUD misol

from proweb import ProWeb, Model, fields
from proweb.templates import render_template
from fastapi import HTTPException

app = ProWeb(__name__)

# Model
class Kitob(Model):
    nomi = fields.CharField(max_length=200)
    muallif = fields.CharField(max_length=100)
    narx = fields.DecimalField(max_digits=10, decimal_places=2)
    nashr_yili = fields.IntField()
    
    class Meta:
        table = "kitoblar"
    
    def __str__(self):
        return f"{self.nomi} - {self.muallif}"

# Views
@app.get("/kitoblar")
async def kitoblar_royxati():
    """Barcha kitoblar"""
    kitoblar = await Kitob.all()
    return await render_template("kitoblar/list.html", kitoblar=kitoblar)

@app.get("/kitoblar/{id}")
async def kitob_detali(id: int):
    """Bitta kitob"""
    kitob = await Kitob.get_or_none(id=id)
    if not kitob:
        raise HTTPException(status_code=404, detail="Kitob topilmadi")
    return await render_template("kitoblar/detail.html", kitob=kitob)

@app.post("/api/kitoblar/")
async def kitob_yaratish(
    nomi: str,
    muallif: str,
    narx: float,
    nashr_yili: int
):
    """Yangi kitob yaratish"""
    kitob = await Kitob.create(
        nomi=nomi,
        muallif=muallif,
        narx=narx,
        nashr_yili=nashr_yili
    )
    return {"id": kitob.id, "xabar": "Kitob qo'shildi"}

@app.put("/api/kitoblar/{id}")
async def kitob_yangilash(
    id: int,
    nomi: str = None,
    narx: float = None
):
    """Kitobni yangilash"""
    kitob = await Kitob.get(id=id)
    if nomi:
        kitob.nomi = nomi
    if narx:
        kitob.narx = narx
    await kitob.save()
    return {"xabar": "Yangilandi"}

@app.delete("/api/kitoblar/{id}")
async def kitob_ochirish(id: int):
    """Kitobni o'chirish"""
    kitob = await Kitob.get(id=id)
    await kitob.delete()
    return {"xabar": "O'chirildi"}

🎨 Template misoli

templates/kitoblar/list.html:

<!DOCTYPE html>
<html lang="uz">
<head>
    <meta charset="UTF-8">
    <title>Kitoblar ro'yxati</title>
    <link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
    <h1>Kitoblar</h1>
    
    {% for kitob in kitoblar %}
    <div class="kitob-karta">
        <h2>{{ kitob.nomi }}</h2>
        <p>Muallif: {{ kitob.muallif }}</p>
        <p>Narx: {{ kitob.narx|raqam_formati }} so'm</p>
        <p>Yil: {{ kitob.nashr_yili }}</p>
        <a href="/kitoblar/{{ kitob.id }}">Batafsil</a>
    </div>
    {% endfor %}
</body>
</html>

🛠️ CLI Komandalar

# Loyiha yaratish
proweb createproject loyiha_nomi

# Ilova yaratish
proweb createapp app_nomi

# Migratsiyalar
proweb makemigrations
proweb migrate

# Server ishga tushirish
proweb runserver
proweb runserver --host 0.0.0.0 --port 8080

# Superuser yaratish
proweb createsuperuser

# Python shell
proweb shell

🔧 Sozlamalar

settings.py:

# Ma'lumotlar bazasi
DATABASE_URL = "sqlite://db.sqlite3"
# DATABASE_URL = "postgres://user:pass@localhost:5432/mydb"
# DATABASE_URL = "mysql://user:pass@localhost:3306/mydb"

# Debug
DEBUG = True

# Secret key
SECRET_KEY = "maxfiy-kalit"

# Ilovalar
INSTALLED_APPS = [
    "proweb.contrib.admin",
    "proweb.contrib.auth",
    "apps.blog",
    "apps.shop",
]

# ORM modellar
MODELS_MODULES = ["apps.blog.models", "apps.shop.models"]

# Templates
TEMPLATES_DIR = "templates"

# Static fayllar
STATIC_DIR = "static"
STATIC_URL = "/static/"

📖 ORM Qo'llanma

Model yaratish

from proweb import Model, fields

class Foydalanuvchi(Model):
    ism = fields.CharField(max_length=100)
    email = fields.CharField(max_length=255, unique=True)
    yosh = fields.IntField()
    faol = fields.BooleanField(default=True)
    yaratilgan = fields.DatetimeField(auto_now_add=True)
    
    class Meta:
        table = "foydalanuvchilar"

CRUD operatsiyalar

# Yaratish
user = await Foydalanuvchi.create(
    ism="Ali",
    email="ali@example.com",
    yosh=25
)

# O'qish
user = await Foydalanuvchi.get(id=1)
users = await Foydalanuvchi.all()

# Filtrlash
faol_userlar = await Foydalanuvchi.filter(faol=True)
yosh_userlar = await Foydalanuvchi.filter(yosh__gte=18)

# Yangilash
user.ism = "Vali"
await user.save()

# O'chirish
await user.delete()

Munosabatlar

class Mualif(Model):
    ism = fields.CharField(max_length=100)

class Kitob(Model):
    nomi = fields.CharField(max_length=200)
    mualif = fields.ForeignKeyField(
        "models.Mualif",
        related_name="kitoblar"
    )

# Ishlatish
mualif = await Mualif.create(ism="O'tkir Hoshimov")
kitob = await Kitob.create(
    nomi="Ikki eshik orasi",
    mualif=mualif
)

# Related objects
kitoblar = await mualif.kitoblar.all()

🎯 Best Practices

1. Asinxron funksiyalardan foydalaning

@app.get("/users")
async def get_users():
    # ✅ To'g'ri - asinxron
    users = await User.all()
    return users

# ❌ Noto'g'ri - sinxron
def get_users_sync():
    users = User.all()  # Bu ishlamaydi!
    return users

2. Try-except ishlatish

@app.get("/user/{id}")
async def get_user(id: int):
    try:
        user = await User.get(id=id)
        return user
    except DoesNotExist:
        raise HTTPException(status_code=404, detail="User topilmadi")

3. Validatsiya

from pydantic import BaseModel, EmailStr

class UserCreate(BaseModel):
    ism: str
    email: EmailStr
    yosh: int

@app.post("/users/")
async def create_user(data: UserCreate):
    user = await User.create(**data.dict())
    return user

🤝 Hissa qo'shish

Loyihaga hissa qo'shmoqchimisiz? Juda zo'r!

  1. Repository ni fork qiling
  2. Feature branch yarating (git checkout -b yangi-xususiyat)
  3. O'zgarishlaringizni commit qiling
  4. Branch'ni push qiling
  5. Pull Request oching

📝 Litsenziya

MIT License - batafsil LICENSE faylida

🌟 Muallif

ProWeb Team - O'zbekiston

📞 Aloqa


⭐ Agar loyiha yoqsa, GitHub'da yulduzcha qo'yishni unutmang!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

proweb-0.1.0.tar.gz (18.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

proweb-0.1.0-py3-none-any.whl (18.2 kB view details)

Uploaded Python 3

File details

Details for the file proweb-0.1.0.tar.gz.

File metadata

  • Download URL: proweb-0.1.0.tar.gz
  • Upload date:
  • Size: 18.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.4

File hashes

Hashes for proweb-0.1.0.tar.gz
Algorithm Hash digest
SHA256 cf5c8040fae28f7e6085a814b2a72500e25da9df73cfa135f1b1ccb9ba42fb44
MD5 87eedb3a8380094d52d094a67f3f9ec6
BLAKE2b-256 69d8df9ab73084e52f277cc78efbb0755f31bd02235b40010b2ca55cb296687f

See more details on using hashes here.

File details

Details for the file proweb-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: proweb-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 18.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.4

File hashes

Hashes for proweb-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 25f74029a62b6a88f4f5479da47d8ac051fe73c165870e648d4704dfeb86f8a7
MD5 866ff1d0075c6539b05b864a4a86c5c3
BLAKE2b-256 4bc879044b9ec01f33deee3565e7a0d300b8612712ab6acc768c3713a5c84123

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page