User:SSapaty (WMF)/PTD/my first python tool
My first Python tool
Overview
Python webservices are used by many existing tools on Toolforge. Python is a general-purpose programming language commonly used for web development, automation, data processing, and many other tasks.
This tutorial is designed to get a sample Python application deployed to Toolforge using Push-to-Deploy as quickly as possible. The application uses Flask and runs on Toolforge using the Build Service.
Then we'll use the database credentials provided by Toolforge to extract the list of available databases from the Wiki Replicas.
The guide will teach you how to:
- Create a new tool
- Run a Python Flask webservice on Kubernetes
- Deploy the application using Push-to-Deploy
- Connect to the Wiki Replicas from Python
- Run a query and extract information
Getting started
Prerequisites
Skills
- Basic knowledge of Python
- Basic knowledge of SSH
- Basic knowledge of the Unix command line
- Basic knowledge of Git
Accounts
Step-by-step guide
Step 1: Create a new tool account
- Follow the Toolforge quickstart guide to create a Toolforge tool and SSH into Toolforge.
- For the examples in this tutorial,
sample-python-ptd-appis used to indicate places where your unique tool name is used in another command.
- For the examples in this tutorial,
- Make sure to create a Git repository for the tool. You can get one like this:
- Log into the Toolforge admin page.
- Select your tool.
- On the left side panel, under
Git repositories, clickcreate repository. - Copy the URL in the
Clonesection.- There is a private URL that we will use to clone the repository locally, starting with
git:git@gitlab.wikimedia.org/toolforge-repos/sample-python-ptd-app.git - There is also a public URL that Toolforge will use to build the application, starting with
https:https://gitlab.wikimedia.org/toolforge-repos/sample-python-ptd-app.git
- There is a private URL that we will use to clone the repository locally, starting with
Step 2: Create a basic Python Flask webservice
What is Flask?
Flask is a lightweight Python web framework that can be used to create web applications and APIs.
How to create a basic Python Flask webservice
Clone your tool Git repository
You will have to clone the tool repository to be able to add code to it. On your local computer, with Git installed, run:
laptop:~$ git clone git@gitlab.wikimedia.org:toolforge-repos/sample-python-ptd-app.git
laptop:~$ cd sample-python-ptd-app
That will create a folder called sample-python-ptd-app. We are going to put the code in that folder.
Add the Python dependencies
requirements.txt to keep track of the Python dependencies required by the application.
Create requirements.txt:
laptop:~/sample-python-ptd-app$ cat > requirements.txt << EOF
Flask
gunicorn
PyMySQL
EOF
Create a "Hello World!" Python application
Create a file named app.py:
from flask import Flask
app = Flask(**name**)
@app.route("/")
def index():
return "<p>Hello World!</p>"
Create the Procfile
The Procfile defines the command that the Build Service should use to start the web application.
Create it with:
laptop:~/sample-python-ptd-app$ cat > Procfile << EOF
web: gunicorn --bind 0.0.0.0:\$PORT app:app
EOF
The web entry defines the command used to start the Flask application. Gunicorn runs the application and listens on the port provided by Toolforge through the PORT environment variable.
Create the Toolforge configuration file
Create toolforge.yaml:
laptop:~/sample-python-ptd-app$ cat > toolforge.yaml << EOF
# yaml-language-server: \$schema=https://gitlab.wikimedia.org/repos/cloud/toolforge/components-api/-/raw/main/openapi/tool-config-schema.json
source_url: https://gitlab.wikimedia.org/toolforge-repos/sample-python-ptd-app/-/raw/main/toolforge.yaml?ref_type=heads
components:
webservice:
build:
repository: https://gitlab.wikimedia.org/toolforge-repos/sample-python-ptd-app
ref: main
run:
command: web
publish: /
port: 8000
EOF
If you don't want your webservice to be reachable from the internet, remove the publish setting. If you are deploying a process without a port, you can remove port too. See Deploy your tool for more information.
Commit your changes and push
laptop:~/sample-python-ptd-app$ git add .
laptop:~/sample-python-ptd-app$ git commit -m "First commit"
laptop:~/sample-python-ptd-app$ git push origin main
Initialize the tool configuration
Now SSH to login.toolforge.org and become your tool:
laptop:~/sample-python-ptd-app$ ssh login.toolforge.org
user@tools-sgebastion-XX:~$ become sample-python-ptd-app
Create the Components Service configuration using the public copy of toolforge.yaml:
tools.sample-python-ptd-app@tools-sgebastion-XX:~$ curl 'https://gitlab.wikimedia.org/toolforge-repos/sample-python-ptd-app/-/raw/main/toolforge.yaml?ref_type=heads' | toolforge components config create
You should see a message indicating that the configuration was updated successfully.
Create the first deployment
Create a deployment:
tools.sample-python-ptd-app@tools-sgebastion-XX:~$ toolforge components deployment create
Push-to-Deploy will build the application from your Git repository and deploy the webservice.
toolforge.yaml must be publicly accessible so that Toolforge can clone and build it.
Wait for the deployment to finish
Check the deployment status:
tools.sample-python-ptd-app@tools-sgebastion-XX:~$ toolforge components deployment show
Wait for the deployment status to be ok(Succeeded).
Once the deployment has finished, navigate to:
https://sample-python-ptd-app.toolforge.org
You should see:
Hello World!
It might take a couple of minutes for the application to become reachable.
Automate deployment on push
You can follow this guide to configure and automate deployment of your tool whenever you push or merge changes to the main branch.
Connecting to the replicas
Toolforge provides database credentials to your application through environment variables. We will use these credentials to connect to the special meta_p database and retrieve the names of the available Wiki Replica databases.
First, update requirements.txt if PyMySQL is not already present:
Flask
gunicorn
PyMySQL
Now update app.py:
from flask import Flask
import os
import pymysql
app = Flask(**name**)
def get_db_connection():
return pymysql.connect(
host="meta.web.db.svc.wikimedia.cloud",
user=os.environ["TOOL_REPLICA_USER"],
password=os.environ["TOOL_REPLICA_PASSWORD"],
database="meta_p",
cursorclass=pymysql.cursors.DictCursor,
)
def get_db_names():
connection = get_db_connection()
```
try:
with connection.cursor() as cursor:
cursor.execute("SELECT dbname FROM wiki;")
return cursor.fetchall()
finally:
connection.close()
```
@app.route("/")
def index():
databases = get_db_names()
```
rows = "".join(
f"<tr><td>{row['dbname']}</td></tr>"
for row in databases
)
return f"""
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Database names</title>
</head>
<body>
<p>
Sample Python application accessing the
<a href="https://wikitech.wikimedia.org/wiki/Help:Toolforge/Database">
Wiki Replicas
</a>
special <code>meta_p</code> database.
</p>
<table>
<thead>
<tr>
<th>Database name</th>
</tr>
</thead>
<tbody>
{rows}
</tbody>
</table>
</body>
</html>
"""
```
The application connects to meta.web.db.svc.wikimedia.cloud using the TOOL_REPLICA_USER and TOOL_REPLICA_PASSWORD environment variables provided by Toolforge.
The query:
SELECT dbname FROM wiki;
retrieves the database names from the special meta_p database.
Commit, push, and redeploy
Commit and push your changes:
laptop:~/sample-python-ptd-app$ git add .
laptop:~/sample-python-ptd-app$ git commit -m "Query meta_p database"
laptop:~/sample-python-ptd-app$ git push origin main
Then create a new deployment:
laptop:~/sample-python-ptd-app$ ssh login.toolforge.org
user@tools-sgebastion-XX:~$ become sample-python-ptd-app
tools.sample-python-ptd-app@tools-sgebastion-XX:~$ toolforge components deployment create
tools.sample-python-ptd-app@tools-sgebastion-XX:~$ toolforge components deployment show
Wait for the deployment to finish and refresh the application in your browser.
You should now see a list of Wiki Replica database names.
Notes
You can see the code used in this example in the sample-python-ptd-app repository.
Troubleshooting
See Toolforge Build Service troubleshooting.
You can also inspect the status of your Push-to-Deploy deployments with:
toolforge components deployment list
toolforge components deployment show
See also
Communication and support
Support and administration of the WMCS resources is provided by Wikimedia Foundation staff and Wikimedia movement volunteers. Please reach out with questions and join the conversation:
Discuss and receive general support
- Chat in real time in the IRC channel
#wikimedia-cloudor the bridged Telegram group. - Discuss via email after you have subscribed to the cloud@ mailing list.
Stay aware of critical changes and plans
- Subscribe to the cloud-announce@ mailing list. Messages are also mirrored to the cloud@ list.
Track work tasks and report bugs
Use a subproject of the Cloud-Services Phabricator project to track confirmed bug reports and feature requests about the Cloud Services infrastructure itself.
Communication and support
Support and administration of the WMCS resources is provided by Wikimedia Foundation staff and Wikimedia movement volunteers. Please reach out with questions and join the conversation:
- Chat in real time in the IRC channel #wikimedia-cloud connect or the bridged Telegram group
- Discuss via email after you have subscribed to the cloud@ mailing list
- Subscribe to the cloud-announce@ mailing list (all messages are also mirrored to the cloud@ list)
- Read the News wiki page
Use a subproject of the #Cloud-Services Phabricator project to track confirmed bug reports and feature requests about the Cloud Services infrastructure itself
Read posts about Cloud Services on the Wikimedia Technical Blog. (Older posts can be read from the Cloud Services Blog.)