I use this code to ~randomly place a grid of sample plots for forest inventory:

<!-- language: lang-py -->

    import numpy as np
    from itertools import product
    
    polylayer = iface.activeLayer() #Highlight polygon layer in layer tree
    npoints = 8
    
    pointlayer = QgsVectorLayer('Point?crs=epsg:3006', 'point' , 'memory') #Change
    prov = pointlayer.dataProvider()
    
    for poly in polylayer.getFeatures():
        geom = poly.geometry()
        bbox = poly.geometry().boundingBox()
        xmin, xmax, ymin, ymax = bbox.xMinimum(),bbox.xMaximum(),bbox.yMinimum(),bbox.yMaximum()
        success = 0
        while success == 0:
            featlist = []
            spacing = ((geom.area()/npoints)**0.5)*np.random.uniform(0.7,1.3) #Adjust random range
            nspacesx = np.ceil((xmax-xmin)/spacing)
            nspacesy = np.ceil((ymax-ymin)/spacing)
            randomstart = [xmin-spacing*np.random.random(),ymin-spacing*np.random.random()]
            xlist=[randomstart[0]+(x*spacing) for x in range(int(nspacesx)+1)]
            ylist=[randomstart[1]+(y*spacing) for y in range(int(nspacesy)+1)]
            for x,y in product(xlist,ylist):
                feat = QgsFeature()
                feat.setGeometry(QgsPoint(x,y))
                featlist.append(feat)
            points_inside = [1 if f.geometry().intersects(geom.buffer(-5,10)) else 0 for f in featlist] #I use negative buffer to prevent points to end up near polygon edge. You need to adjust -5 m or remove the buffering.
            #print(sum(points_inside))
            if sum(points_inside)==npoints:
                featlist = [p for p,i in zip(featlist, points_inside) if i==1]
                prov.addFeatures(featlist)
                success = 1
    
    QgsProject.instance().addMapLayer(pointlayer)

[![enter image description here][1]][1]


  [1]: https://i.sstatic.net/lG7lK.png