i'm try upload file with django(xlsx) this is my code:
myfile = request.FILES['document']
fs = FileSystemStorage()
filename = fs.save(myfile.name, myfile)
on the model i have setup the folder "media" to uploads, get this error:
Permission denied: '/var/www/html/inventariosRG/media/my_file.xlsx'
this error i'm try fixed with this:
PATH = 'media/'
myfile = request.FILES['document']
try:
import subprocess
RUTA_ABSOLUTA = os.path.join(os.path.dirname(os.path.dirname(__file__)),PATH)
subprocess.Popen('sudo chmod -R 777 '+RUTA_ABSOLUTA, shell=True)
except Exception as e:
raise Exception ("Error ",e)
fs = FileSystemStorage()
filename = fs.save(myfile.name, myfile)
this code only show the same error "permission denied..." please i'm try set the permission by command on django, any suggest thanks..!!
These answers probably relate and are better than 777-ing:
Django - Media upload [Errno 13] Permission denied
A file from the internet is owned by user 'www-data:www-data' and that user has tightly restricted permissions (because files from the internet might be bad.) Your Django media/ folder needs to be accessible and writeable to the www-data user, so making that owner the user is appropriate.
Also, I'm not a sysadmin by any means and I may be speaking from unrecognized ignorance, but building the use of sudo into your Django application seems like a big security risk to me.
I can see a use for a 'config' script, that ensures a new deployment rolls out correctly, but keep that script and your Django code well separated from files from the internet. You could add your script to /etc/sudoers to give it the authority it needs (but remember to edit sudoers with visudo) if there was some reason to automate it.
Related
Hello Awesome People!
I will try to be clear with my question.
All of my media files are uploaded to AWS, I created a view that allows each user to download images. Before, I did it without the boto that summed up
"this back-end doesn't support absolute path."
And now, after some research, I'm using the s3 boto3 connection.
Model
class Photo(models.Model):
file = models.ImageField(upload_to="uploaded_documents/")
total_download = models.PositiveIntegerField()
View
def download_file(request,id):
photo = get_object_or_404(Photo,id=id)
photo.total_download += 1
photo.save()
path = os.path.basename(photo.file.name)
# path = '/media/public/uploaded_documents/museum.jpg'
client = boto3.client('s3',aws_access_key_id=settings.AWS_ACCESS_KEY_ID,
aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY)
resource = boto3.resource('s3')
bucket = resource.Bucket(settings.AWS_STORAGE_BUCKET_NAME)
bucket.download_file(path, 'my_local_image.jpg')
Here I don't know what to do to trigger it. when I run it, I get the following error:
NoCredentialsError at /api/download-file/75
Exception Type: NoCredentialsError
Exception Value: Unable to locate credentials
UPDATE
I use the credentials in resources instead of client
client = boto3.client('s3')
resource = boto3.resource('s3',aws_access_key_id=settings.AWS_ACCESS_KEY_ID,
aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY)
and it seems to be authenticated. But now I got the error:
Exception Type: ClientError
Exception Value: An error occurred (404) when calling the HeadObject operation: Not Found
please try looking at the answers in:
Boto3 Error: botocore.exceptions.NoCredentialsError: Unable to locate credentials
also check that the file path is correct in S3
My problem is that I cannot upload a file from my deployed project to a S3 bucket, even though I am able to upload from local host. Expect the URL, everything remains the same (headers, body etc.) when I am calling the method.
I am using boto3 to interact with s3 and using created IAM users' credentials. Also, for deployment, I am using AWS Elastic Beanstalk.
Below is the code I am using for uploading;
def put(self, bytes, data, folder, file_name):
self.ext = file_name.split(".")[-1]
if self.__is_audio_ext(self.ext):
if folder == self.__voice_record:
self.__create_voice_record(data, folder, file_name)
elif folder == self.__voice_message:
self.__create_voice_message(data, folder, file_name)
else:
return "Response cannot be constructed."
self.s3_client.put_object(Body=bytes, Bucket=self.bucket_name, Key=folder + "/" + file_name)
return "Successfully created at URL " \
+ self.bucket_url + self.bucket_name + "/" + folder + "/" + file_name
else:
return "Invalid file type"
Also, below is how I setup the boto3
def __init__(self):
self.ext = ""
self.env = {
"aws_access_key_id": settings.AWS_ACCESS_KEY_ID,
"aws_secret_access_key": settings.AWS_SECRET_ACCESS_KEY,
"region_name": 'eu-central-1'
}
self.bucket_name = "********"
self.session = session.Session(region_name='eu-central-1')
self.s3_client = self.session.client('s3', config=boto3.session.Config(signature_version='s3v4'))
self.bucket_url = "http://s3-eu-central-1.amazonaws.com/"
When I make my PUT request to the my server, this is the error I got:
An error occurred (AccessDenied) when calling the PutObject operation:
Access Denied"
Note that I created IAM user and give it the full permission of using S3 and I am sure that I am using the right credentials. This can be understood easily from that I can actually upload file from local.
This is why I believe the problem is somewhere between the file in my request and the deployment project. But it does not seem still right to me. Anyway, do not listen to me, I am pretty confused here.
Please do not hesitate asking me about what you do not understand. I may skip clearing some points.
I am working on it for hours and could not come up with any proper solutions, so I will be really glad for any help!
Thanks!
It's too late but hope fully helpful to other new users. We should attach instance profile to EC2 with right permissions for S3 bucket permission and make sure bucket policy should allow to the role attached to instance.
Follow this link
I have a process that scans a tape library and looks for media that has expired, so they can be removed and reused before sending the tapes to an offsite vault. (We have some 7 day policies that never make it offsite.) This process takes around 20 minutes to run, so I didn't want it to run on-demand when loading/refreshing the page. Rather, I set up a django-cron job (I know I could have done this in Linux cron, but wanted the project to be as self-contained as possible) to run the scan, and creates a file in /tmp. I've verified that this works -- the file exists in /tmp from this morning's execution. The problem I'm having is that now I want to display a list of those expired (scratch) media on my web page, but the script is saying that it can't find the file. When the file was created, I use the absolute filename "/tmp/scratch.2015-11-13.out" (for example), but here's the error I get in the browser:
IOError at /
[Errno 2] No such file or directory: '/tmp/corpscratch.2015-11-13.out'
My assumption is that this is a "web root" issue, but I just can't figure it out. I tried copying the file to the /static/ and /media/ directories configured in django, and even in the django root directory, and the project root directory, but nothing seems to work. When it says it cant' find /tmp/file, where is it really looking?
def sample():
""" Just testing """
today = datetime.date.today() #format 2015-11-31
inputfile = "/tmp/corpscratch.%s.out" % str(today)
with open(inputfile) as fh: # This is the line reporting the error
lines = [line.strip('\n') for line in fh]
print(lines)
The print statement was used for testing in the shell (which works, I might add), but the browser gives an error.
And the file does exist:
$ ls /tmp/corpscratch.2015-11-13.out
/tmp/corpscratch.2015-11-13.out
Thanks.
Edit: was mistaken, doesn't work in python shell either. Was thinking of a previous issue.
Use this instead:
today = datetime.datetime.today().date()
inputfile = "/tmp/corpscratch.%s.out" % str(today)
Or:
today = datetime.datetime.today().strftime('%Y-%m-%d')
inputfile = "/tmp/corpscratch.%s.out" % today # No need to use str()
See the difference:
>>> str(datetime.datetime.today().date())
'2015-11-13'
>>> str(datetime.datetime.today())
'2015-11-13 15:56:19.578569'
I ended up finding this elsewhere:
today = datetime.date.today() #format 2015-11-31
inputfilename = "tmp/corpscratch.%s.out" % str(today)
inputfile = os.path.join(settings.PROJECT_ROOT, inputfilename)
With settings.py containing the following:
PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
Completely resolved my issues.
In my Django app I have this kind of error: "IOError: [Errno 13] Permission denied: 'file_name'"
This is my code:
def record_export():
for file_name, tab_name in tab:
if len(globals()[tab_name].objects.all()) <> 0:
f = open(file_name, 'wb')
writer = csv.writer(f, delimiter='|')
for record in globals()[tab_name].objects.values_list():
writer.writerow([unicode(s).encode("utf-8") for s in record])
f.close()
In development enviroment all it's ok. I think that I have the permission.
In production I have: "IOError: [Errno 13] Permission denied: 'file_name'"
Do you know why?
Thanks for your help
Djangos's runserver usually runs as root, this is probably your problem.
Your webserver needs rights to read/write the file. You can use ls -l /your/path/to/file to check permissions for a given directory. To change rights and owner, use chmod and chown.
If you are running a apache2 webserver your user and group is in most cases www-data.
So I have the following problem:
On an ivent a javascript sends some text to the django server and there are two functions that should work:
views.py:
def log(request):
f = open('media/log.txt', 'r')
return HttpResponse(f, mimetype='text/plain')
def modelers(request):
mod_stat = request.POST['id']
time = datetime.datetime.now().strftime("%b %d %Y %H:%M:%S")
file=open('media/log.txt', 'a')
file.write(time)
file.write(' ')
file.write(mod_stat)
file.write('\n')
file.close()
return ErrorResponse()
so the user clicks on a button and the "modelers" function is getting the info and is trying to add a line to the log file. But it doesn't work!
The apache error.log says that
IOError: [Errno 13] Permission denied: 'media/log.txt', referer: ...
chmod 777 media doesn't help.. I know that I must config the apache somehow to let the django write files, but didn't find how :(
If not under apache it works great(so the url.py is OK), but I need to make it work with apache. The other part of the application also works fine but there are no operations with files.. until now..
Have you tried chmod 777 media/log.txt? Does ls -l media/ say rwxrwxrwx log.txt? If yes then try to specify absolute path to log.txt in f = open('...log.txt')