Python for AutoCAD (pyautocad module)

In this post I want to introduce a module available in Python for automatizing the creation of drawings in AutoCAD. The module is called pyautocad. It is supported by pip install for easy installation. The pyautocad module will also allow you to adjust existing drawings, by e.g. manipulating objects in the drawing.

In a previous post I have already introduced AutoCAD basics and various AutoCAD commands. For example I have introduced AutoCAD LINE, AutoCAD MLINE, AutoCAD PLINE, AutoCAD XLINE, AutoCAD CIRCLE, AutoCAD RECTANG, AutoCAD OFFSET and many more. A full overview is provided under the AutoCAD tab of this blog, or as part of my AutoCAD tutorials.

pyautocad recognizes the AutoCAD drawing currently open and it also recognizes the currently active model space. Before running the Python code below I therefore open a new AutoCAD drawing.

I then import pyautocad. I create an AutoCAD instance using pyautocad.

# importing pyautocad
import pyautocad
# creating AutoCAD instance
acad = pyautocad.Autocad()

Let us check that the module really recognizes the currently active AutoCAD drawing:

# print name of document currently recognized as being active in AutoCAD
print(acad.doc.Name)
Drawing1.dwg

Next, I can e.g. create a circle in 2D plane. In other posts we also demonstrate how to add pyautocad polylines, pyautocad arcs, a pyautocad ellipse, pyautocad splines, pyautocad helices, pyautocad texts and pyautocad solid objects. We also wrote posts demonstrating e.g. polar arrays in pyautocad and rectangular arrays in pyautocad.

# specify x and y coordinates of circle center point
from pyautocad import APoint
point1 = APoint(100.0,100.0) # x and y coordinates of points
# add circle to drawing
circle1 = acad.model.AddCircle(point1,100)

The following circle has been added to my AutoCAD drawing:

The change in color of the circle is possible with pyautocad too. I do so in the code below:

# change color of circle to red
circle1.Color = 10 # 10 is a red color

The result in my drawing when executing the Python code looks like this:

The color index numbers can be found in AutoCAD. See screenshot below.

I can also check other current property values for the circle I just added to the drawing. Below are some examples:

# check layer assignment
print("current layer: "  + str(circle1.Layer))
# check current linetype
print("current linetype: " + str(circle1.Linetype))
# check linetype scale
print("current linetype scale: " + str(circle1.LinetypeScale))
# check current line weight
print("current line weight: " + str(circle1.Lineweight))
# check current thickness
print("current thickness: " + str(circle1.Thickness))
# check current material
print("current material:" + str(circle1.Material))
current layer: 0
current linetype: ByLayer
current linetype scale: 1.0
current line weight: -1
current thickness: 0.0
current material:ByLayer

I can use the AutoCAD PROPERTIES command in AutoCAD to get an understanding of the property attrbitutes that an object can have:

I can use the property attributes of e.g. the circle object to make adjustments. For example I have the layer “circles” which I want to assign the circle to. I can do this using pyautocad:

circle1.Layer = "circles"

I could now also adjust the color setting for the circle object, such that the color is specified by the layer – the index for this is the color index number 256:

circle1.Color = 256

Below you see the result in AutoCAD:

I now create two additional circles inside my drawing, using pyautocad. Afterwards I use pyautocad iter_objects method to loop through all objects in the drawing, demonstrating the option of doing so if needed:

# adding two circles to drawing
circle2 = acad.model.AddCircle(APoint(200.0,200.0),100)
circle3 = acad.model.AddCircle(APoint(300.0,300.0),100)
# looping through all objects
for obj in acad.iter_objects():
    print(obj)
<POINTER(IAcadCircle) ptr=0x223f8ed65f8 at 223faa5c848>
<POINTER(IAcadCircle) ptr=0x223f8ed6358 at 223faa5ca48>
<POINTER(IAcadCircle) ptr=0x223f89ede28 at 223faa5c148>

This is what the result looks like in my AutoCAD drawing:

This completes my introduction to working with AutoCAD in Python, using pyautocad. To get a better understanding of AutoCAD I refer to my other AutoCAD trainings and recommend checking the pyautocad documentation.

In other posts we also demonstrate how to implement and execute operations in pyautocad, as well as we e.g. demonstrate how to mirror objects in pyautocad.

Links to related AutoCAD automatization content

If you want to learn more about AutoCAD automatization with Python then I suggest you have a look at some of our other pyautocad and pywin32 related articles. Here is a list with some of them:

You May Also Like

Leave a Reply

57 comments

Waleed says:

Hi Mr. Felkl

Thank you for this, very useful content. I wanted to ask if there is a way to read .dwg file in python completely without having autoCAD in my machine to start with?

For example if its possible to read entire content of a .dwg file using python and print it on the console?

Thank you!

Good question. I don`t know at the moment. Hope someone will join the discussion and answer your comment 🙂

franz says:

puedes manipular con ezdxf excelente biblioteca de python es un formato que puedes exportar en distintos software

Thank you for suggesting the ezdxf module. This is a completely different module which we will look into. We will cover it on this blog.

Javier Vidal says:

Hi Mr. Felk!

What a great post!
I have a doubt… how can I delete everything in the model with pyautocad, could you help me with that?

Thx in advance!

Hello Mr. Vidal,

Nice question. We can use the delete command over every object we receive by using the iter_objects function. e.g.

from pyautocad import Autocad:
acad = Autocad(create_if_not_exists=True)
for object in acad.iter_objects():
object.Delete()

Very sorry for the delay in reply to your comment.

Have a nice day, thank you.

Tanmay Sawant says:

Hi Mr. Felkl,

Can you please tell me where can I get a full-fledged course to learn the complete usage of pyautocad ?

There are some shorter courses out there but currently, I cannot come up with a recommendation. I am working on a more extensive series of use case examples on this blog myself.

Alex Papageorgiou says:

Hello,
when I try to run the first command to print the name of the document I get a traceback error:
OSError: [WinError -2147221005] Invalid class string

any idea why this is happening?

Hello Mr Papageorgiou,

Thank you for the question.
It is because the default permissions of the document are not allowing pyautocad to access information from the document. Please try changing the permissions of the documents or try running python IDE as administrator.

Have a great day!

erle says:

hello,

i get the same error, did you manage to find a solution ?

thank you.

Erle, any feedback from you?

For project specific advice and need for coaching please contact us and donate a consulting fee

Patrick J. Phillips says:

Mr. Falkl,

Most of you code works great for me; however, I can’t get the Copy() and Move() methods to work. Might I ask about your programming environment? What version of Python are you using? What version of pyautocad? What version of AutoCAD?

My error is in comtypes\client\lazybind.py and it is an AttributeError on Copy, and/or Move.

Dear Mr. Phillips,

Thank you for your question. This was with Python 3.5, AutoCAD 2020. The pyautocad version must have been up to date in October 2020. I do not remember what pyautocad version it was back then.

I have seen that you contacted Mr. Sawant. He is building the pyautocad documentation on this blog for now, and he will get back to you with a response.

Thank you and have a good day.

Patrick J. Phillips says:

Linnart;

Thanks for the reply. I’ve tried with Python 2.7 and Python 3.8. I’ve loaded the pyautocad module using pip in each instance of Python that I’m running. I too am using AutoCAD 2020.

As I mentioned earlier, I can access most properties of the circle; however, I can’t access the “Move” method. The error I get is as follows:

Traceback (most recent call last):
File “”, line 1, in
c2 = c1.Move(APoint(100,100),APoint(150,200))
File “C:\Python27\StandAlone\lib\site-packages\comtypes\client\lazybind.py”, line 163, in __getattr__
raise AttributeError(name)
AttributeError: Move

Of course it is different under Python 3.8 as there it references the “comtypes” package under 3.8. But other than that… same error.

Hi Mr. Phillips,

Thanks for your question. There must be a python version-related issue. As you said, higher versions of python referes to the “comtypes” package, we can try importing com packages in the lower versions where the move command is not working. Please try the below mentioned script:

import win32com.client
import pythoncom

acad = win32com.client.Dispatch(“AutoCAD.Application”)
acadModel = acad.ActiveDocument.ModelSpace

def APoint(x, y, z = 0):
return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, (x, y, z))

p1 = APoint(100, 100)
c1 = acadModel.AddCircle(p1, 100)

c2 = c1.Move(p1, APoint(200,200))

Have a great day!

Patrick J. Phillips says:

Mr. Sawant,

Under Python 3.8.1 I get a “ModuleNotFoundError”:
Traceback (most recent call last):
File “”, line 1, in
import win32com.client
ModuleNotFoundError: No module named ‘win32com’

And under Python 2.7.14 I get a similar error:
Traceback (most recent call last):
File “”, line 1, in
import win32com.client
ImportError: No module named win32com.client

Each “pyautocad” install has included a “comtypes” module along with “pyautocad.” Does the “comtypes” module make calls to “win32com.client?” If this is a dependency, why does it not get installed when using “pip?”

BTW the installed version of “comtypes” that came with the “pyautocad” pip install is “1.1.10”

Hi Mr. Phillips,

Since there is no package named win32com, it is showing the error as:
“ImportError: No module named win32com.client”

Please try installing win32com.client using the below-mentioned command and package name as pywin32:
pip install pywin32

Thank you

Patrick,

I forwarded your question to Tanmay Sawant and I can see he answered you. Tanmay is building a documentation for our blog here, and he is going to be expanding this documentation over the upcoming months.

Patrick J. Phillips says:

Thank You Tanmay,

I don’t fully understand, but I expect pyautocad was not fully hooking into the AutoCAD application and/or its API. So with the “pywin32” module, or wrapper, we forced a better connection to the AutoCAD application object. Is that a fair assessment?

Respectfully,

Patrick

P.S. Linnart, Thanks for maintaining interest in the subject and forwarding my early query to Mr. Sawant

Most welcome Mr Phillips.

Yes actually.
As I said earlier, the problem must be with internal communication of python with AutoCAD. While communicating with any other application in a windows system with python, we use win32com.client, whether it is AutoCAD, excel or any other application. In previous versions of python, it must be like we have to specify the communication API by importing com libraries. But in the latest versions pyautocad module itself takes care of communication between python and AutoCAD.

Hope the given script worked for you, to move the objects.

Thank you

Patrick J. Phillips says:

Mr. Sawant,

Yes, the most recent script worked using win32com.client. And I’m thankful for that. What I don’t understand is your statement that “in the latest versions pyautocad module itself takes care of communication between python and AutoCAD.” And I don’t understand it because I thought I was using the latest version of pyautocad (0.2.0?) and though I was able to use the properties (Layer, Color, Thickness, etc.) I was not able to use the Move() method. If I have the latest version of pyautocad, why did it only half way work? If I don’t have the latest version, how do I acquire the latest version? Shouldn’t the latest version have been installed when I asked pip to install it?

Please know that I am not complaining. I am making an effort to understand pyautocad, its installation and use. I also hope that others learn from my questions and your polite answers.

Thanks again for your time and effort.

Respectfully,

Patrick

Hello Mr. Phillips,

Yes, the pyautocad version that you installed has to be the latest version i.e. 0.2.0. What I wanted to say is, it might be because the python version on which you have installed the pyautocad module is an older version of python. I do understand your question that why only the Move() method is not working and others are. But as per the experience I have till now, even I have faced such issues while working with certain commands, and I am also finding solutions to those issues and I look forward to posting the solutions for those as soon as I find them.

Also, I am very thankful to you for asking questions, as this will build a strong foundation for those who really want to learn pyautocad. Your questions or opinions may also help others understand this in a much better way. 🙂

Have a nice day!

Patrick J. Phillips says:

Hello Mr. Sawant,

I appreciate all your efforts so far and look forward to reading more of your articles in the near future.

Enjoy your work and leave time for play!

Mr. Phillips,

was your problem solved? Otherwise let us know so that we can collect open issues related to this module here on this blog 🙂

Kind regards,

Linnart Felkl

Patrick J. Phillips says:

Yes and no. No, I can’t get “pyautocad” to work properly. I have always used the latest version, so that is not it. As for Python itself, I can’t get it to work properly with python 2.7 or python 3.8. Neither case works as it should. I can access many, but not all, properties but few methods. The issue seems to be with “COM” objects, but to what extent I don’t know.

Mr. Sawant did demonstrate that If I use win32com objects through the “pywin32” module, I can access the “move” method of an AutoCAD Circle object. But I don’t know the full win32com object model and was hoping to use “pyautocad” as it has a shallower learning curve.

Hello Mr. Phillips,

Thanks for your reply. I think we can solve your problem if we get access to your system once, to check whether there is a module path-related error or is that a template referencing error that is fetching such issues. As that would be a paid session with a nominal fee, if you are interested, you can schedule an appointment with us by sending an email via the contact us page on our website.

Have a great day!

Hello Mr. Cris,

Thanks for your question. Maybe it is possible with comtypes (pywin32) module in python, if the object model of Fabrication is available online.
Since pyautocad is AutoCAD specific, I cant be sure whether it would work with Fabrication, but I can say that the way we integrate python using pywin32 with AutoCAD should be similar to that with Fabrication.

Kind regards,
Tanmay

Giridhar N V says:

Hi ,
How do I get the position (co-ordinates) of each object after I iter through a block or model space?
I am able to get the position of text using InsertionPoint property. Is there something similar I could use for objects or object points?
Thank You

Ben T says:

Is it possible to extract the geometry data (Position X, Position Y etc) in the same fashion as the color, layer etc.? I am trying to use the same method to no luck, presumably because there is a space in all of those attribute names.

Hi Ben,

Thanks for your question, yes you can find such geometrical attributes of any entity present on the model space depending on the type of geometry. You can go through our other blogs on pyautocad and pywin32 to check which methods shall be used to extract what data.

Have a great day!

Ramesh says:

Hello Ben T

I am also working in the same line, did you get any answer for this problem?

We can help you get acces to all attributes on the model space. Send us your problem and budget that you have available to spend on it. Thanks

Michael B says:

Hi Mr. Linnart Felkl M.Sc. and Mr. Tanmay Sawant,

Is there a way for me to get the Autocad Command-Line output in python for example for the command “TIME” or “EDITTIME”. I’m trying to see how much time was spent on a drawing and have a list of over 500 drawings and would like to automate that process.

Thank you!

Tanmay Sawant says:

Hello Michael,

Thanks for the question.

While iterating through different drawings to run your programme you can use the time module by python to calculate time spent on each programme.

e. g.
import time
start_time = time. time()

print(“%s seconds :” %(time.time() – start_time))

This will fetch the time spent by your programme in seconds. You can explore more on time module for other time formats to use in your programme.

Have a great day!

Ehsan says:

Hi
How to import a point by pick a point in cad draw?

Ehsan,

we can write a code for this for you. If you are interested please contact us via the contact form with more details and send us the drawing. We will then give you a price (might be as low as 20 or 50 USD, but could also be more depending on your more elaborate problem description). In any case, we cannot answer all questions for free as we too have to buy eggs, milk, bread, gasoline 🙂 Cheers

Amir says:

Hello Mr Linnart Felkl

When I use iter_objects function the objects returned are in Pointer type

and I need them to be in Dispatch object

How can I access to the Dispatch object when using iter_objects function

With gratitude

sassi hamid says:

from pyautocad import Autocad, APoint, ACAD, aDouble
from pyautocad import utils
from pyautocad.contrib.tables import Table
import array
import comtypes.client
#———————————————————————–
acad = Autocad(create_if_not_exists=True)
acad = comtypes.client.GetActiveObject(“AutoCAD.Application”)
doc = acad.ActiveDocument
ms = doc.ModelSpace

#——————————————————————
mylayer=”L_test”
layer1 = doc.Layers.Add(mylayer)
layer1.Color = 140 # blue
layer1.LayerOn = True
#——————————-dessine un pt———————————–
pt0=APoint(21.15,27.12,0)
point = ms.AddPoint(pt0)
point.Layer=mylayer
#—————————–dessine une ligne————————————-
pt1=APoint(25.15,22.12,0)
pt2=APoint(37.27,38.38,0)
line = ms.AddLine(pt1, pt2) #
line.Layer=mylayer
#——————————————————————
acad.ZoomExtents()
#——————————————————————
# Select an item
returnObj = doc.Utility.GetEntity(“Select Object:”)
#——————————————————————
entity_name=returnObj[0].EntityName
Entity_Type=returnObj[0].EntityType
entity_layer=returnObj[0].Layer
entity_handle=returnObj[0].Handle
#——————————————————————
if Entity_Type == 22: # cas point
print( “*” *45)
print(“c’est un point”)
entity_coord=returnObj[0].Coordinates
print(“coordonnees =”,entity_coord)
returnObj[0].color=50 #jaune clair
returnObj[0].Layer=mylayer
#——————————————————————
elif Entity_Type == 19: # cas ligne
print( “*” *45)
print(“c’est une ligne”)
entity_length=returnObj[0].Length
print( “Longueur de l’objet=”,entity_length)
entity_startpt=returnObj[0].StartPoint
print(“start point =”,entity_startpt)
entity_endpt=returnObj[0].EndPoint
print(“end point =”,entity_endpt)
returnObj[0].color=50 #jaune clair
returnObj[0].Layer=mylayer

# #————————-my question————–

# # how to use ?#

# returnpt = ms.AddPoint(“Pick point on the screen:”)
# print (” returnpt: “, returnpt.coordinates) # repertoire du fichier dessin

# # or

# returnpt = ms.GetCorner(“Pick point on the screen:”)
# print (” returnpt: “, returnpt.coordinates) # repertoire du fichier dessin

# #——————————————————————

sassi hamid says:

Thanks i have found it:

pt0=APoint(0,0,0)
#——————————————————————
try:
point1 = doc.Utility.GetPoint(pt0,”Select your first point :”)
x1,y1,z1=point1[0],point1[1],point1[2]
print(f”mon 1er point: x= {x1} y= {y1} z= {z1}”)

pt1=APoint(x1,y1,z1)
point2 = doc.Utility.GetCorner(pt1,”Select your second point :”)
x2,y2,z2=point2[0],point2[1],point2[2]
print(f”mon 2eme point: x= {x2} y= {y2} z= {z2}”)

except:
messagebox.showwarning(“”,”Selectionnez les 2 points sur ecran svp”)

Arend says:

Would this also work with AutoCAD LT? Right now i get the following error: OSError: [WinError -2147221005] Invalid class string.

Matt says:

I have been able to get pyautocad to draw lines in AutoCAD. I would also like to be able to draw lines from Python in IntelliCAD. Does anyone have any idea how to do this or know if it is possible?

pyautocad is for AutoCAD, so it will not work for IntelliCAD.

You can try this and see if it works for IntellicCAD

import ezdxf
doc = ezdxf.new(dxfversion=’R2010′)
msp = doc.modelspace()
msp.add_line((0, 0), (1, 1))
doc.saveas(‘test.dxf’)

naddaf says:

i tried the following simple code
import pyautocad
acad = pyautocad.Autocad()

print(acad.doc.Name)
and it always gives me error
SyntaxError: multiple exception types must be parenthesized

T-Br says:

Thanks for the nice and well organized lecture. Can you help please on how to draw Leader line. Thank you

Martin says:

I’m trying to insert from an external document a dynamic bloc in an Autocad file.
I used InsertBlock and the bloc is well inserted.
However, it becomes a simple drawing loosing all the properties that were designed with this block and I can’t find a way to keep them.
I’ve went through pyautocad but I can’t find anything to help me
Do you have any idea on how I could do that ?

Thank you very much

Seungkyu Yang says:

Hi, thank you for you postings on pyautocad. It helped a lot.

I have questions about where to find out more functions and properties of Class pyautocad.Autocad(). You are using lots of properties or functions, like, acad.doc.Blocks.Add() or acad.model.AddBox(). But I can not find any properties or functions defined under pyautocad.Autocad().model or pyautocad.Autocad().doc in pyautocad official document or module source code.

Could you give me any website or document to figure it out? Personally I’m guessing it might be using the VB Code after pyautocad.Autocad() is called. If it is, also suggest me any document to refer to.

Thank you.

Orlando Taddeo says:

Hi,

thank you for your effort in developing such a Python module!!

I have an issue tha t I believe is related to comtypes not being able to connect to the AutoCAD instance running on my PC.
I just tried this simple code:

“””
from pyautocad import Autocad

acad = Autocad()
print (acad.ActiveDocument.Name)
“””

I get the following error:

“””
print (acad.ActiveDocument.Name)
Traceback (most recent call last):

File “C:\Users\orlan\AppData\Local\Temp\ipykernel_6604\781730298.py”, line 1, in
print (acad.ActiveDocument.Name)

File “C:\ProgramData\Anaconda3\lib\site-packages\pyautocad\api.py”, line 74, in doc
return self.app.ActiveDocument

File “C:\ProgramData\Anaconda3\lib\site-packages\pyautocad\api.py”, line 63, in app
self._app = comtypes.client.GetActiveObject(‘AutoCAD.Application’, dynamic=True)

File “C:\ProgramData\Anaconda3\lib\site-packages\comtypes\client\__init__.py”, line 180, in GetActiveObject
obj = comtypes.GetActiveObject(clsid, interface=interface)

File “C:\ProgramData\Anaconda3\lib\site-packages\comtypes\__init__.py”, line 1239, in GetActiveObject
oledll.oleaut32.GetActiveObject(byref(clsid), None, byref(p))

File “_ctypes/callproc.c”, line 997, in GetResult

OSError: [WinError -2147221021] Operazione non disponibile
“””
Tne line at the end “Operazione non disponibile” is in Italian, and unfortunately I don’t know the respective error message in English. It can be translated as “operation not available”.

Is there any way I can make it work?

Thank you very much in advance!

Federico says:

Hi, is it possible to use python with AutoCAD Electrical? I want to create a new project and new drawings (e.g. 20 pages electrical design) automatically, so I don’t have to create one by one
Thanks

Jim says:

Hi, I’d like to know if it is possible to select objects through pyautocad for using commands like FILLET. I can send the FILLET command to autocad via the acad.ActiveDocument.SendCommand() method, but I am unable to select the objects that I need to fillet through pyautocad. It asks me to select the objects on the AutoCAD interface. Any ideas?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.