I'm trying to access variables that are contained in functions after an operation is performed in another Python script, but I don't want to run through the operations of the function, I just need access to the returned value of the variables gh and user.
I've tried different ways to do this such as setting the initial value of the variable to None in the main script, but the problem I run into is when I do an import of script1 into script2, it runs through the script and resets the variable in question to None again. In addition, I've tried to wrap them in a class with no luck.
Also, I've tried using if __name__ = '__main__': to run the functions, but I can't seem to figure out how to get the values out of the functions into script2 to use as global variables.
I've seen some answers here that may work such as returning the values of the function to another function for use??, but I I can't quite nail the syntax as the function doesn't seem to hold the value of the variable.
If I have asked this question incorrectly, please let me know how to improve it as I'm trying to ask "good" questions so I don't get banned. I'm still learning and I do ask a lot of questions here, but I've learned a lot by doing so.
script1.py:
#! /usr/bin/python
import github3
from github3 import login, GitHub, authorize
from getpass import getuser, getpass
import requests
import configparser
def getCreds():
try:
user = input('GitHub username: ')
except KeyboardInterrupt:
user = getuser()
password = getpass('GitHub token for {0}: '.format(user))
gh = login(user, password)
if __name__ == '__main__':
getCreds()
exec(open("next_file.py").read())
script2.py
import os
import github3
from github3 import login, GitHub, authorize
from getpass import getuser, getpass
import requests
import csv
import configparser
import sys
import script1
import codecs
gh = script1.gh
user = script1.user
def one_commit_one_file_change_pr():
#open csv file and create header rows
with open('c:\\commit_filechange.csv', 'w+') as f:
csv_writer = csv.writer(f)
csv_writer.writerow(['Login', 'Title', 'Commits', 'Changed Files','Deletions', 'Additions'])
for pr in result:
data = pr.as_dict()
changes = (gh.repository(user, repo).pull_request(data['number'])).as_dict()
if changes['commits'] == 1 and changes['changed_files'] == 1:
#keep print to console statement for testing purposes
#print changes['user']['login']
with open('c:\\commit_filechange.csv', 'a+') as f:
csv_writer = csv.writer(f)
csv_writer.writerow([changes['user']['login'], changes['title'], changes['commits'], changes['changed_files']])
one_commit_one_file_change_pr()
Here is a solution which I believe is common practice. Set up a file called global_var.py (or something like it) and store global variables there. (See this post by #systemizer) Here is a simplified version of what will work with your code:
script1.py
if __name__=='__main__':
user = raw_input('GitHub username: ')
with open('global_var.py','w') as f:
f.write("user = '%s'" % user)
password = 'blah'
gh = '<login(user, password)>'
script2.py
from script1 import gh
from global_var import user
print user
print gh
This answer is purely based on my assumption that you want get the user credentials only once and want to re-use it "n" number of times later in other scripts.
Here is how I would do it ,
Update1
Your problem also has to do with how you want to organize and run your scripts, the below examples work if you have bundled your scripts in to python package and run them
For. eg
but if you are planning to run individual scripts separately , then you have no other option but to invoke the login prompt for each script unless you plan to completely remove asking for user credentials and use the pre-configured data from a file.
script1
from github3 import login
USER_CREDS = None # Store raw input credentials here ,not recomended
GIT_USERS = {} # global dict to store multiple users with username as key
def getCredentials():
global USER_CREDS
if USER_CREDS:
print "returning user credentials"
return USER_CREDS
print "gettting user credentials"
user = raw_input("Enter Username")
pwd = raw_input("Enter Password")
USER_CREDS = (user, pwd)
return USER_CREDS
def do_login():
global GIT_USERS
user, pwd = getCredentials()
if not GIT_USERS.get(user, None):
gh = login(user, password=pwd)
GIT_USERS[user] = gh
return GIT_USERS[user]
in other scripts
from script1 import do_login
# the first time do_login() is called it asks for user credentials
print do_login()
# the next times it just returns the previously collected one
print do_login()
Example 2
script 3
from script1 import do_login
creds = do_login()
script 4
from script3 import creds
from script1 import do_login
print creds
print do_login() # No input prompt would be provided
Related
I made a User login system in which user must enter one of three alphabets that is x to stop the program, y if you are a new user and n if you are not a new user.
self.register = input('Enter y if you have register or n if you are new or x to quit:')
If user enter's 'n' then it will create a new user and store it into a dictionary:-
ex:- username = Fread
password = hello
{'Fread':'hello'}
From here if user enter's y then it will check if te user exist with this condition:-
self.existing_Id = input('Please enter your existing id here:')
self.existing_Password = input('Please enter your existing password here:')
if self.existing_Id in self.save and self.save[self.id] == self.password:
print('you have successfully logged in')
else:
print('user not found please try again')
Also if the user already exist then it will also not create a user:-
while True:
self.id = input('please enter your ID here:')
if self.id in self.save:
print('User already exist!!!')
break
Here i am trying to save all the username and password into file then everytime i stop and rerun te code again it should load all the previous saved file into a dictionary?
What you're trying to do is called serialization : Turning python objects into things you can write into files, and back into python objects.
Python has some built in capabilities in the form of pickles :
from pathlib import Path
import pickle
SAVE_FILE = Path('some/path/file.pickle')
def save_state(state_dict):
pickle.dump(state_dict, SAVE_FILE)
def restore_state():
return pickle.load(SAVE_FILE)
In this example, you can use the save_state function before exiting the program to write your data to some/path/file.saved, and load_state when you open to read data.
Note that pickling has some security issues if the saved state file will be handled by someone malicious. In those circumstances, you could do a similar job with the JSON module, albeit with a little less leway with the data structures you could store in the file.
import JSON
from pathlib import Path
SAVE_FILE = Path('some/path/file.json')
def save_state(state_dict):
JSON.dump(state_dict, SAVE_FILE)
def restore_state():
return JSON.load(SAVE_FILE)
I know how to get the current user using os or getpass.getuser(), but is there a way to get a list of all user and not only the current one? Read os and getpass documentations but i didn't thing anything.
This is OS-specific.
In Linux, see Python script to list users and groups.
In Windows:
via WMI
parse the output of wmic UserAccount get Name, or
make the same call with the wmi module:
import wmi
w=wmi.WMI()
# The argument (field filter) is only really needed if browsing a large domain
# as per the warning at https://learn.microsoft.com/en-us/windows/desktop/cimwin32prov/win32-useraccount
# Included it for the sake of completeness
for u in w.Win32_UserAccount(["Name"]): #Net
print u.Name
del u
via the NetUserEnum API
parse the output of net user, or
make the same call with pywin32:
import win32net, win32netcon
names=[]; resumeHandle=0
while True:
data,_,resumeHandle=win32net.NetUserEnum(None,0,
win32netcon.FILTER_NORMAL_ACCOUNT,resumeHandle)
names.extend(e["name"] for e in data)
if not resumeHandle: break
del data,resumeHandle
print names
Two ideas for methods that are Windows-specific:
from pathlib import Path
users = [x.name for x in Path(r'C:\Users').glob('*') if x.name not in ['Default', 'Default User', 'Public', 'All Users'] and x.is_dir()]
print(users)
Paths in C:\Users
import os
os.system('net user > users.txt')
users = Path('./users.txt').read_text()
print(users)
Output from net user
I am trying to write unit tests for a python script. My script takes user input whether proxy credentials are required or not. I have seen several answer-1, answer-2, answer-3 like executing with subprocess and pexpect. But my intention is that after taking user input, I have to execute other functions in the script. So executing the script doesn't help. My python script is below. Can someone provide me suggestions or with a way to achieve this?
import getpass
class ProxyDetails:
def __init__(self,option):
self.option = option
self.proxy_option = self.get_web_proxy_details()
self.call_request()
self.parse_test()
def get_web_proxy_details(self):
if self.option == "Default":
choice = raw_input("Enter credentials : Y/N ").lower()
if choice.lower() == "y":
self.proxy_username = getpass.getpass("Enter Username for Proxy : ")
self.proxy_password = getpass.getpass("Enter Password for Proxy : ")
self.requireProxyCredentials = "Y"
elif choice.lower() == "n":
print("credentials are not present ")
else:
print("proxy is none ")
def call_request(self):
# this method will do API call
pass
def parse_test(self):
#this method will parse the json
pass
obj=ProxyDetails(option="Default")
I want to send input value when Enter credentials : Y/N is prompted.
Actually, this is a duplicate question.I am not deleting this as it might be useful for someone else.
import sys
import StringIO
f1 = sys.stdin
f = StringIO.StringIO('n')
sys.stdin = f
obj=ProxyDetails(option="Default")
sys.stdin = f1
I am working on a reporting system which automatically updates results overnight and puts them in files on a google drive.
The way it is working right now is by hardcoding the login and password information which is by no means ideal even if it works. A search in StackOverflow does not point this question specifically, which surprises me.
A very simplified example with the relevant sections of code looks like:
import gdata.docs.service
class GDrive(object):
def __init__(self, email, password)
self.gd_client = gdata.docs.service.DocService()
self.gd_client.ClientLogin(email, password)
def upload(self):
# Code to Upload file somewhere in GDrive.
gd = GDrive("the#email.address", "ThePassword")
gd.upload()
Can something be done to avoid writing explicitly the username and password?
I would make use of the OAuth2 protocol. It is a secure way to store credentials for a long time (but not forever).
A bit of a short answer from my cell, but check:
https://developers.google.com/drive/about-auth
And this bit makes working with Oauth2 a lot easier:
https://developers.google.com/api-client-library/python/platforms/google_app_engine#Decorators
import gdata.docs.service
import sys
class GDrive(object):
def __init__(self, email, password)
self.gd_client = gdata.docs.service.DocService()
self.gd_client.ClientLogin(email, password)
def upload(self):
# Code to Upload file somewhere in GDrive.
if __name__ == "__main__":
username = sys.argv[1]
password = sys.argv[2]
gd = GDrive(username, password)
gd.upload()
now run from your commandline like script.py the#email.address ThePassword where script.py is the name of your python scripts...
I am running into a problem when running the follow python script on the server looking for commit information for the push making sure it follows a particular syntax, I am unable to get input from the user which is why the username and password are hard coded. I am now also unable to get the list of commit message that occurred before this particular push.
#!/usr/bin/python
import SOAPpy
import getpass
import datetime
import sys
import re
import logging
import os
def login(x,y):
try:
auth = soap.login(x, y)
return auth
except:
sys.exit( "Invalid username or password")
def getIssue(auth,issue):
try:
issue = soap.getIssue(auth, issue)
except:
sys.exit("No issue of that type found : Make sure all PRs are vaild jira PRs")
def git_get_commit_msg(commit_id):
return get_shell_cmd_output("git rev-list --pretty --max-count=1 " + commit_id)
def git_get_last_commit_id():
return get_shell_cmd_output("git log --pretty=format:%H -1")
def getCommitText():
commit_msg_filename = sys.argv[1]
try:
commit_msg_text = open(commit_msg_filename).read()
return commit_msg_text
except:
sys.exit("Could not read commit message")
def git_get_array_of_commit_ids(start_id, end_id):
output = get_shell_cmd_output("git rev-list " + start_id + ".." + end_id)
if output == "":
return None
commit_id_array = string.split(output, '\n')
return commit_id_array
def get_shell_cmd_output(cmd):
try:
proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
return proc.stdout.read().rstrip('\n')
except KeyboardInterrupt:
logging.info("... interrupted")
except Exception, e:
logging.error("Failed trying to execute '%s'", cmd)
def findpattern(commit_msg):
pattern = re.compile("\w\w*-\d\d*")
group = pattern.findall(commit_msg)
print group
found = len(group)
found =0
issues = 0
for match in group:
auth = soap.login(jirauser,passwd)
getIssue(auth,match)
issues = issues + 1
found+=1
if found ==0:
sys.exit("No issue patterns found.")
print "Retrieved issues: " + str(issues)
def update():
print sys.argv[2]
print sys.argv[3]
old_commit_id = sys.argv[2]
new_commit_id = sys.argv[3]
commit_id_array = git_get_array_of_commit_ids(old_commit_id, new_commit_id)
for commit_id in commit_id_array:
commit_text = git_get_commit_msg(commit_id)
findpattern(commit_text)
soap = SOAPpy.WSDL.Proxy('some url')
# this line if for repointing the input from dev/null
#sys.stdin = open('/dev/tty', 'r') # this fails horribly.
#ask user for input
#jirauser = raw_inp
#("Username for jira: ")
jirauser = "username"
passwd = "987654321"
#passwd = getpass.getpass("Password for %s: " % jirauser)
login(jirauser,passwd)
#commit_msg = getCommitText()
#findpattern(commit_msg)
update()
The intended goal of this code is to check the commits made locally, and to parse through them for the intended pattern, as well as checking the in jira if that PR exists. it is a server side hook that get activated on a push to the repository.
Any tips on writing python hooks would be appreciated. Please and thank you.
I suggest that you have a look at gitorious (http://gitorious.org/gitorious).
They use ssh to handle authentication and rights management (getting the username given by ssh).
They also have some hooks on git repositories. I guess it could help to see how they are processing git hooks using ruby.
By the time your update hook fires, the server has the new commits: the question is whether your hook will allow the ref in question to move. What information from the local (sending) repository do you want?
For the credentials issue, funnel everyone through a single user. For example, GitHub does it with the git user, which is why their SSH URLs begin with git#github.com:.... Then in ~git/.ssh/authorized_keys, associate a username with each key. Note that the following should be on a single line but is wrapped for presentation purposes.
no-agent-forwarding,no-port-forwarding,no-pty,no-X11-forwarding,
command="env myuser=gbgcoll /usr/bin/git-shell -c \"${SSH_ORIGINAL_COMMAND:-}\""
ssh-rsa AAAAB...
Now to see who's trying to do the update, your hook examines the $myuser environment variable.
This doesn't give you each user's Jira credentials. To solve that issue, create a dummy Jira account that has read-only access to everything, and hardcode that Jira account's credentials in your hook. This allows you to verify that a given PR exists.