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:
- Link: Dimaligned object in AutoCAD using Python
- Link: AutoCAD attribute object in Python
- Link: AutoCAD block object in Python
- Link: AutoCAD document object inpyautocad
- Link: AutoCAD application object class in Python
- Link: addextrudedsolidalongpath in AutoCAD
- Link: Region object in AutoCAD with Python
- Link: add method in pyautocad
- Link: Solved “call was rejected by callee” in pythoncom
- Link: Tree data structure for AutoCAD objects using Python
- Link: Extending the objects in AutoCAD using pyautocad in Python
- Link: Operations with intersecting objects in AutoCAD using pyautocad in Python
- Link: Using Python lists and dictionaries to work with AutoCAD objects with pyautocad
- Link: Raster image object in AutoCAD with pyautocad in Python
- Link: Hatching objects in AutoCAD template using pywin32 in Python
- Link: Working with 3D mesh object in AutoCAD using pyautocad in Python
- Link: Creating adouble constructor using pywin32 in Python
- Link: Python integration with AutoCAD using pywin32 (win32com)
- Link: Deleting objects in a AutoCAD template with pyautocad and pywin32 in Python
- Link: Working with texts in AutoCAD using pyautocad in Python
- Link: Mirror object on a 2D plane with pyautocad in Python
- Link: Rectangular arrays in AutoCAD using pyautocad in Python
- Link: Operations with autocad objects using pyautocad in Python
- Link: Solid objects in AutoCAD using pyautocad in Python
- Link: Working with helices in AutoCAD using pyautocad in Python
- Link: Drawing splines in AutoCAD with pyautocad in Python
- Link: Drawing ellipse and ellipse arcs in AutoCAD using pyautocad in Python
- Link: Drawing arcs in AutoCAD using pyautocad
- Link: Polylines in pyautocad for drawing AutoCAD polygons
- Link: Near-simultaneous factory design and process optimization with ProModel AutoCAD edition
- Link: The pyautocad module
Data scientist focusing on simulation, optimization and modeling in R, SQL, VBA and Python
57 comments
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 🙂
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.
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.
Hi Mr. Vidal,
Tanmay Sawant published a post covering the deletion of objects: https://www.supplychaindataanalytics.com/deleting-objects-in-a-autocad-template-with-pyautocad-pywin32-python/
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.
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!
hello,
i get the same error, did you manage to find a solution ?
thank you.
Erle, did you do as Tanmay told you to?
Hi,
Please try this code:
print(acad.ActiveDocument.Name)
Thank you
Erle, any feedback from you?
For project specific advice and need for coaching please contact us and donate a consulting fee
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.
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!
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.
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
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!
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!
Thank you Mr. Phillips.
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
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!
I would like to manipulate objects of these CID’s using pyautocad:
https://knowledge.autodesk.com/support/fabrication-products/learn-explore/caas/CloudHelp/cloudhelp/2018/ENU/Fabrication-UsersGuide/files/GUID-86F864BB-A9A8-4AF1-8CC7-1C80803E4159-htm.html
Is it possible?
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
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
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!
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
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!
Working on a reply to this
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!
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
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
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
# #——————————————————————
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”)
Would this also work with AutoCAD LT? Right now i get the following error: OSError: [WinError -2147221005] Invalid class string.
AutoCAD LT does not support the AutoCAD COM API that pyautocad relies on
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’)
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
Thanks for the nice and well organized lecture. Can you help please on how to draw Leader line. Thank you
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
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.
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!
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
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?