Python + CGI script cannot access environment variables
Asked Answered
Q

9

6

I'm coding a webservice on python that uses an Oracle database. I have cx_Oracle installed and working but I'm having some problems when I run my python code as CGI using Apache.

For example the following code works perfectly at the command line:

#!/usr/bin/python 
import os 
import cx_Oracle 
import defs as df 

os.putenv('ORACLE_HOME', '/oracledb/10.2.0/') 
os.putenv('LD_LIBRARY_PATH', '/oracledb/10.2.0/lib') 

con = cx_Oracle.Connection(df.DB_USER, df.DB_PASS, df.DB_SID) 
print con

But when I run it as CGI I get a "cx_Oracle.InterfaceError: Unable to acquire Oracle environment handle" at the apache error log.

I searched the Net and everybody says that I have to set the ORACLE_HOME and LD_LIBRARY_PATH environment variables. Somehow the CGI script cannot access this environment variables even when I define them using os.putenv as you can see at the code.

What I'm I doing wrong? Thanks!

Quintilla answered 1/7, 2009 at 18:3 Comment(1)
Why aren't you using mod_wsgi?Rondo
Q
2

I've managed to solve the problem.

Somehow the user and group that apache was using didn't have access to the environment variables. I solved the problem by changing the user and group that apache was using to a user that I was certain to have access to this variables.

It's strange (and frustrating) that it's so difficult to set this variables using Python.

Thanks to everyone that answered my question!

Quintilla answered 17/7, 2009 at 14:17 Comment(0)
F
5

This is working for me:

os.putenv('ORACLE_HOME', '/oracle/client/v10.2.0.3-64bit')
os.putenv('LD_LIBRARY_PATH', '/oracle/client/v10.2.0.3-64bit/lib')
os.environ['ORACLE_HOME'] = '/oracle/client/v10.2.0.3-64bit'
os.environ['LD_LIBRARY_PATH'] = '/oracle/client/v10.2.0.3-64bit/lib'

Mind that first putenv, then update environ.

Failing answered 22/3, 2011 at 16:31 Comment(0)
A
3

You need this:

os.environ['ORACLE_HOME'] = '/oracledb/10.2.0/'
os.environ['LD_LIBRARY_PATH'] = '/oracledb/10.2.0/lib'

instead of using os.putenv() because os.putenv() doesn't update os.environ, which cx_Oracle is presumably looking at.

Documentation: Miscellaneous operating system interfaces says: "Note: Calling putenv() directly does not change os.environ, so it’s better to modify os.environ."

Avilla answered 1/7, 2009 at 18:6 Comment(3)
Try combining this and eduffy's solution?Avilla
Nops. It's a really strange problem. If I add print os.environ I get ORACLE_HOME and LD_LIBRARY_PATH defined at the dictionary. Could this be an apache configuration problem?Quintilla
I'd guess that there's another missing piece besides these two environment variables. Either another missing environment variable, or maybe a permissions problem. Try using setuid on your CGI script to run it as the same user as your command line test (not that I'd recommend that for production! but it might help to isolate the problem).Avilla
H
3

Don't forget adding env module for apache:

a2enmod env

in .htaccess or apache configuration:

SetEnv LD_LIBRARY_PATH /oracle_lib_path

in /etc/apache2/envvars doesn't work

Haematoxylin answered 24/1, 2012 at 12:37 Comment(0)
W
2

You can eliminate the problem altogether if you eliminate the need to set the environment variables. Here's a note on how to do this by installing the Oracle Instant Client on your box.

installing Oracle Instantclient on Linux without setting environment variables?

Wixted answered 3/7, 2009 at 7:10 Comment(0)
Q
2

I've managed to solve the problem.

Somehow the user and group that apache was using didn't have access to the environment variables. I solved the problem by changing the user and group that apache was using to a user that I was certain to have access to this variables.

It's strange (and frustrating) that it's so difficult to set this variables using Python.

Thanks to everyone that answered my question!

Quintilla answered 17/7, 2009 at 14:17 Comment(0)
H
1

From just a short google on the problem, it could be that your problem is related to the the ending / in ORACLE_HOME.
Try removing it (and using also suggestion from Richie) and see if it works.

Hugohugon answered 1/7, 2009 at 18:32 Comment(0)
K
1

You could use a shell script to implement the CGI, set the environment variables in the shell script and call the python script from the shell script.

Setting environment variables from within python seems to be a tricky thing, especially when you are dealing with how libraries are loaded...

Kantian answered 1/7, 2009 at 18:42 Comment(0)
T
1

The actual question why the questioner's code did not work has not yet been answered.

The answer is that the environment variable LD_LIBRARY_PATH is only evaluated when an application is started (in this case the Python interpreter). When Python has started, it is already too late to mess with this variable; and it doesn't matter at all whether you set it using os.environ or os.putenv (but generally the former should be used).

The solution is to set the LD_LIBRARY_PATH environment variable in a wrapper script that starts the Python script, or to start Apache with that environment variable already set. On OpenSUSE, you can do the latter by setting LD_LIBRARY_PATH in /etc/sysconfig/apache2, for instance.

By the way, the same problem exists when using mod_wsgi instead of a CGI script. See the section "Unable To Find Python Shared Library" on the mod_wsgi Installation Issues page.

Tutu answered 30/11, 2011 at 18:42 Comment(0)
F
0

Are your statements out of order?

#!/usr/bin/python 
import os 
os.putenv('ORACLE_HOME', '/oracledb/10.2.0/') 
os.putenv('LD_LIBRARY_PATH', '/oracledb/10.2.0/lib') 

import cx_Oracle 
import defs as df 

con = cx_Oracle.Connection(df.DB_USER, df.DB_PASS, df.DB_SID) 
print con
Frantz answered 1/7, 2009 at 18:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.