Aiortc simple radio server (no duplex audio channel) - solved - python

File: index.html
<html>
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- jquery -->
<script src="jquery-3.5.1.min.js"></script>
<!-- own javascript -->
<script src="telephone_calls.js"></script>
</head>
<body>
<audio style="width:100%;margin-top:5mm;background:rgb(241,243,244)" id="audio" autoplay="true" controls="true"></audio>
</body>
</html>
File telephone_calls.js
// peer connection
var pc = null;
function createPeerConnection() {
var config = {
sdpSemantics: 'unified-plan',
iceServers: [{urls: ['stun:stun.l.google.com:19302']}]
};
pc = new RTCPeerConnection(config);
// connect audio
pc.addEventListener('track', function(evt) {
if (evt.track.kind == 'audio'){
document.getElementById('audio').srcObject = evt.streams[0];
};
});
return pc;
}
function negotiate() {
return pc.createOffer().then(function(offer) {
return pc.setLocalDescription(offer);
}).then(function() {
// wait for ICE gathering to complete
return new Promise(function(resolve) {
console.log(pc.iceGatheringState);
if (pc.iceGatheringState === 'complete') {
resolve();
} else {
function checkState() {
console.log(pc.iceGatheringState);
if (pc.iceGatheringState === 'complete') {
pc.removeEventListener('icegatheringstatechange', checkState);
resolve();
}
}
pc.addEventListener('icegatheringstatechange', checkState);
}
});
}).then(function() {
var offer = pc.localDescription;
return fetch('/offer', {
body: JSON.stringify({
sdp: offer.sdp,
type: offer.type
}),
headers: {
'Content-Type': 'application/json'
},
method: 'POST'
});
}).then(function(response) {
return response.json();
}).then(function(answer) {
return pc.setRemoteDescription(answer);
}).catch(function(e) {
alert(e);
console.log(e);
});
}
function start() {
pc = createPeerConnection();
dc = pc.createDataChannel('radio_metadata', {"ordered": true});
dc.onclose = function() {
};
dc.onopen = function() {
};
dc.onmessage = function(evt) {
console.log(evt.data);
};
//negotiate();
constraints = {audio:true,video:false};
navigator.mediaDevices.getUserMedia(constraints).then(function(stream) {
stream.getTracks().forEach(function(track) {
pc.addTrack(track, stream);
});
return negotiate();
}, function(err) {
alert('Could not acquire media: ' + err);
});
}
$(document).ready(function(){
start();
})
File: server.py
from aiohttp import web
from aiortc.mediastreams import MediaStreamTrack
from aiortc import RTCPeerConnection, RTCSessionDescription
from aiortc.contrib.media import MediaPlayer
from pydub import AudioSegment
import av
import pyaudio
import asyncio
import json
import os
from multiprocessing import Process, freeze_support
from queue import Queue
import sys
import threading
from time import sleep
import fractions
import time
class RadioServer(Process):
def __init__(self,q):
super().__init__()
self.q = q
self.ROOT = os.path.dirname(__file__)
self.pcs = []
self.channels = []
self.stream_offers = []
def run(self):
self.app = web.Application()
self.app.on_shutdown.append(self.on_shutdown)
self.app.router.add_get("/", self.index)
self.app.router.add_get("/telephone_calls.js", self.javascript)
self.app.router.add_get("/jquery-3.5.1.min.js", self.jquery)
self.app.router.add_post("/offer", self.offer)
threading.Thread(target=self.fill_the_queues).start()
web.run_app(self.app, access_log=None, host="192.168.1.20", port="8080", ssl_context=None)
def fill_the_queues(self):
while(True):
frame = self.q.get()
for stream_offer in self.stream_offers:
stream_offer.q.put(frame)
async def index(self,request):
content = open(os.path.join(self.ROOT, "index.html"), encoding="utf8").read()
return web.Response(content_type="text/html", text=content)
async def javascript(self,request):
content = open(os.path.join(self.ROOT, "telephone_calls.js"), encoding="utf8").read()
return web.Response(content_type="application/javascript", text=content)
async def jquery(self,request):
content = open(os.path.join(self.ROOT, "jquery-3.5.1.min.js"), encoding="utf8").read()
return web.Response(content_type="application/javascript", text=content)
async def offer(self,request):
params = await request.json()
offer = RTCSessionDescription(sdp=params["sdp"], type=params["type"])
pc = RTCPeerConnection()
self.pcs.append(pc)
# prepare epalxeis media
self.stream_offers.append(CustomRadioStream())
pc.addTrack(self.stream_offers[-1])
#player = MediaPlayer(os.path.join(self.ROOT, "ΑΓΙΑ ΚΥΡΙΑΚΗ.mp3"))
#pc.addTrack(player.audio)
#pc.on("datachannel")
def on_datachannel(channel):
self.channels.append(channel)
self.send_channel_message(str(len(self.pcs)))
#pc.on("iceconnectionstatechange")
async def on_iceconnectionstatechange():
if pc.iceConnectionState == "failed":
self.pcs.remove(pc)
print("Current peer connections:"+str(len(self.pcs)))
# handle offer
await pc.setRemoteDescription(offer)
# send answer
answer = await pc.createAnswer()
await pc.setLocalDescription(answer)
return web.Response(content_type="application/json",text=json.dumps({"sdp": pc.localDescription.sdp, "type": pc.localDescription.type}))
async def on_shutdown(self,app):
# close peer connections
if self.pcs:
coros = [pc.close() for pc in self.pcs]
await asyncio.gather(*coros)
self.pcs = []
self.channels = []
self.stream_offers = []
def send_channel_message(self,message):
for channel in self.channels:
channel.send(message)
class CustomRadioStream(MediaStreamTrack):
kind = "audio"
def __init__(self):
super().__init__() # don't forget this!
self.q = Queue()
self._start = None
async def recv(self):
frame = self.q.get()
frame_time = frame.time
if self._start is None:
self._start = time.time() - frame_time
else:
wait = self._start + frame_time - time.time()
await asyncio.sleep(wait)
return frame
class RadioOutputStream:
def __init__(self,q):
self.sample_rate = 44800
self.AUDIO_PTIME = 0.744
self.samples = int(self.AUDIO_PTIME * self.sample_rate)
self.packet_time = 20
self.FORMAT = pyaudio.paInt16
self.CHANNELS = 2
self.RATE = self.sample_rate
self.CHUNK = int(44100*0.744)
self.file_segment = AudioSegment.from_file(r"ΑΓΙΑ ΚΥΡΙΑΚΗ.mp3").set_frame_rate(self.sample_rate)
self.duration_milliseconds = len(self.file_segment)
self.chunk_number = 0
self.silence = AudioSegment.silent(duration=self.packet_time)
self.q = q
self.codec = av.CodecContext.create('pcm_s16le', 'r')
self.codec.sample_rate = 44800
self.codec.channels = 2
self.audio_samples = 0
def run_stream(self):
while(True):
time_start = time.time()
if((self.chunk_number+1)*(self.packet_time)<=self.duration_milliseconds):
final_slice = self.file_segment[self.chunk_number*self.packet_time:(self.chunk_number+1)*self.packet_time]
#final_slice = final_slice + 100
self.chunk_number += 1
packet = av.Packet(final_slice.raw_data)
frame = self.codec.decode(packet)[0]
frame.pts = self.audio_samples
frame.time_base = fractions.Fraction(1, self.codec.sample_rate)
self.audio_samples += frame.samples
self.q.put(frame)
else:
if(self.chunk_number*self.packet_time<self.duration_milliseconds):
final_slice = self.file_segment[self.chunk_number*self.packet_time:]
final_slice = final_slice + self.silence
#final_slice = final_slice + 100
self.chunk_number += 1
packet = av.Packet(final_slice.raw_data)
frame = self.codec.decode(packet)[0]
frame.pts = self.audio_samples
frame.time_base = fractions.Fraction(1, self.codec.sample_rate)
self.audio_samples += frame.samples
self.q.put(frame)
else:
#start song from begin
self.chunk_number=0
#time_end = time.time()
#sleep_time = time_end-time_start
#if sleep_time>0.020:
# sleep(sleep_time-0.020)
sleep(0.01)
if __name__ == "__main__":
freeze_support()
q = Queue()
radio_stream = RadioOutputStream(q)
threading.Thread(target=radio_stream.run_stream).start()
custom_server_child_process = RadioServer(q)
custom_server_child_process.run()
I want to change this:
constraints = {audio:true,video:false};
navigator.mediaDevices.getUserMedia(constraints).then(function(stream) {
stream.getTracks().forEach(function(track) {
pc.addTrack(track, stream);
});
return negotiate();
}, function(err) {
alert('Could not acquire media: ' + err);
});
to this:
negotiate();
but if i do that the following error is oquered in the server side:
C:\Users\Χρήστος\Desktop\radio>python server.py
======== Running on http://192.168.1.20:8080 ========
(Press CTRL+C to quit)
Error handling request
Traceback (most recent call last):
File "C:\Python\lib\site-packages\aiohttp\web_protocol.py", line 422, in _handle_request
resp = await self._request_handler(request)
File "C:\Python\lib\site-packages\aiohttp\web_app.py", line 499, in _handle
resp = await handler(request)
File "C:\Users\Χρήστος\Desktop\radio\server.py", line 90, in offer
await pc.setLocalDescription(answer)
File "C:\Python\lib\site-packages\aiortc\rtcpeerconnection.py", line 768, in setLocalDescription
t._currentDirection = and_direction(t.direction, t._offerDirection)
File "C:\Python\lib\site-packages\aiortc\rtcpeerconnection.py", line 247, in and_direction
return sdp.DIRECTIONS[sdp.DIRECTIONS.index(a) & sdp.DIRECTIONS.index(b)]
ValueError: None is not in list
Can anyone help me to create an empty offer please?

I change the negotiate javascript function.
Now is:
function negotiate() {
return pc.createOffer({offerToReceiveAudio:true}).then(function(offer) {
return pc.setLocalDescription(offer);
}).then(function() {
// wait for ICE gathering to complete
return new Promise(function(resolve) {
console.log(pc.iceGatheringState);
if (pc.iceGatheringState === 'complete') {
resolve();
} else {
function checkState() {
console.log(pc.iceGatheringState);
if (pc.iceGatheringState === 'complete') {
pc.removeEventListener('icegatheringstatechange', checkState);
resolve();
}
}
pc.addEventListener('icegatheringstatechange', checkState);
}
});
}).then(function() {
var offer = pc.localDescription;
return fetch('/offer', {
body: JSON.stringify({
sdp: offer.sdp,
type: offer.type
}),
headers: {
'Content-Type': 'application/json'
},
method: 'POST'
});
}).then(function(response) {
return response.json();
}).then(function(answer) {
return pc.setRemoteDescription(answer);
}).catch(function(e) {
alert(e);
console.log(e);
});
}
The only change is:
pc.createOffer()
-->
pc.createOffer({offerToReceiveAudio:true})
Link for further research

Related

Arduino to Windows serial communication stops working suddenly

I wanted to exchange some Informations from the Windows PC to an arduino Leonardo. I wanted to use that data and display it on a SPI TFT-Display. The code worked fine and suddenly the code stopped working. I'm not an edvanced Developer so I wished someone here could help me find the error in my code/s. The main Problem is that the Python code should repond to the words which were send from the arduino. I my case the python code should answer with ,,clock: 12:34" if the Arduino said ,,First Message from Arduino!".
The Arduino Code:
#include <Arduino.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <SPI.h>
#include <RotaryEncoder.h>
#define TFT_CS 10
#define TFT_RST 8
#define TFT_DC 12
#define PIN_IN1 9
#define PIN_IN2 11
bool LoadingScreenIsAcitv = true;
bool firstSerialMessage = true;
int loadingSteps = 0;
int clock;
int profil = 1;
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
RotaryEncoder encoder(PIN_IN1, PIN_IN2, RotaryEncoder::LatchMode::TWO03);
String incomingByte;
String oldincomingByte;
String firstCommand;
void MainScreen(){
tft.fillScreen(ST7735_BLACK);
tft.fillRect(10,10,60,15,ST7735_BLACK);
tft.drawRoundRect(5,5,70,25,8,ST7735_WHITE);
tft.setCursor(5,117);
tft.setTextColor(ST7735_WHITE);
tft.setTextSize(1);
tft.write("Profil: Desktop(Standard)");
tft.setCursor(5,50);
tft.write("1. Launch Badlion");
tft.setCursor(5,60);
tft.write("2. Launch Minecraft");
tft.setCursor(5,70);
tft.write("3. Launch Fusion360");
tft.setCursor(5,80);
tft.write("4. Launch Visual-Studio");
tft.setCursor(5,90);
tft.write("5. Empty Launch-Slot");
tft.setCursor(5,100);
tft.write("6. Empty Launch-Slot");
}
void Loading(){
tft.fillRoundRect(5,80,10,25,5,ST7735_GREEN);
tft.drawRoundRect(5,80,150,25,5,ST7735_WHITE);
if(loadingSteps == 1){
tft.fillRoundRect(5,80,30,25,5,ST7735_GREEN);
tft.drawRoundRect(5,80,150,25,5,ST7735_WHITE);
delay(15);
tft.fillRoundRect(5,80,50,25,5,ST7735_GREEN);
tft.drawRoundRect(5,80,150,25,5,ST7735_WHITE);
delay(15);
tft.fillRoundRect(5,80,70,25,5,ST7735_GREEN);
tft.drawRoundRect(5,80,150,25,5,ST7735_WHITE);
delay(15);
tft.fillRoundRect(5,80,90,25,5,ST7735_GREEN);
tft.drawRoundRect(5,80,150,25,5,ST7735_WHITE);
delay(15);
tft.fillRoundRect(5,80,110,25,5,ST7735_GREEN);
tft.drawRoundRect(5,80,150,25,5,ST7735_WHITE);
delay(15);
tft.fillRoundRect(5,80,130,25,5,ST7735_GREEN);
tft.drawRoundRect(5,80,150,25,5,ST7735_WHITE);
delay(15);
tft.fillRoundRect(5,80,150,25,5,ST7735_GREEN);
tft.drawRoundRect(5,80,150,25,5,ST7735_WHITE);
MainScreen();
}
}
void setup() {
tft.initR(INITR_BLACKTAB);
tft.setRotation(3);
tft.fillScreen(INITR_BLACKTAB);
tft.setCursor(23,25);
tft.setTextColor(ST7735_WHITE);
tft.setTextSize(2);
tft.write("Loading...");
Loading();
Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
static int pos = 0;
encoder.tick();
int newPos = encoder.getPosition();
if(pos != newPos){
tft.println(newPos);
pos = newPos;
}
if(firstSerialMessage == true){
if(Serial){
Serial.println("First Message from Arduino!");
firstSerialMessage = false;
}
}
if (Serial.available() > 0) {
incomingByte = Serial.readStringUntil('\n');
if (incomingByte == "end loading") {
if(LoadingScreenIsAcitv == true){
loadingSteps = 1;
Loading();
LoadingScreenIsAcitv = false;
//Serial.println("Main Screen was Loaded!");
MainScreen();
}
} else if(LoadingScreenIsAcitv == false){
String word1 = "clock";
String word2 = "date";
String word3 = "day";
if(strstr(incomingByte.c_str(),word1.c_str())){
char dummyy1[50];
String dummy1 = incomingByte;
Serial.write("Clock wurde empfangen!");
dummy1.remove(0,6);
dummy1.toCharArray(dummyy1,50);
tft.fillRect(10,10,60,15,ST7735_BLACK);
tft.setCursor(10,10);
tft.setTextSize(2);
tft.write(dummyy1);
} else if(strstr(incomingByte.c_str(),word2.c_str())){
digitalWrite(LED_BUILTIN,HIGH);
char dummyy2[50];
String dummy2 = incomingByte;
Serial.write("Datum wurde empfangen!");
dummy2.remove(0,5);
dummy2.toCharArray(dummyy2,50);
tft.setCursor(85,10);
tft.setTextSize(1);
tft.write(dummyy2);
} else if(strstr(incomingByte.c_str(),word3.c_str())){
digitalWrite(LED_BUILTIN,HIGH);
char dummyy3[50];
String dummy3 = incomingByte;
Serial.write("Tag wurde empfangen!");
dummy3.remove(0,4);
dummy3.toCharArray(dummyy3,50);
tft.setCursor(85,20);
tft.setTextSize(1);
tft.write(dummyy3);
} else {
Serial.write("Eingabe wurde auf dem TFT ausgegeben");
tft.print(incomingByte);
}
} else{
Serial.print("invalid input");
}
}
}
The python code:
import serial
import serial.tools.list_ports
import time
import datetime
import pandas as pd
from datetime import date
ports = list(serial.tools.list_ports.comports())
for p in ports:
serialcomm = serial.Serial(p.name, 9600)
serialcomm.timeout = 1
f = True
while True:
if f == True:
i = input("Enter Input: ").strip()
f = False
if i == "Close":
print('finished')
break
serialcomm.write(i.encode())
dummy = serialcomm.read_until('\n').decode('ascii')
print(dummy)
time.sleep(0.5)
dummy = serialcomm.read_until('\n').decode('ascii')
print(dummy)
now = datetime.datetime.now()
if(dummy == "First Message from Arduino!"):
addstringsclock = "clock:" + str(now.hour) + ":" + str(now.minute)
serialcomm.write(addstringsclock.encode())
print("Uhrzeit wurde übermittelt: " + addstringsclock)
if(dummy == "First Message from Arduino!"):
time.sleep(1)
addstringsdate = "date:" + str(now.day) + "." + str(now.month) + "." + str(now.year)
serialcomm.write(addstringsdate.encode())
print("Datum wurde übermittelt: " + addstringsdate)
if(dummy == "First Message from Arduino!"):
time.sleep(2)
temp = pd.Timestamp(date.today())
addstringsday = "day:" + temp.day_name()
serialcomm.write(addstringsday.encode())
print("Tag wurde übermittelt: " + addstringsday)
serialcomm.close()
I tried troubleshooting and my thought is that the error is somewhere in the python code. I tried to run it from the python IDLE.

Extracting JSON from HTML with BeautifulSoup

I've now tried everything for the past few hours but I can't extract a specific thing from the HTML below. I want to grab the "sessionCartId" but I can't figure out how....
Thats what i tried so far :
sessioncartid = BeautifulSoup(response.text, "html.parser").findAll("script", {"type":"text/javascript"})[2]
data = json.loads(sessioncartid.text)
print(data)
^^ This gives me the correct script tag but i cant transform it into a json nor get the sessioncarId
<script type="text/javascript">
/*<![CDATA[*/
var ACC = {config: {}};
ACC.config.contextPath = "";
ACC.config.encodedContextPath = "/de/web";
ACC.config.commonResourcePath = "/_ui/20220811221438/responsive/common";
ACC.config.themeResourcePath = "/_ui/20220811221438/responsive/theme-gh";
ACC.config.siteResourcePath = "/_ui/20220811221438/responsive/site-ghstore";
ACC.config.rootPath = "/_ui/20220811221438/responsive";
ACC.config.CSRFToken = "81b0156a-5a78-4969-b52e-e5080473fb83";
ACC.pwdStrengthVeryWeak = 'password.strength.veryweak';
ACC.pwdStrengthWeak = 'password.strength.weak';
ACC.pwdStrengthMedium = 'password.strength.medium';
ACC.pwdStrengthStrong = 'password.strength.strong';
ACC.pwdStrengthVeryStrong = 'password.strength.verystrong';
ACC.pwdStrengthUnsafePwd = 'password.strength.unsafepwd';
ACC.pwdStrengthTooShortPwd = 'password.strength.tooshortpwd';
ACC.pwdStrengthMinCharText = 'password.strength.minchartext';
ACC.accessibilityLoading = 'aria.pickupinstore.loading';
ACC.accessibilityStoresLoaded = 'aria.pickupinstore.storesloaded';
ACC.config.googleApiKey = "";
ACC.config.googleApiVersion = "3.7";
ACC.autocompleteUrl = '/de/web/search/autocompleteSecure';
ACC.config.loginUrl = '/de/web/login';
ACC.config.authenticationStatusUrl = '/de/web/authentication/status';
/*]]>*/
var OCC =
{
"token": "1799248c-8de0-4199-b5fe-1d610452010a",
"currentUser": "test#gmail.com",
"sessionCartGuid": "2323121232323",
"sessionCartId": "121212123435324",
"sessionLanguageIso": "de",
"sessionCountryIso": "DE",
"urlPosCode": "web",
"isASM": false,
"intermediaryID": "",
"isASMCustomerEmulated": false,
"siteId": "ghstore",
"OCCBaseUrl": "/ghcommercewebservices/v2/ghstore",
"availablePointsOfService": "BUD,FRA,DTM,HAM,GRZ,HAJ,SZG,VIE,WEB,BER",
"primaryPointOfSevice": "WEB",
"clientChannel": "web-eu"
};
</script>
This is how you can extract that dictionary:
from bs4 import BeautifulSoup
import json
import re
html = '''
<script type="text/javascript">
/*<![CDATA[*/
var ACC = {config: {}};
ACC.config.contextPath = "";
ACC.config.encodedContextPath = "/de/web";
ACC.config.commonResourcePath = "/_ui/20220811221438/responsive/common";
ACC.config.themeResourcePath = "/_ui/20220811221438/responsive/theme-gh";
ACC.config.siteResourcePath = "/_ui/20220811221438/responsive/site-ghstore";
ACC.config.rootPath = "/_ui/20220811221438/responsive";
ACC.config.CSRFToken = "81b0156a-5a78-4969-b52e-e5080473fb83";
ACC.pwdStrengthVeryWeak = 'password.strength.veryweak';
ACC.pwdStrengthWeak = 'password.strength.weak';
ACC.pwdStrengthMedium = 'password.strength.medium';
ACC.pwdStrengthStrong = 'password.strength.strong';
ACC.pwdStrengthVeryStrong = 'password.strength.verystrong';
ACC.pwdStrengthUnsafePwd = 'password.strength.unsafepwd';
ACC.pwdStrengthTooShortPwd = 'password.strength.tooshortpwd';
ACC.pwdStrengthMinCharText = 'password.strength.minchartext';
ACC.accessibilityLoading = 'aria.pickupinstore.loading';
ACC.accessibilityStoresLoaded = 'aria.pickupinstore.storesloaded';
ACC.config.googleApiKey = "";
ACC.config.googleApiVersion = "3.7";
ACC.autocompleteUrl = '/de/web/search/autocompleteSecure';
ACC.config.loginUrl = '/de/web/login';
ACC.config.authenticationStatusUrl = '/de/web/authentication/status';
/*]]>*/
var OCC =
{
"token": "1799248c-8de0-4199-b5fe-1d610452010a",
"currentUser": "test#gmail.com",
"sessionCartGuid": "2323121232323",
"sessionCartId": "121212123435324",
"sessionLanguageIso": "de",
"sessionCountryIso": "DE",
"urlPosCode": "web",
"isASM": false,
"intermediaryID": "",
"isASMCustomerEmulated": false,
"siteId": "ghstore",
"OCCBaseUrl": "/ghcommercewebservices/v2/ghstore",
"availablePointsOfService": "BUD,FRA,DTM,HAM,GRZ,HAJ,SZG,VIE,WEB,BER",
"primaryPointOfSevice": "WEB",
"clientChannel": "web-eu"
};
</script>
'''
soup = BeautifulSoup(html, 'html.parser')
info = soup.select_one('script', string = re.compile('sessionCartGuid'))
json_obj = json.loads(info.text.split('var OCC =')[1].split(';')[0])
# print(json_obj)
print(json_obj['token'])
print(json_obj['currentUser'])
print(json_obj['sessionCartId'])
Result:
1799248c-8de0-4199-b5fe-1d610452010a
test#gmail.com
121212123435324
BeautifulSoup docs: https://beautiful-soup-4.readthedocs.io/en/latest/index.html

PyQt5 how to start multiprocess but in not main thread

I am writing a program that reads data from an excel file to some system via API.
The function that fetches data from excel and sends it via API is in a separate thread to keep the GUI alive.
Loading via API is a long process. Most of the time is sending and waiting for API data.
I wanted to send each excel line in a separate process. How to do it?
def api_import(k, sheet,number_columns, items_number, ok, total, total_success):
item = sheet[get_column_letter(3)+str(k)].value
templ_id = sheet[get_column_letter(number_columns)+str(k)].value
item_id = get_item_id(item)['item_id']
query = {"template_id": str(templ_id)}
resp = templ_attach(item_id, query)
if resp==200:
ok += 1
total += 1
item_create_param = 0
item_update_param = 0
item_error = 0
for l in range(number_columns):
if l <4:
pass
else:
param_name = sheet[get_column_letter(l)+str(1).upper().replace(" ", "")].value
param_description = sheet[get_column_letter(l)+str(2)].value
param_value = sheet[get_column_letter(l)+str(k)].value
param_type = sheet[get_column_letter(l)+str(3)].value
if "[T]" in param_type:
param_type = 4
query = {"name": str(param_name), "type": param_type, "description": str(param_description), "text_value": str(param_value)}
elif "[D]" in param_type:
param_type = 0
query = {"name": str(param_name), "type": param_type, "description": str(param_description), "numeric_value": param_value}
else:
param_type = 1
query = {"name": str(param_name), "type": param_type, "description": str(param_description), "logical_value": param_value}
resp = input_param(item_id, query)
if resp==201:
item_create_param += 1
elif resp==202:
item_update_param += 1
else:
item_error += 1
if item_error == 0:
total_success += 1
return {'total':total, 'total_success':total_success, 'ok':ok}
class MainWindow(QDialog):
def __init__(self):
super(MainWindow,self).__init__()
loadUi("gui.ui",self)
self.browse.clicked.connect(self.browsefiles)
self.load.clicked.connect(self.send)
def browsefiles(self):
fname=QFileDialog.getOpenFileName(self, 'Open file', 'C:\Program files', 'Excel Spreadsheet files (*.xlsx, *.xls)')
self.filename.setText(fname[0])
def send(self):
self.worker = WorkerThread()
self.worker.start()
#self.worker.worker_complete.connect(self.evt_worker_finished)
self.worker.update_progress.connect(self.evt_update_progress)
#def evt_worker_finished(self, emp):
#self.QMessageBox.information(self, "Done!", "Wczytywanie zakonczone!\n\n{} {}".format(emp["fn"], emp["ln"]))
def evt_update_progress(self, val):
self.progressBar.setValue(val)
class WorkerThread(QThread):
update_progress = pyqtSignal(int)
worker_complete = pyqtSignal(dict)
def run(self):
start_time = time.time()
file_path = "import.xlsx"
print(file_path)
wb = load_workbook(file_path)
sheetnames = wb.sheetnames
for sheet in wb:
print(sheet)
number_rows = sheet.max_row
print(number_rows)
number_columns = sheet.max_column
items_number = number_rows-3
ok = 0
total = 0
progress = 0
total_success = 0
for k in range(number_rows+1):
if k>3:
report = api_import(k, sheet,number_columns, items_number, ok, total, total_success)
total = report['total']
ok = report['ok']
total_success = report['total_success']
progress = round(total/items_number*100)
print("{}%".format(progress))
self.update_progress.emit(progress)
self.worker_complete.emit({"emp_id":1234, "fn":"XXX", "ln":"YYYY"})
end_time = time.time() - start_time
item_time = end_time/total

Implementing a Windows Service with ctypes. ServiceCtrl handler not called

I am trying to implement a Windows service in Python with ctypes.
import ctypes
import logging
import logging.config
import threading
import six
logger = logging.getLogger("service3")
SERVICE_MAIN = ctypes.WINFUNCTYPE(ctypes.c_bool, ctypes.c_uint32)
HANDLER_FUNCTION = ctypes.WINFUNCTYPE(ctypes.c_uint32, ctypes.c_uint32)
class ServiceTable (ctypes.Structure):
_fields_ = [("serviceName", ctypes.c_char_p),
("serviceProc", SERVICE_MAIN),
("serviceNameTerm", ctypes.c_char_p),
("serviceProcTerm", ctypes.c_void_p)]
class ServiceStatus (ctypes.Structure):
_fields_ = [("dwServiceType", ctypes.c_uint32),
("dwCurrentState", ctypes.c_uint32),
("dwControlsAccepted", ctypes.c_uint32),
("dwWin32ExitCode", ctypes.c_uint32),
("dwServiceSpecificExitCode", ctypes.c_uint32),
("dwCheckPoint", ctypes.c_uint32),
("dwWaitHint", ctypes.c_uint32)]
advapi32 = ctypes.windll.advapi32
kernel32 = ctypes.windll.kernel32
advapi32.StartServiceCtrlDispatcherA.argtypes = [ctypes.POINTER(ServiceTable)]
StartServiceCtrlDispatcherA = advapi32.StartServiceCtrlDispatcherA
advapi32.SetServiceStatus.argtypes = [ctypes.c_void_p, ctypes.POINTER(ServiceStatus)]
SetServiceStatus = advapi32.SetServiceStatus
advapi32.RegisterServiceCtrlHandlerA.argtypes = [ctypes.c_char_p, HANDLER_FUNCTION]
advapi32.RegisterServiceCtrlHandlerA.restype = ctypes.c_void_p
RegisterServiceCtrlHandlerA = advapi32.RegisterServiceCtrlHandlerA
SERVICE_WIN32_OWN_PROCESS = 0x10
SERVICE_ACCEPT_STOP = 0x1
SERVICE_CONTROL_STOP = 0x1
SERVICE_RUNNING = 0x4
SERVICE_STOPPED = 0x1
SERVICE_STOP_PENDING = 0x3
class Service:
serviceName = "RSJTest"
ServiceStatusHandle = None
def __init__(self):
self.TerminateEvent = threading.Event()
def StartMain(self):
try:
logger.debug("ServiceMain")
self.serviceProc = SERVICE_MAIN(self.StartMain2)
self.serviceTable = ServiceTable(serviceName=self.encode(self.serviceName), serviceProc=self.serviceProc)
StartServiceCtrlDispatcherA(self.serviceTable)
except:
logger.exception("ServiceMain")
def StartMain2(self, argC):
try:
logger.debug("StartMain2 %d", argC)
self.handlerProc = HANDLER_FUNCTION(self.HandlerProc)
self.ServiceStatusHandle = RegisterServiceCtrlHandlerA( self.encode(self.serviceName), self.handlerProc)
logger.debug("ServiceStatusHandle %xd", self.ServiceStatusHandle)
self.SetServiceStatus(SERVICE_RUNNING)
self.Start()
logger.debug("Start returned")
self.SetServiceStatus(SERVICE_STOPPED)
except:
logger.exception("StartMain2")
return 0
def Start(self):
self.TerminateEvent.wait()
def Stop(self):
self.TerminateEvent.set()
def HandlerProc(self, dwControl):
try:
logger.debug("HandlerProc")
if dwControl == SERVICE_CONTROL_STOP:
self.SetServiceStatus(SERVICE_STOP_PENDING)
self.Stop()
except:
logger.exception("HandlerProc")
return 0
def SetServiceStatus(self, newStatus):
serviceStatus = ServiceStatus(dwServiceType=SERVICE_WIN32_OWN_PROCESS,
dwCurrentState=newStatus,
dwControlsAccepted=SERVICE_ACCEPT_STOP)
ret = SetServiceStatus(self.ServiceStatusHandle, serviceStatus)
logger.debug("SetServiceStatus returned %d", ret)
def encode(self, stringParm):
if stringParm == None:
return None
return six.ensure_binary(stringParm)
logConfig = {
"version": 1,
"disable_existing_loggers": False,
"loggers": {
"": {
"level": "DEBUG",
"handlers": ["file"]
}
},
"handlers": {
"file": {
"class": "logging.handlers.TimedRotatingFileHandler",
"formatter": "precise",
"filename": "c:\\temp\service.log",
"when": "midnight",
"backupCount": 30,
"level": "NOTSET"
}
},
"formatters": {
"precise": {
"format": "%(asctime)s %(levelname)-8s %(name)-15s %(message)s",
"datefmt": "%Y-%m-%d %H:%M:%S"
}
}
}
def main():
logging.config.dictConfig(logConfig)
logger.debug("started")
service = Service()
service.StartMain()
if __name__ == "__main__":
main()
I can start my service (eg from Service Manager) with no problems.
I can also stop my service (from Service Manager) but get an error 1061:
My HandlerProc is not called (at least it is not logged)
The service process terminates
I get 1062 I try to stop the service again
NB: Calling self.handlerProc(0) from StartMain2 calls the the ServiceCtrlHandler
Whats wrong?
I did my test tests on Windows 10.
After replacing RegisterServiceCtrlHandlerA with RegisterServiceCtrlHandlerExA (and including the additional arguments in the method call (and HANDLER_FUNCTION) everything works as expected.
HANDLER_FUNCTION_EX = ctypes.WINFUNCTYPE(ctypes.c_uint32, ctypes.c_uint32, ctypes.c_uint32, ctypes.c_void_p, ctypes.c_void_p)
advapi32.RegisterServiceCtrlHandlerExA.argtypes = [ctypes.c_char_p, HANDLER_FUNCTION_EX, ctypes.c_void_p]
advapi32.RegisterServiceCtrlHandlerExA.restype = ctypes.c_void_p
RegisterServiceCtrlHandlerExA = advapi32.RegisterServiceCtrlHandlerExA
...
self.handlerProcEx = HANDLER_FUNCTION_EX(self.HandlerProcEx)
self.ServiceStatusHandle = RegisterServiceCtrlHandlerExA(self.encode(self.serviceName), self.handlerProcEx, None)
...
def HandlerProcEx(self, dwControl, dwEventType, lpEventData, lpContext):
...

how to fix JSON decoder issue when using REST in Python to connect to SharePoint & Read data

i am following this Guide in an effort to connect to a sharepoint site with python and grab some data using the REST api. however, i keep having trouble with the JSON decoder in order to read the data like it suggests in the guide.
I have followed the Guide to the letter and keep having the same issues. I tried to change the headers to headers = {'content-type':'application/json'}as it suggests on another question asked on here; but nothing has worked.
This is what i have so far much like the guide suggests:
import requests
from requests_ntlm import HttpNtlmAuth
headers = {"accept": "application/json;odata=verbose"}
response = requests.get("http://Sharepointsite/_api/web/", auth=HttpNtlmAuth('User','Pass'),headers=headers)
print(response.content)
print(response.json()["d"]["CustomMasterUrl"])
This is the error message that i get:
Traceback (most recent call last):
File "C:/Users/User/MyProjects/ProductivityTracking/SharepointConnection/Sharepoint Integration.py", line 9, in <module>
print (response.json()["d"]["CustomMasterUrl"])
File "C:\Users\user\AppData\Local\Programs\Python\Python37-32\lib\site-packages\requests\models.py", line 897, in json
return complexjson.loads(self.text, **kwargs)
File "C:\Users\User\AppData\Local\Programs\Python\Python37-32\lib\json\__init__.py", line 348, in loads
return _default_decoder.decode(s)
File "C:\Users\User\AppData\Local\Programs\Python\Python37-32\lib\json\decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Users\User\AppData\Local\Programs\Python\Python37-32\lib\json\decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 2 column 1 (char 2)
if you guys can point me in the right direction to start trouble shooting this, that would be awesome - i searched everywhere on stack and beyond.
Additional Info - the response content:
b'\r\n<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"\r\n\t"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\r\n<html dir="ltr" lang="en-US">\r\n<head><meta name="GENERATOR" content="Microsoft SharePoint" /><meta http-equiv="Content-type" content="text/html; charset=utf-8" /><meta http-equiv="X-UA-Compatible" content="IE=10" /><meta http-equiv="Expires" content="Fri, 11 Oct 2019 15:09:01 GMT" /><meta name="msapplication-TileImage" content="/_layouts/15/images/SharePointMetroAppTile.png" /><meta name="msapplication-TileColor" content="#0072C6" /><link rel="shortcut icon" href="/_layouts/15/images/favicon.ico?rev=23" type="image/vnd.microsoft.icon" id="favicon" />\r\n<script type=\'text/javascript\'>\r\n// <![CDATA[\r\nvar url = window.location.href; var g_initUrl=\'\';\r\nvar hashSaverUrl = \'\';var keyName = \'MDSLoginAllowedUrl\';var idx = url.indexOf(\'&\' + keyName + \'=\');\r\nif (idx != -1) {\r\n var idx2 = url.indexOf(\'&\', idx + 1);\r\n if (idx2 == -1)\r\n idx2 = url.length;\r\n hashSaverUrl = url.substring(idx + keyName.length + 2, idx2);\r\n hashSaverUrl = decodeURIComponent(hashSaverUrl);\r\n}\r\nif (!hashSaverUrl || hashSaverUrl == \'\') {\r\n var g_MDSStartTime = new Date();\r\n var g_MinimalDownload = true;var g_mdsReady=false;var isStartPlt1 = true;var startDate = g_MDSStartTime.valueOf().toString();\r\n var skipOverlay=true;var startRenderComplete=false;var initContentComplete=false;\r\n var hashParts=window.location.hash.substr(1).split(\'#\');var ch=hashParts[0];var localAnc=null; \r\n for (var i=1;i<hashParts.length;i++){\r\n var s=hashParts[i];\r\n if (s.indexOf(\'=\') == -1) {\r\n localAnc=s; \r\n break;\r\n }\r\n }\r\n\r\n var requestUrlFull;\r\n if (ch.length >= 2 && ch[0] === \'/\' && ch[1] === \'/\')\r\n {\r\n if (ch[2] !== \'/\')\r\n {\r\n g_initUrl = ch.substr(1);\r\n requestUrlFull = window.location.hash.substr(2);\r\n }\r\n } else if (typeof(ch) != \'undefined\' && ch.length >= 1 && ch[0] === \'/\')\r\n {\r\n var loc = window.location.pathname;\r\n var pos = loc.indexOf(\'/_layouts/15/start.aspx\');\r\n var hash = window.location.hash.substr(1);\r\n var hPos = hash.indexOf(\'#\');\r\n hPos = hPos >= 0 ? hPos : hash.length;\r\n g_initUrl = loc.substr(0, pos) + ch;\r\n requestUrlFull = g_initUrl + hash.substr(hPos);\r\n }\r\n\r\n if(g_initUrl){\r\n var delim=ch.indexOf(\'?\')!=-1 ? \'&\' : \'?\';\r\n var xhr=new XMLHttpRequest();\r\n xhr.open(\'GET\',g_initUrl+delim+\'AjaxDelta=1&isStartPlt1=\' + startDate, true);\r\n xhr.setRequestHeader(\'Pragma\', \'SharePointAjaxDelta=|SITES|SANDBOX:|SITES|SANDBOX|_CATALOGS|MASTERPAGE|SEATTLE.MASTER:2.15.0.0.0.15.0.5131.1000.0.FALSE.:en-US:en-US:RW\');\r\n xhr.onreadystatechange=function(){\r\n if(xhr.readyState==4){\r\n if(g_mdsReady){\r\n asyncDeltaManager._navigate(requestUrlFull, localAnc);}\r\n else\r\n {g_mdsReady=true;}}};\r\n xhr.send(null);}\r\n else\r\n {g_mdsReady=true;}\r\n}\r\n\r\n// ]]>\r\n</script>\r\n<link rel="stylesheet" type="text/css" href="/_layouts/15/1033/styles/Themable/corev15.css?rev=2bpHeX9U8DH09TB5zpJcsQ%3D%3D"/>\n<script type="text/javascript" src="/_layouts/15/init.js?rev=ZwTQYqYlNTyyuMWaLlhwSg%3D%3D"></script>\n<script type="text/javascript" src="/ScriptResource.axd?d=ideow4fpAMtT1LU3KRk4QdrhD1jlPBAePc9i8Ib6lUnFTPWZBlpLxAiBo8ORwOMMJgN20_t9vRkidn1TCfn8SlPTG2UqSNGHdiXmH-2qG7qawwjHGYQutflvf9Bq4OfLRdTYGOD6T8DyvDQ6rrD3oPhj_zf3sNcoJxJOKX0a2n2TdJGcEtmFj3kTppa6_7PE0&t=ffffffffc60ca17c"></script>\n<script type="text/javascript" src="/_layouts/15/blank.js?rev=ZaOXZEobVwykPO9g8hq%2F8A%3D%3D"></script>\n<script type="text/javascript" src="/_layouts/15/start.js?rev=RJ1wZoVJ%2F7xfKjfBnjaWng%3D%3D"></script>\n<script type="text/javascript">RegisterSod("initstrings.js", "\\u002f_layouts\\u002f15\\u002f1033\\u002finitstrings.js?rev=S11vfGURQYVuACMEY0tLTg\\u00253D\\u00253D");</script>\n<script type="text/javascript">RegisterSod("strings.js", "\\u002f_layouts\\u002f15\\u002f1033\\u002fstrings.js?rev=0Q8SquDYHrVJnF3A1pfsSQ\\u00253D\\u00253D");RegisterSodDep("strings.js", "initstrings.js");</script>\n<script type="text/javascript">RegisterSod("sp.init.js", "\\u002f_layouts\\u002f15\\u002fsp.init.js?rev=jvJC3Kl5gbORaLtf7kxULQ\\u00253D\\u00253D");</script>\n<script type="text/javascript">RegisterSod("sp.res.resx", "\\u002f_layouts\\u002f15\\u002fScriptResx.ashx?culture=en\\u00252Dus\\u0026name=SP\\u00252ERes\\u0026rev=yNk\\u00252FhRzgBn40LJVP\\u00252BqfgdQ\\u00253D\\u00253D");</script>\n<script type="text/javascript">RegisterSod("sp.ui.dialog.js", "\\u002f_layouts\\u002f15\\u002fsp.ui.dialog.js?rev=3Oh2QbaaiXSb7ldu2zd6QQ\\u00253D\\u00253D");RegisterSodDep("sp.ui.dialog.js", "sp.init.js");RegisterSodDep("sp.ui.dialog.js", "sp.res.resx");</script>\n<script type="text/javascript">RegisterSod("core.js", "\\u002f_layouts\\u002f15\\u002fcore.js?rev=GpU7vxyOqzS0F9OfEX3CCw\\u00253D\\u00253D");RegisterSodDep("core.js", "strings.js");</script>\n<script type="text/javascript">RegisterSod("menu.js", "\\u002f_layouts\\u002f15\\u002fmenu.js?rev=cXv35JACAh0ZCqUwKU592w\\u00253D\\u00253D");</script>\n<script type="text/javascript">RegisterSod("mQuery.js", "\\u002f_layouts\\u002f15\\u002fmquery.js?rev=VYAJYBo5H8I3gVSL3MzD6A\\u00253D\\u00253D");</script>\n<script type="text/javascript">RegisterSod("callout.js", "\\u002f_layouts\\u002f15\\u002fcallout.js?rev=ryx2n4ePkYj1\\u00252FALmcsXZfA\\u00253D\\u00253D");RegisterSodDep("callout.js", "strings.js");RegisterSodDep("callout.js", "mQuery.js");RegisterSodDep("callout.js", "core.js");</script>\n<script type="text/javascript">RegisterSod("clienttemplates.js", "\\u002f_layouts\\u002f15\\u002fclienttemplates.js?rev=OJfMNjaofDqyBzPvjPo3XA\\u00253D\\u00253D");RegisterSodDep("clienttemplates.js", "initstrings.js");</script>\n<script type="text/javascript">RegisterSod("sharing.js", "\\u002f_layouts\\u002f15\\u002fsharing.js?rev=XxxHIxIIc8BsW9ikVc6dgA\\u00253D\\u00253D");RegisterSodDep("sharing.js", "strings.js");RegisterSodDep("sharing.js", "mQuery.js");RegisterSodDep("sharing.js", "clienttemplates.js");RegisterSodDep("sharing.js", "core.js");</script>\n<script type="text/javascript">RegisterSod("suitelinks.js", "\\u002f_layouts\\u002f15\\u002fsuitelinks.js?rev=REwVU5jSsadDdOZlCx4wpA\\u00253D\\u00253D");RegisterSodDep("suitelinks.js", "strings.js");RegisterSodDep("suitelinks.js", "core.js");</script>\n<link type="text/xml" rel="alternate" href="/sites/sandbox/_vti_bin/spdisco.aspx" /></head>\r\n<body>\r\n <div id="imgPrefetch" style="display:none">\r\n</div>\r\n\r\n <noscript><div class=\'noindex\'>You may be trying to access this site from a secured browser on the server. Please enable scripts and reload this page.</div></noscript>\r\n \r\n <form method="post" action="./start.aspx" id="aspnetForm" onsubmit="if (typeof(_spFormOnSubmitWrapper) == "function") return _spFormOnSubmitWrapper();">\r\n<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTY1NDU2MTA1Mg9kFgJmD2QWAgIBD2QWAgIJDxYCHghvbnN1Ym1pdAVSaWYgKHR5cGVvZihfc3BGb3JtT25TdWJtaXRXcmFwcGVyKSA9PSAiZnVuY3Rpb24iKSByZXR1cm4gX3NwRm9ybU9uU3VibWl0V3JhcHBlcigpO2Rk82P14L36F04gkzB9Q1Z5k5kq+AtfmPqNYl/2Da94T8s=" />\r\n\r\n\r\n<script type="text/javascript">\r\n//<![CDATA[\r\nvar g_presenceEnabled = true;\nvar g_wsaEnabled = false;\nvar g_wsaQoSEnabled = false;\nvar g_wsaQoSDataPoints = [];\nvar g_wsaLCID = 1033;\nvar g_wsaListTemplateId = null;\nvar _fV4UI=true;var _spPageContextInfo = {webServerRelativeUrl: "\\u002fsites\\u002fsandbox", webAbsoluteUrl: "http:\\u002f\\u002fhemportal.hem.jmhuber.com\\u002fsites\\u002fsandbox", siteAbsoluteUrl: "http:\\u002f\\u002fhemportal.hem.jmhuber.com\\u002fsites\\u002fsandbox", serverRequestPath: "\\u002f_layouts\\u002f15\\u002fstart.aspx", layoutsUrl: "_layouts\\u002f15", webTitle: "", webTemplate: "", tenantAppVersion: "none", isAppWeb: false, Has2019Era: true, webLogoUrl: "_layouts\\u002f15\\u002fimages\\u002fsiteicon.png", webLanguage: 1033, currentLanguage: 1033, currentUICultureName: "en-US", currentCultureName: "en-US", clientServerTimeDelta: new Date("2019-09-11T15:09:01.6585779Z") - new Date(), siteClientTag: "0$$15.0.5131.1000", crossDomainPhotosEnabled:false, webUIVersion:15, webPermMasks:{High:0,Low:0}, pagePersonalizationScope:1, alertsEnabled:true, customMarkupInCalculatedFieldDisabled: true, siteServerRelativeUrl: "\\u002fsites\\u002fsandbox", allowSilverlightPrompt:\'True\'};var MSOWebPartPageFormName = \'aspnetForm\';//]]>\r\n</script>\r\n\r\n<script src="/_layouts/15/blank.js?rev=ZaOXZEobVwykPO9g8hq%2F8A%3D%3D" type="text/javascript"></script>\r\n<script type="text/javascript">\r\n//<![CDATA[\r\nif (typeof(DeferWebFormInitCallback) == \'function\') DeferWebFormInitCallback();//]]>\r\n</script>\r\n\r\n<input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="A31D3FD9" />\r\n\t<script type="text/javascript"> var submitHook = function () { return false; }; theForm._spOldSubmit = theForm.submit; theForm.submit = function () { if (!submitHook()) { this._spOldSubmit(); } }; </script>\r\n\t<span id="DeltaSPWebPartManager"></span>\r\n\t\r\n\t<span id="DeltaDelegateControls"></span>\r\n<div id="TurnOnAccessibility" style="display:none" class="s4-notdlg noindex">\r\n\t<a id="linkTurnOnAcc" href="#" class="ms-accessible ms-acc-button" onclick="SetIsAccessibilityFeatureEnabled(true);UpdateAccessibilityUI();document.getElementById(\'linkTurnOffAcc\').focus();return false;">Turn on more accessible mode</a>\r\n</div>\r\n<div id="TurnOffAccessibility" style="display:none" class="s4-notdlg noindex">\r\n\t<a id="linkTurnOffAcc" href="#" class="ms-accessible ms-acc-button" onclick="SetIsAccessibilityFeatureEnabled(false);UpdateAccessibilityUI();document.getElementById(\'linkTurnOnAcc\').focus();return false;">Turn off more accessible mode</a>\r\n</div>\r\n<div class="s4-notdlg s4-skipribbonshortcut noindex">\r\n\tSkip Ribbon Commands\r\n</div>\r\n<div class="s4-notdlg noindex">\r\n\tSkip to main content\r\n</div>\r\n<div id="TurnOffAnimation" style="display:none;" class="s4-notdlg noindex">\r\n\t<a id="linkTurnOffAnimation" href="#" class="ms-accessible ms-acc-button" onclick="ToggleAnimationStatus();return false;">Turn off Animations</a>\r\n</div>\r\n<div id="TurnOnAnimation" style="display:none;" class="s4-notdlg noindex">\r\n\t<a id="linkTurnOnAnimation" href="#" class="ms-accessible ms-acc-button" onclick="ToggleAnimationStatus();return false;">Turn on Animations</a>\r\n</div>\r\n<a id="HiddenAnchor" href="javascript:;" style="display:none;"></a>\r\n<div id="suiteBar" class="ms-dialogHidden noindex">\r\n\t<div id="suiteBarLeft">\r\n\t\t<div class="ms-table ms-fullWidth">\r\n\t\t\t<div class="ms-tableRow">\r\n\t\t\t\t<div class="ms-tableCell ms-verticalAlignMiddle">\r\n\t\t\t\t\t\r\n\t\t\t\t</div>\r\n\t\t\t\t<div id="DeltaSuiteLinks" class="ms-core-deltaSuiteLinks">\r\n\r\n</div>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t</div>\r\n\t<div id="suiteBarRight">\r\n\t\t<div id="DeltaSuiteBarRight" class="ms-core-deltaSuiteBarRight">\r\n\r\n</div>\r\n\t</div>\r\n</div>\r\n\t\t<div id="ms-hcTest"></div>\r\n\t\t<div id="s4-ribbonrow">\r\n\t\t<div id="globalNavBox" class="noindex">\r\n<div id="ribbonBox">\r\n\t<div id="s4-ribboncont">\r\n\t\t<div id="DeltaSPRibbon">\r\n\r\n</div>\r\n\t</div>\r\n\t<span id="DeltaSPNavigation"></span>\r\n</div>\r\n<div id="DeltaWebPartAdderUpdatePanelContainer" class="ms-core-webpartadder">\r\n\r\n</div>\r\n\t\t</div>\r\n\t\t</div>\r\n\t\t<div id="s4-workspace" class="ms-core-overlay">\r\n\t\t<div id="s4-bodyContainer">\r\n\t\t<div id="s4-titlerow"\r\n\t\t\tclass="ms-dialogHidden s4-titlerowhidetitle">\r\n\t\t<div id="titleAreaBox"\r\n\t\t\tclass="ms-noList ms-table ms-core-tableNoSpace">\r\n\t\t<div id="titleAreaRow"\r\n\t\t\tclass="ms-tableRow">\r\n<div id="siteIcon" class="ms-tableCell ms-verticalAlignTop">\r\n\t<div id="DeltaSiteLogo">\r\n\r\n</div>\r\n</div>\r\n\t\t\t<div class="ms-breadcrumb-box ms-tableCell ms-verticalAlignTop">\r\n\t\t\t\t<div\r\n\t\t\t\t\tclass="ms-breadcrumb-top">\r\n<div class="ms-breadcrumb-dropdownBox" style="display:none;">\r\n<span id="DeltaBreadcrumbDropdown"></span>\r\n</div>\r\n<div id="DeltaTopNavigation" class="ms-displayInline ms-core-navigation" role="navigation">\r\n\r\n</div>\r\n\t\t\t\t</div>\r\n<h1 id="pageTitle" class="ms-core-pageTitle">\r\n <span id="DeltaPlaceHolderPageTitleInTitleArea"></span>\r\n <div id="DeltaPlaceHolderPageDescription" class="ms-displayInlineBlock ms-normalWrap">\r\n\r\n</div>\r\n</h1>\r\n\t\t\t</div>\r\n\t\t\t<div class="ms-tableCell ms-verticalAlignTop">\r\n<div id="DeltaPlaceHolderSearchArea" class="ms-mpSearchBox ms-floatRight">\r\n\r\n</div>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t\t</div>\r\n\t\t</div>\r\n\t\t<div id="contentRow">\r\n<div id="sideNavBox"\r\n\t class="ms-dialogHidden ms-forceWrap ms-noList">\r\n <div id="DeltaPlaceHolderLeftNavBar" class="ms-core-navigation" role="navigation">\r\n\r\n</div>\r\n</div>\r\n<div id="contentBox"\r\n aria-live="polite" aria-relevant="all">\r\n <div id="notificationArea" class="ms-notif-box"></div>\r\n\t<div id="DeltaPageStatusBar">\r\n\r\n</div>\r\n\t<div id="DeltaPlaceHolderMain">\r\n\r\n</div>\r\n</div>\r\n<div id="DeltaFormDigest">\r\n\r\n</div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\t\t</div>\r\n\t\t</div>\r\n\t\t</div>\r\n\r\n\r\n<script type="text/javascript">\r\n//<![CDATA[\r\n\r\nvar filesExist = true;\r\nif (typeof(initJsLoaded) === \'undefined\') { filesExist = false; }\r\nelse if (typeof(Sys) === \'undefined\') { filesExist = false; }\r\nelse if (typeof(Sys.WebForms) === \'undefined\') { filesExist = false; }\r\nelse if (typeof(startJsLoaded) === \'undefined\') { filesExist = false; }\r\nvar sessionStorageEnabled = window.sessionStorage != null;\r\nif (!filesExist) {\r\n if (!sessionStorageEnabled || window.sessionStorage[\'spFilesExist\'] === \'false\'){\r\n if (\'undefined\' != typeof(g_initUrl) && null != g_initUrl && \'\' != g_initUrl)\r\n {\r\n try\r\n {\r\n if (sessionStorageEnabled) \r\n {\r\n window.sessionStorage[\'spFilesExist\'] = \'true\';\r\n }\r\n }\r\n catch (e) {}\r\n var tempAnchor = document.createElement(\'a\');\r\n tempAnchor.href = g_initUrl;\r\n var redir = tempAnchor.href;\r\n tempAnchor = null;\r\n window.location.href=redir;\r\n }\r\n }else{\r\n try\r\n {\r\n window.sessionStorage[\'spFilesExist\'] = \'false\';\r\n window.location.reload(true);\r\n }\r\n catch (e) {}\r\n }\r\n} else {\r\n if (sessionStorageEnabled)\r\n {\r\n window.sessionStorage[\'spFilesExist\'] = \'true\';\r\n }\r\n}\r\nvar workingOnIt = \'Working on it...\';var _spFullDownloadList = [\'closeconnection\', \'download\', \'signout\', \'xlviewer\', \'wordviewer\', \'wordeditor\', \'powerpoint\', \'powerpointframe\', \'onenote\', \'visiowebaccess\', \'storefront\', \'wopiframe\', \'appredirect\', \'wfstart\'];\nif (\'undefined\' != typeof(AsyncDeltaManager$onError)) window.onerror = AsyncDeltaManager$onError;\nvar _fV4UI = true;var origMP = \'|SITES|SANDBOX:|SITES|SANDBOX|_CATALOGS|MASTERPAGE|SEATTLE.MASTER:2.15.0.0.0.15.0.5131.1000.0.FALSE.:en-US:en-US:RW\';var phMain = \'DeltaPlaceHolderMain\';var g_AjaxDeltaList = [{id:\'DeltaPlaceHolderAdditionalPageHead\', container:false},{id:\'DeltaSPWebPartManager\', container:true},{id:\'DeltaDelegateControls\', container:true},{id:\'DeltaSuiteLinks\', container:true},{id:\'DeltaSuiteBarRight\', container:true},{id:\'DeltaSPRibbon\', container:true},{id:\'DeltaSPNavigation\', container:true},{id:\'DeltaWebPartAdderUpdatePanelContainer\', container:true},{id:\'DeltaSiteLogo\', container:true},{id:\'DeltaBreadcrumbDropdown\', container:true},{id:\'DeltaTopNavigation\', container:true},{id:\'DeltaPlaceHolderPageTitleInTitleArea\', container:true},{id:\'DeltaPlaceHolderPageDescription\', container:true},{id:\'DeltaPlaceHolderSearchArea\', container:true},{id:\'DeltaPlaceHolderLeftNavBar\', container:true},{id:\'DeltaPageStatusBar\', container:true},{id:\'DeltaPlaceHolderMain\', container:true},{id:\'DeltaFormDigest\', container:true},{id:\'DeltaPlaceHolderUtilityContent\', container:true}];\n\r\nfunction submitHook() {{return asyncDeltaManager._onFormSubmit();}}\r\nfunction _startOnSubmitStatement() {{return asyncDeltaManager._doSubmitStatements();}}\r\nfunction WebForm_OnSubmit() {{ return asyncDeltaManager._doSubmitStatements(); }}\r\n\r\nif (typeof(hashSaverUrl) != \'undefined\' && hashSaverUrl && hashSaverUrl != \'\') {\r\n if ( (function(u, d) {\r\n var idxDb = u.indexOf(\'//\');\r\n if (-1 != idxDb) {\r\n var idxDe = u.indexOf(\'/\', idxDb+2);\r\n if (-1 == idxDe) idxDe = u.length;\r\n var D = u.substring(idxDb+2, idxDe);\r\n if (d.toUpperCase() != D.toUpperCase()) return true;\r\n }\r\n return false;\r\n }) (hashSaverUrl, document.location.host)) { hashSaverUrl = \'/\';}\r\n window.location.replace(STSPageUrlValidation(hashSaverUrl));\r\n}\r\nvar g_clientIdDeltaPlaceHolderMain = "DeltaPlaceHolderMain";\r\nvar g_clientIdDeltaPlaceHolderPageTitleInTitleArea = "DeltaPlaceHolderPageTitleInTitleArea";\r\nvar g_clientIdDeltaPlaceHolderUtilityContent = "DeltaPlaceHolderUtilityContent";\r\n//]]>\r\n</script>\r\n</form>\r\n\t<span id="DeltaPlaceHolderUtilityContent"></span>\r\n\t<script type="text/javascript">// <![CDATA[ \n\r\n\r\n\t\tvar g_Workspace = "s4-workspace";\r\n\t// ]]>\r\n</script>\r\n</body>\r\n</html>\r\n'
Check the steps below.
1.Install requests.
pip install requests
2.Install requests_ntlm.
pip install requests_ntlm
3.Make the username(domain\username) and password are right, and run the code as below.
import requests
from requests_ntlm import HttpNtlmAuth
headers = {'accept': 'application/json;odata=verbose'}
r = requests.get("http://sp2013/sites/team/_api/web", auth=HttpNtlmAuth('domain\\admin', 'password'), headers=headers)
print(r.json()["d"]["CustomMasterUrl"])

Categories