Posts for: #Python

Cheatsheet Python untuk Developer Modern

Kuasai Python dengan Cepat: Cheatsheet Praktis

Cheatsheet ini memberikan ringkasan sintaks dan konsep penting dalam Python, cocok untuk pemula maupun yang ingin menyegarkan ingatan. Kita akan membahas tipe data, struktur kontrol, fungsi, dan sedikit tips praktis.

Mengenal Python: Bahasa Serbaguna

Python merupakan bahasa pemrograman tingkat tinggi yang populer karena sintaksnya yang mudah dibaca dan fleksibilitasnya. Python digunakan luas dalam berbagai bidang, mulai dari pengembangan web, data science, machine learning, hingga scripting.

Read more

Best practice menggunakan bahasa Python

Best practice dalam Python tergantung pada konteks penggunaannya, misalnya untuk web development, data science, atau automation. Tapi secara umum, berikut adalah beberapa best practice yang berlaku secara luas:


1. Gunakan Versi Python yang Terbaru (Stable)

Pastikan selalu menggunakan versi Python terbaru yang masih mendapatkan update keamanan dan fitur baru.

Cek versi Python yang sedang digunakan:

python --version

📜 2. Gunakan Penulisan Kode Sesuai PEP 8

PEP 8 adalah standar gaya penulisan kode Python yang membuat kode lebih mudah dibaca. Gunakan black atau flake8 untuk memeriksa dan memformat kode secara otomatis.

Read more

Contoh File Dari Rekomendasi Folder Python FastAPI Project

Tentu! Berikut adalah contoh lengkap untuk setiap file dan folder dalam struktur folder FastAPI yang telah saya jelaskan sebelumnya. Saya akan memberikan contoh kode untuk setiap file utama, termasuk contoh main.py, API endpoints, model, schema, dan sebagainya. Ini akan memberikan gambaran lebih jelas tentang bagaimana mengorganisasi aplikasi FastAPI yang skalabel.

1. my_fastapi_project/app/main.py

from fastapi import FastAPI
from app.api.v1 import endpoints

app = FastAPI()

# Include the routes from the API version 1
app.include_router(endpoints.router, prefix="/v1", tags=["v1"])

2. my_fastapi_project/app/api/v1/endpoints/user.py

from fastapi import APIRouter, Depends
from app.schemas.user import User, UserCreate
from app.services.user_service import create_user, get_user

router = APIRouter()

@router.post("/users/", response_model=User)
def create_user_endpoint(user: UserCreate):
    return create_user(user)

@router.get("/users/{user_id}", response_model=User)
def get_user_endpoint(user_id: int):
    return get_user(user_id)

3. my_fastapi_project/app/api/v1/endpoints/item.py

from fastapi import APIRouter, Depends
from app.schemas.item import Item, ItemCreate
from app.services.item_service import create_item, get_item

router = APIRouter()

@router.post("/items/", response_model=Item)
def create_item_endpoint(item: ItemCreate):
    return create_item(item)

@router.get("/items/{item_id}", response_model=Item)
def get_item_endpoint(item_id: int):
    return get_item(item_id)

4. my_fastapi_project/app/core/config.py

import os
from dotenv import load_dotenv

load_dotenv()  # Load environment variables from .env

class Config:
    API_KEY = os.getenv("API_KEY")
    DB_URL = os.getenv("DATABASE_URL")
    SECRET_KEY = os.getenv("SECRET_KEY")

config = Config()

5. my_fastapi_project/app/core/security.py

from passlib.context import CryptContext

# Password hashing
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

def hash_password(password: str) -> str:
    return pwd_context.hash(password)

def verify_password(plain_password: str, hashed_password: str) -> bool:
    return pwd_context.verify(plain_password, hashed_password)

6. my_fastapi_project/app/models/user.py

from sqlalchemy import Column, Integer, String
from app.db.session import Base

class User(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True, index=True)
    username = Column(String, unique=True, index=True)
    hashed_password = Column(String)

7. my_fastapi_project/app/models/item.py

from sqlalchemy import Column, Integer, String
from app.db.session import Base

class Item(Base):
    __tablename__ = "items"

    id = Column(Integer, primary_key=True, index=True)
    name = Column(String, index=True)
    description = Column(String)

8. my_fastapi_project/app/schemas/user.py

from pydantic import BaseModel

class User(BaseModel):
    id: int
    username: str

    class Config:
        orm_mode = True

class UserCreate(BaseModel):
    username: str
    password: str

9. my_fastapi_project/app/schemas/item.py

from pydantic import BaseModel

class Item(BaseModel):
    id: int
    name: str
    description: str

    class Config:
        orm_mode = True

class ItemCreate(BaseModel):
    name: str
    description: str

10. my_fastapi_project/app/services/user_service.py

from app.models.user import User
from app.schemas.user import UserCreate
from app.db.session import SessionLocal
from app.core.security import hash_password

def create_user(user_create: UserCreate):
    db = SessionLocal()
    hashed_password = hash_password(user_create.password)
    db_user = User(username=user_create.username, hashed_password=hashed_password)
    db.add(db_user)
    db.commit()
    db.refresh(db_user)
    db.close()
    return db_user

def get_user(user_id: int):
    db = SessionLocal()
    db_user = db.query(User).filter(User.id == user_id).first()
    db.close()
    return db_user

11. my_fastapi_project/app/services/item_service.py

from app.models.item import Item
from app.schemas.item import ItemCreate
from app.db.session import SessionLocal

def create_item(item_create: ItemCreate):
    db = SessionLocal()
    db_item = Item(name=item_create.name, description=item_create.description)
    db.add(db_item)
    db.commit()
    db.refresh(db_item)
    db.close()
    return db_item

def get_item(item_id: int):
    db = SessionLocal()
    db_item = db.query(Item).filter(Item.id == item_id).first()
    db.close()
    return db_item

12. my_fastapi_project/app/db/session.py

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db"  # Replace with your actual database URL

engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False})
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

Base = declarative_base()

# To initialize the database (create tables)
def init_db():
    Base.metadata.create_all(bind=engine)

13. my_fastapi_project/app/tests/test_user.py

from fastapi.testclient import TestClient
from app.main import app

client = TestClient(app)

def test_create_user():
    response = client.post("/v1/users/", json={"username": "testuser", "password": "password123"})
    assert response.status_code == 200
    assert response.json()["username"] == "testuser"

def test_get_user():
    response = client.post("/v1/users/", json={"username": "testuser", "password": "password123"})
    user_id = response.json()["id"]
    
    response = client.get(f"/v1/users/{user_id}")
    assert response.status_code == 200
    assert response.json()["id"] == user_id

14. my_fastapi_project/app/utils/date_utils.py

from datetime import datetime

def current_time():
    return datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")

15. my_fastapi_project/.env

API_KEY=your_api_key_here
DATABASE_URL=sqlite:///./test.db  # Replace with your actual database URL
SECRET_KEY=your_secret_key_here

16. my_fastapi_project/requirements.txt

fastapi
uvicorn
sqlalchemy
pydantic
passlib
python-dotenv

17. my_fastapi_project/Dockerfile (optional)

# Use official Python image
FROM python:3.10-slim

# Set working directory
WORKDIR /app

# Copy requirements and install
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy the rest of the application
COPY . .

# Expose port 8000 for FastAPI
EXPOSE 8000

# Run the application with Uvicorn
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

18. my_fastapi_project/docker-compose.yml (optional)

version: "3.8"
services:
  app:
    build: .
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=sqlite:///./test.db
    volumes:
      - .:/app
    command: uvicorn app.main:app --host 0.0.0.0 --port 8000

Conclusion

Dengan struktur ini, Anda memiliki aplikasi FastAPI yang terorganisir dengan baik, memisahkan setiap bagian dari aplikasi (API, model, schema, logika bisnis, dll). Ini memudahkan pengembangan dan pemeliharaan proyek, serta mendukung pengembangan lebih lanjut saat aplikasi Anda tumbuh.

Read more

Jika Kamu Bingung Kok Ada File init.py tapi gak ada dicontoh, ini solusinya

Berikut adalah contoh isi dari file __init__.py yang perlu dimasukkan dalam setiap folder untuk memastikan folder tersebut diperlakukan sebagai paket Python (module), dan memungkinkan Anda untuk mengimpor modul-modul dalam folder tersebut.

1. my_fastapi_project/app/__init__.py

File ini akan menginisialisasi folder app sebagai paket. Biasanya file ini kosong, tetapi kadang bisa berisi pengaturan atau import global.

# app/__init__.py

# Tidak ada yang perlu dimasukkan di sini jika tidak ada pengaturan tambahan
# Tetapi Anda bisa menambah kode global yang ingin diekspor jika diperlukan

2. my_fastapi_project/app/api/__init__.py

Folder ini berisi modul API. Anda bisa menambah pengaturan impor umum di sini, terutama jika Anda ingin mengelompokkan versi API.

Read more

Recommendation Structure Folder For a Python FastAPI Projects

When structuring a folder for a Python FastAPI project, it’s essential to maintain modularity and scalability, especially as your project grows. A good folder structure helps to separate concerns, making it easier to manage and maintain the codebase.

Here’s a recommended folder structure for a typical FastAPI project:

my_fastapi_project/
│
├── app/                        # Main application code
│   ├── __init__.py
│   ├── main.py                 # Entry point for the FastAPI application
│   ├── api/                    # API routes and business logic
│   │   ├── __init__.py
│   │   ├── v1/                 # Versioned API (optional, but good for future scalability)
│   │   │   ├── __init__.py
│   │   │   ├── endpoints/      # Routes for version 1 API
│   │   │   │   ├── __init__.py
│   │   │   │   ├── user.py     # Example: user-related routes
│   │   │   │   ├── item.py     # Example: item-related routes
│   │   ├── v2/                 # (Optional) Future version of the API
│   │   ├── dependencies.py     # Shared dependencies (e.g., DB session)
│   ├── core/                   # Core components like settings, config, security
│   │   ├── __init__.py
│   │   ├── config.py           # Configuration settings (e.g., environment variables)
│   │   ├── security.py         # Security-related utilities (e.g., JWT)
│   │   ├── settings.py         # Settings management (e.g., loading env variables)
│   ├── models/                 # ORM models or Pydantic schemas
│   │   ├── __init__.py
│   │   ├── user.py             # Example: user model
│   │   ├── item.py             # Example: item model
│   ├── schemas/                # Pydantic schemas for validation
│   │   ├── __init__.py
│   │   ├── user.py             # Example: user schema
│   │   ├── item.py             # Example: item schema
│   ├── services/               # Business logic and service layer
│   │   ├── __init__.py
│   │   ├── user_service.py     # Example: user service
│   │   ├── item_service.py     # Example: item service
│   ├── db/                     # Database-related code (e.g., SQLAlchemy models, migrations)
│   │   ├── __init__.py
│   │   ├── session.py          # Database session management
│   │   ├── init_db.py          # Database initialization code (e.g., creating tables)
│   ├── tests/                  # Unit and integration tests
│   │   ├── __init__.py
│   │   ├── test_user.py        # Example test file for user-related functionality
│   │   ├── test_item.py        # Example test file for item-related functionality
│   ├── utils/                  # Utility functions that are used across the app
│   │   ├── __init__.py
│   │   ├── date_utils.py       # Example utility: date-related functions
│
├── .env                         # Environment variables for sensitive data (e.g., DB URI, API keys)
├── .gitignore                   # Git ignore file to exclude unnecessary files
├── requirements.txt             # Project dependencies (including FastAPI and Uvicorn)
├── alembic.ini                  # Alembic configuration file (if using migrations with SQLAlchemy)
├── Dockerfile                   # Dockerfile for containerizing the app (optional)
├── docker-compose.yml           # Docker Compose file for multi-container setup (optional)
└── README.md                    # Project documentation

Explanation of the Structure:

  1. app/: This is where the majority of your code resides. It contains all your app-specific logic and modules.

Read more