For several years, pip and pip-tools have become distinguished in Python packaging
for their usability and ubiquity. Recently there has been some interesting new developments
in the realm of Python packaging tools. In a trend that started around 2022, there has been an
ongoing "Rustification" of Python tooling.
uv is designed as a drop-in replacement for pip and pip-tools, and is
ready for production use today in projects built around those workflows.
- Charlie Marsh, "uv: Python Packaging in Rust", https://astral.sh/blog/uv
First, Rye was released in pursuit of a "cargo for Python". Cargo is Rust's package manager. It seems to
have inspired Python developers to keep trying to improve on what we have with pip.
While this was happening, in secret Astral Software and Charlie Marsh were also working on yet another hybrid
Rust + Python package manager named uv. There's seemingly no end to this man and the Astral team's projects!
ruff quickly supplanted the incumbent Python linters to become a favorite among Python developers.
Could lightning strike twice for the creators of ruff? Seems they won't be a one-hit wonder when it
comes to developing hit Python packages.
Improving Python packaging is an audacious and challenging task. Part of the problem
is that out of the box Python installs can be tough to reason about for new Python developers,
not to mention the hassle of explaining the purpose of virtual environments in Python coding via venv.
One perk of uv is that it includes virtual environments in its workflow.
uv is 8-10x faster than pip and pip-tools without caching, and 80-115x faster
when running with a warm cache
- Charlie Marsh, "uv: Python Packaging in Rust", https://astral.sh/blog/uv
A new space of potential optimization is now accessible to Python developers. We can now use uv
to make our development environment build faster. A modest 8x speedup in Python library installs
might shave off a shocking amount of time it takes your freshly minted Docker image to build,
especially if you have lots of Python library dependencies. Now, imagine an 80-115x speedup with caching.
Docker images also use caching after an image is built the first time. They are an optimization use case
along with building your development environment in general. In some development shops,
this could cut a lot of time installing developer tooling. It's a potential incredible improvement
we can now make with uv!
In the case of Rye and uv, two developers simultaneously identified the same opportunity
and are now combining their efforts. Sounds like a win for all Python developers. Armin Ronacher, the
creator of the Flask web framework and Charlie Marsch with the proven success of ruff are converging
to tackle one of Python's biggest pain points. They could be merged into a "cargo for Python" super tool eventually:
Will Rye be retired for uv?
Not today, but the desire is that these tools eventually converge into one.
- Armin Ronacher, "Rye Grows with uv", https://lucumr.pocoo.org/2024/2/15/rye-grows-with-uv/
Per Armin's recent blog post, Rye is probably not the final solution. He thinks Rye will get absorbed
into a more fleshed out project like uv. It seems Python packaging will continue evolving and improving,
a welcome sight for Pythonistas!
Image Source: "uv: Python Packaging in Rust", https://astral.sh/blog/uv
Install uv and rye
pip install uv
pip install rye
# Alternative install for uv with curl
curl -LsSf https://astral.sh/uv/install.sh | sh
# Alternative Install for rye on Linux and Mac
curl -sSf https://rye-up.com/get | bash
Create a Virtual Environment With uv
uv venv # Create a virtual environment at .venv.
# Activate venv on macOS and Linux.
source .venv/bin/activate
Installing a New Module With uv
uv pip install requests
pip sync a requirements.txt file with uv
uv pip sync requirements.txt # Install from a requirements.txt file.
Optional: Configure Rye on Top of uv
rye config --set-bool behavior.use-uv=true
Create a New Python project With Rye
rye init my-project
rye pin 3.10
rye add black
rye sync
rye run black
uv and rye Documentation and Blog Links
uv: Python Packaging in Rust
uv Github Repo
Rye Grows with uv
Rye User Guide
Below are the steps I followed to install both Python 3.11 and Python 3.12 in my Ubuntu Linux shell.
Make sure to adjust your Python version to match 3.11 or 3.12 in all commands.
I downloaded the .tgz file from Python.org, not sure initially how to build Python from it.
Once I unpacked the compressed files, I saw the build instructions in the README.rst
to build a functional Python 3.11 on my Ubuntu computer. Here's how to install the speedier Python versions 3.11 or 3.12.
How to Install Python 3.11 or 3.12
Install Linux build libraries.
I followed this step posted on this blog.
If you don't do this, you'll likely see an error about C not being found when running the ./configure command.
sudo apt install build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev
Install sqllite Libraries (Django Requirement)
If you wish to make a Django website, install sqllite libraries before you build Python.
sudo apt install sqlite3 libsqlite3-dev
Use curl to download the Python gzip file.
curl https://www.python.org/ftp/python/3.11.0/Python-3.11.0.tgz --output Python-3.11.0.tgz
Unpack gzip file to folder.
tar -xvzf Python-3.11.0.tgz
Change directory, read the README + find build commands.
cd Python-3.11.0
cat README.rst
Build Python.
# Build Python on Unix, Linux, BSD, macOS, and Cygwin:
./configure --enable-optimizations
make
make test
sudo make install
Building Python on Various Platforms
This will install Python as python3.
You can pass many options to the configure script; run ./configure --help
to find out more. On macOS case-insensitive file systems and on Cygwin,
the executable is called python.exe; elsewhere it's just python.
Building a complete Python installation requires the use of various
additional third-party libraries, depending on your build platform and
configure options. Not all standard library modules are buildable or
useable on all platforms. Refer to the
Install dependencies
section of the Developer Guide for current detailed information on
dependencies for various Linux distributions and macOS.
On macOS, there are additional configure and build options related
to macOS framework and universal builds. Refer to Mac/README.rst.
On Windows, see PCbuild/readme.txt.
- Python 3.11 Linux README.rst
There are usually many ways to do most things in Python. I've retrieved
random numbers a few different ways at various times within the random
module, often after reading a Stack Overflow post. This time in my most
recent search for random digits, I discovered in the Python docs the
random.sample()
function with its k parameter:
Return a k length list of unique elements chosen from the
population sequence or set. Used for random sampling without
replacement.
https://docs.python.org/3/library/random.html#random.sample
When combined with the range() built-in,
it makes doing this easy. Being able to specify a length and return a
list of random numbers is mighty convenient. This function seems a
Pythonic way to randomize to me. Have a look!
| import random
# Returns a list of 5 random numbers.
numbers = random.sample(range(10000000), k=5)
print(numbers)
# Returns a single random number.
number = random.sample(10000000), k=1)[0]
print(number)
|
To choose a sample from a range of integers, use a range() object as an
argument.
"This is especially fast and space efficient for sampling from a large
population":
| sample(range(10000000), k=60)
|
- Python Docs, https://docs.python.org/3/library/random.html#random.sample
Black is a code formatting tool that I have been testing out recently to see what the hype is about. It is the defacto "uncompromising code formatter in Python". I normally do not use any code formatters since I'm not required to use them. This short post aims to convince you that Black is an insightful way to see the parts of your code that are dangerously unreadable.
I have found it interesting to see what black does with my gnarliest code. It has taught me what is considered "good formatting" by some Pythonistas. The areas where I see the most improvement is how it enforces PEP-8's characters per line limit. Often before, I didn't know how to break my code into several lines. My scripts tended to have one-liners trailing off the edge of my text editor. Black teaches you new ways to organize your code and makes it easier to understand. Now I write my code like Black the first time instead of letting it trail off the screen.
Initially I was hesitant to try Black because I didn't want to sabotage my own code style. But since running Black on a few of my scripts, it has taught me new ways to write code. Give Black a chance and you will learn how to write more readable Python.
Here's the project on GitHub: https://github.com/psf/black
You may want to download an archive of your tweets before deleting them. I did this and it took about a day to get my archive download.
How To Purge Your Tweet History with Python
- Per the Tweepy library documentation, install tweepy with pip. It worked fine in my python 3.8 virtual environment.
pip install tweepy
- Sign up for a Twitter Developer account and create an app. I named mine "tweetcleanr".
- Find your app under "Projects & Apps". Edit your app's permissions to "Read + Write + Direct Messages".
- After you update your permissions, select the "Keys and tokens" tab. Then regenerate new API keys. Then paste them in the below script.
- Save the below script as a python file. In command prompt or terminal, run python delete_tweets.py or whatever you want to name it!
- You'll be asked to go to a link and enter an authorization code. Then you'll see your tweets being deleted like pictured below.
delete_tweets.py
I found this Github Gist via Google and updated the print and input statements to Python 3. I also added the traceback module in case you need to debug it. Initially, I received an error telling me to complete step 3 above. I didn't see the error message at first, until adding traceback.print_exc() like you see below.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 | import tweepy
import traceback
"""Delete All Your Tweets - Github Gist by davej
Credit: https://gist.github.com/davej/113241
Ported to Python 3 by Lo-Fi Python: https://lofipython.com/delete-all-your-tweets-with-tweepy-and-the-twitter-api/
"""
CONSUMER_KEY = "get_from_dev_portal"
CONSUMER_SECRET = "get_from_dev_portal"
def oauth_login(consumer_key, consumer_secret):
"""Authenticate with twitter using OAuth"""
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth_url = auth.get_authorization_url()
verify_code = input(
"Authenticate at %s and then enter you verification code here > " % auth_url
)
auth.get_access_token(verify_code)
return tweepy.API(auth)
def batch_delete(api):
print(
"You are about to delete all tweets from the account @%s."
% api.verify_credentials().screen_name
)
print("Does this sound ok? There is no undo! Type yes to carry out this action.")
do_delete = input("> ")
if do_delete.lower() == "yes":
for status in tweepy.Cursor(api.user_timeline).items():
try:
api.destroy_status(status.id)
print("Deleted:", status.id)
except Exception:
traceback.print_exc()
print("Failed to delete:", status.id)
if __name__ == "__main__":
api = oauth_login(CONSUMER_KEY, CONSUMER_SECRET)
print("Authenticated as: %s" % api.me().screen_name)
batch_delete(api)
|
✅ Twitter Cleanse Complete
Twitter has a really slick developer dashboard. Its API combined with the tweepy library got the job done for me. It's great when stuff just works. And it only cost me about 1 hour to complete. Time to start a clean slate. Here's to looking forward.
Supplementary Reading
Tweepy Documentation Tutorial
Twitter's API Tutorials
Twitter Postman Tutorial