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 distutils
instead of setuptools
, however, distutils
is 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.py
script.
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
- SetupTools – Build Extension Modules