Instantiate COM object that doesn't have ProgID by class/interface name - python

pywin32 docs for client-side COM show this basic way to instantiate COM objects:
obj = win32com.client.Dispatch("<ProgID>")
I'm trying to work with PersistentZoneIdentifier akin to Manipulating the zone identifier to specify where a file was download from – The Old New Thing - MSDN blogs. That class, as the registry at HKEY_CLASSES_ROOT\CLSID\{0968e258-16c7-4dba-aa86-462dd61e31a3} shows, doesn't have a corresponding ProgID.
I see that there's an underlying pythoncom.CoCreateInstance function that accepts a CLSID to instantiate and an IID to apparently query from it.
But this is inconvenient because I have to use unintelligible GUIDs instead of human-readable names.
The question is:
Is there a stock way in pywin32/underlying WinAPI to look up the aforementioned GUIDs by names? (do not suggest searching the registry by hand)
Or maybe some other way to instantiate that object with names?
What I tried and failed: win32com.client.IDispatch(<class/interface name>), pythoncom.IID(<class/interface name>). Also looked through the Net, MSDN and PyWin32 docs, of course.

There is no, and can't be any, "stock mechanism" to instantiate a class/query an interface by its name because their names aren't guaranteed to be unique, unlike GUIDs.

Related

Azure python SDK: How to get a list of all Virtual Networks which contained in a Resource Group?

I am reletive new to Azure python SDK, and I have a basic question.
My goal is simple: Given a resource group name, I want create a variables list of
type List[VirtualNetwork] which are all the virtual networks in that resource group.
looking in this microsoft documentetion, the 'VirtualNetworksOperations' class have a 'list' method
which "Gets all virtual networks in a resource group."
The return type if this method is 'ItemPaged[VirtualNetworkListResult]'.
ItemPaged is some kind of iterator, so I can get a 'VirtualNetworkListResult' object from it.
According to this microsoft documentetion, it is not clear if the described parameters (which include the type List[VirtualNetwork]) are also the instance attribute or not.
If the answer is no, Is there any way to retrive what I want from that object?
Thank you
Regarding
The return type if this method is
ItemPaged[VirtualNetworkListResult]. ItemPaged is some kind of
iterator, so I can get a 'VirtualNetworkListResult' object from it.
According to this Microsoft documentation, it is not clear if the
described parameters (which include the type List[VirtualNetwork])
are also the instance attribute or not.
VirtualNetworksOperations.list operation indeed returns an iterator object where VirtualNetworkListResult conforms to an object type which only instructs Deserializer which type(model) response object gets deserialized into.
From usage perspective no extra work is needed to manipulate VirtualNetworkListResult, the following example demonstrates how to return list of VirtualNetwork instances:
vn_it = network_client.virtual_networks.list(res_name)
vn_list = list(vn_it)
Complete sample
credential = ClientSecretCredential(
tenant_id=tenant_id,
client_id=client_id,
client_secret=client_secret
)
network_client = NetworkManagementClient(
credential=credential,
subscription_id=subscription_id
)
vn_it = network_client.virtual_networks.list(res_name)
for vn in vn_it:
print(vn.name)

How do I update the status of an asset in VersionOne using the REST API

How can I update the status of an asset in V1 using the Rest API?
I would assume I could do something like this using the Python SDK:
from v1pysdk import V1Meta
v1 = V1Meta()
for s in (v1.PrimaryWorkitem
.filter("Number='D-01240'")):
s.StoryStatus = v1.StoryStatus(134)
v1.commit()
This is at least how I understand the Python SDK examples here:
https://github.com/versionone/VersionOne.SDK.Python
However this does not change anything, even though I have the rights to change the status.
Try using:
s.Status = v1.StoryStatus(134)
According to ~/meta.v1?xsl=api.xsl#PrimaryWorkitem The attribute on PrimaryWorkitem of type StoryStatus is named Status, so I think it's just a mistaken attribute name.
What's probably happening is that you're setting a new attribute on that python object, but since StoryStatus is not one of the setters that the SDK created from the instance schema metadata, it doesn't attempt to add it to the uncommitted data collection, and thus the commit is a no-op and yields neither error nor any action.
It might be possible to fence off arbitrary attribute access on those objects so that misspelled names raise errors. I'll investigate adding that.
Try doing:
s.set(Status = v1.StoryStatus(134))

SQLAlchemy introspection of declarative classes

I'm writing a small sqlalchemy shim to export data from a MySQL database with some lightweight data transformations—mostly changing field names. My current script works fine but requires me to essentially describe my model twice—once in the class declaration and once as a list of field names to iterate over.
I'm trying to figure out how to use introspection to identify properties on row-objects that are column accessors. The following works almost perfectly:
for attr, value in self.__class__.__dict__.iteritems():
if isinstance(value, sqlalchemy.orm.attributes.InstrumentedAttribute):
self.__class__._columns.append(attr)
except that my to-many relation accessors are also instances of sqlalchemy.orm.attributes.InstrumentedAttribute, and I need to skip those. Is there any way to distinguish between the two while I am inspecting the class dictionary?
Most of the documentation I'm finding on sqlalchemy introspection involves looking at metadata.table, but since I'm renaming columns, that data isn't trivially mappable.
The Mapper of each mapped entity has an attribute columns with all column definitions. For example, if you have a declarative class User you can access the mapper with User.__mapper__ and the columns with:
list(User.__mapper__.columns)
Each column has several attributes, including name (which might not be the same as the mapped attribute named key), nullable, unique and so on...
I'd still like to see an answer to this question, but I've worked around it by name-mangling the relationship accessors (e.g. '_otherentity' instead of 'otherentity') and then filtering on the name. Works fine for my purposes.
An InstrumentedAttribute instance has an an attribute called impl that is in practice a ScalarAttributeImpl, a ScalarObjectAttributeImpl, or a CollectionAttributeImpl.
I'm not sure how brittle this is, but I just check which one it is to determine whether an instance will ultimately return a list or a single object.

How can I tell if an Expando subclass has a property defined?

I'm creating an app that I want to have an expandable set of properties (each a RatingProperty) I also want to validate that any dynamic properties are of the RatingProperty type.
In the Expando documentation it says:
Tip: If you want to validate a dynamic property value using a Property class, you can instantiate the Property class and call its validate() method on the value.
So if I want to validate a dynamic property I need to know what the class's non-dynamic properties are. How can I ask my class what it's defined properties are?
I've considered creating a class method that takes a string and returns true if that string is in a list of property names that I create and maintain, but it seems like a hack. I've searched the Google for tips, but haven't had any luck.
Thanks,
Pat
After a bit more research (damn you lazyweb!) I've found a solution that I think is acceptable:
A dynamic property can't be of a db subclassed property type. Thus, there are two distinct steps that must be taken. First you need to create an instance of your property class and validate your value:
test = db.RatingProperty()
if test.validate(valueToSave):
#do your thing
Next you need to check if the property you want to save is a declared property:
if valueToSaveKey not in myObject.properties():
#if not save it as desired
myObject.valueToSaveKey = valueToSave
The down side here is that the value you save isn't stored as the property type you want.
http://code.google.com/appengine/docs/python/datastore/modelclass.html#Model_properties
db.Model has methods to find out all the properties on an instance.
The class exposes a list of Property objects: db.Model.properties()
The instance exposes the dynamic names only: instance.dynamic_properties()
You want to loop through the list and build Property objects, and run p.validate().
for p_name in instance.dynamic_properties():
p = db.RatingProperty()
p.validate() # raises BadValueError, etc.
I may be misunderstanding your question, but if you have a list of properties you expect to find, why not just use a standard db.Model, instead of an Expando? You can add additional properties to a Model class, as long as you either provide a default or don't make them required.
It's actually quite easy!
ExpandoObject implements (IDictionary<String, Object>) so you just need to do this :
dynamic person = new ExpandoObject();
person.FirstName = "Barack";
person.LastName = "Obama"
(((IDictionary<String, Object>)person).Keys
=> { "FirstName", "LastName" }
(((IDictionary<String, Object>)person).ContainsKey("FirstName")
=> true
Note: You need to explicitly cast to (IDictionary<string, object> because ExpandoObject explicitly implements this interface - and the instance itself doesn't have ContainsKey() or Keys.
Don't expect this method to work with all dynamic objects - just ExpandoObject and anything else that implements this interface.

How do I get the key value of a db.ReferenceProperty without a database hit?

Is there a way to get the key (or id) value of a db.ReferenceProperty, without dereferencing the actual entity it points to? I have been digging around - it looks like the key is stored as the property name preceeded with an _, but I have been unable to get any code working. Examples would be much appreciated. Thanks.
EDIT: Here is what I have unsuccessfully tried:
class Comment(db.Model):
series = db.ReferenceProperty(reference_class=Series);
def series_id(self):
return self._series
And in my template:
more
The result:
more
Actually, the way that you are advocating accessing the key for a ReferenceProperty might well not exist in the future. Attributes that begin with '_' in python are generally accepted to be "protected" in that things that are closely bound and intimate with its implementation can use them, but things that are updated with the implementation must change when it changes.
However, there is a way through the public interface that you can access the key for your reference-property so that it will be safe in the future. I'll revise the above example:
class Comment(db.Model):
series = db.ReferenceProperty(reference_class=Series);
def series_id(self):
return Comment.series.get_value_for_datastore(self)
When you access properties via the class it is associated, you get the property object itself, which has a public method that can get the underlying values.
You're correct - the key is stored as the property name prefixed with '_'. You should just be able to access it directly on the model object. Can you demonstrate what you're trying? I've used this technique in the past with no problems.
Edit: Have you tried calling series_id() directly, or referencing _series in your template directly? I'm not sure whether Django automatically calls methods with no arguments if you specify them in this context. You could also try putting the #property decorator on the method.

Categories