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:

  • setuptools
  • Cython

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!

Links