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:
- 🌐 Veb sayt: http://127.0.0.1:8000
- 🛠️ Admin panel: http://127.0.0.1:8000/admin
- 📚 API Docs: http://127.0.0.1:8000/docs
📚 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!
- Repository ni fork qiling
- Feature branch yarating (
git checkout -b yangi-xususiyat) - O'zgarishlaringizni commit qiling
- Branch'ni push qiling
- Pull Request oching
📝 Litsenziya
MIT License - batafsil LICENSE faylida
🌟 Muallif
ProWeb Team - O'zbekiston
📞 Aloqa
- 🌐 Website: https://proweb.uz
- 📧 Email: info@proweb.uz
- 💬 Telegram: @proweb_uz
- 🐙 GitHub: https://github.com/proweb/proweb
⭐ Agar loyiha yoqsa, GitHub'da yulduzcha qo'yishni unutmang!
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cf5c8040fae28f7e6085a814b2a72500e25da9df73cfa135f1b1ccb9ba42fb44
|
|
| MD5 |
87eedb3a8380094d52d094a67f3f9ec6
|
|
| BLAKE2b-256 |
69d8df9ab73084e52f277cc78efbb0755f31bd02235b40010b2ca55cb296687f
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
25f74029a62b6a88f4f5479da47d8ac051fe73c165870e648d4704dfeb86f8a7
|
|
| MD5 |
866ff1d0075c6539b05b864a4a86c5c3
|
|
| BLAKE2b-256 |
4bc879044b9ec01f33deee3565e7a0d300b8612712ab6acc768c3713a5c84123
|