Home Blog Page 25

Jinja2 Templating in Flask: A Comprehensive Guide

0
python course
python course

Table of Contents

  • Introduction to Jinja2
  • What is Templating in Flask?
  • Why Use Jinja2 in Flask?
  • Setting Up Jinja2 with Flask
  • Basic Syntax of Jinja2
  • Using Variables in Templates
  • Control Structures in Jinja2 (Loops, Conditionals)
  • Template Inheritance in Jinja2
  • Passing Data from Flask to Templates
  • Including Other Templates
  • Working with Static Files (CSS, JS, Images)
  • Best Practices for Templating in Flask
  • Conclusion

Introduction to Jinja2

Flask uses Jinja2, a powerful templating engine for Python, to help you create dynamic web pages with ease. Jinja2 is widely known for its simplicity and flexibility, making it the perfect choice for Flask applications.

Templating engines allow you to separate the business logic from the presentation layer, ensuring that your web application’s HTML is clean, reusable, and maintainable. With Jinja2, you can embed Python-like expressions directly in HTML, making it a core component in Flask for building interactive and dynamic web applications.


What is Templating in Flask?

Templating in Flask refers to the process of generating dynamic HTML content by rendering templates. Rather than writing raw HTML code in your Python scripts, you can create HTML templates that define the structure of your webpage, and then populate them with dynamic data using Jinja2.

Templates are separate from the application logic, making it easier to manage your application’s structure and improving code readability. Flask’s built-in support for Jinja2 helps bridge the gap between your application’s logic and the presentation layer.


Why Use Jinja2 in Flask?

Flask uses Jinja2 for several important reasons:

  1. Separation of Concerns: Templating allows you to separate the logic (Python code) from the presentation (HTML) to improve maintainability.
  2. Reusability: With Jinja2, you can create reusable templates that save development time.
  3. Flexibility: Jinja2 provides a rich set of features, including loops, conditionals, template inheritance, and more.
  4. Ease of Use: The syntax is simple and intuitive, making it easy to use for both beginners and experienced developers.
  5. Security: Jinja2 automatically escapes HTML, preventing potential cross-site scripting (XSS) vulnerabilities.

Setting Up Jinja2 with Flask

Flask comes with Jinja2 pre-installed, so you don’t need to install it separately. To get started, simply create a new Flask project and make sure to place your HTML templates in a folder named templates.

Here’s how you can set up a simple Flask application with Jinja2 templating:

1. Create a Project Directory

mkdir flask_jinja_project
cd flask_jinja_project

2. Create a Virtual Environment

python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate

3. Install Flask

pip install Flask

4. Create a Basic Flask Application

In your project folder, create a new file app.py:

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def home():
return render_template('index.html')

if __name__ == "__main__":
app.run(debug=True)

5. Create the Templates Folder and HTML File

In the same project folder, create a folder named templates and then add an HTML file, index.html:

flask_jinja_project/
├── app.py
└── templates/
└── index.html

In index.html, you can use basic Jinja2 syntax to render dynamic content later.


Basic Syntax of Jinja2

Jinja2 syntax is very similar to Python but embedded within HTML. Below are some of the core components of Jinja2.

1. Variables

To display a variable’s value in a template, use the following syntax:

<h1>{{ title }}</h1>

In this case, title is a variable passed from the Flask view function to the template.

2. Expressions and Filters

You can apply filters to modify variables. Filters are applied with a pipe (|):

<p>{{ name|capitalize }}</p>

This example capitalizes the value of the name variable.


Using Variables in Templates

To pass variables from your Flask app to the template, you use the render_template() function. This function takes the name of the template and a series of keyword arguments representing the variables.

For example:

@app.route('/')
def home():
return render_template('index.html', title="Welcome to Flask")

In index.html, you can then use the title variable:

<h1>{{ title }}</h1>

This will output:
Welcome to Flask


Control Structures in Jinja2 (Loops, Conditionals)

Jinja2 allows you to include logic inside templates, such as loops and conditionals.

1. Loops

To loop through a list and display its items, use the {% for %} loop:

<ul>
{% for item in items %}
<li>{{ item }}</li>
{% endfor %}
</ul>

2. Conditionals

You can also use {% if %} for conditionals:

{% if user %}
<h1>Welcome, {{ user }}!</h1>
{% else %}
<h1>Welcome, Guest!</h1>
{% endif %}

Template Inheritance in Jinja2

Jinja2 supports template inheritance, allowing you to create a base template and extend it in other templates. This helps maintain a consistent layout across your website.

1. Base Template (base.html)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}My Website{% endblock %}</title>
</head>
<body>
<header>
<h1>My Website</h1>
</header>
<div id="content">
{% block content %}{% endblock %}
</div>
<footer>
<p>Footer content here</p>
</footer>
</body>
</html>

2. Child Template (index.html)

{% extends 'base.html' %}

{% block title %}Home{% endblock %}

{% block content %}
<h2>Welcome to the homepage!</h2>
{% endblock %}

In this example, index.html extends base.html and overrides the title and content blocks.


Passing Data from Flask to Templates

You can pass multiple variables from Flask to the template using render_template():

@app.route('/greet/<name>')
def greet(name):
return render_template('greet.html', name=name)

In greet.html, you can access name:

<h1>Hello, {{ name }}!</h1>

Including Other Templates

You can also include one template inside another using the {% include %} tag. This is useful for reusing common parts of your pages (like headers, footers, or navigation).

{% include 'header.html' %}
<p>Welcome to the website!</p>
{% include 'footer.html' %}

Working with Static Files (CSS, JS, Images)

Flask also supports serving static files like CSS, JavaScript, and images. These files should be placed in the static/ folder in your project.

flask_jinja_project/
├── app.py
├── templates/
│ └── index.html
└── static/
├── style.css
└── image.png

In your HTML templates, link to static files like so:

<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
<img src="{{ url_for('static', filename='image.png') }}" alt="Image">

Best Practices for Templating in Flask

  1. Organize your templates: Use a clear folder structure with templates organized into subdirectories if needed.
  2. Use template inheritance: To avoid code duplication, use a base template for common elements like headers and footers.
  3. Avoid complex logic in templates: Keep the logic in the Python views, not in the templates. Templates should focus on presentation, not computation.
  4. Security: Always escape user input using Jinja2’s automatic escaping to prevent cross-site scripting (XSS).

Conclusion

Jinja2 templating in Flask provides an effective and powerful way to separate the HTML structure from the Python code, making web applications clean, maintainable, and scalable. By using variables, control structures, and template inheritance, you can create dynamic web pages that meet your project’s needs.

Introduction to Flask and Building Your First Web Application

0
python course
python course

Table of Contents

  • Introduction
  • What is Flask?
  • Why Choose Flask?
  • Setting Up the Environment
  • Installing Flask
  • Your First Flask Web Application
  • Understanding the Code
  • Running and Testing Your Flask App
  • Common Errors and Debugging
  • Best Practices for Beginners
  • Conclusion

Introduction

In today’s world, developing web applications has become an essential skill for every programmer.
Among the many web frameworks available for Python, Flask stands out for its simplicity and flexibility.

In this article, we will explore what Flask is, why it is widely used, how to set it up, and how to build your very first web application from scratch.


What is Flask?

Flask is a lightweight, micro web framework for Python, developed by Armin Ronacher.
It is designed to be simple yet extensible, allowing developers to create both simple and highly complex web applications.

Flask provides the necessary components to build a web server:

  • URL routing
  • Request and response handling
  • Templating system (using Jinja2)
  • Sessions and cookies
  • And much more, via extensions

Flask follows the WSGI (Web Server Gateway Interface) standard and is based on the Werkzeug toolkit and Jinja2 templating engine.


Why Choose Flask?

Some major reasons why developers prefer Flask include:

  • Minimalist Core: You are free to add only what you need.
  • Flexibility: No constraints on project structure or components.
  • Large Ecosystem: Tons of extensions are available (e.g., Flask-SQLAlchemy, Flask-Login).
  • Easy Learning Curve: Perfect for beginners and fast prototyping.
  • Scalability: Start small and scale your application as it grows.

Flask is widely used in both startups and large-scale enterprise applications because of its adaptability.


Setting Up the Environment

Before starting, it is highly recommended to set up a virtual environment to manage dependencies cleanly.

Create a virtual environment:

python -m venv venv

Activate it:

  • On Windows:
venv\Scripts\activate
  • On macOS/Linux:
source venv/bin/activate

Once activated, your terminal prompt should change, indicating the environment is active.


Installing Flask

Now, install Flask using pip:

pip install Flask

You can verify the installation by checking the version:

python -m flask --version

This should display the Flask version installed along with Werkzeug’s version.


Your First Flask Web Application

Create a new Python file named app.py.

Add the following basic Flask application code:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def home():
return "Hello, World! Welcome to your first Flask web application."

if __name__ == "__main__":
app.run(debug=True)

Let’s break this down:

  • We import Flask and create an instance of it.
  • We define a route (/) and a function that returns a simple text message.
  • We run the app if the script is executed directly.

Understanding the Code

  • Flask(__name__):
    Creates an instance of the Flask application. __name__ is a special Python variable that represents the name of the module.
  • @app.route('/'):
    A decorator that maps the URL / to the home() function.
  • app.run(debug=True):
    Starts the server. The debug=True mode restarts the server automatically upon code changes and provides an interactive debugger in the browser for errors.

Running and Testing Your Flask App

Run the application:

python app.py

You should see output similar to:

 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Open a web browser and navigate to http://127.0.0.1:5000/.
You will see the message:
“Hello, World! Welcome to your first Flask web application.”

Congratulations! You have successfully created and run your first Flask web app.


Common Errors and Debugging

  • Port Already in Use:
    If you see an error like “Address already in use,” either stop the other application using the port or change the port using:
app.run(port=5001)
  • ModuleNotFoundError:
    Ensure Flask is installed inside your virtual environment.
  • IndentationError or SyntaxError:
    Python is indentation-sensitive. Make sure you do not mix spaces and tabs.
  • Debug Mode Warning:
    Never run your app in debug mode (debug=True) in a production environment for security reasons.

Best Practices for Beginners

  • Always use virtual environments to manage dependencies cleanly.
  • Structure your project properly even for small projects (you will thank yourself later).
  • Use templates and static folders:
    Flask looks for templates/ for HTML files and static/ for CSS, JS, images by default.
  • Understand how HTTP Methods (GET, POST) work.
  • Explore Flask Extensions like Flask-WTF for forms, Flask-SQLAlchemy for ORM, Flask-Login for authentication.

Conclusion

Flask provides a perfect entry point into the world of web development with Python.
It is easy to learn, yet powerful enough to build professional-grade web applications.
In this article, you created your first Flask web app and understood the basic concepts behind it.

Data Integrity, Transactions, and Connection Pooling in Python

0
python course
python course

Table of Contents

  • Introduction
  • What is Data Integrity?
  • Ensuring Data Integrity in Python Applications
  • What are Database Transactions?
    • ACID Properties
    • Using Transactions in Python (SQLite, PostgreSQL)
  • Connection Pooling
    • Why is Connection Pooling Important?
    • Implementing Connection Pooling in Python
  • Best Practices
  • Conclusion

Introduction

When building database-driven applications, maintaining data integrity, handling transactions, and managing connections efficiently are crucial for stability and performance.
Ignoring these aspects often leads to issues like data corruption, race conditions, performance bottlenecks, and even application crashes.

In this module, we will dive deep into how to ensure data integrity, properly use transactions, and efficiently manage connections through pooling — all from a Python developer’s perspective.


What is Data Integrity?

Data Integrity refers to the accuracy, consistency, and reliability of data over its lifecycle.
It ensures that data remains correct and unaltered during operations like creation, storage, retrieval, update, and deletion.

Types of Data Integrity:

  • Entity Integrity: Ensuring unique and non-null primary keys.
  • Referential Integrity: Maintaining correct foreign key relationships.
  • Domain Integrity: Validating that data entered falls within a predefined domain (like date ranges, enum types).
  • User-Defined Integrity: Enforcing business rules, like “an order cannot exist without a customer.”

Ensuring Data Integrity in Python Applications

  1. Proper Database Schema Design:
    Define proper constraints like PRIMARY KEY, FOREIGN KEY, UNIQUE, NOT NULL, CHECK in your tables.
  2. Input Validation:
    Validate user inputs at both the client and server side.
  3. Use ORM Tools:
    Tools like SQLAlchemy automatically enforce many integrity rules through models.
  4. Error Handling:
    Gracefully handle errors like IntegrityError, ValidationError, etc.

Example with SQLAlchemy:

from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import declarative_base

Base = declarative_base()

class User(Base):
__tablename__ = 'users'

id = Column(Integer, primary_key=True)
email = Column(String, unique=True, nullable=False)

This schema ensures that:

  • Each user has a unique email.
  • Email cannot be NULL.

What are Database Transactions?

A transaction is a sequence of database operations executed as a single logical unit of work.
Transactions ensure that either all operations succeed, or none do, maintaining the database’s consistent state.

ACID Properties

  • Atomicity: All operations succeed or none.
  • Consistency: Transitions from one valid state to another.
  • Isolation: Simultaneous transactions do not interfere.
  • Durability: Once committed, changes are permanent.

Using Transactions in Python

Most database libraries (like psycopg2, SQLAlchemy) manage transactions automatically, but manual control is often needed.

SQLite Example (manual transaction):

import sqlite3

conn = sqlite3.connect('example.db')
try:
cursor = conn.cursor()
cursor.execute("INSERT INTO users (name) VALUES (?)", ('Alice',))
cursor.execute("INSERT INTO users (name) VALUES (?)", ('Bob',))
conn.commit()
except Exception as e:
conn.rollback()
print(f"Transaction failed: {e}")
finally:
conn.close()

PostgreSQL Example with psycopg2:

import psycopg2

conn = psycopg2.connect(database="testdb", user="user", password="password", host="localhost")
try:
cursor = conn.cursor()
cursor.execute("INSERT INTO employees (name) VALUES (%s)", ("John",))
conn.commit()
except Exception as e:
conn.rollback()
print(f"Error: {e}")
finally:
conn.close()

Connection Pooling

Why is Connection Pooling Important?

  • Database Connections are Expensive:
    Opening and closing connections frequently is costly in terms of time and resources.
  • Connection Limits:
    Databases often have maximum connection limits. Exhausting them can crash the system.
  • Performance Boost:
    Reusing existing connections saves latency and improves scalability.

In short, connection pooling maintains a cache of database connections that your application can reuse.


Implementing Connection Pooling in Python

Using SQLAlchemy Connection Pool:

SQLAlchemy uses connection pools by default, but you can configure it manually:

from sqlalchemy import create_engine

engine = create_engine(
'postgresql+psycopg2://user:password@localhost/mydb',
pool_size=5, # Maximum number of connections
max_overflow=10, # Additional connections beyond pool_size
pool_timeout=30, # Wait time before throwing an error
pool_recycle=1800 # Recycle connections after 30 minutes
)

connection = engine.connect()
# Use the connection
connection.close()

Using psycopg2 with a Pooling Library:

from psycopg2 import pool

db_pool = pool.SimpleConnectionPool(1, 10,
user="user",
password="password",
host="localhost",
database="testdb"
)

conn = db_pool.getconn()

try:
cursor = conn.cursor()
cursor.execute("SELECT * FROM employees")
finally:
db_pool.putconn(conn)

Popular Pooling Libraries:

  • SQLAlchemy’s built-in pools
  • psycopg2.pool
  • pgbouncer (external tool for PostgreSQL)

Best Practices

  • Always Use Transactions: Especially when modifying data.
  • Catch Exceptions and Rollback: Prevent partial writes.
  • Use Connection Pooling in Production: Especially in high-traffic applications.
  • Validate at Multiple Layers: Both at application and database level.
  • Monitor Connection Usage: Use monitoring tools to observe connection pool health.

Conclusion

Mastering data integrity, transactions, and connection pooling is essential for building production-grade, database-driven Python applications.
These concepts not only prevent catastrophic data loss and corruption but also significantly boost your application’s performance and scalability.

Building Mini-Applications Using Databases: A Complete Guide for Python Developers

0
python course
python course

Table of Contents

  • Introduction
  • Why Build Mini-Applications?
  • Setting Up the Environment
  • Project 1: Simple To-Do List App (SQLite)
    • Project Structure
    • Database Schema
    • CRUD Operations
    • Sample Code
  • Project 2: Contact Manager App (PostgreSQL)
    • Project Structure
    • Database Schema
    • Key Functionalities
    • Sample Code
  • Project 3: Notes API (Flask + MongoDB)
    • Project Structure
    • API Endpoints
    • MongoDB Collections
    • Sample Code
  • Best Practices for Database-Driven Applications
  • Conclusion

Introduction

Building mini-applications using databases is an excellent way to reinforce your knowledge of Python, SQL, and database management systems.
These projects simulate real-world application development, giving you practical experience with designing schemas, handling connections, performing CRUD operations, and structuring maintainable codebases.

In this module, you will learn how to build database-driven mini-projects step-by-step, covering everything from schema design to application logic implementation.


Why Build Mini-Applications?

Here are several reasons why working on mini-projects is crucial:

  • Solidifies Core Concepts: Reinforces learning through application.
  • Portfolio Building: Mini-projects make excellent portfolio pieces for job applications.
  • Real-World Simulation: Get hands-on experience with scenarios like user management, data validation, transactions, and error handling.
  • Database Best Practices: Understand normalization, indexing, and query optimization.

Setting Up the Environment

Make sure you have the following installed:

  • Python 3.10+
  • pip (Python package installer)
  • SQLite3 (built-in with Python)
  • PostgreSQL (and psycopg2 package)
  • MongoDB (local or cloud instance like Atlas)
  • Flask (for building simple APIs)

Install necessary packages:

pip install sqlalchemy psycopg2-binary pymongo flask

Project 1: Simple To-Do List App (SQLite)

Project Structure

todo_app/
├── database.py
├── models.py
├── app.py
└── requirements.txt

Database Schema

We will have a single table called tasks:

ColumnTypeAttributes
idINTEGERPRIMARY KEY, AUTOINCREMENT
descriptionTEXTNOT NULL
completedBOOLEANDEFAULT False

CRUD Operations

We will perform:

  • Create: Add a new task
  • Read: View all tasks
  • Update: Mark task as complete
  • Delete: Remove a task

Sample Code

database.py

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

engine = create_engine('sqlite:///tasks.db')
Session = sessionmaker(bind=engine)
session = Session()

models.py

from sqlalchemy import Column, Integer, String, Boolean
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Task(Base):
__tablename__ = 'tasks'

id = Column(Integer, primary_key=True)
description = Column(String, nullable=False)
completed = Column(Boolean, default=False)

app.py

from database import session
from models import Base, Task
from sqlalchemy import create_engine

engine = create_engine('sqlite:///tasks.db')
Base.metadata.create_all(engine)

def add_task(description):
task = Task(description=description)
session.add(task)
session.commit()

def list_tasks():
tasks = session.query(Task).all()
for task in tasks:
print(f"{task.id}: {task.description} [{'Done' if task.completed else 'Pending'}]")

def mark_done(task_id):
task = session.query(Task).filter_by(id=task_id).first()
if task:
task.completed = True
session.commit()

def delete_task(task_id):
task = session.query(Task).filter_by(id=task_id).first()
if task:
session.delete(task)
session.commit()

Project 2: Contact Manager App (PostgreSQL)

Project Structure

contact_manager/
├── database.py
├── models.py
├── app.py
└── requirements.txt

Database Schema

ColumnTypeAttributes
idSERIALPRIMARY KEY
nameTEXTNOT NULL
phoneTEXTUNIQUE
emailTEXTUNIQUE

Key Functionalities

  • Add a new contact
  • Search contacts by name
  • Update contact information
  • Delete a contact

Sample Code

database.py

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

DATABASE_URL = 'postgresql+psycopg2://username:password@localhost/contactdb'
engine = create_engine(DATABASE_URL)
Session = sessionmaker(bind=engine)
session = Session()

models.py

from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Contact(Base):
__tablename__ = 'contacts'

id = Column(Integer, primary_key=True)
name = Column(String, nullable=False)
phone = Column(String, unique=True)
email = Column(String, unique=True)

app.py

from database import session
from models import Base, Contact

Base.metadata.create_all()

def add_contact(name, phone, email):
contact = Contact(name=name, phone=phone, email=email)
session.add(contact)
session.commit()

def find_contact(name):
return session.query(Contact).filter(Contact.name.ilike(f"%{name}%")).all()

def update_contact(contact_id, phone=None, email=None):
contact = session.query(Contact).filter_by(id=contact_id).first()
if phone:
contact.phone = phone
if email:
contact.email = email
session.commit()

def delete_contact(contact_id):
contact = session.query(Contact).filter_by(id=contact_id).first()
if contact:
session.delete(contact)
session.commit()

Project 3: Notes API (Flask + MongoDB)

Project Structure

notes_api/
├── app.py
├── requirements.txt

API Endpoints

  • POST /notes: Create a new note
  • GET /notes: List all notes
  • GET /notes/<id>: Get a specific note
  • PUT /notes/<id>: Update a note
  • DELETE /notes/<id>: Delete a note

MongoDB Collections

Collection: notes

Each document:

{
"_id": "ObjectId",
"title": "Meeting Notes",
"content": "Discuss project roadmap",
"timestamp": "ISO8601 DateTime"
}

Sample Code

app.py

from flask import Flask, request, jsonify
from pymongo import MongoClient
from bson.objectid import ObjectId
from datetime import datetime

app = Flask(__name__)
client = MongoClient('mongodb://localhost:27017/')
db = client['notesdb']
notes_collection = db['notes']

@app.route('/notes', methods=['POST'])
def create_note():
data = request.json
data['timestamp'] = datetime.utcnow()
result = notes_collection.insert_one(data)
return jsonify({"id": str(result.inserted_id)}), 201

@app.route('/notes', methods=['GET'])
def get_notes():
notes = list(notes_collection.find())
for note in notes:
note['_id'] = str(note['_id'])
return jsonify(notes)

@app.route('/notes/<id>', methods=['GET'])
def get_note(id):
note = notes_collection.find_one({'_id': ObjectId(id)})
if note:
note['_id'] = str(note['_id'])
return jsonify(note)
return jsonify({'error': 'Note not found'}), 404

@app.route('/notes/<id>', methods=['PUT'])
def update_note(id):
data = request.json
result = notes_collection.update_one({'_id': ObjectId(id)}, {'$set': data})
if result.matched_count:
return jsonify({'success': True})
return jsonify({'error': 'Note not found'}), 404

@app.route('/notes/<id>', methods=['DELETE'])
def delete_note(id):
result = notes_collection.delete_one({'_id': ObjectId(id)})
if result.deleted_count:
return jsonify({'success': True})
return jsonify({'error': 'Note not found'}), 404

if __name__ == '__main__':
app.run(debug=True)

Best Practices for Database-Driven Applications

  • Always validate and sanitize user input.
  • Implement proper error handling for database failures.
  • Close database connections properly.
  • Use environment variables for sensitive data (like database credentials).
  • Create indexes on frequently queried fields to improve performance.
  • Use migrations tools like Alembic for schema changes.
  • Always backup databases in production environments.

Conclusion

Building mini-applications using databases is one of the most effective ways to master backend development concepts in Python.
By creating To-Do lists, contact managers, and simple APIs, you not only strengthen your Python skills but also become comfortable with real-world database interactions.

Today in History – 27 April

0
today in history 27 april

4977 B.C.

On this very day in 4977 B.C.,  according to German mathematician and astronomer Johannes Kepler, considered a founder of modern science,the universe was created. Kepler is best known for his theories explaining the motion of planets.

1773

The British Parliament passed the Tea Act, a bill designed to save the faltering East India Company from bankruptcy by greatly lowering the tea tax it paid to the British government and, thus, granting it a de facto monopoly on the American tea trade.

1526

Babur Shah was declared as the Emperor of Dehli.

1606

Jahangir arrested Khusroo.

1705

Aurangzeb captured the Fort of Vagingera.

1748

Muhammad Shah, Mughal emperor, passed away and was succeeded by his son Ahmad Shah.

1854

First telegram was sent between Mumbai and Pune.

1857

Jamshedji Framji Madan ( J. F. Madan ), founder of India’s first Cinema Hall – ‘Elphinstone Palace’ – at Calcutta and Parsi Theatrical Company, was born.

1878

Calcutta University started Women’s Education, and allowed them to appear in the Entrance Examination.

1906

China, as suzerain of Tibet,  agreed to the terms of a treaty proposed by Britain.  The treaty said that foreign powers might not send representatives to Tibet, receive transportation or mining concessions, or occupy, buy or lease any territory in Tibet without British permission. The British wanted to prevent the Russians from establishing a protectorate over Tibet, which lay on India’s northern border. Lord Curzon, Viceroy of India, failed in attempts to communicate with Tibet’s ruler, the Dalai Lama. A British military expedition fought its way to the capital at Lhasa and concluded the agreement.

1918

Gandhiji attended Viceroy’s War Conference at Delhi and addressed it in Hindustani; subsequently toured Kaira District to raise recruits for army.

1960

Presidential orders were issued on the report of the Committee of Parliament on official Languages which included issues relating to preparation of terminology (Hindi glossaries, Hindi translation of codes and procedural literature, imparting training in Hindi to employees for propagation of Hindi).

1993

A national credit fund for women called the ‘Rashtriya Mahila Kosh’ was set up.

1994

Supreme Court struck down section 309 of the Indian Penal Code(which makes suicide a punishable offence) that  violates  Article 21.

1996

General Election (11th) of India began.

Related Articles:

Today in History – 26 April

Today in History – 25 April

Today in History – 24 April

Today in History – 23 April