I'm trying to access a file on our Samba server using Python. I found out I need to use a Samba client for this, so I started using PySmbClient. Even though there are many examples online of how to do this, mine just does not want to work. See below.
smb = smbclient.SambaClient(server="192.168.0.320", share="DATA", domain="WORKGROUP",username="admin", password="abc123")
f = smb.open('test.json', 'r')
This produces the following error:
OSError: [Errno 2] No such file or directory
with the following trace:
Traceback (most recent call last):
File "create_dataset.py", line 35, in <module>
f = smb.open('serverSaver.txt', 'r')
File "/home/grant/Development/create_dataset/env/local/lib/python2.7/site-packages/smbclient.py", line 408, in open
f = _SambaFile(self, path, mode)
File "/home/grant/Development/create_dataset/env/local/lib/python2.7/site-packages/smbclient.py", line 448, in __init__
connection.download(remote_name, self._tmp_name)
File "/home/grant/Development/create_dataset/env/local/lib/python2.7/site-packages/smbclient.py", line 393, in download
result = self._runcmd('get', remote_path, local_path)
File "/home/grant/Development/create_dataset/env/local/lib/python2.7/site-packages/smbclient.py", line 184, in _runcmd
return self._raw_runcmd(fullcmd)
File "/home/grant/Development/create_dataset/env/local/lib/python2.7/site-packages/smbclient.py", line 168, in _raw_runcmd
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
File "/usr/lib/python2.7/subprocess.py", line 711, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1343, in _execute_child
raise child_exception
I've read and implemented many "solutions", but so far nothing has worked for me. I can access the Samba server with the given credentials through my file manager just fine, so I know those values should be fine. I even spoke to our sys admin and he doesn't know what could be wrong.
It must be more than the simple code I wrote. Do you think there's an issue on the server side of things? Something with the values I input into SambaClient? At this point I'm pretty much open to anything that leads to a solution.
Here's some code that works for me, transferring a file from a Linux Samba share to my Windows laptop. It's also known to work fine in the other direction (Linux client, Windows server).
I'm using the pysmb library version 1.1.19 (the latest) and Python 2.7.1.
See the pysmb site for the pysmb package; I actually downloaded and installed it directly from its tarball and setup.py, as pip was throwing an error.
The pysmb package is less user-friendly but it does work well for Windows clients.
I set up a share called "my_share" on the Linux machine for user "edwards" using the following entry in smb.conf:
[my_share]
path = /home/edwards
valid_users = edwards
read only = no
guest ok = yes
browseable = yes
And then used the following code to list the files on the share, and download a file called "rti_license.dat" to my laptop:
import tempfile
import smb
import shutil
from smb.SMBConnection import SMBConnection
share_name = "my_share"
user_name = "edwards"
password = "######" # secret :-)
local_machine_name = "laptop" # arbitrary
server_machine_name = "edwards-Yocto" # MUST match correctly
server_IP = "192.162.2.1" # as must this
# create and establish connection
conn = SMBConnection(user_name, password, local_machine_name, server_machine_name, use_ntlm_v2 = True)
assert conn.connect(server_IP, 139)
# print list of files at the root of the share
files = conn.listPath(share_name, "/")
for item in files:
print item.filename
# check if the file we want is there
sf = conn.getAttributes(share_name, "rti_license.dat")
print sf.file_size
print sf.filename
# create a temporary file for the transfer
file_obj = tempfile.NamedTemporaryFile(mode='w+t', delete=False)
file_name = file_obj.name
file_attributes, copysize = conn.retrieveFile(share_name, "rti_license.dat", file_obj)
print copysize
file_obj.close()
# copy temporary file
shutil.copy(file_name, "rti_license.dat")
# close connection
conn.close()
Note that the server name must be correct or the connection won't work (from a Linux machine it's the output of the hostname command)
Hope this may be useful.
Related
Im looking to download a CSV file that is on a shared dropbox folder. The code that I currently have given me an ApiError. Full code and error below:
My Code:
import dropbox
ACCESS_TOKEN = '***MY ACCESS_TOKEN***'
dbx = dropbox.Dropbox(ACCESS_TOKEN)
url = "https://www.dropbox.com/sh/s8vwbg46zjsg3rw/AAC0T1BhIgfp5BfH_sJ_Vnb1a?dl=0"
file = "https://www.dropbox.com/sh/s8vwbg46zjsg3rw/AAC0T1BhIgfp5BfH_sJ_Vnb1a?dl=0&preview=Stock+List+2021-03-08.csv"
md, res = dbx.sharing_get_shared_link_file(url=file)
print(md)
print(res)
Error:
Traceback (most recent call last):
File "D:\***\PyCharm\Furniture\Test 1\dropbox_test.py", line 10, in <module>
md, res = dbx.sharing_get_shared_link_file(url=file)
File "C:\Python39\lib\site-packages\dropbox\base.py", line 4181, in sharing_get_shared_link_file
r = self.request(
File "C:\Python39\lib\site-packages\dropbox\dropbox_client.py", line 346, in request
raise ApiError(res.request_id,
dropbox.exceptions.ApiError: ApiError('90075839f9f94c53a112a48692314d4f', GetSharedLinkFileError('shared_link_is_directory', None))
Any help would be great. I have also tried files_download and I also get an error.
The "https://www.dropbox.com/sh/s8vwbg46zjsg3rw/AAC0T1BhIgfp5BfH_sJ_Vnb1a?dl=0..." link itself points to a folder, not a particular file (whether or not you have the preview parameter on it).
Here are two ways you can make this work:
Supply the path parameter on sharing_get_shared_link_file to specify the file in the folder you want:
md, res = dbx.sharing_get_shared_link_file(url=url, path="/Stock List 2021-03-08.csv")
Use the actual link to the file in particular (which I retrieved manually via the shared link page):
file = "https://www.dropbox.com/sh/s8vwbg46zjsg3rw/AABhEIN92e98iufhllgVuIvga/Stock%20List%202021-03-08.csv?dl=0"
md, res = dbx.sharing_get_shared_link_file(url=file)
Also, if the file is in the connected account for the access token you're using, you should certainly be able to use files_download to download it. Feel free to open another question with the details of that issue if you wish.
so I have a problem trying to run this python code as administrator so I am not able to access and write on host file. Can anyone help me? I have looked through many of other questions but non of them seem to work.
Host File Directory: C:\Windows\System32\Drivers\etc\hosts
(Such as)
Request UAC elevation from within a Python script?
Some of these answers actually work on prompting to get administrator access, but it still doesn't give permission to my program. The only way I figured out is to run python shell as administrator first and then run the code or run the command prompt as administrator and open python file with command prompt.
WEBSITE
https://boostlog.io/#faisalnad/create-a-website-blocker-with-python-5afe86ff47018500491f4898
This program is made for blocking website.
import time
from datetime import datetime as dt
# change hosts path according to your OS
hosts_path = r”C:\Windows\System32\Drivers\etc\hosts”
# localhost's IP
redirect = "127.0.0.1"
# websites That you want to block
website_list = ["www.facebook.com","facebook.com",
"dub119.mail.live.com","www.dub119.mail.live.com",
"www.gmail.com","gmail.com"]
while True:
# time of your work
if dt(dt.now().year, dt.now().month, dt.now().day,8) < dt.now() < dt(dt.now().year, dt.now().month, dt.now().day,16):
print("Working hours...")
with open(hosts_path, 'r+') as file:
content = file.read()
for website in website_list:
if website in content:
pass
else:
# mapping hostnames to your localhost IP address
file.write(redirect + " " + website + "\n")
else:
with open(hosts_path, 'r+') as file:
content=file.readlines()
file.seek(0)
for line in content:
if not any(website in line for website in website_list):
file.write(line)
# removing hostnmes from host file
file.truncate()
print("Fun hours...")
time.sleep(5)
This is the error:
Working hours...
Traceback (most recent call last):
File "C:\Users\Key\Desktop\random project.py", line 19, in <module>
with open(hosts_path, 'r+') as file:
PermissionError: [Errno 13] Permission denied: 'C:\\Windows\\System32\\Drivers\\etc\\hosts'
FILE DIRECTORY
You can add write permission for the user under which your program runs following this link to add permission to the host file
I want to print a pdf file in python. My code is as below:
def printing_reports():
import os
fp = open("/path-to-file/path.txt",'r')
for line in fp:
os.system('lp -d HPLaserJ %s' % (str(line)))
I am on Fedora 20. path.txt is a file that contain path to the pdf file like '/home/user/a.pdf'
When I run the code it says no such file or directory.
Thanks
Try this code may help:
import os
def printing_reports():
fp = open("/path-to-file/path.txt",'r')
for line in fp:
os.system('lp -d HPLaserJ {0}'.format(line.strip()))
printing_reports()
Make sure the file in every line exists.
Old question, but as I needed a an answer of how to print a pdf file from python, I found this answer more profound:
import cups
conn = cups.Connection()
printers = conn.getPrinters()
printer_name = printers.keys()[0]
ppd_options = {}
cups_job_id = conn.printFile(printer_name,'/path/to/a.pdf',"Title printjob", ppd_connection_options)
It uses the pycups module, which needs CUPS >= 1.7 installed on your system (according to their GitHub page)
The ppd_options dictionary might just be empty. (PPD - Postscript Printer Driver)
I have written a simple program that opens a csv file and text all the numbers in it. I am using Twilio (twilio-python) as a service provider. My code works fine as a python script. However, when I compile the script (using py2exe), the exe file errors. This is the error I receive from the log file....
Traceback (most recent call last):
File "sms.py", line 39, in <module>
File "twilio\rest\resources\messages.pyc", line 112, in create
File "twilio\rest\resources\base.pyc", line 352, in create_instance
File "twilio\rest\resources\base.pyc", line 204, in request
File "twilio\rest\resources\base.pyc", line 129, in make_twilio_request
File "twilio\rest\resources\base.pyc", line 101, in make_request
File "httplib2\__init__.pyc", line 1570, in request
File "httplib2\__init__.pyc", line 1317, in _request
File "httplib2\__init__.pyc", line 1252, in _conn_request
File "httplib2\__init__.pyc", line 1021, in connect
File "httplib2\__init__.pyc", line 80, in _ssl_wrap_socket
File "ssl.pyc", line 387, in wrap_socket
File "ssl.pyc", line 141, in __init__
ssl.SSLError: [Errno 185090050] _ssl.c:340: error:0B084002:x509 certificate
routines:X509_load_cert_crl_file:system lib
I don't recieve this error when i am using the un-compiled code (below)
import sys #2 params --- /path/to/contact/file --- up to 160 char msg
import csv
import time
from twilio.rest import TwilioRestClient
ACCOUNT_SID = "**************************"
AUTH_TOKEN = "**************************"
client = TwilioRestClient(ACCOUNT_SID, AUTH_TOKEN)
sys.argv.pop(0)
contactFile = sys.argv[0]
sys.argv.pop(0)
msg = (' ').join(sys.argv)
print contactFile
print " "
print msg
info = []
with open(contactFile,'rb') as csvfile:
reader = csv.reader(csvfile, delimiter=',', quotechar='|')
for row in reader:
info.append(row)
contactCount = len(info)-1
if contactCount > 0:
#remove first item from list because its not a value that is needed....
info.pop(0)
for i in info:
print " "
contactName = i[0]
phoneNumber = i[1]
print "Texting " + contactName + "... \n"
client.messages.create(
to=phoneNumber,
from_="+14782856136",
body=msg
)
time.sleep(1.5)
else:
print("SMSify Error \n The contact file doesn't have any contacts in it.")
Any thoughts on what is going on??
EDIT:
Here is my setup.py file
from distutils.core import setup
import py2exe, sys, os
sys.argv.append('py2exe')
Mydata_files = [('cacert.pem', ['C:\\Python27\\Lib\\site-
packages\\twilio\\conf\\cacert.pem'])]
setup(
console=['sms.py'],
data_files = Mydata_files,
options={
"py2exe":{
"bundle_files": 1,
"compressed": True
}
}
)
It's happened because self-signed certificate file missed in bundle.
This problem is same for requests and httplib2 modules.
For example, if you have a file named req_example.py that using request module:
import requests
url = 'https://google.com/'
requests.get(url)
It works when you run it as python req_example.py, but when bundle it, it's not working.
Or if you have a file named http2_example.py that using http2 module:
import httplib2
url = 'https://google.com/'
http = httplib2.Http()
http.request(url)
It works when you run it as python http2_example.py , but when bundle it, it's not working.
To fix that, you have two options, one bad and one good.
Disable verifying SSL certificates:
To do that for requests module:
import requests
url = 'https://google.com/'
requests.get(url, verify=False)
And for httplib2 module:
import httplib2
http = httplib2.Http(disable_ssl_certificate_validation=True)
http.request(url)
Add self-signed certificate file to bundle:
For requests module, the file cacert.pem is located in:
.../PythonXX/lib/site-packages/requests/cacert.pem
And for httplib2 module is in:
.../PythonXX/lib/site-packages/httplib2/cacerts.txt
For each of them, you can copy it to inside of your project (or just address to it),
And config setup.py for including it:
setup(console=['temp.py'],
# for `requests` module
data_files=['cacert.pem'] ) # or data_files=['cacerts.txt'] ) for `httplib2`
And change your code to using that, for request module:
import os
import requests
url = 'https://google.com/'
cert ='cacert.pem'
# or os.environ['REQUESTS_CA_BUNDLE'] = cert
os.environ['REQUESTS_CA_BUNDLE'] = os.path.join(os.getcwd(), cert)
requests.get(url)
And for httplib2 module:
import httplib2
cert = 'cacerts.txt'
http = httplib2.Http(ca_certs=cert)
http.request(url)
Or if your httplib2 version is 0.8, you can create a file that
should named ca_certs_locater.py, and define a get function,
that return path of ca_certs file.
def get():
return 'cacerts.txt'
Ok, now for your error, and for twilio module, it use httplib2, and cacert.pem of it is in:
.../twilio/conf/cacert.pem
So you need to add this file to setup.py as described above.
But twilio itself has a function with name get_cert_file that pass ca_cert file to httplib2.
I think if you using ca_certs_locater.py that described above, it also will works for that,
but if not, you have yet an ugly option, so you can monkey patch get_cert_file function of twilio:
from twilio.rest.resources.base import get_cert_file
get_cert_file = lambda: 'cacert.pem'
Note that this may an issue for twilio or even for py2exe or PyInstaller .
I had the same problem with twilio and pyinstaller, and was able to fix it by modifying the base.py module in twilio\rest\resources:
def get_cert_file():
""" Get the cert file location or bail """
# XXX - this currently fails test coverage because we don't actually go
# over the network anywhere. Might be good to have a test that stands up a
# local server and authenticates against it.
try:
# Apparently __file__ is not available in all places so wrapping this
# in a try/catch
current_path = os.path.realpath(__file__)
#ca_cert_path = os.path.join(current_path, "..", "..", "..", (old path)
# "conf", "cacert.pem")
ca_cert_path = os.getcwd() + '\Config\cacert.pem' (my new path)
return os.path.abspath(ca_cert_path)
(I am storing my cacert.pem file in a Config folder off my main script directory)
There should probably be a way for py2exe to bundle up non-Python files, like templates or in this case the SSL certificate stored in cacert.pem. Normally this is done automatically with the MANIFEST.in, but I am not sure how that project handles it. Check the documentation there for more information.
I am trying to read a file from an FTP server. The file is a .gz file. I would like to know if I can perform actions on this file while the socket is open. I tried to follow what was mentioned in two StackOverflow questions on reading files without writing to disk and reading files from FTP without downloading but was not successful.
I know how to extract data/work on the downloaded file but I'm not sure if I can do it on the fly. Is there a way to connect to the site, get data in a buffer, possibly do some data extraction and exit?
When trying StringIO I got the error:
>>> from ftplib import FTP
>>> from StringIO import StringIO
>>> ftp = FTP('ftp://ftp.ncbi.nlm.nih.gov/pub/pmc/PMC-ids.csv.gz')
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
ftp = FTP('ftp://ftp.ncbi.nlm.nih.gov/pub/pmc/PMC-ids.csv.gz')
File "C:\Python27\lib\ftplib.py", line 117, in __init__
self.connect(host)
File "C:\Python27\lib\ftplib.py", line 132, in connect
self.sock = socket.create_connection((self.host, self.port), self.timeout)
File "C:\Python27\lib\socket.py", line 553, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
gaierror: [Errno 11004] getaddrinfo failed
I just need to know how can I get data into some variable and loop on it until the file from FTP is read.
I appreciate your time and help. Thanks!
Make sure to login to the ftp server first. After this, use retrbinary which pulls the file in binary mode. It uses a callback on each chunk of the file. You can use this to load it into a string.
from ftplib import FTP
ftp = FTP('ftp.ncbi.nlm.nih.gov')
ftp.login() # Username: anonymous password: anonymous#
# Setup a cheap way to catch the data (could use StringIO too)
data = []
def handle_binary(more_data):
data.append(more_data)
resp = ftp.retrbinary("RETR pub/pmc/PMC-ids.csv.gz", callback=handle_binary)
data = "".join(data)
Bonus points: how about we decompress the string while we're at it?
Easy mode, using data string above
import gzip
import StringIO
zippy = gzip.GzipFile(fileobj=StringIO.StringIO(data))
uncompressed_data = zippy.read()
Little bit better, full solution:
from ftplib import FTP
import gzip
import StringIO
ftp = FTP('ftp.ncbi.nlm.nih.gov')
ftp.login() # Username: anonymous password: anonymous#
sio = StringIO.StringIO()
def handle_binary(more_data):
sio.write(more_data)
resp = ftp.retrbinary("RETR pub/pmc/PMC-ids.csv.gz", callback=handle_binary)
sio.seek(0) # Go back to the start
zippy = gzip.GzipFile(fileobj=sio)
uncompressed = zippy.read()
In reality, it would be much better to decompress on the fly but I don't see a way to do that with the built in libraries (at least not easily).
There are two easy ways I can think of to download a file using FTP and store it locally:
Using ftplib:
from ftplib import FTP
ftp = FTP('ftp.ncbi.nlm.nih.gov')
ftp.login()
ftp.cwd('pub/pmc')
ftp.retrbinary('RETR PMC-ids.csv.gz', open('PMC-ids.csv.gz', 'wb').write)
ftp.quit()
Using urllib
from urllib import urlretrieve
urlretrieve("ftp://ftp.ncbi.nlm.nih.gov/pub/pmc/PMC-ids.csv.gz", "PMC-ids.csv.gz")
If you don't want to download and store it to a file, but you want to process it gradually as it comes, I suggest using urllib2:
from urllib2 import urlopen
u = urlopen("ftp://ftp.ncbi.nlm.nih.gov/pub/pmc/readme.txt")
for line in u:
print line
which prints your file line by line.
That is not possible. To process data on the server, you need to have some sort of execution permissions, be it for a shell script you would send or SQL access.
FTP is pure file transfer, no execution allowed. You will need either to enable SSH access, load the data into a Database and access that with queries or download the file with urllib then process it locally, like this:
import urllib
handle = urllib.urlopen('ftp://ftp.ncbi.nlm.nih.gov/pub/pmc/PMC-ids.csv.gz')
# Use data, maybe: buffer = handle.read()
In particular, I think the third one is the only zero-effort solution.