Michael Driscoll's Blog, page 7

November 20, 2023

Black Friday Python Deals 2023

Black Friday and Cyber Monday are just around the corner, so let’s start the holidays early with some amazing Python-related deals!

You can take 33% off ANY of my self-published books on Gumroad by using the following coupon code: black23

https://www.blog.pythonlibrary.org/wp-content/uploads/2023/11/black23_gumroad.mp4

I am also running a 33% off sale on all my Python courses over on Teach Me Python using the same black23 code. Some courses are text-based, and I also have a video course with a new video course coming soon. The coupon will work on both individual purchases as well as membership subscriptions.

Other Great Python Sales

Check out these other great deals!

Books

 

Boost Your Git DX by Adam Johnson is 50% off, no code needed (usual price is $39).Boost Your Django DX and Speed Up Your Django Tests by Adam Johnson are 50% off, no code needed.All Books Bundle by Sundeep Agarwal is a bundle with 13 programming books and is 69% off until the end of November, no code needed.The bundle Learn Python by Example by Sundeep Agarwal is 70% off and the book Understanding Python re(gex)? is free, both until the end of November, no code needed.The Python Problem-Solving Bootcamp is 40% off for Black FridayCoursesTalk Python is having a Black Friday salePython Essentials for Data Scientists and all other Data School courses will be 40% off between the 24th and 27th of NovemberMembershipsThe Python Coding Place lifetime membership (by Stephen Gruppeta) is 70% off, no code needed.Python Morsels (by Trey Hunner) lifetime access for the price of a 2-year subscription, no code needed.Great Django Deals

Adam Johnson, a Django maintainer and an author, has a great round-up of lots deals on his website.

Note: This post will be updated as new deals get reported. Let me know of any great deals on X/Twitter or on Mastodon.

Get Python tutorials in your inbox by subscribing to The Python Papers Newsletter

The post Black Friday Python Deals 2023 appeared first on Mouse Vs Python.

 •  0 comments  •  flag
Share on Twitter
Published on November 20, 2023 09:18

November 17, 2023

Episode 22 – Git and Django with Adam Johnson

You may know Adam from all his work around the Django web framework. If you head to the Python Package Index (PyPI), you will see that Adam has made or contributed to more than 80 projects!

Adam recently released a new book called Boost Your Git DX

Listen in as we chat about:

Book writingDjangoPythonGitand much more!LinksBoost Your Django DXBoost Your Git DXSpeed Up Your Django TestsAdam Johnson’s website

The post Episode 22 – Git and Django with Adam Johnson appeared first on Mouse Vs Python.

 •  0 comments  •  flag
Share on Twitter
Published on November 17, 2023 05:57

November 15, 2023

Using CSS to Style a Python TUI with Textual

Textual is a Python framework for creating Text Based user interfaces (TUIs). You can create graphical user interfaces in your terminal with Textual.

If you haven’t heard of Textual before, check out An Intro to Textual – Creating Text User Interfaces with Python

In this tutorial, you will learn how to create and style a form. The form won’t do anything, but this tutorial teaches how to add widgets, lay them out, and then give them some style.

Getting Started

If you don’t have Textual yet, you must install it. Textual is not built-in to Python, so you can use pip to get it on your machine.

Open up your terminal and run the following command to install Textual:

python -m pip install textual

Now you’re ready to rock!

Creating a Form in Textual

You are now ready to start coding with Textual. Open up your favorite Python editor and create a new file named form.py.

Then enter the following code:

# form.py

from textual.app import App, ComposeResult
from textual.containers import Center
from textual.screen import Screen
from textual.widgets import Button, Footer, Header, Input, Static


class Form(Static):
def compose(self) -> ComposeResult:
"""
Creates the main UI elements
"""
yield Input(id="first_name", placeholder="First Name")
yield Input(id="last_name", placeholder="Last Name")
yield Input(id="address", placeholder="Address")
yield Input(id="city", placeholder="City")
yield Input(id="state", placeholder="State")
yield Input(id="zip_code", placeholder="Zip Code")
yield Input(id="email", placeholder="email")
with Center():
yield Button("Save", id="save_button")


class AddressBookApp(App):
def compose(self) -> ComposeResult:
"""
Lays out the main UI elemens plus a header and footer
"""
yield Header()
yield Form()
yield Footer()


if __name__ == "__main__":
app = AddressBookApp()
app.run()

Here, you import all the bits and bobs you’ll need to create your form. You can use the Static class to group together multiple widgets. Think of it as a container-widget.

You create the Form() class to contain most of your form’s widgets. You will compose a series of text input widgets where users can fill in their name and address information. There is also a reference to something called Center(), an actual container in Textual that helps you align widgets.

Next, in the AddressBookApp() class, you create a header, the form, and a footer. Now you are ready to run can run your code.

Open up your terminal again and use the following command:

python form.py

When you run your code, you will see something like the following:

Textual form

The default colors work, but you may want to change them to give your application a different look.

You will learn how to do that by using CSS!

CSS Styling

Textual supports a limited subset of CSS that you can use to style your widgets.Create a new file and name it form.css.

Next, add the following code:

Input {
background: white;
}

Button {
background: blue;
}

The Input parameter tells Textual to style all the widgets that are of the Input type. In this example, you are setting the background color white.

The Button line item will set all the Button widget’s background color to blue. Of course, in this example, there is only one Button.

Now you need to update your code to tell Textual that you want to load a CSS file:

from textual.app import App, ComposeResult
from textual.containers import Center
from textual.screen import Screen
from textual.widgets import Button, Footer, Header, Input, Static


class Form(Static):

def compose(self) -> ComposeResult:
"""
Creates the main UI elements
"""
yield Input(id="first_name", placeholder="First Name")
yield Input(id="last_name", placeholder="Last Name")
yield Input(id="address", placeholder="Address")
yield Input(id="city", placeholder="City")
yield Input(id="state", placeholder="State")
yield Input(id="zip_code", placeholder="Zip Code")
yield Input(id="email", placeholder="email")
with Center():
yield Button("Save", id="save_button")


class AddressBookApp(App):
CSS_PATH = "form.css"

def compose(self) -> ComposeResult:
"""
Lays out the main UI elemens plus a header and footer
"""
yield Header()
yield Form()
yield Footer()


if __name__ == "__main__":
app = AddressBookApp()
app.run()

One-line change is all you need and that change is the first line in your AddressBookApp() class where you set a CSS_PATH variable. You can supply a relative or an absolute path to your CSS file here.

If you want to modify the style of any of the widgets in your TUI, you only need to go into the CSS file.

Try re-running the application and you’ll see an immediate difference:

If you’d like to be more specific about which widgets you want to style, change your CSS to the following:

Input {
background: white;
}

#first_name {
background: yellow;
color: red
}

#address {
background: green;
}

#save_button {
background: blue;
}

Here, you leave the Input widgets the same but add some hash-tag items to the CSS. These hash-tagged names must match the id you set for the individual widgets you want to style.

If you specify incorrect id names, those style blocks will be ignored. In this example, you explicitly modify the first_name and address Input widgets. You also call out the save_button Button,. This doesn’t really change the look of the button since you didn’t change the color, but if you add a second Button, it won’t get any special styling.

Here is what it looks like when you run it now:

You may not like these colors, so feel free to try out some of your own. That’s part of the fun of creating a TUI.

Wrapping Up

Now you know the basics of using CSS with your Textual applications. CSS is not my favorite way of applying styling, but this seems to work pretty well with Textual. The other nice thing about Textual is that there is a developer mode that you can enable where you can edit the CSS and watch it change the user interface live.

Give Textual a try and see what you can make!

The post Using CSS to Style a Python TUI with Textual appeared first on Mouse Vs Python.

 •  0 comments  •  flag
Share on Twitter
Published on November 15, 2023 05:32

November 13, 2023

PyDev of the Week: Phil Ewels

This week, we welcome Phil Ewels as our PyDev of the Week! Phil is the creator of the rich-click package. You can find Phil on TwitterMastodon,  or BlueSky.

You can also catch up with Phil over on GitHub.

Let’s spend a few moments getting to know Phil better!

Phil Ewels

Can you tell us a little about yourself (hobbies, education, etc):

I’m a scientist turned software developer from the UK, now living in Sweden. My education and career path is a little winding: I studied Biochemistry at Bristol and went on to do a PhD in Molecular Biology at Cambridge, working with techniques to tease out the three-dimensional structure of DNA in order to figure out why some cancers happen more often than we expect. During school and university I did web development on the side for fun, and at some point the two interests fused and I got into the field of bioinformatics – computational analysis of biological data. I ended up at SciLifeLab in Sweden working at a national center doing DNA sequencing and analysis for academic researchers. I’ve been lucky enough to have the opportunity to be behind some popular open-source software for scientists over the years and recently joined Seqera to focus on building scientific OSS and the communities that drive them.

I have three young children so I don’t have much time for hobbies these days! But if I get a chance I love to get out on my bike or into the mountains, and I spent much of my earlier life rowing competitively.

Why did you start using Python?

I switched from Perl to Python when I moved to Sweden, as it was used by everyone else in the group. It immediately clicked with me and I never looked back. I’ve never had any formal training, but I had some great mentors in those early days – Per Kraulis, Mario Giovacchini and Guillermo Carrasco to name a few. I learnt quickly, mostly through their pull-request reviews!

What other programming languages do you know and which is your favorite?

My first languages were BASIC on my older brother’s BBC Micro and then Actionscript in Macromedia Flash! Then PHP, JavaScript, Perl and Python. More recently, I’ve done a lot of work with Nextflow which is a domain-specific language based on Groovy. If I start a new project I’ll always reach for Python, unless there’s a compelling reason to do otherwise.

What projects are you working on now?

As of this month I’m project manager for open-source software at Seqera, so my official remit covers Nextflow (data pipelines), MultiQC (data visualisation / reporting), Wave (on-the-fly containers) and Fusion (fast virtual filesystems). I’m also the co-founder of nf-core and am heavily involved in writing the developer tools for that community. Those are my day job projects, after that I have a long tail of pet projects lurking on GitHub that never quite get the attention that they deserve! The most recent ones are rich-click (see below) and rich-codex, for auto-generating terminal output screenshots from simple markdown commands.

Which Python libraries are your favorite (core or 3rd party)?

I have a soft spot for user-friendly interfaces and fell in love with Rich by Will McGugan / theTextualize team the moment I came across it. More recently they released Textual which is pure magic and a delight to work with. Before Textual I used Questionary for interactive CLI prompts, which is fun. Oh and I love all ofSebastián Ramírez’s libraries, but especially FastAPI. Those are beautiful in their simplicity and a great source of inspiration, as well as being super intuitive to work with. Also worth a mention are Pyodide and Ruff – neither are really libraries, but both do really cool things with Python code, in different ways.

How did the rich-click package come about?

As mentioned above, I’m a bit of a fan-boy when it comes to Rich. I had used it to pretty good effect to make the CLI output of most of my tools colourful. As a result, the output from Click (used for the CLI interface) started to stand out as being a bit.. bland. I’d been toying with the idea of building a plugin for a few months, then Will launched rich-cli complete with an attractive CLI. I took his code (with his permission, and help) and generalised it into a package that would do the same for any Python package using Click to generate a CLI. My priority was to make it as simple to use as possible: the basic usage is simply `import rich_click as click`, and the CLI output looks magically nicer. The package has since found its way into quite a few people’s projects and inspired native Typer functionality which is cool. Most recently, Daniel Reeves offered to help with maintenance which I hope gives the project a more stable base to live on (he also did a cool new logo!).

What is your elevator pitch for the MultiQC tool?

MultiQC is a data visualisation tool that understands the log outputs from hundreds of different scientific software packages. At the end of a typical genomics analysis run you might have outputs from 10s – 100s of different tools for 10s – 1000s of samples. MultiQC can scoop up the summary statistics from all of these and generate a Human-readable HTML report summarising the key quality-control metrics, letting you spot any outlier samples. Whilst MultiQC’s origins lie in genomics, it doesn’t do anything specific to that field, and it’s built in a modular way that makes it easy to extend to any tool outputs. You can play around with it in your browser (the recent Pyodidetoy I’ve been playing with) here.

Is there anything else you’d like to say?

Just a big thanks to you and everyone in the Python community for being such a lovely bunch of people. Python folk are one of a small handful of enclaves that I still really enjoy interacting with on social media and I think much of that stems from our diverse backgrounds. Long may that continue! Oh, and if anyone fancies writing a rich-pre-commit library that I could use, then that’d be awesome!

 

Thanks for doing the interview, Phil!

The post PyDev of the Week: Phil Ewels appeared first on Mouse Vs Python.

 •  0 comments  •  flag
Share on Twitter
Published on November 13, 2023 05:30

November 10, 2023

Episode 21 – Sanic – The Async Python Web Framework

Python has many remarkable web frameworks to choose from. Sanic is another excellent web framework and one of the first to support async programming.

Sanic is built to be able to build fast and run fast.

In this episode, we talk to Adam Hopkins, one of the maintainers of the Sanic web framework.

We discuss the following topics:

SanicOther Python web frameworksMsgspecMayim – The NOT ORM Python HydratorOther LinksAdam Hopkin’s Sanic bookAdam Hopkin’s personal website

The post Episode 21 – Sanic – The Async Python Web Framework appeared first on Mouse Vs Python.

 •  0 comments  •  flag
Share on Twitter
Published on November 10, 2023 05:33

November 9, 2023

wxPython 101 – wx.NewId() is Deprecated!

Deprecation warnings are handy ways for open-source maintainers to alert their users that some part of their package is no longer going to be supported. Good maintainers will provide migration guides that tell you what to do when you see a deprecation warning.

You don’t want to ignore a deprecation warning because it alerts you that a feature is disappearing. If you upgrade to the latest without mitigating the warnings, you will almost certainly have one or more broken applications to fix.

wxPython is not immune to deprecation warnings either. In this article, you will learn about what to do when see a DeprecationWarning about wx.NewId().

Ye Olde wx.NewId

If you would like to see the deprecation error, all you need is wxPython 4-4.2 or so and add a call to wx.NewId().

One of the most common places to use wx.NewId() is in a wx.Menu item. Here’s an example:

import wx


class MyFrame(wx.Frame):
def __init__(self):
super().__init__(parent=None, title="wx.Menu Tutorial")

self.panel = wx.Panel(self, wx.ID_ANY)

menu_bar = wx.MenuBar()
file_menu = wx.Menu()
exit_menu_item = file_menu.Append(wx.NewId(), "Exit", "Exit the application")
menu_bar.Append(file_menu, "&File")
self.Bind(wx.EVT_MENU, self.on_exit, exit_menu_item)
self.SetMenuBar(menu_bar)

def on_exit(self, event):
self.Close()


# Run the program
if __name__ == "__main__":
app = wx.App(False)
frame = MyFrame().Show()
app.MainLoop()

When you run this code, you will see the following text in your terminal or IDE’s stdout:

C:\code\bad_menu.py:12: DeprecationWarning: NewId() is deprecated
exit_menu_item = file_menu.Append(wx.NewId(), "Exit", "Exit the application")

Let’s find out how to fix this problem in the next section!

Using wx.NewIdRef()

The fix for this particular deprecation warning from wxPython is to use wx.NewIdRef() instead of wx.NewId().

Swap out the new call like so:

import wx


class MyFrame(wx.Frame):
def __init__(self):
super().__init__(parent=None, title="wx.Menu Tutorial")

self.panel = wx.Panel(self, wx.ID_ANY)

menu_bar = wx.MenuBar()
file_menu = wx.Menu()
exit_menu_item = file_menu.Append(wx.NewIdRef(), "Exit", "Exit the application")
menu_bar.Append(file_menu, "&File")
self.Bind(wx.EVT_MENU, self.on_exit, exit_menu_item)
self.SetMenuBar(menu_bar)

def on_exit(self, event):
self.Close()


# Run the program
if __name__ == "__main__":
app = wx.App(False)
frame = MyFrame().Show()
app.MainLoop()

You will no longer receive a deprecation warning when you run this updated code!

Wrapping Up

Deprecation warnings are not a big deal. But if you plan to do a new release, then you should spend a little extra time taking care of them so they don’t bite you later on.

Have fun and happy coding!

The post wxPython 101 – wx.NewId() is Deprecated! appeared first on Mouse Vs Python.

 •  0 comments  •  flag
Share on Twitter
Published on November 09, 2023 05:46

November 7, 2023

lxml objectify and Working with XML Tag Containing Periods

Recently, I have been working on automating Jenkin’s config XML files using Python and the lxml package.

I have several articles on using lxml and its handy objectify functionality:

Python: Creating XML with lxml.objectify

Parsing XML with Python using lxml.objectify

But I’ve never really covered what to do when you need to create or parse an XML tag that contains periods.

For example, Jenkin’s config files are notorious for having tags named like this:

The way to get the value of a tag that contains periods is to use lxml’s objectify’s __getattr__() method and pass in the strangely named tag name:

For example:

from lxml import objectify

with open("config_no_build_trigger.xml") as xml_file:
config = xml_file.read()

root = objectify.fromstring(config.encode())

timer_trigger = root.triggers.__getattr__("hudson.triggers.TimerTrigger")

But what do you do if you need to create a tag that contains periods in its name?

I wanted to enable the Build Periodically function in Jenkins programmatically. There are several tags and sub-tags that contain periods that I would need to create if I wanted to turn this feature on in a Jenkins job.

To do it successfully, you need to use __setattr__() !

Here’s an example:

from lxml import etree, objectify

with open("config_no_build_trigger.xml") as xml_file:
config = xml_file.read()

root = objectify.fromstring(config.encode())

try:
_ = root.properties.__getattr__(
"org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty"
)
except AttributeError:
# Add org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty
# XML element
root.properties.__setattr__("org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty", "")

try:
trigger_prop = root.properties.__getattr__(
"org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty"
)
_ = trigger_prop.triggers
except AttributeError:
# Add trigger XML element
trigger_prop = root.properties.__getattr__(
"org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty"
)
_ = trigger_prop.triggers = objectify.Element("triggers")

try:
trigger_prop = root.properties.__getattr__(
"org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty"
)
_ = trigger_prop.triggers.__getattr__("hudson.triggers.TimerTrigger")
except AttributeError:
# Add hudson.triggers.TimerTrigger XML element
trigger_prop = root.properties.__getattr__(
"org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty"
)
_ = trigger_prop.triggers.__setattr__("hudson.triggers.TimerTrigger", "")

try:
trigger = root.properties.__getattr__(
"org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty"
)
trigger.triggers.__getattr__(
"hudson.triggers.TimerTrigger"
).spec
except AttributeError:
# Add spec XML element
trigger = root.properties.__getattr__(
"org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty"
)
trigger.triggers.__getattr__(
"hudson.triggers.TimerTrigger"
).spec = objectify.Element("spec")

# Modify the schedule
try:
trigger = root.properties.__getattr__(
"org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty"
)
trigger.triggers.__getattr__(
"hudson.triggers.TimerTrigger"
).spec = "H 18 * * *"
except AttributeError:
print(f"ERROR: Unable to add schedule!")

objectify.deannotate(root)
etree.cleanup_namespaces(root)

config_xml = etree.tostring(root, pretty_print=True, encoding=str)
with open("new_config.xml", "w") as xml_file:
xml_file.write(config_xml)

This example demonstrates how to use Python exception handling to create all the XML tags and sub-tags effectively and how to set the new tag to a value.

Hopefully, you have found this mini-tutorial helpful and will be able to use it yourself someday!

The post lxml objectify and Working with XML Tag Containing Periods appeared first on Mouse Vs Python.

 •  0 comments  •  flag
Share on Twitter
Published on November 07, 2023 09:06

November 6, 2023

PyDev of the Week: Gláucia Esppenchutz

This week we welcome Gláucia Esppenchutz (@glauesppen) as our PyDev of the Week! Gláucia is the author of Data Ingestion with Python Cookbook.

Let’s spend some time getting to know Gláucia better!

Can you tell us a little about yourself (hobbies, education, etc):

Hi, my name is Glaucia; 31 years old, Brazilian, and living in Portugal.

Married and “mother” of dog beautiful dogs! Last year, I bought a 3D printer and got utterly addicted to it. So, my hobbies include printing random stuff, playing video games, and reading.

I have worked as a Data Engineer for the past eight years and love what I do. I enjoy reading about data, how to optimize ingestion and transformation pipelines, and how to better monitor them.

I’ve been recently allocated to a team focused on Data Operations, which thrills me! Monitoring data and ensuring data quality is challenging.

A fun fact about me is that I have yet to graduate in Science Computing or any engineering grad school. Actually, I graduated in the biomedical field. I changed my career when I met my husband, who is a software engineer.

I am a late diagnosed autistic, and the diagnosis saved my life.

Why did you start using Python?

Python is my mother language! I started using it when I shifted my career path. The language’s simplicity helped me learn it quickly and start working in a small startup.

What other programming languages do you know, and which is your favorite?

I learned how to program in JavaScript and PHP, but it was so long ago that I had no idea how to do it anymore, haha.

I had to learn Scala because of a project in a previous work. It’s not my favorite language, but it helps me a lot when I need to debug something in Spark.

Python will always be the language of my heart <3

What projects are you working on now?

Currently, I am working on two personal projects. One is called Apache Wayang, and it is in the incubator phase at Apache Org. I work with them as a release manager, improving the docs and website.

The other project I am working on is the DE&I initiative in the Apache Org. The idea is to increase the diversity in the open-source community and remove biases we find in the tech area.

Both are long-term projects but very exciting!

Which Python libraries are your favorite (core or 3rd party)?

Hum… that’s a tricky question.. Based on what I work, I will say Pandas. I can’t make a count of how many times this lib saved me when analyzing data. Even when using PySpark, I sometimes invoke the inner compatibility with Pandas (.toPandas()) to analyze something.

On the core side, datetime lib is on my top list. Who didn’t have any problems with date formats when working with data? This core lib always saves me.

How did your book, Data Ingestion with Python Cookbook, come about?

I got an invitation from Packt publisher. They wanted to make a book about Python and Data in a cookbook format. Then, I proposed something for beginners to start in the data world, but with some intermediate topics for the ones who already work with data pipelines.

The book covers the beginning of the data journey, like understanding the data we will work on and how to plan and monitor the pipelines.

What are the top three things you learned writing a book?

The first thing I learned was how to structure and plan a chapter. It seems simple, but creating a content flow and connecting the topics can take a lot of work. Now, I feel more confident to create writing content for my Medium blog, which I started to write posts after the book was released.

Second, my English improved a lot! I had to search for synonyms and different ways to write some things constantly, which made me read a lot of new things.

Third was how to do proper research. All the explanations in the book were made using pieces of code or documentation present in the source codes. Of course, there are citations of other writers and blog posts. Still, I double-checked all the information I needed to make correct assumptions and content.

Is there anything else you’d like to say?

Thank you for the invitation! I am pleased to be part of this! And, of course, you can follow me on LinkedIn or Twitter by the username @glauesppen.

Thanks for doing the interview, Gláucia!

The post PyDev of the Week: Gláucia Esppenchutz appeared first on Mouse Vs Python.

 •  0 comments  •  flag
Share on Twitter
Published on November 06, 2023 05:32

November 3, 2023

Episode 20 – Python on Windows with Steve Dower

The latest episode of The Python Podcast came out this week. In this episode, I chatted with Steve Dower.

The Python Show Podcast Logo

Steve is a part of the Python team at Microsoft and is also a core developer of the Python language. If you have ever used Python on Windows, then you’ve used some of the code he’s worked on as he completely rewrote the Windows Python installer, got Python into the Windows Store and more.

In this episode, we talk about Steve’s contributions, Python in Excel, how Python has been improved on Windows and much more!

Listen to the podcast using any of the following:Python Show on Apple PodcastPython Show on SpotifyPython Show on Amazon MusicPython Show on Pocket CastPython Show on Google Podcasts

The post Episode 20 – Python on Windows with Steve Dower appeared first on Mouse Vs Python.

 •  0 comments  •  flag
Share on Twitter
Published on November 03, 2023 07:24

November 1, 2023

How to Create a pyd File in Python

Python has several other Python files besides the traditional *.py file that it supports. In this tutorial, you will learn about the PYD file.

A PYD file is a dynamic link library (DLL) written in Python that can be imported like a Python file. However, if you attempt to open a PYD file, you will find it is an unreadable binary file. When you create a PYD file, you will save it with a .pyd extension, such as hello.pyd

The PYD file is to be used on the Windows operating system. The source code is not accessible inside of a PYD file.

Let’s get started and learn how to create a PYD file!

Getting Dependencies

You will need to install a couple of other modules to create PYD files successfully. Specifically, you will need the following:

setuptoolsCython

Technically, you can use distutilsinstead of setuptools, however, distutilsis no longer included with Python, starting in version 3.12. Since you are creating a DLL, you will need Cython to compile your Python code to C and then into the DLL.

If you don’t already have the two packages listed above, you can use pip to install them. Open up a terminal, PowerShell or cmd.exe and run the following command:

python -m pip install setuptools Cython

If everything worked correctly, you should now have setuptools and Cython installed on your machine!

You are now ready to learn how to create a PYD file.

Creating a PYD File

For this tutorial, you will be creating a Python script named api.py. Open up your favorite Python IDE or text editor and add the following code:

# api.py
api_key = "MY_API_KEY"

def PyInit_api():
pass

Note that when you create this file,

Here is the setup file, you need to create a specially named function: PyInit_CUSTOM_NAME(). In this example, your module is named api.py, so you’ll want to name your special function PyInit_api(). Your special function does not need any code inside it. Instead, this function will remain empty.

When the api module is called, it will execute the PyInit_api() function, will run automatically, and initialize all the variables and other pieces of code in the module so that you can import them.

In this example, you create module-level variable called api_key that you can import and access in your other Python code.

Now that the module is ready, you must turn it into a PYD file. To create your PYD file, you need to create a setup.pyscript.

Create a new file in your Python IDE or text editor and enter the following code:

# setup.py

from Cython.Distutils import build_ext
from setuptools import Extension, setup

ext_modules = [Extension("api", ["api_key.py"])]

setup(
name="Test Program",
cmdclass={"build_ext": build_ext},
ext_modules=ext_modules,
)

Here, you create a list of extension modules. In this case, you only create one extension. You pass in the extension’s name and a list of sources relative to the distribution root. There are additional arguments you could pass in, but you don’t need them for this example.

Next, you configure setup() so it will build your PYD file. Since you want to build one or more extensions, you must set the cmdclass to build_ext and pass in Cython’s special extension builder module. You also pass in your custom Extensions list.

Now you’ll need to run setup to build your PYD file. Open your terminal back up and navigate to your source code’s folder. Then run the following command:

python setup.py build_ext --inplace

When you run this command, you will see a bunch of text output  to the screen that will look similar to the following:

running build_ext
Compiling api_key.py because it changed.
[1/1] Cythonizing api_key.py
C:\Users\Mike\AppData\Local\Programs\Python\Python311\Lib\site-packages\Cython\Compiler\Main.py:381: FutureWarning: Cooks\code_play\api_key.py
tree = Parsing.p_module(s, pxd, full_module_name)
creating build\temp.win-amd64-cpython-311
creating build\temp.win-amd64-cpython-311\Release
"C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.37.32822\bin\HostX86\x64\cl.exe" /c /nologo /O2 /W3 /GL /DNDEBUG /MD -IC:\Users\Mike\AppData\Local\Programs\Python\Python311\include -IC:\Users\Mike\AppDSVC\14.37.32822\include" "-IC:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\VS\include" "-IC.22621.0\\um" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\shared" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\winrt" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\cppwinrt" -IC:\PROGRA~1\IBM\SQLLIB\INCLUDE -IC:\PROGRA~1\IBM\SQLLIB\LIB /Tcapi_key.c /Fobuild\temp.win-amd64-cpython-311\Release\api_key.obj
api_key.c
"C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.37.32822\bin\HostX86\x64\link.exe" /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:C:\Users\Mike\AppData\Local\Programs\Python\Python311\libs /LIBPATH:C:\Users\Mike\AppData\Local\Programs\Python\Python311 /LIBPATH:C:\Users\Mike\AppData\Local\Programs\Python\Python311\PCbuild\amd64 "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.37.32822\lib\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.22621.0\ucrt\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22621.0\\um\x64" /LIBPATH:C:\PROGRA~1\IBM\SQLLIB\LIB /EXPORT:PyInit_api build\temp.win-amd64-cpython-311\Release\api_key.obj /OUT:C:\books\code_play\api.cp311-win_amd64.pyd /IMPLIB:build\temp.win-amd64-cpython-311\Release\api.cp311-win_amd64.lib
Creating library build\temp.win-amd64-cpython-311\Release\api.cp311-win_amd64.lib and object build\temp.win-amd64-cpython-311\Release\api.cp311-win_amd64.exp

If everything worked correctly, you should now have a file named something like this: api.cp311-win_amd64.pyd

You will also have the following files and folders:

build (a folder)__pycache__ (a folder)api_key.c  (C file)

You should rename your PYD file to something else to import it. For example, you can rename it to api.pyd

Now that it’s renamed run Python in your terminal and make sure it works:

$ python
Python 3.11.5 (tags/v3.11.5:cce6ba9, Aug 24 2023, 14:38:34) [MSC v.1936 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import api
>>> api.api_key
'MY_API_KEY'

Great! You just created a PYD file!

Wrapping Up

You can use PYD files as a type of obfuscation. You may be able to get some speed increases using PYD files, if you are careful.

Probably the best use case for PYD files is allowing programs other than Python to load them. Give it a try and see if you can find a good use for these types of files!

LinksSetupTools – Build Extension Modules

The post How to Create a pyd File in Python appeared first on Mouse Vs Python.

 •  0 comments  •  flag
Share on Twitter
Published on November 01, 2023 02:40