AutoCAD Block object in Python

In this article I elaborate on Block objects in AutoCAD and how working with them can be automatized using Python.

Although for this practical example I am using the pyautocad library I can also use pythoncom. I have explained how to use communication modules in Python in previous blog posts. More precisely, I am specifically referring to pythoncom and win32com.

Creating AutoCAD Block objects in Python

Firstly, let me explain why AutoCAD Block objects are so significant.

Whenever I want to use certain objects repeatedly, I create a block for those objects. That one block object can contain multiple other objects with e.g. different geometries, attributes, etc.

Once I create a AutoCAD Block object with the pyautocad module in Python, it gets saved in the Document database. I have explained how this Document object works in one of my previous articles.

I can save multiple AutoCAD Block objects in the Document database. Likewise, I can do the same for Blocks collectively in the form of a Blocks Collection object.

Creating instances with InsertBlock()-method in pyautocad

Now that I have created blocks I want to use them in my drawing. This is when I use the InsertBlock method. This method creates an AutoCAD Block object instance for the block that I pass as an input parameter value.

The Block that is present in my drawing by now is known as the BlockReference object.

Let me write the code to explain this considering all the things above.

from pyautocad import Autocad, APoint, aDouble
acad = Autocad(create_if_not_exists=True)

# flow
# Document > BlocksCollection > Block > BlockReference

# insertion point for block
ip = APoint(0, 0, 0)

# adding block to documents block collection
b1 = acad.doc.Blocks.Add(ip, "Test_block_1")

# adding geometries to block
pl = b1.AddPolyline(aDouble(0, 0, 0, 10000, 0, 0, 10000, 5000, 0, 0, 5000, 0, 0, 0, 0))
l = b1.AddLine(APoint(0, 250, 0), APoint(10000, 250, 0))

# adding block instance to drawing (creating a reference to the block)
block_ref1 = acad.model.InsertBlock(APoint(50, 50, 0), "Test_block_1", 1, 1, 1, 0)
Block Reference object created using Block from Block Collections

AutoCAD Block and BlockReference object properties

As I have now created both AutoCAD Block and AutoCAD BlockReference objects I will now walk you through the various different properties of these two object types.

Firstly, let me talk about some of the important properties of the AutoCAD Block object. While using blocks I have different requirements. For example, I have to decide whether or not my block has to be explodable, whether it should be dynamic or static, and whether I want to keep it flexible to scale or not, etc.

Below is the code showing how I can use all such properties using the pyautocad module in Python.

# properties

print("Object Name: " + b1.ObjectName)
print("Name of Block: " + b1.Name)
print("Native units of measures for the Block: ", end="")
print("Is scaling allowed for the Block ? ", end="")
print("Is the Block explodable ? ", end="")
print("Is the Block dynamic ? ", end="")


Object Name: AcDbBlockTableRecord
Name of Block: Test_block_1
Native units of measures for the Block: 0
Is scaling allowed for the Block ? 0
Is the Block explodable ? True
Is the Block dynamic ? False

In above code the BlockScaling property is returning a “0”. This represents a type of scaling from the list of types given below:

  • acAny: 0
  • acUniform: 1

On the other hand, I have BlockReference properties. Check the code displayed below.

# properties of BlockReference
print("Object Name: " + block_ref1.ObjectName)
print("Block Name: " + block_ref1.Name)
print("Original Block Name: " + block_ref1.EffectiveName)

print("Entity Transparency: ", end="")

print("Does the Block contain any Attributes: ", end="")

print("Insertion Point: ", end="")

print("Insert units saved with Blocks: ", end="")

print("Conversion factor between Block units and drawing units: ", end="")

print("Is the Block dynamic ? ", end="")

print("Layer: " + block_ref1.Layer)

print("Line type: " + block_ref1.Linetype)

print("Line type scale: ")

print("Line weight: ")

print("Rotation angle for the block: ")

#Scale factors
print("X Scale factor of block: ", end="")

print("X Scale factor for block or external reference (xref): ", end="")

print("Y Scale factor of block: ", end="")

print("Y Scale factor for block or external reference (xref): ", end="")

print("Z Scale factor of block: ", end="")

print("Z Scale factor for block or external reference (xref): ", end="")


Object Name: AcDbBlockReference
Block Name: Test_block_1
Original Block Name: Test_block_1
Entity Transparency: ByLayer
Does the Block contain any Attributes: False
Insertion Point: (50.0, 50.0, 0.0)
Insert units saved with Blocks: Unitless
Conversion factor between Block units and drawing units: 1.0
Is the Block dynamic ? False
Layer: 0
Line type: ByLayer
Line type scale:
Line weight: 
Rotation angle for the block:
X Scale factor of block: 1.0
X Scale factor for block or external reference (xref): 1.0
Y Scale factor of block: 1.0
Y Scale factor for block or external reference (xref): 1.0
Z Scale factor of block: 1.0
Z Scale factor for block or external reference (xref): 1.0

Block (Reference) methods in AutoCAD using Python

This section is just to introduce two of the important methods for Block objects:

  • InsertBlock
  • Delete

As I have already mentioned in the first section I need the BlockCollections object from Document (object/database) in order to be able to insert a Block.

acad.doc.Blocks.Add(Insertion point, Block name)

To delete a AutoCAD Block object I can simply take the respective AutoCAD Block instance and apply the Delete method on the same.


Coming to the BlockReference object there are a few methods I have to mention:

  • ConvertToAnonymousBlock
  • ConvertToStaticBlock
  • GetConstantAttributes
  • GetDynamicBlockProperties
  • ResetBlock

The ConvertToAnonymousBlock method converts a Dynamic block to Anonymous Block.


On the other hand, the ConvertToStaticBlock method converts a Dynamic block to a named block. This takes a name as a parameter.


To fetch the constant attributes from a Block or external reference I can use the GetConstantAttributes method. This method returns an array of AutoCAD Attribute objects that are constant for the BlockReference object.


Also, If I want to fetch an array of dynamic properties assigned to a block I can use the following code:


Lastly, to reset any dynamic block to the default state I can use the ResetBlock method.


Besides that, the BlockReference object has all those same methods available as I use with any other AutoCAD objects such as Line, Layer, Circle, Raster, etc. Some of those important methods are listed below:

  • ArrayPolar
  • ArrayRectangular
  • Copy
  • Delete
  • GetBoundingBox
  • IntersectWith
  • Mirror
  • Mirror3D
  • Move
  • Rotate
  • Rotate3D
  • ScaleEntity
  • Update
  • UpdateMTextAttribute

Do check out my previous blog posts to understand how to implement those methods.

Example of an AutoCAD Attributed Block

Coming to an end, I would like to share an example of an Attributed Block. An attributed block is the one containing different attributes which further contains metadata of that Block or entities inside the same.

I will explain more about the Attribute objects and the AttributeReference objects separately in the future.

from pyautocad import Autocad, APoint, aDouble

acad = Autocad(create_if_not_exists=True)

ip = APoint(0, 0, 0)
b1 = acad.doc.Blocks.Add(ip, "Attributed_Block_1")

pl = b1.AddPolyline(aDouble(0, 0, 0, 10000, 0, 0, 10000, 5000, 0, 0, 5000, 0, 0, 0, 0))
l = b1.AddLine(APoint(0, 250, 0), APoint(10000, 250, 0))
l = b1.AddLine(APoint(5000, 250, 0), APoint(5000, 0, 0))

a1 = b1.AddAttribute(50, 0, "DATE", aDouble(200, 100, 0), "DATE", "Date: 17/07/2022")
a2 = b1.AddAttribute(50, 0, "DWG", aDouble(5200, 100, 0), "DWG", "Drawing Name: Drawing 1")

br = acad.model.InsertBlock(APoint(50, 50, 0), "Attributed_Block_1", 1, 1, 1, 0)
AutoCAD Block, enhanced attribute editor

Evidently, as it contains attributes if I use the HasAttribute property method for this Block reference, I will get a True value.

print("Does the Block contain any Attributes: ", end="")

Does the Block contain any Attributes: True

Concluding remarks

To sum up, I can conclude that using the above methods I can automatize different tasks related to AutoCAD Block and AutoCAD BlockReference objects.

Also, in case of any queries do leave your question in the comment section below. As well as you can contact me using our contact form for any kind of technical consultation. Please check out my other articles for understanding the usage and significance of the pyautocad and pywin32 Python modules.

References to related content

I, together with other SCDA members, have built a series of blog posts documenting AutoCAD, pyautocad and pywin32 for AutoCAD automatization with Python. Here is a list of some related content:

You May Also Like

Leave a Reply


Sam says:

Hey Tanmay,
Thank You for various use cases with Blocks.
However, I am struggling to get geometric extents of block (i.e title block) in python console.
Is there anyway to get minpoint and maxpoint of the block object?
I tired using AcDbBlockReference but it’s throwing unknown attribute error.
Thank You.

see below example

import win32com.client
acad = win32com.client.Dispatch(“AutoCAD.Application”)
doc = acad.ActiveDocument
mspace = doc.ModelSpace
block_ref = mspace.InsertBlock(point, block_name, 1.0, 1.0, 1.0, 0.0)
bbox = block_ref.BoundingBox
min_point = bbox[0]
max_point = bbox[1]

David Long says:

Hello Tanmay,

This is the issue that I am running into. I have a drawing that has several values saved as Parameters. I would like to have the python script write to that document and change that specific parameter. In that same document I have a text box where I would like to change the text according to a python script.

import win32com.client
acad = win32com.client.Dispatch(“AutoCAD.Application”)
doc = acad.ActiveDocument
named_objs = doc.NamedObjects
param_name = “MyParam”
param = named_objs.Item(param_name)
param.Value = 42
text_name = “MyText”
text_obj = named_objs.Item(text_name)
text_obj.TextString = “Hello, world!”

TAIEB says:

Hello Thank you for Tutorial,
It s possible to introdus the point APoint() by mouse?
Thank You again

try something like this:
import pyautocad
acad = pyautocad.Autocad()
point = acad.doc.Utility.GetPoint()
circle = acad.model.AddCircle(point, 10)

this should prompt you to select a point using your mouse

TAIEB says:

Thank you for your response, magic 🙂

Dmitry says:

Thank you for your work!
Please tell me how to change the parameter of the dynamic block?

Dmitry says:

Thank you for your work!
Please tell me where to look for information on my problem:
I have a dynamic block in the form of a frame with a table. I need to change this block in length (pull the frame to one side). I tried the scaling method when inserting a block, but the table inside the block is also stretched and this method is not suitable. There is a parameter “length” in the block properties. If this parameter is changed, then the block stretches as I need. How to do it using Python code?

does this work for you?

import win32com.client
import pythoncom
import time
acad = win32com.client.Dispatch(“AutoCAD.Application”)
def stretch_block(block_name, x_scale_factor, y_scale_factor, insertion_point):
doc = acad.ActiveDocument
ms = doc.ModelSpace
blk_def = doc.Database.BlockTableId.GetObject(acad.ActiveDocument.Database).GetBlockDefinitionNames()[block_name]
blk_ref = ms.InsertBlock(insertion_point, blk_def.Name, 1, 1, 1, 0)
blk_ref.ScaleFactors = (x_scale_factor, y_scale_factor, 1)
stretch_action = blk_ref.GetDynamicBlockProperties().GetAction(“Stretch”)
stretch_action.GetParameter(“X”).Value = x_scale_factor
stretch_action.GetParameter(“Y”).Value = y_scale_factor

# example application
stretch_block(“MyDynamicBlock”, 2, 2, (0, 0, 0))

Dmitry says:

Thank you, but this method is not suitable, because inside the block the table is drawn with lines (this is not an autocad table, it cannot have an ID). I tried to add the autocad table to my block. Returns the error “KeyError: (‘BlockTableId’, 3)”. I did it with the help of this construction:
acad1 = win32com.client.Dispatch(‘AutoCAD.Application’)
acad1.Visible = True
acadModel = acad1.ActiveDocument.ModelSpace
n = 10
for i in acadModel:
if i.IsDynamicBlock:
if i.EffectiveName == ‘Block_test’:
for p in i.GetDynamicBlockProperties():
if p.PropertyName == ‘quantity_columns’:
p.Value *= n
This method does not change the entire block, but only part of it with columns for information. Is it possible to simplify this method somehow? or maybe there is a solution that does not sort through the space of the autocad model in search of the right block?

Dmitry says:

Hello, please help! I have been struggling with the problem for 3 days.
I have a function that inserts the “Block_test” block into the autocad drawing. Then I look for this block in the space of the autocad model, find the properties of this block, change one of the properties to the value I need. Then I will transform this block into a static one. Up to this point, the code works fine. But as soon as I insert the same block again by shifting the Y coordinate, this block is no longer searched for as dynamic. The line of code “print(i.efficiename)” does not print the name of this block. Accordingly, it is not possible to edit this block. How can I solve this problem? Please help me!!!

boxes_list = [“Box1′, ‘Box2’]
cor_x = 0
cor_y = 0

def create_box_to_autocad(name_box, x, y):
block_table_box = acad.model.InsertBlock(APoint(x, y), ‘Block_test’, 1, 1, 1, 0) # Insert block_test
for i in acadModel:
if i.IsDynamicBlock:
if i.EffectiveName == “Block_test”:
for p in i.GetDynamicBlockProperties():
if p.PropertyName == ‘Length’:
p.Value *= 5
block_table_box.ConvertToStaticBlock(“static_Block_test-” + name_box)
for box in boxes_list:
create_box_to_autocad(box, cor_x, cor_y)
cor_y -= 350

Thank you for your question. Please remember that I am not the core developer or package owner. I run this blog for personal interest and commercial profit. We offer consulting against a fee and would love to help you. Just make inquiry via contact form. Alternatively will get back to your comment at earliest convenience. Thanks and have a nice day

Dmitry says:

I realised you! Anyway, thank you! While I was writing, there were some ideas to correct the error. If nothing works out, I’ll contact you for a paid consultation!

Prakash Kumar says:


I need your help regarding Inserting multiple blocks with the python scripts. can you help me

Deep Patel says:

Respected Sir,
I have created a number of blocks, and now I want to give them dimensions. Can you provide me with suggestions on that, please? Also, can you suggest resources to learn more about different methods that help me work with blocks?

Dmitry says:

Hello, please help me to translate this VBA code into python language:

Set blockRef = ThisDrawing.ModelSpase.InsertBlock(APoint(x, y), ‘Name_block’, 1, 1, 1, 0)
If blockRef.IsDynamicBlock = True Then
Props = blockRef.GetDynamicBlockProperties
For Index = LBound(Props) to UBound(Props)
Set prop = Props(Index)
If prop.PropertyName == ‘Length’ Then
prop.Value = 50

Zena says:


How do I add a block or external reference to paperspace? I have tried it multiple ways and can’t seem to get python to recognize paperspace.

Matu says:


Thanks for this article. It helped me a lot. However, I am looking for something I could not find anywhere on the net, so I give it a go there: does anyone know how to hatch a block through pyautocad or through pythoncom and win32com.client?

I am able to define a block in pyautocad, add polylines and text, but I can’t find the way to hatch it – I am able to hatch any closed area in the model space though , but not in the BlockEditor.

Yet, I think that such a way exists, because in AutoCAD, it is easy to create a block with hatches in it.

Any help would be really appreciated,



Halumglass says:

# Checking layer exist or not
def layerexist(lay):
layers = acadDoc.Layers
layers_nums = layers.Count
layers_names = [layers.Item(i).Name for i in range(layers_nums)] # List of ACAD layers
if lay in layers_names:
return True
return False
# Create polyline
def make_pline(pts, lay):
plineObj = acadModel.AddPolyline(vtFloat(pts))
if not layerexist(lay):
plineObj.Layer = lay
return plineObj
b1 = acadDoc.Blocks.Add(p3, “Test_block_1”)
# thanh bao ngang trên C3328=1.23
pontos1 = [p1x,p1y,0,p2x,p2y,0,p2x+A,p2y-A,0,p1x-A,p1y-A,0,p1x,p1y,0]
thanh1=make_pline(pontos1, “haaa”)
How to add object “thanh1” in to Block “b1”

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.