Python: Reading / storing configuration file in a restrictive environment? - python

Here's the scenario:
I am writing a program that will run inside a Telit HE910 GSM module, which has an on-board python interpreter.
I would like my program to be able to read and store some parameters inside a configuration file onboard the GSM module.
The file may occasionally be transferred into a separate machine for viewing and changing, so it should be both machine-readable and writeable on multiple platforms.
So far, there are multiple solutions for this issue. Here's the kicker though:
The GSM module does not have any python modules for parsing / writing configuration files (so I can't simply use import yaml, import json, import configparser, or even import csv)
The GSM module does not allow the creation of subdirectories. From my limited understanding, this prevents me from simply dumping the contents of say, the PyYAML python module into the GSM module and calling it from my program.
I found a similar question here, but I don't even know where in the GSM module's filesystem I am. import os doesn't seem to work, which is strange (contrary to documentation).
I know I can use a Python file to store some read-only configurations, but I also want to be able to write to the config file (redesigning the system to avoid this is really undesirable).
I think my best bet so far seems to be to write a simple csv parser / writer myself, unless someone has a better idea (or know how to utilise Python modules without any subdirectories).
PS: The documentation below has a list of supported modules. None of the config-related modules seem to be available however.
GSM Module homepage: http://www.telit.com/en/products/umts-hsdpa.php?p_ac=show&p=108
Python interpreter manual : http://www.telit.com/module/infopool/download.php?id=4378
EDIT: I should have mentioned, the configuration file needs to be readable / writeable from a c# .NET application, not another python interpreter on the desktop.

You have _ast (ยง5.2.36), so it should be possible to reimplement ast.literal_eval(). At that point reading and writing becomes mostly trivial.

I wouldn't recommend it in normal Python usage, but a possible option would be the marshal module mentioned in 5.2.34 of the manual you posted, and description/limitations/warnings here: http://docs.python.org/library/marshal.html

Why don't you just open a txt file and store all info as a text file? I read the Easy Script Manual for your module, there is a posix module which supports methods like open, close, unlink.

Related

How to embed python into a standalone C++ application? (i.e. do not rely on Libs folder on disk)

I'm trying to embed python into my C++ application, but also make it standalone, i.e. do not rely on python dependencies on a disk, like Libs folder with standard library scripts, but still be able to use them. I can find a way to store all the the scripts from Libs in the binary by myself and load them into the memory after running the program, but the problem is that I don't know how to "load" them into python interpreter directly from memory, either from text or binary (compiled) scripts, without dropping them on disk, how pyinstaller does (it extracts all compiled scripts into temp system dir).
I'm wondering if there is any kind of callback in cpython that allows a user to override import keyword and general modules import logic so I could import a module from memory instead of loading it from disk. I couldn't find anything like that on google. Maybe you know if there is such feature?
Thanks in advance!

How do I get the list of imports and dependant files from python script?

I have a .py file that imports from other python modules that import from config files, other modules, etc.
I am to move the code needed to run that .py file, but only whatever the py file is reading from (I am not talking about packages installed by pip install, it's more about other python files in the project directory, mostly classes, functions and ini files).
Is there a way to find out only the external files used by that particular python script? Is it something that can be found using PyCharm for example?
Thanks!
Static analysis tools (such as PyCharm's refactoring tools) can (mostly) figure out the module import tree for a program (unless you do dynamic imports using e.g. importlib.import_module()).
However, it's not quite possible to statically definitively know what other files are required for your program to function. You could use Python's audit events (or strace/ptrace or similar OS-level functions) to look at what files are being opened by your program (e.g. during your tests being run (you do have tests, right?), or during regular program use), but it's likely not going to be exhaustive.

Trouble with pySerial deployment

I have a custom python script that depends on MinimalModbus and the pySerial library. I am trying to deploy it to a router which runs a python interpreter.
MinimalModbus is just a single .py file which is trivial to deploy. However, the pySerial library appears to be much more robust. It looks like several python files that work together to "automatically select the appropriate backend".
Does one have to "install" pySerial in order to use it? Or is there some way to extract just the pertinent files/dependencies for a given OS?
I don't know what all is performed when you run pySerial's setup.py (e.g. files copied?). I don't know if it will work for this particular type of deployment. I was hoping to just include specific files.
Any help will be appreciated.
We are using Python version 2.6.
Update:
I basically took the "installed" files from the /site-packages/serial folder on my development box and uploaded them to the device. This got me a bit further; however, I am now getting the following error:
Line ~273 of serialposix.py , it's calling:
self.fd = os.open(self.portstr, os.O_RDWR|os.O_NOCTTY|os.O_NONBLOCK)
Why would it not be able to find the os.open routine?
Update 2:
Further simplifying the problem, my script now consists of something as simple as the following, and it still fails with the same error:
import os
serfd = os.open("/com/0", os.O_RDWR | os.O_NONBLOCK)
Under Python Standard Modules with Digi-Specific behavior, they make the following comment about the os module:
Use of the os module in Digi devices is currently very limited. The primary purpose in exposing it is to allow access to the serial ports, which are presented as nodes in the file system. Serial ports are available as files with the path in the form /com/0 with the zero replaced by the zero-based index of the serial port to control.
In addition, both of their sample applications use the os.open routine for serial communication.
I would have expected to maybe see an error such as: OSError: [Errno 2] No such file or directory: '/com/0', but this is not the case. Python can't even locate the os.open routine.
Would you expect the os.py file to have a def open(...) routine defined?
After opening a support case with the manufacturer of this router, it turns out that the os.open function is not supported on this device. However, the device does support io.open which I believe is similar. More importantly, I learned that the manufacturer provides their own "pyserial" implementation specifically designed to work on the device's operating system. Internally, it looks like they've switched out the calls to use io.open equivalent.
having had a look through the source files, i believe that it is entirely python based, and when it installs it copies the files across to the site-packages folder.
having said that it appears that you would need several of the source files in order for it to work, and if you were simply copying them across you may need to modify their imports to ensure they work properly.
eg for linux you would need the serialposix.py file and the serialutil.py
you may need more than just this, but i have only had a quick look through.
but at the top of serialposix.py there is a line:
from serial.serialutil import *
this would need to be changed to:
from serialutil import *
and there may be other such changes to make.
but ultimately this seems to use ctypes to do the hard work talking to the underlying OS, so you should be able to make it work.
UPDATE:
to explain why it is calling os.open, on most platforms serial ports are treated almost like files, in tthat the return a "file like" handle, the idea behind pyserial is to abstract operating system level differences away to create a single easy to interface to these, but ultimately it is still treated as a file like handle by the OS.
just for clarification could you let us know what version of pyserial you are using? as the line number you quoted and what i'm looking at don't match.
i suspect the main reason you are having difficulty is the zip nature of the python deployment you are using, but i do find it hard to believe that OS is not included in it, have you checked the OS python file in the ZIP or is it a compiled python file?
UPDATE 2:
haveing looked at the documentation for the distro you are using i would suggest you have a read through the following:
Python Standard Modules with Digi-Specific Behavior
where is states that some funtionality is limited on these devices, it also gives a method by which you can test if it is supported by telnet/SSH into the device and trying it on the python command line.
also, while it is anot as neat and easy to use as the pyserial module, i suggest you give this a read too:
Digi Serial Port Access

Using libexif in Python

I'm writing a Python-based [web] application that needs to be able to read and write EXIF data.
libexif seems to have all the right ingredients, but I can't work out how (or if) I could access it access it by using Python's ctypes library? I'm new to C, suppose I need see a .so for this to work?
You need to be running on an os that you can obtain the required library, to download the .h files, (usually the -dev package gives you these).
Then you need to work your way through the ctypes tutorial found here which explains all the steps you need to take.

Programmatically editing Python source

This is something that I think would be very useful. Basically, I'd like there to be a way to edit Python source programmatically without requiring human intervention. There are a couple of things I would like to do with this:
Edit the configuration of Python apps that use source modules for configuration.
Set up a "template" so that I can customize a Python source file on the fly. This way, I can set up a "project" system on an open source app I'm working on and allow certain files to be customized.
I could probably write something that can do this myself, but I can see that opening up a lot of "devil's in the details" type issues. Are there any ways to do this currently, or am I just going to have to bite the bullet and implement it myself?
Python's standard library provides pretty good facilities for working with Python source; note the tokenize and parser modules.
Most of these kinds of things can be determined programatically in Python, using modules like sys, os, and the special _file_ identifier which tells you where you are in the filesystem path.
It's important to keep in mind that when a module is first imported it will execute everything in the file-scope, which is important for developing system-dependent behaviors. For example, the os module basically determines what operating system you're using on import and then adjusts its implementation accordingly (by importing another module corresponding to Linux, OSX, Windows, etc.).
There's a lot of power in this feature and something along these lines is probably what you're looking for. :)
[Edit] I've also used socket.gethostname() in some rare, hackish instances. ;)
I had the same issue and I simply opened the file and did some replace: then reload the file in the Python interpreter. This works fine and is easy to do.
Otherwise AFAIK you have to use some conf objects.

Categories