Where I should put my python scripts in Linux? - python

My python program consists of several files:
the main execution python script
python modules in *.py files
config file
log files
executables scripts of other languages.
All this files should be available only for root. The main script should run on startup, e.g. via upstart.
Where I should put all this files in Linux filesystem?
What's the better way for distribution my program? pip, easy_install, deb, ...? I haven't worked with any of these tool, so I want something easy for me.
The minimum supported Linux distributive should be Ubuntu.

For sure, if this program is to be available only for root, then the main execution python script have to go to /usr/sbin/.
Config files ought to go to /etc/, and log files to /var/log/.
Other python files should be deployed to /usr/share/pyshared/.
Executable scripts of other languages will go either in /usr/bin/ or /usr/sbin/ depending on whether they should be available to all users, or for root only.

If only root should access the scripts, why not put it in /root/ ?
Secondly, if you're going to distribute your application you'll probably need easy_install or something similar, otherwise just tar.gz the stuff if only a few people will access it?
It all depends on your scale..
Pyglet, wxPython and similar have a hughe userbase.. same for BeautifulSoup but they still tar.gz the stuff and you just use setuptools to deply it (whcih, is another option).

Related

How to distribute an application for Mac OS so that it can be run by double clicking it?

Goal
I've written a simple python application and I want to build it in a way such that I can email it to a non-technical person using a Mac OS machine such that they can just download the file and double click it to run.
What I've tried so far
I've built a single file executable using pyinstaller, but when I email it and download it, the file doesn't have permission to be executed. I know that this can be fixed with chmod, but the goal is for a non-technical person to be able to just double click to run.
I've also tried creating a "installation file" that's just a file with a .command file extension that is essentially this:
#!/bin/bash
cd -- "$(dirname "$BASH_SOURCE")"
sudo chmod a+x MyApplication
exit 0
But this has the same problem as above - the file doesn't have permission to be run by default.
Is there something simple that I'm missing? I'm open to not necessarily having to email the app, but I do need a simple way to share it.
Platypus allows scripts in different languages (including Python) to be bundled into OSX applications. Python is typically installed on newer versions of OSX anyway, so there might be no need to ship Python itself, and the app could be tiny in file size.
Generally, since OSX applications are really folders, it might be worthwile to pack the folder before emailing as
tar cjf YourApp.tbz YourApp
where YourApp is the folder containing the application. OSX recognizes the tbz extension and will unpack the app/folder when doubleclicked, say in Downloads or the Desktop, where the user can then doubleclick the application to run it.
tar cjf archive.tbz singlefile
will similarly also work for archiving a single file, where tar will preserve the executable and other flags.

python - How to handle file locations and paths when installing package?

I'm working on building my first Python package for a client to use. At the most, I am envisioning the user pulling the code from GitHub, then pip installing (pip install .). This package will be used in a Windows environment. What is the convention or where is the easiest place to put log files? Is there a way to tell setup.py to make a log directory that is easily accessible for the user?
For a more specific example, let's say I had the code base locally at C:\Users\iamuser\projects\client_project. I pip install . while in the client_project directory. There is a logs\ directory (C:\Users\iamuser\projects\client_project\logs) that I'd like the log files to be placed into. Is there a way to have my setup.py place log files in that directory? If not, are there any other tools I should try?
I have tried something like this, but any paths acquired while running setup are not where the original setup.py file was located (example: os.path.abspath(__file__) shows some other location than within the client_project directory).
While creating a Python package, I would not make any assumptions about the user's filesystem or permissions therein (ideally not even about the OS). If your Python package creates log files, you could use Python's build-in logging system and logging information would go wherever the user wants it to go (stdout and stderr by default).
If your package generates files the user should have the option to decide where they go, either using a settings or config file or environmental variables.
There are a few places where you could safely store them by default. Such as the home or current working directory (or subfolders of them, see pro and cons in the comments). Important is to use relative paths either in relationship to ~, os.getcwd() or the __file__ attribute of your script. Linux systems have a few places that are usually present and can be used such as /tmp or /var/log but that does not work on Windows.
Sometimes, I store output files in the parent of the current working directory in order not to checkin output files into a Git repo but this relays on additional assumptions.

Use .py or .pyc file when sharing/backing up?

This answer tells me that a .pyc file gets created when a .py file is run, which I understand saves loading time when re-run. Which makes me wonder what the point of the .py file is after the .pyc is created.
When backing up my code, or sharing it, I don't want to include redundant or extraneous files. Which filetype should I focus on?
Side question: I have one script that calls another. After running them, the called script got a .pyc file written, but the master script that does the calling did not. Why would that be?
Python .pyc files are generated when a module is imported, not when a top level script is run. I'm not sure what you mean by calling, but if you ran your master script from the command line and it imported the other script, then only the imported one gets a .pyc.
As for distributing .pyc files, they are minor version sensitive. If you bundle your own python or distribute multiple python-version sensitive files, then maybe. But best practice is to distribute the .py files.
Python's script and module rules seem a bit odd until you consider its installation model. A common installation model is that executables are installed somewhere on the system's PATH and shared libraries are installed somewhere in a library path.
Python's setup.py does the same thing. Top level scripts go on the PATH but modules and packages go in an library path. For instance on my system, pdb3 (a top level script) is at /usr/bin/pdb3 and os (an imported module) is at /usr/lib/python3.4/os.py. Suppose python compiled pdb3 to pdb3.pyc. Well, I'd still call pdb3 and the .pyc is useless. So why clutter the path?
Its common for installs to run as root or administrator so you have write access on those paths. But you wouldn't have write access to them later as a regular user. You can have setup.py generate .pyc files during install. You get the right .pyc files for whatever python you happen to have, and since you are running as root/admin during install you still have acess to the directories. Trying to build .pyc files later is a problem because a regular user doesn't have access to the directories.
So, best practice is to distribute .py files and have setup.py build the .pyc during install.
If you simply want to run your Python script, all you really need is .pyc which is the bytecode generated from your source code. See here for details on running a .pyc file. I will warn that some of the detials are bit twisty.
However I recommend including your source code and leaving out your .pyc files as they are generated automatically by the Python Interpreter. Besides, if you, or another person would want to revise/revisit your source code at a later point, you would need the .py files. Furthermore, it is usually best practice to just include your source code.

Python program needs full path in Notepad++

Not a major issue but just an annoyance I've come upon while doing class work. I have my Notepad++ set up to run Python code straight from Notepad++ but I've noticed when trying to access files I have to use the full path to the file even given the source text file is in the same folder as the Python program being run.
However, when running my Python program through cmd I can just type in the specific file name sans the entire path.
Does anyone have a short answer as to why this might be or maybe how to reconfigure Notepad++?
Thanks in advance.
The problem is that your code is assuming that the current working directory is the same as the script directory. This is not true in general. Of course it is true if you're in a cmd window, and you cd to the script directory before running it.
If you don't want to rely on that (e.g., because you want to be able to run scripts from Notepad++, or directly from Explorer), what you want to do is use the script directory explicitly. For example:
import os
import sys
scriptdir = os.path.abspath(os.path.dirname(sys.argv[0]))
with open(os.path.join(scriptdir, 'myfile.txt')) as f:
# etc.
If you have a ton of files that your scripts reference in a ton of places, it might be better to explicitly set the working directory. Just add one line:
os.chdir(scriptdir)
For anything beyond quick&dirty scripts, it's usually better to build an installable package and use pkg_resources to access the data files. Read the Tutorial on Packaging and Distributing Projects for more details. But as long as you're only hacking up scripts to help you maintain your specific system, the scriptdir solution is workable.
In the properties of the shortcut that you use to start Notepad++, you can change its working directory, to whichever directory you're more accustomed to starting from in Python. You can also begin your python program with the appropriate os.chdir() command.

Make a Python app package/install for Mac

I have developed an application for a friend. Aplication is not that complex, involves only two .py files, main.py and main_web.py, main being the application code, and _web being the web interface for it. As the web was done later, it's kept in this format, I know it can be done with one app but not to complicate it too much, I kept it that way. Two two communicate with some files, and web part uses Flask so there's "templates" directory too.
Now, I want to make a package or somehow make this easier for distribution, on a OSX system. I see that there is a nice py2app thingy, but I am running Windows and I can't really use it since it won't work on Win. I also don't know will py2app make problems since some configs are in text files in the directory, and they change during the runtime.
So, I am wondering, is there any other way to make a package of this, some sort of setup like program, or maybe some script or something? Some simple "way" of doing this would be to just copy the files in the directory in the "Documents", and add some shortcuts to the desktop to run those two apps, and that would be it, no need for anything else. DMG would be fine, but not mandatory.
I believe what you are looking for is to add: #!/usr/bin/python to the first line of your code will allow your friend to just double click on the file and it should open. Just as a warning osx does not tell us what version and as such what version of python and what standard libraries are going to be present.
Also, just make sure that if they have played around with their settings to much and they double click on python it does not work they will have to choose to open the file in "terminal.app" in the Utilities Applications folder (/Applications/Utilities/terminal.app)
The other idea is borrow a mac and compile it with the py2app program that you already mentioned. Otherwise there is no generic binary file that you will be able to compile in windows and have run on mac.

Categories