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.

Leave a Reply

50 thoughts on “Python for AutoCAD (pyautocad module)

  1. 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!

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

  2. 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!

    1. 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.

  3. Hi Mr. Felkl,

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

    1. 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.

  4. 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?

    1. 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!

  5. 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.

    1. 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.

      1. 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.

        1. 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!

          1. 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”

          2. 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

        2. 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.

          1. 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

          2. 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

  6. 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

    1. 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!

  7. 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!

    1. 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

      1. 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.

        1. 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!

  8. 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

  9. 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

  10. 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.

    1. 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!

  11. 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!

  12. 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!

    1. 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

  13. 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

  14. 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

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

  15. 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”)

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

  17. 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?

    1. 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’)

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.

Close

Meta