Solution for the Invalid URL non-numeric port error? - python

I am trying to use a cryptcurrency API to get some information from a remote server in python. The example from the API how to do it is here: https://developers.cryptoapis.io/technical-documentation/blockchain-data/unified-endpoints/get-transaction-details-by-transaction-id
But when I try to run it I get an exception
Exception has occurred: InvalidURL
nonnumeric port: '//rest.cryptoapis.io/v2'
I am not sure what is wrong here (new to Python). Can someone please point out? I thought at least the formal example from the API provider must work?
My code is:
import http.client
conn = http.client.HTTPConnection("https://rest.cryptoapis.io/v2")
headers = {
'Content-Type': "application/json",
'X-API-Key': "API key provided by the software provider"
}
conn.request("GET", "blockchain-data,bitcoin,testnet,transactions,4b66461bf88b61e1e4326356534c135129defb504c7acb2fd6c92697d79eb250", headers=headers )
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))

Looks like you misunderstood the documentation. You may find this helpful:-
import requests
import json
APIKEY = 'YourAPIKeyGoesHere' # <-----
BASE = 'https://rest.cryptoapis.io/v2'
BLOCKCHAIN = 'bitcoin'
NETWORK = 'testnet'
TID = '4b66461bf88b61e1e4326356534c135129defb504c7acb2fd6c92697d79eb250'
with requests.Session() as session:
h = {'Content-Type': 'application/json',
'X-API-KEY': APIKEY}
r = session.get(
f'{BASE}/blockchain-data/{BLOCKCHAIN}/{NETWORK}/transactions/{TID}', headers=h)
r.raise_for_status()
print(json.dumps(r.json(), indent=4, sort_keys=True))

Related

How to trigger pipeline API in AzureDevOps from Python (urllib3)

I have to trigger a pipeline in Azure DevOps from a python script. I have already found out that i need a private access token and that part is fine. I can, however, not get the script to work. I am trying something like this:
data = [
{
}
]
http = urllib3.PoolManager()
r = http.request('POST', api_url, headers={'Content-Type': 'application/json-patch+json', "Authorization": private_access_token}, body=data)
print(r.status)
print(r.data)
Its a requirement that i have to use urllib3 because I cant use the requests package
data is empty, because looking at the parameters here https://learn.microsoft.com/en-us/rest/api/azure/devops/pipelines/runs/run%20pipeline?view=azure-devops-rest-6.0. Then i dont need any input data? I just want to trigger a pipeline, nothing else
Error message is not very helpful. I get error message 203.
I solved it by using:
authorization = str(base64.b64encode(bytes(':'+private_access_token, 'ascii')), 'ascii')
data = {}
a = json.dumps(data)
http = urllib3.PoolManager()
r = http.request('POST', api_url, headers = {'Content-Type': 'application/json', 'Authorization': 'Basic '+authorization}, body=a)

How to solve "[Winerror]:10054 An existing connection was forcibly closed by the remote host"?

I am trying to fetch the json response using the VirusTotal API. To fetch the results as a response I have created a python script which is as shown below : Then error show like this : [Winerror]:10054 An existing connection was forcibly closed by the remote host
import requests
url = "https://www.virustotal.com/vtapi/v2/file/scan"
api_key = "MyApiKey"
params = {"apikey": api_key}
files = {"file": ("app.exe", open("C:/Users/Administrator/Desktop/malware detection/app.exe", "rb")}
try:
response = requests.post(url, files=files, params=params)
print(response.json())
except Exception as e:
print(e)
To provide more information, please try the following:
import requests
url = "https://www.virustotal.com/vtapi/v2/file/scan"
api_key = "MyApiKey"
params = {"apikey": api_key}
files = {"file": ("app.exe", open("C:/Users/Administrator/Desktop/malware detection/app.exe", "rb"))}
try:
response = requests.post(url, files=files, params=params)
print(response.json())
except Exception as e:
print(e)
And post the error response you receive from the updated code.
This issue is resolved, The issue was encountered only for the skype.exe file. while scanning using malware machine learning.

Xero : OAuth2: Python3: Example Code to get the refresh token

Xero has changed its API to require OAuth2 connections instead of OAuth1.
I had a working solution in OAuth1, but the examples for Oauth2 are scarce at best, but mainly for web sites.
I'm another developer who managed to create an Oauth1 solution, that successfully worked as a machine to machine solution with no web server involved.
Xero has some examples that run in Postman, that easily work in my test environment.
I'm attempting to reproduce the postman action of refreshing the token in Python3.
My basic code below is where I currently am:
#client_id = "xxxxx"
#client_secret = "xxxxx"
callback_url = "https://api.xero.com/connections"
re_directURI = "https://developer.xero.com"
scopes = "offline_access accounting.contacts accounting.transactions"
refresh_url = "https://identity.xero.com/connect/token"
access_token = open('AccessToken.txt').read()
old_refresh_token = open('RefreshToken.txt','r').read()
# Refresh Token code...
import requests
#def refresh_xero_token(refresh_token):
headers = {
'grant_type': 'refresh_token',
'Content-Type': 'application/json',
}
data = {
'grant_type': 'refresh_token',
'refresh_token': old_refresh_token,
'client_id': client_id,
'client_secret': client_secret
}
print(data,headers)
response = requests.post(refresh_url, headers=headers, data=data)
#return response.json()
print(response.text)
I have so far failed to find an example that works without a web server, just using python to communicate with the Xero servers to transfer local data into the Zero API.
Using xoauth,.exe (windows) to get the access_token, and then in postman I can run the examples for refresh token, connections, invoices etc to the demo company.
and I believe just being able to replicate these examples will provide me with what I need to get a working solution.
currently with this python code I only get
{"error":"invalid_request"}
So, clearly I am missing something.
I'll class myself as a newbie with Python or Oauth2, but have chosen this path due to my previous success with an Oauth1 connected solution.
I would ask the Xero developer community, but I'm writing this for a user of our software to push data into their Xero accounts, and so for testing I only have a trial account, which does not give me access to the Xero developer community.
Which by itself is really annoying.
Xero support seems of little use also, I tried.
If there is anyone out there able to assist, that would be fabulous.
Thank you in advance for any help given.
After using the xoauth application and setting up the connection, I have since found that with the refresh token, running this function keeps the connection up and running.
def refresh_xero_token():
refresh_url = "https://identity.xero.com/connect/token"
old_refresh_token = open('RefreshToken.txt','r').read()
tokenb4 = f"{client_id}:{client_secret}"
basic_token = base64.urlsafe_b64encode(tokenb4.encode()).decode()
headers = {
'Authorization': f"Basic {basic_token}",
'Content-Type': 'application/x-www-form-urlencoded',
}
data = {
'grant_type': 'refresh_token',
'refresh_token': old_refresh_token
}
try:
response = requests.post(refresh_url, headers=headers, data=data)
results = response.json()
open('RefreshToken.txt','w').write(results["refresh_token"])
open('AccessToken.txt','w').write(results["access_token"])
except Exception as err:
print("ERROR ! Refreshing token error?")
print(response.text)
As additional information, I can then also use this connection to, for example create a contact in Xero:
In this example the irContact is a SQLAlchemy row of data from a SQL table.
def create_contact( connection, irContact, access_token):
#Setup new contact
address1 = {"AddressType": "POBOX"}
if irContact['addressline1'] is not None: address1.update({"AddressLine1": irContact['addressline1']})
if irContact['addressline2'] is not None: address1.update({"AddressLine2": irContact['addressline2']})
if irContact['addressline3'] is not None: address1.update({"AddressLine3": irContact['addressline3']})
if irContact['addressline4'] is not None: address1.update({"AddressLine4": irContact['addressline4']})
if irContact['city'] is not None: address1.update({"City": irContact['city']})
if irContact['region'] is not None: address1.update({"Region": irContact['region']})
if irContact['postalcode'] is not None: address1.update({"PostalCode": irContact['postalcode']})
if irContact['country'] is not None: address1.update({"Country": irContact['country']})
if irContact['attentionto'] is not None: address1.update({"AttentionTo": irContact['attentionto']})
#print (address1.values())
addresses = []
addresses.append(address1)
phones = []
if irContact['phonenumber'] is not None:
phone1 = {"PhoneType": "DEFAULT"}
#phone1.update({"PhoneType": "DEFAULT"})
if irContact['phonenumber'] is not None: phone1.update({"PhoneNumber": irContact['phonenumber']})
if irContact['phoneareacode'] is not None: phone1.update({"PhoneAreaCode": irContact['phoneareacode']})
if irContact['phonecountrycode'] is not None: phone1.update({"PhoneCountryCode": irContact['phonecountrycode']})
phones.append(phone1)
#print (phone1.values())
if irContact['mobilenumber'] is not None:
phone2 = {"PhoneType": "MOBILE"}
if irContact['phonenumber'] is not None: phone2.update({"PhoneNumber": irContact['mobilenumber']})
if irContact['phoneareacode'] is not None: phone2.update({"PhoneAreaCode": irContact['mobileareacode']})
if irContact['phonecountrycode'] is not None: phone2.update({"PhoneCountryCode": irContact['mobilecountrycode']})
phones.append(phone2)
#print (phone2.values())
contact = { "Name": irContact['name'],
"ContactNumber": irContact['contactnumber'],
"AccountNumber": irContact['accountnumber'],
#"ContactStatus": "ACTIVE",
"FirstName": irContact['firstname'],
"LastName": irContact['lastname'],
#"EmailAddress": irContact['emailaddress'],
"Addresses": addresses,
#"Phones":phones
}
contacts = [contact]
#print(contacts)
contacts_url = "https://api.xero.com/api.xro/2.0/Contacts"
headers = {
'Authorization': f"Bearer {access_token}",
'Accept': 'application/json',
'Content-Type': 'application/json',
'xero-tenant-id': tenant_id,
}
data = {
'Contacts': [contact],
}
#print(data)
try:
response = requests.post(contacts_url, headers=headers, json=data)
except Exception as err:
print("ERROR! Contact: %s" % (str(err) ))
print(response.text)
return 0
#print(response.text)
results = response.json()
if 'Contacts' in results:
newcontacts = results['Contacts']
for newcontact in newcontacts: break
query = "update xero_contact set errortext='', ContactID='%s' where id=%d" % (newcontact["ContactID"], irContact['id'])
connection.execute(query)
query = "update xero_invoice_header set ContactID='%s' where OurContactID=%d and (InvoiceID='' or InvoiceID is null ) " % ( newcontact["ContactID"], irContact['id'] )
connection.execute(query)
I believe, with this amount of information, anyone can be capable of creating their own Xero machine to machine interface...
Realising that other records can be read and created using minimal tweaks to the header and or data element of the requests call.
I found the lack of this information so very frustrating, if people can find this, it may help them in future.

Using JSON data from API GET to POST to another API via python script

So, I'm new to python and am struggling, self taught, and still learning to code. So be easy on me :)
I am using a script to get data from one source (Jira's API) and trying to use those results to post to another (PowerBi).
I've managed to successfully get the data, I just don't know how to pass the data to this other API.
I know how to use the GET and POST calls, it's just using the data from one to another than I can't seem to find anything about. Assuming since what I'm asking for is very specific?
edit: I also want to mention that while my get is asking for specific data, I'm getting more than I actually need. So I need a way to specify (hopefully) what data is actually being sent to PowerBi's API
import json
import requests
url = 'https://mydomain.atlassian.net/rest/api/2/search'
headers = { 'Content-Type' : 'application/json',
'Authorization' : 'Basic 123456789' }
params = {
'jql' : 'project IN (, PY, CH, NW, RP, DP, KR, DA, RE, SS, CR, CD, AB) AND issueType=incident AND statusCategory!=Done',
'startAt': 0,
'maxResults' : 50,
}
requestget = requests.get(url, headers=headers, params=params)
if requestget.status_code == 200:
print(json.dumps(json.loads(requestget.text), sort_keys=True, indent=4, separators=(",", ": ")))
else:
print("None")
Apologies if I miss understood what you were asking help on, but you could use this to send a POST request as json.
request = urllib.request.Request()#Put the powerbi api here
request.add_header('Content-Type', 'application/json; charset=utf-8')
jsondata = #your json data
jsonBytes = jsondata.encode('utf-8')
#Has to be bytes
request.add_header('Content-Length', len(jsonBytes))
response = urllib.request.urlopen(request, jsonBytes)
You could go with a requests.post instead.
jsondata = #put json data here
headers = {'content-type': 'application/json'}
response = requests.post(url, data=json.dumps(jsondata), headers=headers)
Requests documentation

Post request through GAE headers issue

I send a POST request from a GAE Flask service to other GAE Flask service
try:
service_url = 'http://localhost:4040/getservice'
headers = {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache',
'Auth-Key': AUTH_KEY,
'Customer': str(CUSTOMER)
}
s = Session()
req = requests.Request('POST', service_url, data=conf, headers=headers)
readytogo = req.prepare()
#del readytogo.headers['Content-Lenght']
#del readytogo.headers['Host']
module = s.send(readytogo)
except Exception as e:
print('error')
print(e)
return e
But i have this error:
Stripped prohibited headers from URLFetch request: ['Host', 'Content-Length']
If I delete that header i have this error in console:
error
'content-lenght'
and this error in page:
An internal error occurred:
'exceptions.KeyError' object is not callable
See logs for full stacktrace.
The header Content-Lenght and Host are not supported from GAE!
How can I send a POST request from GAE to other GAE endpoint???
You have a typo in the statement removing a header, which is what's causing the error:
del readytogo.headers['Content-Lenght']
instead of
del readytogo.headers['Content-Length']

Categories