Update examples
This commit is contained in:
parent
c69e9801e9
commit
1b4ba81ab0
|
@ -0,0 +1,47 @@
|
|||
#!/usr/bin/env python3
|
||||
"""bcrypt_test.py
|
||||
This module provides utilities for user authentication, including functions to
|
||||
store hashed passwords, create new users, and authenticate existing users using
|
||||
bcrypt for password hashing and a CSV file to store user data.
|
||||
"""
|
||||
import bcrypt
|
||||
import csv
|
||||
|
||||
|
||||
def store_password(password):
|
||||
hashed_password = bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt())
|
||||
return hashed_password
|
||||
|
||||
|
||||
def check_password(password, hashed_password):
|
||||
return bcrypt.checkpw(password.encode("utf-8"), hashed_password)
|
||||
|
||||
|
||||
def create_user(username, password):
|
||||
hashed_password = store_password(password).decode("utf-8")
|
||||
|
||||
with open("passwords_db.csv", "a", newline="") as file:
|
||||
writer = csv.writer(file)
|
||||
writer.writerow([username, hashed_password])
|
||||
|
||||
|
||||
def authenticate_user(username, password):
|
||||
try:
|
||||
with open("passwords_db.csv", "r") as file:
|
||||
reader = csv.reader(file)
|
||||
for row in reader:
|
||||
if row and row[0] == username:
|
||||
hashed_password = row[1].encode("utf-8")
|
||||
return check_password(password, hashed_password)
|
||||
return False
|
||||
except FileNotFoundError:
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
create_user("user1", "mysecurepassword")
|
||||
|
||||
if authenticate_user("user1", "mysecurepassword"):
|
||||
print("Authentication successful")
|
||||
else:
|
||||
print("Authentication failed")
|
|
@ -1,23 +1,22 @@
|
|||
# Import smtplib for the actual sending function
|
||||
"""
|
||||
This module sends an email with the contents of a specified text file as the
|
||||
body. The "smtplib" and "email.message" modules are used to construct and send
|
||||
the email.
|
||||
"""
|
||||
|
||||
import smtplib
|
||||
|
||||
# Import the email modules we'll need
|
||||
from email.message import EmailMessage
|
||||
|
||||
textfile = "textfile"
|
||||
# Open the plain text file whose name is in textfile for reading.
|
||||
with open(textfile) as fp:
|
||||
# Create a text/plain message
|
||||
msg = EmailMessage()
|
||||
msg.set_content(fp.read())
|
||||
|
||||
# me == the sender's email address
|
||||
# you == the recipient's email address
|
||||
msg["Subject"] = f"The contents of {textfile}"
|
||||
msg["From"] = "roland@rtj.dev"
|
||||
msg["To"] = "roland@rtj.dev"
|
||||
msg["From"] = "roland"
|
||||
msg["To"] = "roland"
|
||||
|
||||
# Send the message via our own SMTP server.
|
||||
s = smtplib.SMTP("localhost")
|
||||
s.send_message(msg)
|
||||
s.quit()
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import unittest
|
||||
from io import StringIO
|
||||
from unittest.mock import patch
|
||||
import print_things # import the module containing the function with print statements
|
||||
import print_things
|
||||
|
||||
|
||||
class TestPrintFunction(unittest.TestCase):
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
This module contains a Python script utilizing the PyQt5 library to create a
|
||||
basic graphical user interface (GUI) application. The application showcases a
|
||||
tabbed window with two tabs, each containing a grid of numbers. The first tab
|
||||
displays numbers from 1 to 100, and the second tab displays numbers from 101 to
|
||||
200, arranged in a grid format.
|
||||
|
||||
Dependencies:
|
||||
PyQt5
|
||||
"""
|
||||
import sys
|
||||
from PyQt5.QtWidgets import (
|
||||
QApplication,
|
||||
|
@ -13,50 +24,40 @@ class TabbedWindow(QMainWindow):
|
|||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
# Set the main window title and size
|
||||
self.setWindowTitle("Tabbed Window")
|
||||
self.resize(300, 300)
|
||||
|
||||
# Create a tab widget
|
||||
self.tab_widget = QTabWidget()
|
||||
self.setCentralWidget(self.tab_widget)
|
||||
|
||||
# Create the first tab
|
||||
self.tab1 = QWidget()
|
||||
self.tab_widget.addTab(self.tab1, "1-100")
|
||||
|
||||
# Create a grid layout for the first tab
|
||||
layout1 = QGridLayout()
|
||||
layout1.setHorizontalSpacing(10)
|
||||
layout1.setVerticalSpacing(10)
|
||||
|
||||
# Add the numbers 1-100 to the layout
|
||||
for i in range(1, 101):
|
||||
column = (i - 1) % 10
|
||||
row = (i - 1) // 10
|
||||
label = QLabel(str(i))
|
||||
layout1.addWidget(label, row, column)
|
||||
|
||||
# Set the layout for the first tab
|
||||
self.tab1.setLayout(layout1)
|
||||
|
||||
# Create the second tab
|
||||
self.tab2 = QWidget()
|
||||
self.tab_widget.addTab(self.tab2, "101-200")
|
||||
|
||||
# Create a grid layout for the second tab
|
||||
layout2 = QGridLayout()
|
||||
layout2.setHorizontalSpacing(10)
|
||||
layout2.setVerticalSpacing(10)
|
||||
|
||||
# Add the numbers 101-200 to the layout
|
||||
for i in range(101, 201):
|
||||
column = (i - 101) % 10
|
||||
row = (i - 101) // 10
|
||||
label = QLabel(str(i))
|
||||
layout2.addWidget(label, row, column)
|
||||
|
||||
# Set the layout for the second tab
|
||||
self.tab2.setLayout(layout2)
|
||||
|
||||
|
||||
|
|
20
rand_char.py
20
rand_char.py
|
@ -2,13 +2,13 @@
|
|||
"""
|
||||
Generate and Print Random Unicode Characters
|
||||
|
||||
This module generates a string of random Unicode characters, specifically avoiding the
|
||||
surrogate pair range (0xD800 to 0xDFFF). The generated string has a default length of
|
||||
5000 characters.
|
||||
This module generates a string of random Unicode characters, specifically
|
||||
avoiding the surrogate pair range (0xD800 to 0xDFFF). The generated string has
|
||||
a default length of 5000 characters.
|
||||
|
||||
Usage:
|
||||
Run the script with an argument to specify the length of the string to be generated:
|
||||
`python script_name.py 5000`
|
||||
Run the script with an argument to specify the length of the string to be
|
||||
generated: `python script_name.py 5000`
|
||||
"""
|
||||
import random
|
||||
from argparse import ArgumentParser
|
||||
|
@ -21,7 +21,11 @@ def generate_string(length):
|
|||
[
|
||||
chr(
|
||||
random.choice(
|
||||
[i for i in range(0x0, 0xD7FF + 1) if i < 0xD800 or i > 0xDFFF]
|
||||
[
|
||||
i
|
||||
for i in range(0x0, 0xD7FF + 1)
|
||||
if i < 0xD800 or i > 0xDFFF
|
||||
]
|
||||
)
|
||||
)
|
||||
for _ in range(length)
|
||||
|
@ -30,7 +34,7 @@ def generate_string(length):
|
|||
except UnicodeEncodeError as e:
|
||||
print(f"Error encoding character: {e}")
|
||||
|
||||
return(characters)
|
||||
return characters
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -45,4 +49,4 @@ if __name__ == "__main__":
|
|||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
print(generate_string(args.length))
|
||||
print(generate_string(args.length))
|
||||
|
|
|
@ -1,12 +1,21 @@
|
|||
#!/usr/bin/env
|
||||
"""
|
||||
This module implements a simple console application to manage a list of creatures.
|
||||
It provides functionalities to add a creature to the list, lookup creatures with
|
||||
autocomplete support (press tab to auto-complete creature names), and quit the
|
||||
application.
|
||||
"""
|
||||
import readline
|
||||
|
||||
creatures = []
|
||||
|
||||
|
||||
def add_creature():
|
||||
creature = input("Enter a creature name: ")
|
||||
creatures.append(creature)
|
||||
print(f"{creature} added to the list of creatures.")
|
||||
|
||||
|
||||
def lookup_creature():
|
||||
def completer(text, state):
|
||||
options = [c for c in creatures if c.startswith(text)]
|
||||
|
@ -14,46 +23,51 @@ def lookup_creature():
|
|||
return options[state]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
readline.set_completer(completer)
|
||||
readline.parse_and_bind("tab: complete")
|
||||
|
||||
|
||||
print("List of creatures:")
|
||||
for creature in creatures:
|
||||
print(f"- {creature}")
|
||||
|
||||
|
||||
while True:
|
||||
creature = input("Enter the name of a creature or press enter to return to the main menu: ")
|
||||
creature = input(
|
||||
"Enter the name of a creature or press enter to return to the main menu: "
|
||||
)
|
||||
if not creature:
|
||||
break
|
||||
elif creature in creatures:
|
||||
print(f"{creature} found!")
|
||||
else:
|
||||
print(f"{creature} not found.")
|
||||
|
||||
|
||||
readline.set_completer(None)
|
||||
readline.parse_and_bind("tab: ")
|
||||
|
||||
|
||||
def quit():
|
||||
print("Goodbye!")
|
||||
exit()
|
||||
|
||||
menu = {
|
||||
"1": add_creature,
|
||||
"2": lookup_creature,
|
||||
"3": quit
|
||||
}
|
||||
|
||||
while True:
|
||||
print("Menu:")
|
||||
print("[1] Add Creature")
|
||||
print("[2] Lookup Creature")
|
||||
print("[3] Quit")
|
||||
|
||||
choice = input("Enter your choice: ")
|
||||
action = menu.get(choice)
|
||||
if action:
|
||||
action()
|
||||
else:
|
||||
print(f"{choice} is not a valid option.")
|
||||
menu = {"1": add_creature, "2": lookup_creature, "3": quit}
|
||||
|
||||
|
||||
def main():
|
||||
while True:
|
||||
print("Menu:")
|
||||
print("[1] Add Creature")
|
||||
print("[2] Lookup Creature")
|
||||
print("[3] Quit")
|
||||
|
||||
choice = input("Enter your choice: ")
|
||||
action = menu.get(choice)
|
||||
if action:
|
||||
action()
|
||||
else:
|
||||
print(f"{choice} is not a valid option.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -1,15 +1,25 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
This module defines a command-line interface (CLI) application which allows
|
||||
users to interact with a predefined list of completion options, specifically,
|
||||
card names from the "Alara Reborn" set.
|
||||
|
||||
It leverages the `cmd` module to build the CLI and has tab-completion
|
||||
functionality for adding items from the predefined list of card names.
|
||||
"""
|
||||
import cmd
|
||||
|
||||
completions = [
|
||||
'Mage Slayer (Alara Reborn)',
|
||||
'Magefire Wings (Alara Reborn)',
|
||||
'Sages of the Anima (Alara Reborn)',
|
||||
'Sanctum Plowbeast (Alara Reborn)',
|
||||
'Sangrite Backlash (Alara Reborn)',
|
||||
'Sanity Gnawers (Alara Reborn)',
|
||||
'Sen Triplets (Alara Reborn)'
|
||||
"Mage Slayer (Alara Reborn)",
|
||||
"Magefire Wings (Alara Reborn)",
|
||||
"Sages of the Anima (Alara Reborn)",
|
||||
"Sanctum Plowbeast (Alara Reborn)",
|
||||
"Sangrite Backlash (Alara Reborn)",
|
||||
"Sanity Gnawers (Alara Reborn)",
|
||||
"Sen Triplets (Alara Reborn)",
|
||||
]
|
||||
|
||||
|
||||
class mycmd(cmd.Cmd):
|
||||
def __init__(self):
|
||||
cmd.Cmd.__init__(self)
|
||||
|
@ -21,9 +31,10 @@ class mycmd(cmd.Cmd):
|
|||
pass
|
||||
|
||||
def complete_add(self, text, line, begidx, endidx):
|
||||
mline = line.partition(' ')[2]
|
||||
mline = line.partition(" ")[2]
|
||||
offs = len(mline) - len(text)
|
||||
return [s[offs:] for s in completions if s.startswith(mline)]
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
if __name__ == "__main__":
|
||||
mycmd().cmdloop()
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
import cmd
|
||||
import os
|
||||
import readline
|
||||
import sys
|
||||
|
||||
# Set up history file
|
||||
histfile = os.path.join(os.path.expanduser('~'), '.history')
|
||||
try:
|
||||
readline.read_history_file(histfile)
|
||||
except FileNotFoundError:
|
||||
open(histfile, 'wb').close()
|
||||
|
||||
# Define add and subtract functions
|
||||
def add(x, y):
|
||||
return x + y
|
||||
|
||||
def subtract(x, y):
|
||||
return x - y
|
||||
|
||||
# Define command processor
|
||||
class MyCmd(cmd.Cmd):
|
||||
prompt = '> '
|
||||
intro = 'Type help for commands'
|
||||
|
||||
def do_exit(self, arg):
|
||||
"""Exit the program"""
|
||||
return True
|
||||
|
||||
def do_add(self, arg):
|
||||
"""Add two numbers: add <num1> <num2>"""
|
||||
try:
|
||||
num1, num2 = map(float, arg.split())
|
||||
except ValueError:
|
||||
print('Invalid input')
|
||||
return
|
||||
print(add(num1, num2))
|
||||
|
||||
def complete_add(self, text, line, begidx, endidx):
|
||||
if not text:
|
||||
completions = ['<num1>', '<num2>']
|
||||
elif '<num1>' in line:
|
||||
completions = ['<num2>']
|
||||
else:
|
||||
completions = ['<num1>']
|
||||
return [c for c in completions if c.startswith(text)]
|
||||
|
||||
def do_subtract(self, arg):
|
||||
"""Subtract two numbers: subtract <num1> <num2>"""
|
||||
try:
|
||||
num1, num2 = map(float, arg.split())
|
||||
except ValueError:
|
||||
print('Invalid input')
|
||||
return
|
||||
print(subtract(num1, num2))
|
||||
|
||||
def complete_subtract(self, text, line, begidx, endidx):
|
||||
if not text:
|
||||
completions = ['<num1>', '<num2>']
|
||||
elif '<num1>' in line:
|
||||
completions = ['<num2>']
|
||||
else:
|
||||
completions = ['<num1>']
|
||||
return [c for c in completions if c.startswith(text)]
|
||||
|
||||
def do_clear(self, arg):
|
||||
"""Clear the screen"""
|
||||
if sys.platform.startswith('win'):
|
||||
os.system('cls')
|
||||
else:
|
||||
os.system('clear')
|
||||
|
||||
def default(self, line):
|
||||
print('Invalid command')
|
||||
|
||||
def emptyline(self):
|
||||
pass
|
||||
|
||||
# Run command processor
|
||||
console = MyCmd()
|
||||
readline.set_completer_delims(' \t\n;')
|
||||
readline.parse_and_bind('tab: complete')
|
||||
while True:
|
||||
try:
|
||||
line = input(console.prompt)
|
||||
except EOFError:
|
||||
break
|
||||
console.onecmd(line)
|
||||
|
||||
# Save history file
|
||||
with open(histfile, 'w') as f:
|
||||
readline.write_history_file(histfile)
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
import readline
|
||||
|
||||
# Set up history file
|
||||
histfile = '.history'
|
||||
try:
|
||||
readline.read_history_file(histfile)
|
||||
except FileNotFoundError:
|
||||
open(histfile, 'wb').close()
|
||||
|
||||
# Define add and subtract functions
|
||||
def add(x, y):
|
||||
return x + y
|
||||
|
||||
def subtract(x, y):
|
||||
return x - y
|
||||
|
||||
# Loop for user input
|
||||
while True:
|
||||
# Read user input
|
||||
try:
|
||||
line = input('> ')
|
||||
except EOFError:
|
||||
break
|
||||
|
||||
# Check for exit command
|
||||
if line == 'exit':
|
||||
break
|
||||
|
||||
# Parse user input
|
||||
try:
|
||||
args = line.split()
|
||||
if len(args) != 3:
|
||||
raise ValueError
|
||||
num1 = float(args[0])
|
||||
num2 = float(args[2])
|
||||
op = args[1]
|
||||
if op not in ['+', '-']:
|
||||
raise ValueError
|
||||
except ValueError:
|
||||
print('Invalid input')
|
||||
continue
|
||||
|
||||
# Perform operation
|
||||
if op == '+':
|
||||
result = add(num1, num2)
|
||||
else:
|
||||
result = subtract(num1, num2)
|
||||
|
||||
# Print result and add command to history
|
||||
print(result)
|
||||
readline.add_history(line)
|
||||
|
||||
# Save history file
|
||||
readline.write_history_file(histfile)
|
|
@ -1,66 +0,0 @@
|
|||
import cmd
|
||||
import os
|
||||
import readline
|
||||
|
||||
# Set up history file
|
||||
histfile = os.path.join(os.path.expanduser('~'), '.history')
|
||||
try:
|
||||
readline.read_history_file(histfile)
|
||||
except FileNotFoundError:
|
||||
open(histfile, 'wb').close()
|
||||
|
||||
# Define add and subtract functions
|
||||
def add(x, y):
|
||||
return x + y
|
||||
|
||||
def subtract(x, y):
|
||||
return x - y
|
||||
|
||||
# Define command processor
|
||||
class MyCmd(cmd.Cmd):
|
||||
prompt = '> '
|
||||
intro = 'Type help for commands'
|
||||
|
||||
def do_exit(self, arg):
|
||||
"""Exit the program"""
|
||||
return True
|
||||
|
||||
def do_add(self, arg):
|
||||
"""Add two numbers: add <num1> <num2>"""
|
||||
try:
|
||||
num1, num2 = map(float, arg.split())
|
||||
except ValueError:
|
||||
print('Invalid input')
|
||||
return
|
||||
print(add(num1, num2))
|
||||
|
||||
def do_subtract(self, arg):
|
||||
"""Subtract two numbers: subtract <num1> <num2>"""
|
||||
try:
|
||||
num1, num2 = map(float, arg.split())
|
||||
except ValueError:
|
||||
print('Invalid input')
|
||||
return
|
||||
print(subtract(num1, num2))
|
||||
|
||||
def default(self, line):
|
||||
print('Invalid command')
|
||||
|
||||
def emptyline(self):
|
||||
pass
|
||||
|
||||
# Run command processor
|
||||
console = MyCmd()
|
||||
readline.set_completer_delims(' \t\n;')
|
||||
readline.parse_and_bind('tab: complete')
|
||||
while True:
|
||||
try:
|
||||
line = input(console.prompt)
|
||||
except EOFError:
|
||||
break
|
||||
console.onecmd(line)
|
||||
|
||||
# Save history file
|
||||
with open(histfile, 'w') as f:
|
||||
readline.write_history_file(histfile)
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
import atexit
|
||||
import code
|
||||
import os
|
||||
import readline
|
||||
|
||||
class HistoryConsole(code.InteractiveConsole):
|
||||
def __init__(self, locals=None, filename="<console>",
|
||||
histfile=os.path.expanduser("~/.console-history")):
|
||||
code.InteractiveConsole.__init__(self, locals, filename)
|
||||
self.init_history(histfile)
|
||||
|
||||
def init_history(self, histfile):
|
||||
readline.parse_and_bind("tab: complete")
|
||||
if hasattr(readline, "read_history_file"):
|
||||
try:
|
||||
readline.read_history_file(histfile)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
atexit.register(self.save_history, histfile)
|
||||
|
||||
def save_history(self, histfile):
|
||||
readline.set_history_length(1000)
|
||||
readline.write_history_file(histfile)
|
||||
|
||||
|
||||
# Run console
|
||||
console = HistoryConsole()
|
||||
while True:
|
||||
try:
|
||||
line = input('> ')
|
||||
except EOFError:
|
||||
break
|
||||
|
||||
# Check for exit command
|
||||
if line == 'exit':
|
||||
break
|
||||
|
||||
# Process user input
|
||||
console.push(line)
|
|
@ -1,3 +1,37 @@
|
|||
"""
|
||||
set_get_attr_example.py
|
||||
-----------------------
|
||||
|
||||
This module contains a class named `Number` which implements special attribute
|
||||
access methods to demonstrate custom attribute setting and getting behaviors
|
||||
in a Python class.
|
||||
|
||||
Here is a summary of its functionality and methods:
|
||||
|
||||
- `__init__(self, number)`: Initializes a new instance with a `number` parameter.
|
||||
- `power(self)`: Squares the current value of the `_number` attribute. It utilizes
|
||||
`self.number` to access the `_number` attribute, which works correctly due to
|
||||
the overridden `__getattribute__` method.
|
||||
- `another_func(self)`: Prints a message when invoked.
|
||||
- `__str__(self)`: Returns a string representation of the `_number` attribute.
|
||||
|
||||
The class also overrides special methods (`__setattr__`, `__getattribute__`,
|
||||
`__getattr__`) to define custom behaviors for setting, getting, and accessing
|
||||
non-existent attributes, respectively.
|
||||
|
||||
Usage:
|
||||
If run as the main program, an instance of `Number` is created with an initial
|
||||
value of 5. The script then performs various operations to demonstrate the
|
||||
custom attribute access behaviors.
|
||||
|
||||
Note:
|
||||
The `__getattribute__` method in the `Number` class is implemented such that if
|
||||
an attribute other than the ones listed in the `options` list is accessed, the
|
||||
`_number` attribute value is returned. This is demonstrated in the script where
|
||||
`number.num` and `number.number` (which are non-existing attributes) are accessed,
|
||||
but the `_number` value is printed instead of raising an AttributeError.
|
||||
"""
|
||||
|
||||
class Number:
|
||||
def __init__(self, number):
|
||||
self._number = number
|
||||
|
@ -31,3 +65,11 @@ class Number:
|
|||
|
||||
def __getattr__(self, name):
|
||||
return self._number
|
||||
|
||||
if __name__ == "__main__":
|
||||
number = Number(5)
|
||||
print(number.num)
|
||||
print(number.number)
|
||||
number.power()
|
||||
print(number.num)
|
||||
number.another_func()
|
||||
|
|
15
test.py
15
test.py
|
@ -1,15 +0,0 @@
|
|||
import unittest
|
||||
|
||||
|
||||
class Yest(unittest.TestCase):
|
||||
def test_int(self):
|
||||
n1 = 5
|
||||
self.assertIsInstance(n1, int, "n1 should be an int")
|
||||
int("124124")
|
||||
a = 5
|
||||
self.assertIsInstance(a, int)
|
||||
|
||||
assert isinstance(n1, int)
|
||||
|
||||
|
||||
unittest.main()
|
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
This module demonstrates the use of asyncio to handle asynchronous and blocking
|
||||
functions in Python. The module contains three functions: a blocking function
|
||||
that simulates a long-running process with `time.sleep`, an asynchronous
|
||||
function that demonstrates asyncio's sleep, and a main function that runs
|
||||
both the blocking and async functions concurrently using a ThreadPoolExecutor
|
||||
for the blocking function.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
import time
|
||||
|
||||
|
||||
def blocking_function():
|
||||
time.sleep(2)
|
||||
return "Blocking function completed!"
|
||||
|
||||
|
||||
async def async_function():
|
||||
print("Async function started!")
|
||||
await asyncio.sleep(1)
|
||||
print("Async function completed!")
|
||||
|
||||
|
||||
async def main():
|
||||
loop = asyncio.get_event_loop()
|
||||
executor = ThreadPoolExecutor()
|
||||
|
||||
async_task = asyncio.create_task(async_function())
|
||||
|
||||
result = await loop.run_in_executor(executor, blocking_function)
|
||||
print(result)
|
||||
|
||||
await async_task
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
Loading…
Reference in New Issue