Please , can you help me get rid of this error? - python-3.x

I am trying to create a code for a random password generator with python and flask. I have created both the front end and the backend yet every time i am trying to run it i get a json error:
raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
this is my front end code:
import requests
import json
session=requests.session()
data={"letters":0,"symbols":0,"numbers":0}
header={"content-type": "application/json"}
print("Welcome to the PyPassword generator!")
while True:
data ["letters"]=input("how many lettres would you like in your password? > ")
data ["symbols"]=input("how many symbols would you like? > ")
data ["numbers"]=input("how many numbers would you like? > ")
print(data)
r=session.post("http://127.0.0.1:1337/api/PyPassword_generator", data=json.dumps(data), headers=header)
if r:
break
json_data=r.json()
print(json_data)
EDIT: Ading the response from the server component
Traceback (most recent call last):
File "C:\Users\User\PycharmProjects\pythonProject\venv\lib\site-packages\requests\models.py", line 972, in json
return complexjson.loads(self.text, **kwargs)
File "C:\Users\User\PycharmProjects\pythonProject\venv\lib\site-packages\simplejson\__init__.py", line 525, in loads
return _default_decoder.decode(s)
File "C:\Users\User\PycharmProjects\pythonProject\venv\lib\site-packages\simplejson\decoder.py", line 370, in decode
obj, end = self.raw_decode(s)
File "C:\Users\User\PycharmProjects\pythonProject\venv\lib\site-packages\simplejson\decoder.py", line 400, in raw_decode
return self.scan_once(s, idx=_w(s, idx).end())
simplejson.errors.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\User\Downloads\client.py", line 19, in <module>
json_data = r.json()
File "C:\Users\User\PycharmProjects\pythonProject\venv\lib\site-packages\requests\models.py", line 976, in json
raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
b'<!doctype html>\n<html lang=en>\n<title>405 Method Not Allowed</title>\n<h1>Method Not Allowed</h1>\n<p>The method is not allowed for the requested URL.</p>\n'
Process finished with exit code 1ode here
so this is the server code
from flask import Flask, request, session, jsonify,json
import random
class game:
def __init__(self,lettres,symbols,numbers):
self.letters=lettres
self.symbols=symbols
self.numbers=numbers
self.app = Flask("Shmuel Api server",static_url_path='')
self.app.secret_key="Secret"
#self.app.route('/api/ PyPassword_generator', methods=['Get',"Post"])
def PyPassword_generator():
print(request.data)
print(json.loads(request.data.decode("ascii")))
a=int(request.json["letters"])
b=int(request.json["symbols"])
c=int(request.json["numbers"])
password = self.test(a,b,c)
jsonify({f"your password is : {password}"})
def run(self):
debug=True
self.app.run(host='10.0.0.10', port='5000', debug=debug)
password_list=[]
for char in range(a):
password_list.append(random.choice(self.letters))
for char in range(b):
password_list.append(random.choice(self.symbols))
for char in range(c):
password_list.append(random.choice(self.numbers))
random.shuffle(password_list)
password="".join(password_list)
return password
mp=game(["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"],["0","1","2","3","4","5","6","7","8","9"],["!","#","$","%","&","(",")","*","+"])
mp.run()
and this is the response I get
* Serving Flask app 'Shmuel Api server' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://10.0.0.10:5000 (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 446-336-887
10.0.0.10 - - [11/Jun/2022 21:23:52] "POST /api/PyPassword_generator HTTP/1.1" 405 -

There's a space in the URL of the server component, and the methods must be in caps...
#self.app.route('/api/ PyPassword_generator', methods=['Get',"Post"])
should look like:
#self.app.route('/api/PyPassword_generator', methods=['GET',"POST"])
Defining Flask routes inside an object like this looks wrong though. I would probably simplify it:
from flask import Flask, request, session, jsonify,json
import random
app = Flask("__name__")
app.config['SECRET_KEY']='make me super secret'
#app.route('/api/PyPassword_generator', methods=['GET',"POST"])
def PyPassword_generator():
# print(request.data)
# print(json.loads(request.data.decode("ascii")))
try:
submitted_data = request.get_json()
a=int(submitted_data["letters"])
b=int(submitted_data["symbols"])
c=int(submitted_data["numbers"])
except ValueError: # Some issue with the input
return {'error': 'invalid input data'}, 400
password = generate_password(a,b,c)
return jsonify({'message': f"your password is : {password}"})
Then on the client end, simplify things, by using requests native json argument, which means you don't need to use the json.dumps or pass the headers either, as this arg automatically sets the Content-Type...
import requests
session=requests.session()
data={"letters":0,"symbols":0,"numbers":0}
print("Welcome to the PyPassword generator!")
while True:
data["letters"]=input("how many lettres would you like in your password? > ")
data["symbols"]=input("how many symbols would you like? > ")
data["numbers"]=input("how many numbers would you like? > ")
print(data)
r = session.post("http://127.0.0.1:5005/api/PyPassword_generator", json=data)
json_data=r.json()
print(json_data)
if r.ok:
break
Of course generating passwords comes with its own security considerations, and I assume this is just for learning python. Transmitting passwords over the wire comes with security considerations you should understand first.
With that in mind, instead of random.shuffle for this, perhaps investigate the python secrets module. Let's implement the generate_password function, and instead only work with the input a to set the length of the overall password. Using their example, you could have something like:
import secrets
import string
def generate_password(a,b,c):
alphabet = string.ascii_letters + string.digits + string.punctuation
password = ''.join(secrets.choice(alphabet) for i in range(a))
return password
Now this all works like:
Welcome to the PyPassword generator!
how many lettres would you like in your password? > 20
how many symbols would you like? > 1
how many numbers would you like? > 1
{'letters': '20', 'symbols': '1', 'numbers': '1'}
{'message': 'your password is : R#!o]KFnqk`,+Wg{JQ:#'}
Of course some obvious changes required on your part, but hope this helps.

Related

module 'http.client' has no attribute 'HTTPSConnection' when I run it in VSCode

I am trying to do the lab exercise of Text Analytics of AI-102-AIEngineer, Microsoft using Python in VSCode. But I get the error
module 'http.client' has no attribute 'HTTPSConnection'
when I run the code from my VSCode editor. I configured my key and endpoint correctly. The code is here:
from dotenv import load_dotenv
import os
import http.client, base64, json, urllib
from urllib import request, parse, error
def main():
global cog_endpoint
global cog_key
try:
# Get Configuration Settings
load_dotenv()
cog_endpoint = os.getenv('COG_SERVICE_ENDPOINT')
cog_key = os.getenv('COG_SERVICE_KEY')
# Get user input (until they enter "quit")
userText =''
while userText.lower() != 'quit':
userText = input('Enter some text ("quit" to stop)\n')
if userText.lower() != 'quit':
GetLanguage(userText)
except Exception as ex:
print(ex)
def GetLanguage(text):
try:
# Construct the JSON request body (a collection of documents, each with an ID and text)
jsonBody = {
"documents":[
{"id": 1,
"text": text}
]
}
# Let's take a look at the JSON we'll send to the service
print(json.dumps(jsonBody, indent=2))
# Make an HTTP request to the REST interface
uri = cog_endpoint.rstrip('/').replace('https://', '')
conn = http.client.HTTPSConnection(uri)
# Add the authentication key to the request header
headers = {
'Content-Type': 'application/json',
'Ocp-Apim-Subscription-Key': cog_key
}
# Use the Text Analytics language API
conn.request("POST", "/text/analytics/v3.0/languages?", str(jsonBody).encode('utf-8'), headers)
# Send the request
response = conn.getresponse()
data = response.read().decode("UTF-8")
# If the call was successful, get the response
if response.status == 200:
# Display the JSON response in full (just so we can see it)
results = json.loads(data)
print(json.dumps(results, indent=2))
# Extract the detected language name for each document
for document in results["documents"]:
print("\nLanguage:", document["detectedLanguage"]["name"])
else:
# Something went wrong, write the whole response
print(data)
conn.close()
except Exception as ex:
print(ex)
if __name__ == "__main__":
main()
Make sure /usr/local/lib/python3.8/http/client.py exists.
In an interractive python console, test:
>>> import http.client
>>> http.client.HTTPConnection('www.python.org')
<http.client.HTTPConnection object at 0x106a9f5f8>
>>> http.client.HTTPSConnection('www.python.org')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'http.client' has no attribute 'HTTPSConnection'
Check SSL as well:
>>> import _ssl
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: dlopen(/Users/ishandutta2007/.pyenv/versions/3.5.4/lib/python3.5/lib-dynload/_ssl.cpython-35m-darwin.so, 2): Library not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib
Referenced from: /Users/ishandutta2007/.pyenv/versions/3.5.4/lib/python3.5/lib-dynload/_ssl.cpython-35m-darwin.so
Reason: image not found
It depends on your OS.
For instance, on MacOS, from this issue:
Updating OpenSSL is usually fine, the jump from libssl.1.0.0.dylib to libssl.1.1.dylib is extremely rare.
The dylib version number 1.0.0 has been the same for years.
However, when it does change and you remove the old one, everything that depends on it will break (Homebrew can do its best making sure its packages are all recompiled, but it can't do anything about your pyenv Python installs).
This is not unique to OpenSSL either, just the nature of dynamic linking.
If one day libsqlite3.0.dylib becomes libsqlite4.0.dylib, your old Python installs will break too.

How can I use/authenticate msfrpc with python3.x?

Edited: The code below works, and the changes are commented. As noted, with python3 one must prefix the string literals with a "b" to produce an instance of the byte type instead of a Unicode str type.
I'm trying to use msfrpc (written in Python 2) in Python 3, and I'm encountering authentication errors. The code I'm using is below; see the comments in the code for the changes I made.
The program runs successfully in python2 (when using httplib rather than http.client), with what appears to be the same authentication exchange as seen when using python3.
import msgpack
import http.client #Changed from httplib
class Msfrpc:
class MsfError(Exception):
def __init__(self,msg):
self.msg = msg
def __str__(self):
return repr(self.msg)
class MsfAuthError(MsfError):
def __init__(self,msg):
self.msg = msg
def __init__(self,opts=[]):
self.host = opts.get('host') or "127.0.0.1"
self.port = opts.get('port') or 55552
self.uri = opts.get('uri') or "/api/"
self.ssl = opts.get('ssl') or False
self.authenticated = False
self.token = False
self.headers = {"Content-type" : "binary/message-pack" }
if self.ssl:
self.client = http.client.HTTPSConnection(self.host,self.port) #Changed httplib -> http.client
else:
self.client = http.client.HTTPConnection(self.host,self.port) #Changed httplib -> http.client
def encode(self,data):
return msgpack.packb(data)
def decode(self,data):
return msgpack.unpackb(data)
def call(self,meth,opts = []):
if meth != "auth.login":
if not self.authenticated:
raise self.MsfAuthError("MsfRPC: Not Authenticated")
if meth != "auth.login":
opts.insert(0,self.token)
opts.insert(0,meth)
params = self.encode(opts)
self.client.request("POST",self.uri,params,self.headers)
resp = self.client.getresponse()
return self.decode(resp.read())
def login(self,user,password):
ret = self.call('auth.login',[user,password])
if ret.get(b'result') == b'success': #Added b
self.authenticated = True
self.token = ret.get(b'token') #Added b
return True
else:
raise self.MsfAuthError("MsfRPC: Authentication failed")
if __name__ == '__main__':
# Create a new instance of the Msfrpc client with the default options
client = Msfrpc({})
# Login to the msfmsg server using the password "abc123"
client.login('msf','abc123')
# Get a list of the exploits from the server
mod = client.call('module.exploits')
# Grab the first item from the modules value of the returned dict
print ("Compatible payloads for : %s\n" % mod[b'modules'][0]) #Added () #Added b
# Get the list of compatible payloads for the first option
ret = client.call('module.compatible_payloads',[mod[b'modules'][0]]) #Added b
for i in (ret.get(b'payloads')): #Added b
print ("\t%s" % i) #Added ()
When running the program, the result is:
root#kali:~/Dropbox/PythonStuff/python-nmap-test# python3 test3.py
Traceback (most recent call last):
File "test3.py", line 20, in <module>
client.login('msf','abc123')
File "/usr/local/lib/python3.7/dist-packages/msfrpc.py", line 64, in login
raise self.MsfAuthError("MsfRPC: Authentication failed")
msfrpc.MsfAuthError: 'MsfRPC: Authentication failed'
Curiously, running tcpdump while the program is executing shows a successful authentication and a token being granted:
When the program executes successfully with python2 the authentication exchange appears identical, but if someone feels posting the packet capture of the program (running in python2) completing successfully would help to answer the question I can easily add it.
There wasn't much interest in this but I'm posting the answer should anyone else have the question; the solution was pretty straightforward and I noted the changes in the code posted above.
The problem was that msfrpc was originally written in Python 2, and therefore the prefix of 'b' in the msgpack RPC responses from the Metasploit host was ignored but it is required in Python 3 to indicate that the literal should become a bytes literal instead of a string type.
For more information, check out the link below; once I read it the answer was pretty obvious:
https://timothybramlett.com/Strings_Bytes_and_Unicode_in_Python_2_and_3.html
The above code works fine, but really a better solution is to use the msfrpc module written by Dan McInerney which instead uses the 'requests' package.
https://github.com/DanMcInerney/msfrpc

Logging in as user using discord.py

I am trying to make some simple program, showing received messages through the terminal. Now I am trying to ask the user for their email address and password for the login, but some errors occur, which I do not quite understand. This is what my code looks like:
import discord
class DiscordClient(discord.Client):
def __init__(self, *args, **kwargs):
discord.Client.__init__(self, **kwargs)
async def on_ready(self):
print('Success!')
if __name__ == '__main__':
dc = DiscordClient()
dc.login(input('email : '), input('password : '), bot=False)
dc.run()
and the error is:
Traceback (most recent call last):
File "[...]/Main.py", line 16, in <module>
dc.run()
File "[...]/lib/python3.6/site-packages/discord/client.py", line 519, in run
self.loop.run_until_complete(self.start(*args, **kwargs))
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/base_events.py", line 466, in run_until_complete
return future.result()
File "[...]/lib/python3.6/site-packages/discord/client.py", line 490, in start
yield from self.login(*args, **kwargs)
File "[...]/lib/python3.6/site-packages/discord/client.py", line 418, in login
raise TypeError('login() takes 1 or 2 positional arguments but {} were given'.format(n))
TypeError: login() takes 1 or 2 positional arguments but 0 were given
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x103881fd0>
So, what am I doing wrong, or what should code look like? All I was doing was write an on_message() and some basic commands like send_message().
client.login is a coroutine so it should be (untested) :
await dc.login(input('email : '), input('password : '), bot=False)
Note that in this case, bot parameter is not needed.
However, to use client.login, you need to use the client loop. To avoid that, you can simply do:
dc.run(email, password)
Which will both login and connect and then start the loop.
After that you can (in the on_ready function) get a desired server from dc.servers and a suitable channel to send there, for example, a 'Hello message' with dc.send_message.
When you are done with the connection, do self.close() from within the DiscordClient class.
Working example for Python 3.4 (replace keywords as necessary for Python 3.6)
import discord
import asyncio
import datetime
class DiscordClient(discord.Client):
def __init__(self, *args, **kwargs):
discord.Client.__init__(self, **kwargs)
#asyncio.coroutine
def on_ready(self):
servers = list(self.servers)
for server in servers:
if server.name == 'My server':
break
for channel in server.channels:
if channel.name == 'general':
break
now = datetime.datetime.now()
yield from self.send_message(channel, 'Api Success! at ' + str(now))
print('Success!')
yield from self.close()
if __name__ == '__main__':
dc = DiscordClient()
email = input('email : ')
password = input('password : ')
dc.run(email, password)

Spotipy Authorization Code Flow - Error when username has underscores

I am using the Spotipy Python library to interact with the Spotify web API. One of the two flows for user authentication is Authorization Code Flow. I tried to run the code in the example from the terminal typing my username, which includes an underscore. Here is the code:
import sys
import spotipy
import spotipy.util as util
scope = 'user-library-read'
if len(sys.argv) > 1:
username = sys.argv[1]
else:
print "Usage: %s username" % (sys.argv[0],)
sys.exit()
token = util.prompt_for_user_token(username, scope)
if token:
sp = spotipy.Spotify(auth=token)
results = sp.current_user_saved_tracks()
for item in results['items']:
track = item['track']
print track['name'] + ' - ' + track['artists'][0]['name']
else:
print "Can't get token for", username
But it gives me the following traceback error:
Traceback (most recent call last):
File "", line 1, in
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/spotipy/util.py", line 56, in prompt_for_user_token
token_info = sp_oauth.get_cached_token()
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/spotipy/oauth2.py", line 135, in get_cached_token
if 'scope' not in token_info or not self._is_scope_subset(self.scope, token_info['scope']):
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/spotipy/oauth2.py", line 157, in _is_scope_subset
haystack_scope = set(haystack_scope.split())
AttributeError: 'NoneType' object has no attribute 'split'
Then I tried the same code with other username without underscore and it worked. So the problem is related to splitting a string with an underscore. Any idea to solve this?

Telnet.read.until function doesn't work

Trying to telnet to a Brocade router and the python script is sending out error.... Not sure what is wrong here. Have tried a debug but cant make it working. I believe it's prompt issue. I appreciate if anyone has suggestion how to get it work.
Note: This is Python 3.0
import getpass
import sys
import telnetlib
HOST = "1.1.1.1"
user = "admin"
password = "password"
port = "23"
telnet = telnetlib.Telnet(HOST)
telnet.read_until("sw0 login:,3")
telnet.write(admin + "\r")
if password:
telnet.read_until("Password: ")
telnet.write(password + "\n")
tn.write("term len 0" + "\n")
telnet.write("sh ver br\n")
telnet.write("exit\n")
ERROR:
Traceback (most recent call last):
File "C:\Users\milan\Desktop\telnetNew.py", line 13, in <module>
telnet.read_until("Username :,3")
File "C:\Python33\lib\telnetlib.py", line 299, in read_until
return self._read_until_with_select(match, timeout)
File "C:\Python33\lib\telnetlib.py", line 352, in _read_until_with_select
i = self.cookedq.find(match)
TypeError: Type str doesn't support the buffer API
This is my prompt after logging manually using telnet port 23 and this is what i expected command to work.
_________________________________________________________________________________
Network OS (sw0)
xxxxxxxxxx
sw0 login: xxxxx
Password: xxxxx
WARNING: The default password of 'admin' and 'user' accounts have not been changed.
Welcome to the Brocade Network Operating System Software
admin connected from 10.100.131.18 using console on sw0
sw0# sh ver
sw0#
In looking at the docs, it appears that telnetlib want a bytestr, not a Str. so try this., which should convert everything to bytes as opposed to Str
import sys
import telnetlib
HOST = "1.1.1.1"
user = "admin"
password = "password"
port = "23"
telnet = telnetlib.Telnet(HOST,port)
telnet.read_until(b"login: ")
telnet.write(admin.encode('ascii') + b"\n")
telnet.read_until(b"Password: ")
telnet.write(password.encode('ascii') + b"\n")
tn.write(b"term len 0\n")
telnet.write(b"sh ver br\n")
telnet.write(b"exit\n")
--edit-- I installed python and tried this against one of my routers. Changing the username/password to my credentials I was able to login fine. ( I removed the password check and the getpass as they where not being used, being that your code has them hardcoded). It looks like you copied the 2.x example, but the 3.x requires the buffer compatible ones without the b" i Get this
Traceback (most recent call last):
File "foo.py", line 5, in <module>
telnet.read_until("login: ")
File "/usr/local/Cellar/python32/3.2.5/Frameworks/Python.framework/Versions/3.2/lib/python3.2/telnetlib.py", line 293, in read_until
return self._read_until_with_poll(match, timeout)
File "/usr/local/Cellar/python32/3.2.5/Frameworks/Python.framework/Versions/3.2/lib/python3.2/telnetlib.py", line 308, in _read_until_with_poll
i = self.cookedq.find(match)
TypeError: expected an object with the buffer interface
with the b" I get
[~] /usr/local/bin/python3.2 foo.py
b'\r\n\r\nThis computer system including all related equipment, network devices\r\n(specifically including Internet access), are provided only for\r\nauthorized use. All computer
which shows it is working.. what errors are you getting now
import telnetlib , socket
class TELNET(object):
def __init__(self):
self.tn = None
self.username = "root"
self.password = "12345678"
self.host = "10.1.1.1"
self.port = 23
self.timeout = 5
self.login_prompt = b"login: "
self.password_prompt = b"Password: "
def connect(self):
try :
self.tn = telnetlib.Telnet(self.host,self.port,self.timeout)
except socket.timeout :
print("TELNET.connect() socket.timeout")
self.tn.read_until(self.login_prompt, self.timeout)
self.tn.write(self.username.encode('ascii') + b"\n")
if self.password :
self.tn.read_until(self.password_prompt,self.timeout)
self.tn.write(self.password.encode('ascii') + b"\n")
def write(self,msg):
self.tn.write(msg.encode('ascii') + b"\n")
return True
def read_until(self,value):
return self.tn.read_until(value)
def read_all(self):
try :
return self.tn.read_all().decode('ascii')
except socket.timeout :
print("read_all socket.timeout")
return False
def close(self):
self.tn.close()
return True
def request(self,msg):
self.__init__()
self.connect()
if self.write(msg) == True :
self.close()
resp = self.read_all()
return resp
else :
return False
telnet = TELNET()
#call request function
resp = telnet.request('ps www') # it will be return ps output
print(resp)
That code works on python3
Most of these answers are great in-depth explanations and I found them a little hard to follow. The short answer is that the Sample code is wrong on the Python 3x site.
to fix this, instead of
' telnet.read_until("Username :,3")'
use
' telnet.read_until(b"Username :,3")'
Like the other answers say, the problem is that Telnetlib expects byte strings. In Python 2 the str type is a byte string (a string of binary data) whereas it's a unicode string in Python 3 and a new bytes type that represents binary data in the same was as str did in Python 2.
The upshot of this is that you need to convert your str data into bytes data when using Telnetlib in Python 3. I have some code that works in both Python2 and Python3 that I thought worth sharing.
class Telnet(telnetlib.Telnet,object):
if sys.version > '3':
def read_until(self,expected,timeout=None):
expected = bytes(expected, encoding='utf-8')
received = super(Telnet,self).read_until(expected,timeout)
return str(received, encoding='utf-8')
def write(self,buffer):
buffer = bytes(buffer, encoding='utf-8')
super(Telnet,self).write(buffer)
def expect(self,list,timeout=None):
for index,item in enumerate(list):
list[index] = bytes(item, encoding='utf-8')
match_index, match_object, match_text = super(Telnet,self).expect(list,timeout)
return match_index, match_object, str(match_text, encoding='utf-8')
You then instantiate the new Telnet class instead of telnetlib.Telnet. The new class overrides methods in Telnetlib to perform conversion from str to bytes and bytes to str so that the problem just goes away.
Of course, I've only overriden the methods that I was using, but it should be clear from the example how to extend the idea to other methods. Basically, you need to use
bytes(str_string, encoding='utf-8')
and
str(bytes_string, encoding='utf-8')
My code is valid Python 2 and 3 so will work unmodified with either interpreter. When in Python2 the code that overrides the methods is skipped over, effectively ignored. If you don't care for backwards compatibility you can remove the condition that checks for the Python version.

Resources