how to access the data of a GStreamer buffer in Python? - python

In the old (pre-GObject-introspection) GStreamer bindings, it was possible to access gst.Buffer data via the .data attribute or by casting to str. This is no longer possible:
>>> p buf.data
*** AttributeError: 'Buffer' object has no attribute 'data'
>>> str(buf)
'<GstBuffer at 0x7fca2c7c2950>'

To access the contents of a Gst.Buffer in recent versions, you must first map() the buffer to get a Gst.MapInfo, which has a data attribute of type bytes (str in Python 2).
(result, mapinfo) = buf.map(Gst.MapFlags.READ)
assert result
try:
# use mapinfo.data here
pass
finally:
buf.unmap(mapinfo)
You can also access the buffer's constituent Gst.Memory elements with get_memory(), and map them individually. (AFAICT, calling Buffer.map() is equivalent to calling .get_all_memory() and mapping the resulting Memory.)
Unfortunately, writing to these buffers is not possible since Python represents them with immutable types even when the Gst.MapFlags.WRITE flag is set. Instead, you'd have to do something like create a new Gst.Memory with the modified data, and use Gst.Buffer.replace_all_memory().

Related

Pass Python object as argument to function in "parfeval"

I am trying to pass one Python object as an argument to a function that I am evaluating in the background with parfeval. The Python object is an instance of a Python class, and I detail it below. However, to reproduce the error, I will exemplify with a Python dictionary... However, simply using struct(pydict) would not work because I would lose all the attributes and methods in the Python class.
Assume the Python dictionary is
o = py.dict(pyargs('soup',3.57,'bread',2.29,'bacon',3.91,'salad',5.00));
and the function is
function t = testFunc(x)
t = x{'soup'};
end
If I evaluate the function, I get the correct answer:
>> testFunc(o)
ans =
3.5700
However, if I use parfeval, I get the following error:
>> f = parfeval(#testFunc,1,o);
>> fetchOutputs(f)
Error using parallel.Future/fetchOutputs
One or more futures resulted in an error.
Caused by:
Error using testFunc (line 2)
Invalid or deleted object.
Is there a workaround to this error that doesn't mean I have to recode my whole Python class?
Here is the preview of the object I want to pass as a function to parfeval:
clt =
Python Client with properties:
enforce_enums: 1
api_key: [1×45 py.str]
request_number: [1×1 py.int]
logger: [1×1 py.logging.Logger]
session: [1×1 py.authlib.integrations.httpx_client.oauth2_client.OAuth2Client]
token_metadata: [1×1 py.tda.auth.TokenMetadata]
<tda.client.synchronous.Client object at 0x000001ECA08EAE50>
I didn't find any restrictions in the documentation that says that parfeval function inputs cannot be anything...
https://www.mathworks.com/help/matlab/ref/parfeval.html
"X1,...,Xm — Input arguments
comma-separated list of variables or expressions... Input arguments, specified as a comma-separated list of variables or expressions"
One of the limitations of the MATLAB->Python support is that Python objects cannot be serialized. parfeval (and other parallel constructs) require serialization to transfer data from one MATLAB process to another.
You might be able to work around this by having each worker build the data structure directly and storing it / accessing it via parallel.pool.Constant, like this:
oC = parallel.pool.Constant(#() py.dict(pyargs('soup',3.57,'bread',2.29,'bacon',3.91,'salad',5.00)));
fetchOutputs(parfeval(#(c) c.Value{'salad'}, 1, oC))

What does this mean <_io.BytesIO object at 0x000002244592F1A8>?

I have a url:
https://enterpriseefiling.fcc.gov/dataentry/api/download/dbfile/Current_LMS_Dump.zip
Let
u1 = ['https://enterpriseefiling.fcc.gov/dataentry/api/download/dbfile/Current_LMS_Dump.zip']
I run the following code in my python interpreter
import requests, io
r = requests.get(u1, stream=True)
io.BytesIO(r.content)
I get the following response
<_io.BytesIO object at 0x000002244592F1A8>
My question is: what does this mean? Where is 0x000002244592F1A8? What does 0x000002244592F1A8 refer to?
When python needs to print out an object, and the object doesn't otherwise have a built-in method that tells the interpreter how to print it out (for example, requests.Response and python's built-in list and dict types do have this sort of instruction), python uses this format:
<[objecttype] object at [pointer]>
where pointer is literally a pointer to the object's location in memory. That's what you see here: when you do io.BytesIO(r.content) in your interpreter, you create an io.BytesIO object.
A different method tends to get called when, on the interpreter, you do
>>> print(<object>)
rather than just
>>> <object>
and the io.BytesIO class certainly has methods you can use for more useful output, if you look at its documentation. Try assigning it to a variable instead of printing it:
b = io.BytesIO(r.content)
What does 0x000002244592F1A8 refer to?
It refers to the identity of the object. The number is an implementation detail (in CPython it happens to be the address of the object in memory, the same number returned by the id builtin), but what you can count on is that the number will be different for every BytesIO object currently extant in the process.
That kind of information is included in the __repr__ of many objects because it can come useful when debugging, allowing one to distinguish different objects that might have identical content.
My understanding is that 0x000002244592F1A8 here is the formatted id of the object in memory. I say "formatted", because, if you do id() on the same object, the representation will be a little different (it will be formatted as an int or a long instead of a pointer address:
In [1]: import io
In [2]: obj = io.BytesIO()
In [3]: obj
Out[3]: <_io.BytesIO at 0x10da1ca70>
In [4]: id(obj)
Out[4]: 4523674224
To convert the id() to the format you see, you can do something like this (stolen from this post):
In [5]: format(id(obj), '#010x' if sys.maxsize.bit_length() <= 32 else '#18x')
Out[5]: ' 0x10da1ca70'
This ^^ is not particularly useful, but it just shows you how id() lines up with what you are seeing.
The reason you are seeing it is just that it is displayed as part of the default __repr__() for the BytesIO object.

Python multiprocessing shared variable list can't append

I'm trying to do multiprocessing with Python and there is a variable that needs to be shared across all instances.
The variable to be shared is a list that stores variables of types by appending some user-defined class
<class 'output_handlers.email_output_handler.email_output_handler'>
<class 'output_handlers.dw_output_handler.dw_output_handler'>
as seen from print(type(var)).
I attempted to use a Manager to append the same variables to it's generated list before passing it into the threads:
from multiprocessing import Manager
...
man = Manager()
output_handlers = man.list()
output_handlers.append(variable)
The above yields error TypeError: cannot serialize '_io.TextIOWrapper' object even though it can append simple types like integers and chars.
Attempting to do
tmp = []
tmp.append(variables)
output_handlers = man.list(tmp)
also yields the same error.
I also wanted to use multiprocessing.Value() to explicitly make the list sharable, but I never found the ctype code for the list
Can anyone help out with this problem?

Python: Convert string to instance

I am new to Python and I have been stuck for hours with this problem... I don't know how to convert a variable (type string) to another variable (type instance).
>>from Crypto.PublicKey import RSA
>>from Crypto import Random
>>randomValue = Random.new().read
>>priv = RSA.generate(512, randomValue)
After these lines of code, "priv" is created, and this has type "instance".
And I had to convert this "priv" to type string using str(priv).
>>convertedToStr = str(priv)
>>type(convertedToStr)
<type 'str'>
Now, I need to convert it back to 'instance' and want to get the same thing in value and type as the original "priv". Assume that I cannot use "priv" anymore, and I need to convert "convertedToStr" (type string) into "convertedToStr" (type instance).
Is this ever possible?
Note: The reason I am doing this complex thing is because I have client and server sides and when one side sends a message to the other using sendall(var), it does not allow me to send variable of type 'instance'. So I had to convert it to string before sending it. Now, I want to use that on the receiver side as an variable of type 'instance' but I do not know how to convert it back.
The instance type is used for instances of old-style classes in Python 2. You may want to look at priv.__class__ instead of type(priv) to find out what class it actually has. I expect you'll find that it's class is Crypto.PublicKey.RSA._RSAObject, since that's what the generate function is documented to return.
I don't have the Crypto package installed, so I don't actually know what string you get when you call str on a private key instance. You might be able to parse the string and then call the function Crypto.PublicKey.RSA.construct with appropriate values to reconstruct the key object.
But I think that is doing more work than necessary. Instead of calling str on the key, you should instead call its exportKey method. Then, after you send the string you get back to the other system, you can pass it to Crypto.PublicKey.RSA.importKey.
Note that sending a private key over a network may expose it to eavesdropping, making it useless! You probably shouldn't do it unless the connection between your two systems is encrypted with some other system. Your system is only as secure as its weakest link.
Type instance is nothing specific, you can make a custom class and instantiate it, and it will have type instance:
>>> class x:
... y=1
...
>>> type(x())
<type 'instance'>
You can't arbitrarily convert things to a string by calling str() and guarantee get useful results - it merely asks the object to return a string that could say anything at all. In this case you asked for an RSA private key 512 bytes long and the str() output is ~45 bytes long, there's not 10% of the information needed to get the full object state back from that.
The general problem you're trying to solve is serialization/deserialization, and it's the topic of many modules, libraries and protocols - but luckily RSA keys are easy to convert to useful text and back again (not all objects are).
>>> out = priv.exportKey()
>>> new = RSA.importKey(out)
>>> new == priv
True
NB. when I tried your code, it clearly complained at me that 512 byte keys are weak and refused to generate them, insisting on 1024 bytes or more. You possibly are on an older version, but should specify a longer keylength.

Python: VMware Object data

How does one get all the property values from an object. For example a method returned me an object, but when I print it out there's only type and value displayed. For example I've got an ManagedObjectReference of Task named obj. If I write print obj.info an error occurs:
AttributeError: returnval instance has no attribute 'info'
If you are using PropertyCollector's RetrieveProperties, CheckForUupdates etc then in PropertyFilterSpec set PropertySpec.all=True. This will fetch all properties of the MOR. But this will be a huge performance hit. Instead I would suggest list out the properties you need in the PropertySpec.pathSet.

Categories