Category: Featured

  • What is a Decorators in Python, Django and FastAPI

    🔹 Decorators in Python, Django and FastAPI in details with examples

    In Python, a decorator is a function that wraps another function or class to modify or extend its behavior without changing its code directly.

    Think of it like:

    “A decorator takes a function/class as input → adds some extra functionality → and returns a new function/class.”


    🔹 Example 1 – Simple function decorator

    def my_decorator(func):
        def wrapper():
            print("Before function runs")
            func()
            print("After function runs")
        return wrapper
    
    @my_decorator   # same as: hello = my_decorator(hello)
    def hello():
        print("Hello, World!")
    
    hello()
    

    Output:

    Before function runs
    Hello, World!
    After function runs
    

    Here:

    • @my_decorator wraps the hello() function.
    • When you call hello(), actually wrapper() runs.

    🔹 Example 2 – Decorator with arguments

    def repeat(n):
        def decorator(func):
            def wrapper(*args, **kwargs):
                for _ in range(n):
                    func(*args, **kwargs)
            return wrapper
        return decorator
    
    @repeat(3)   # repeat hello 3 times
    def hello(name):
        print(f"Hello {name}!")
    
    hello("Atif")
    

    Output:

    Hello Atif!
    Hello Atif!
    Hello Atif!
    

    🔹 Example 3 – Django decorator

    In Django, you’ve seen things like:

    from django.contrib.auth.decorators import login_required
    
    @login_required
    def my_view(request):
        ...
    

    Here @login_required ensures that only logged-in users can access that view.


    🔹 Example 4 – Class decorator (Django admin)

    In your admin file, you saw:

    @admin.register(Payment)
    class PaymentAdmin(admin.ModelAdmin):
        ...
    

    This is a class decorator. It tells Django: “Register the Payment model in the admin, using this custom admin class.”

    Equivalent without decorator:

    class PaymentAdmin(admin.ModelAdmin):
        ...
    
    admin.site.register(Payment, PaymentAdmin)
    

    🔹 Example 5 – FastAPI decorator

    In FastAPI, routes are defined with decorators:

    from fastapi import FastAPI
    
    app = FastAPI()
    
    @app.get("/hello")
    def say_hello():
        return {"msg": "Hello World"}
    

    Here @app.get("/hello") is a decorator that says: “When someone sends a GET request to /hello, call this function.”


    ###✅ Summary for decorators:

    • Decorators = wrappers that extend/modify behavior of functions/classes.
    • They’re widely used in Django (admin, views, permissions) and FastAPI (routes, middlewares).

    ##how to write your own decorator step by step

    Let’s build your own decorators step by step. We’ll start from very basic → then add arguments → then apply in Django-like use cases.


    🛠 Step 1: Basic decorator

    def simple_decorator(func):
        def wrapper():
            print("👉 Before the function")
            func()
            print("👉 After the function")
        return wrapper
    
    @simple_decorator
    def say_hello():
        print("Hello Atif!")
    
    say_hello()
    

    Output:

    👉 Before the function
    Hello Atif!
    👉 After the function
    

    📌 Here:

    • @simple_decorator is applied to say_hello.
    • When you call say_hello(), Python actually runs wrapper().

    🛠 Step 2: Decorator for any function with arguments

    def log_args(func):
        def wrapper(*args, **kwargs):
            print(f"Function {func.__name__} called with args={args}, kwargs={kwargs}")
            return func(*args, **kwargs)   # run the real function
        return wrapper
    
    @log_args
    def add(a, b):
        return a + b
    
    print(add(3, 5))
    

    Output:

    Function add called with args=(3, 5), kwargs={}
    8
    

    🛠 Step 3: Decorator with arguments

    Sometimes you want to pass options to your decorator itself.

    def repeat(n):
        def decorator(func):
            def wrapper(*args, **kwargs):
                for i in range(n):
                    print(f"Run {i+1} of {n}")
                    func(*args, **kwargs)
            return wrapper
        return decorator
    
    @repeat(3)   # repeat the function 3 times
    def greet(name):
        print(f"Hello {name}")
    
    greet("Atif")
    

    Output:

    Run 1 of 3
    Hello Atif
    Run 2 of 3
    Hello Atif
    Run 3 of 3
    Hello Atif
    

    Decorator in Django

    🛠 A Django-like decorator

    Let’s make our own login_required style decorator:

    def my_login_required(func):
        def wrapper(request, *args, **kwargs):
            if not getattr(request, "user", None):   # check if request has a user
                return "❌ User not logged in!"
            return func(request, *args, **kwargs)
        return wrapper
    
    # fake request objects
    class Request:
        def __init__(self, user=None):
            self.user = user
    
    @my_login_required
    def dashboard(request):
        return f"Welcome {request.user}!"
    
    print(dashboard(Request()))        # no user
    print(dashboard(Request("Atif")))  # with user
    

    Output:

    ❌ User not logged in!
    Welcome Atif!
    

    🛠 Using class decorator (like Django Admin)

    def register_model(model_name):
        def decorator(admin_class):
            print(f"✅ Registered {model_name} with admin class {admin_class.__name__}")
            return admin_class
        return decorator
    
    @register_model("Payment")
    class PaymentAdmin:
        pass
    

    Output:

    ✅ Registered Payment with admin class PaymentAdmin
    

    📌 This is exactly how @admin.register(Model) works internally.


    ###✅ Summary for Django Decorators:

    • A decorator is a function that wraps another function/class.
    • @decorator_name is just shorthand for function = decorator_name(function).
    • They’re useful for authentication checks, logging, caching, registering routes/admins, etc.

    ##decorators in FastAPI. They work the same as Python decorators, but in FastAPI they’re often used for middleware-like behavior (before/after running your endpoint).


    🛠 Example 1: Simple logging decorator

    from fastapi import FastAPI
    
    app = FastAPI()
    
    # Custom decorator
    def log_request(func):
        async def wrapper(*args, **kwargs):
            print(f"👉 Calling endpoint: {func.__name__}")
            result = await func(*args, **kwargs)
            print(f"✅ Finished endpoint: {func.__name__}")
            return result
        return wrapper
    
    @app.get("/hello")
    @log_request
    async def say_hello():
        return {"message": "Hello Atif!"}
    

    When you visit /hello:

    👉 Calling endpoint: say_hello
    ✅ Finished endpoint: say_hello
    

    🛠 Example 2: Decorator to check API Key

    from fastapi import FastAPI, Request, HTTPException
    
    app = FastAPI()
    
    def require_api_key(func):
        async def wrapper(request: Request, *args, **kwargs):
            api_key = request.headers.get("X-API-Key")
            if api_key != "secret123":
                raise HTTPException(status_code=403, detail="Invalid API Key")
            return await func(request, *args, **kwargs)
        return wrapper
    
    @app.get("/secure")
    @require_api_key
    async def secure_endpoint(request: Request):
        return {"message": "You are authorized!"}
    

    🔑 If you call /secure without X-API-Key: secret123, you’ll get:

    {"detail": "Invalid API Key"}
    

    🛠 Example 3: Decorator with arguments (rate limiter style)

    import time
    from fastapi import FastAPI, HTTPException
    
    app = FastAPI()
    
    def rate_limit(seconds: int):
        last_called = {}
    
        def decorator(func):
            async def wrapper(*args, **kwargs):
                now = time.time()
                if func.__name__ in last_called and now - last_called[func.__name__] < seconds:
                    raise HTTPException(status_code=429, detail="Too many requests")
                last_called[func.__name__] = now
                return await func(*args, **kwargs)
            return wrapper
        return decorator
    
    @app.get("/ping")
    @rate_limit(5)   # limit calls to every 5 seconds
    async def ping():
        return {"message": "pong!"}
    
    • First request works ✅
    • Second request within 5s → 429 Too Many Requests

    🛠 Example 4: Class decorator for routes (like Django’s @admin.register)

    def tag_routes(tag: str):
        def decorator(func):
            func._tag = tag  # attach metadata
            return func
        return decorator
    
    app = FastAPI()
    
    @app.get("/items")
    @tag_routes("inventory")
    async def get_items():
        return {"items": ["apple", "banana"]}
    
    # Later you could inspect `get_items._tag` == "inventory"
    

    ##✅ Summary for FastAPI decorators

    • Work same as Python decorators

    • Useful for:

      • Logging
      • Auth / API keys
      • Rate limiting
      • Attaching metadata
    • You can mix them with FastAPI’s built-in dependencies, but decorators give more fine-grained control.

  • Apple: iPhone China sales slide as Huawei soars, report says

    Apple Faces 24% Decline in iPhone Sales in China as Huawei Surges: Report

    Sales of Apple’s iPhone in China dropped by 24% in the first six weeks of 2024 compared to the previous year, as reported by research firm Counterpoint. This decline is attributed to fierce competition from local rivals, with China’s Huawei experiencing a remarkable 64% increase in sales during the same period. Apple and Huawei have not provided immediate responses to the BBC’s requests for comments.

    Counterpoint Research’s Mengmeng Zhang highlighted that, besides Huawei’s resurgence in the higher-priced segment of the Chinese phone market, Apple faced challenges in the mid-range due to aggressive pricing from competitors like Oppo, Vivo, and Xiaomi. China, being one of Apple’s significant markets, witnessed an overall 7% shrinkage in smartphone sales in the same period.

    Huawei, which struggled for years due to US sanctions, saw a sales surge following the release of its Mate 60 series of 5G smartphones in August. This success was unexpected, considering the challenges Huawei faced in accessing crucial chips and technology for 5G mobile internet.

    The report revealed that Honor, the smartphone brand spun off from Huawei in 2020, was the only other top-five brand to experience sales growth in China during this period. Sales of Vivo, Xiaomi, and Oppo, on the other hand, declined in the first six weeks of the year.

    In terms of market share, Apple’s portion of the Chinese smartphone market dropped from 19% to 15.7% compared to the previous year, causing it to fall from the second to the fourth position. In contrast, Huawei rose to the second position, with its market share growing from 9.4% to 16.5%.

    iPhone 15 [GETTY IMAGES]
    iPhone 15 [GETTY IMAGES]

    Despite a 15% decline in sales over the last year, Vivo remained China’s top-selling smartphone maker, according to Counterpoint. To counter the decline in demand, Apple initiated discounts on its official sites in China and subsidized certain iPhone models through its flagship stores on Alibaba’s marketplace platform Tmall.

    A slowdown in demand in China poses a potential threat to Apple’s revenue, which already disappointed investors when the company released its earnings last month. In the last three months of 2023, Apple’s sales in China were $20.82 billion (£16.4 billion), down from $23.9 billion in the previous year, leading to a 2.8% decline in Apple shares in New York trade on Tuesday.

  • TikTok sparks user revolt in US over sale plan

    American politicians are receiving many calls from TikTok users who aren’t happy about plans to make its parent company sell the social media app. A bill was passed by a US congressional panel, saying TikTok must be sold within six months or it could be banned.

    TikTok sent a notification asking users to call their representative to vote against the bill. The bill will be voted on by the full House next week. It’s supported by a group of 20 lawmakers who are concerned about TikTok’s ties to the Chinese Communist Party.

    The bill aims to protect the US from threats by foreign-controlled apps. Lawmakers believe TikTok’s owner, ByteDance, has links to the Chinese Communist Party, which ByteDance denies.

    Users of the app got a message telling them to stop a TikTok shutdown. Many people have called their representatives about this, including children.

    Tiktok [GETTY IMAGES]
    Tiktok [GETTY IMAGES]

    Under the bill, ByteDance would have to sell TikTok or it could be removed from US app stores. The bill doesn’t target individual users of the app.

    Some lawmakers think TikTok is a threat to national security because its parent company collaborates with China’s government.

    TikTok says the bill would ban the app and violate Americans’ rights. The ACLU also opposes the bill, saying it’s a political move and many people rely on TikTok.

    American lawmakers have tried to control TikTok before. The app is banned on US government devices, but President Biden’s re-election campaign has an account.

    Former President Trump tried to ban TikTok and WeChat, but it didn’t happen because of legal issues.