Python Change Directory Google App Engine - python

I have my webapp written in Python running on Google App Engine; so far only testing in my localhost. My script needs to read text files located in various directories. So in my Python script I would simply use os.chdir("./"+subdirectory_name) and then start opening and reading the files and using the text for analysis. However I cannot do that when trying to move it over to App Engine.
I assume I need to make some sort of changes to app.yaml but I'm stuck after that. Can anyone walk me through this somewhat thoroughly?
From the answer below, I was able to fix this part, I have a followup question about the app.yaml structure though. I have my folder set up like the following, and I'm wondering what I need to put in my app.yaml file to make it work when I deploy the project (it works perfectly on localhost right now).
Main_Folder:
python_my_app.py
app.yaml
text_file1
text_file2
text_file3
subfolder1_with_10_text_files_inside
subfolder2_with_10_text_files_inside
subfolder3_with_10_text_files_inside
...how do I specify this structure in my app.yaml and do I need to change anything in my code if it works right now on localhost?

You don't need to change your working directory at all to read files. Use absolute paths instead.
Use the current file location as the starting point, and resolve all relative paths from there:
import os.path
HERE = os.path.dirname(os.path.abspath(__file__))
somefile = os.path.abspath(os.path.join(HERE, 'subfolder1_with_10_text_files_inside /somefile.txt'))
If you want to be able to read static files, do remember to set the application_readable flag on these, as Google will otherwise only upload them to their content delivery network, not to the app engine.

You can package your text files inside your application and then do something like this:
path = os.path.join(os.path.dirname(__file__), 'subdir', 'file')
file = open(path)

Related

Want to run a kivy app made in windows but while running in mac os showing error

I want to run the main app which is connected with database, my.kv, users.txt file but when I run it it's showing me erroe message.. I made this project in window but when I try to run it in mac os it's showing me error.. please help me out guys
It seems your trying to access the 'users.txt' file as if it were in the current directory. Frequently, IDEs will put the working directory somewhere else that may be inconvenient for you. You can either try to play around with these settings until you get it treat the directory you expect to be the correct directory as the working directory, or you can try working with absolute paths.
For example, if your sure you app will always have this data file right next to your 'main.py' file, you could do something like the following:
import os
def get_users_file():
current_python_script = os.path.abspath(__file__)
current_script_directory = os.path.dirname(current_python_script)
users_file = os.path.join(current_script_directory, 'users.txt')
return users_file
with open(get_users_file(), 'r') as file_handler:
users_file_data = file_handler.readlines()
print(users_file_data)
there are other, cleaner ways to do this with things like pkg_resources, but I typically don't bother with using things like that until I have a proper build environment for my program.
In the future, I also recommend putting the bulk of your question into text form rather than a screen shot, as it makes it more difficult to decipher what you want.

Way to make the directory universal (relative?) across different computers?

I am a high school student building a video game for a project, and you'll have to excuse me, I am very new to python/coding in general.
I assumed this would be a relatively easy thing to figure out or find online but I haven't had any luck. Obviously with a video game there are assets and files that need to be used. How can I set the directory to something that will work if run on another computer. More details below:
Right now I have it set to os.chdir(r'C:\Users\User\Desktop\VideoGame'), and obviously if run on another computer the path would be different. How can I set it so it find that "VideoGame" file and then sets that as the directory.
Obviously I need a directory so python can find all the files I need. But let's say i take my folder with my code and all my assets on it and put it on a USB stick, then give it to my teacher, how can I be sure that the python he is running can find and use the files in that folder.
After you clarified, what I understood is that you want to load all your game assets in a removable drive. I am assuming you will be having the assets folder in the directory where the main.py file will be present.
So my approach to the problem is to first obtain the current working directory of the main.py file and then add assets\ to it and then check if that directory actually exists or not. If yes, then carry on with the operation, else display an error message.
My solution:
import os
dir_path = os.path.dirname(os.path.realpath(__file__))
dir_path = os.path.join(dir_path, r"assets")
if(os.path.exists(dir_path)):
# block of code
print()
else:
print("assets not found!\ncheck your directory")
If I am again missing out something, fell free to comment.

Cannot find file in Python flask API [duplicate]

I downloaded nltk data into the data directory in my Flask app. The views reside in a blueprint in another directory on the same level as the data directory. In the view I'm trying to set the path to the data, but it doesn't work.
nltk.data.path.append('../nltk_data/')
This doesn't work. If I use the whole path, it does work.
nltk.data.path.append('/home/username/myapp/app/nltk_data/')
Why does the first form not work? How can I refer to the location of the data correctly?
In Python (and most languages), where the code resides in a package is different than what the working directory is when running a program. All relative paths are relative to the current working directory, not the code file it's written in. So you would use the relative path nltk_data/ even from a blueprint, or you would use the absolute path and leave no ambiguity.
The root_path attribute on an app (or blueprint) refers to the package directory for the app (or blueprint). Join your relative path to that to get the absolute path.
resource_path = os.path.join(app.root_path, 'enltk_data')
There's probably no reason to be appending this folder every time you call a view. I'm not familiar with nltk specifically, but there's probably a way to structure this so you set up the data path once when you create your app.
project / app / blueprint
/ data
^ join with root_path to get here
^ app.root_path always points here, no matter where cwd is
^ current working directory

How can you get the filepath of a file in flask?

I have a flask application which is utilizing Fabric to deploy code to certain machines.
One particular method, fabric.contrib.files.upload_template, requires a filename which is the path of a file I would like to upload to my remote machines.
I have a file, index.php, which I want to place on my remote machines. I want to use upload_template to accomplish this task.
Where should I place 'index.php' in my flask folder? How will I be able to obtain the path of index.php for upload_template?
Please note that:
My application is hosted on Heroku so the typical /home/Sparrowcide/flaskapp/path/to/file won't work.
I know I can probably get away by invoking a method which writes to /tmp/path/to/file, but I'd rather not as this is not a very elegant solution.
Well the short answer is that you can pretty much put it wherever you want, I don't think flask will enforce any sort of structure on you here. However I personally would create a subdirectory called data and then in the flask app I might do something like this:
path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data', 'index.php')
Or, if I felt I was likely to re-use this information (eg if i had multiple files to upload), I might break it out into multiple variables:
SRCDIR = os.path.dirname(os.path.abspath(__file__))
DATADIR = os.path.join(SRCDIR, 'data')
whatever_upload_function(os.path.join(DATADIR, 'index.php'))

Dynamically running python code on google app engine

I am trying to be able to dynamically run python code, with variables being able to be passed through to the code. I was able to do this on my computer before I added my project to the google app engine environment (because I can access all the files, but now, with google app engine, I can not do that.
I am struggling to find a solution to this problem. It does not need to be too terribly fancy, just send variables in and get html out, as well as scripts being able to be added client side (the crucial part) to whatever database method that is used.
Edit:
well basically what I mean by dynamically is so that I can import (or thats what I did in IDLE when I tested the prototype, the solution will probably not be called importing) a python script with the name of the library being stored in a variable, as well as an unknown number of variables that would be added. I got this to work on Idle, but now I need to get it to work in the google app engine environment, and people need to be able to upload scripts as well (which is the main problem that cascades into many more problems)
Edit:
When I say that I managed to get this to work on my local machine, I mean I was able to manually drop scripts into the same directory as my main script. The script would later import and execute the scripts when necessary. I was able to get this to work with the following code:
#calling function
mod = __import__('actions.'+folder+'.'+FILE)
VAR = getattr(getattr(mod, folder), FILE)
response = VAR.Main()
print response
This code worked on both my laptop and in the google app engine environment, But When I try to add more scripts to the directory is when things get problematic. On my laptop I could just move the file over one way or another because I had full access to the file directory. On Google App engine I do not have the ability to just upload a file to the same directory or subdirectory of the rest of my python scripts. So basically the problem comes up when trying to design a way to allow more code to come into the system (in my case, adding more 'plugins').
The answer is the exec statement (also known as the exec() function) or the eval() function. See http://docs.python.org/reference/simple_stmts.html#the-exec-statement and http://docs.python.org/library/functions.html?highlight=eval#eval. These can execute arbitrary Python code from a string. exec() runs a script and you get the side effects; eval() takes an expression and returns its value. Typically you pass input in as variables in the local namespace.
Ok, So what I eventually did was use the datastore to upload everything such as the name, description, uploader and code of the plugin (for now the code is just entered into a textarea box). I then, instead of importing a file located in a folder under the same directory of my code like I had before when running everything off of my desktop, Imported the plaintext code into a module using this little bit of magic:
#Initiating Variables for use by importing functions
module_name = 'mymod'
filename = 'action_file'
source = PossibleMatches[0][1] #the source code from the best matched option
# define module_name somewhere
import types
module = types.ModuleType(module_name)
# source should the code to execute
# filename should be a pseudo-filename that the code's from
# (it doesn't actually have to exist; it's used for error messages)
code_object = compile(source, filename, 'exec')
#execute the code in the context of the module
exec code_object in module.__dict__
#Executing the 'Main' Function from the code
return module.Main()

Categories