How to save file which was sent to telebot from user Python? - python

I need to save a file which was sent to telegram bot.
import telebot
bot = "Here is my token"
#bot.message_handler(content_types='') #IDK what content type I need to use to receive every file
def addfile(message):
#Here I need to save file which was sent

That would look something like this:
#bot.message_handler(content_types=['document', 'photo', 'audio', 'video', 'voice']) # list relevant content types
def addfile(message):
file_name = message.document.file_name
file_info = bot.get_file(message.document.file_id)
downloaded_file = bot.download_file(file_info.file_path)
with open(file_name, 'wb') as new_file:
new_file.write(downloaded_file)

Related

Sending photos without compression, telegrambot file

How do I send a photo to chat without compression, as a file. When I implement it with the current method, the file is sent as a document without an extension.
bot = TeleBot("API")
#bot.message_handler(content_types=['text'])
def send(message):
with open("5.jpg", "rb") as file:
f = file.read()
bot.send_document(message.chat.id, document=f)
bot.polling(True)
When you do
f = file.read()
Combined with document=f, Telegram will receive the content of the file.
To send the file with the original filenamem, pass the file variable from open():
with open("/tmp/ccatt.jpeg", "rb") as file:
bot.send_document(123456789, document=file)

Delete one object from a JSON file using python

#Bot.command()
async def cl(ctx,member:discord.Member = None):
with open("C:\python3\economy.json","r") as f:
json.load(f)
queue.remove(str(member.id))
with open("C:\python3\economy.json","w") as f:
json.dump(f)
I need to delete only highlighted text оn the picture:
json file
There are 3 errors:
You haven't defined queue
There's no such method as dict.remove, you're looking for dict.pop
You're not saving anything into your JSON file
Fixing your code
with open("C:\python3\economy.json", "r") as f:
queue = json.load(f) # defining `queue`
queue.pop(str(member.id)) # removing the key
with open("C:\python3\economy.json", "w") as f:
json.dump(queue, f) # saving into the JSON file

How do you save multitype/form data to a hard file in Python with FastAPI UploadFile?

https://fastapi.tiangolo.com/tutorial/request-files/
*Solved Below *
I've gotten an appropriately sized array of bytes and I'm not sure how to parse it correctly to save received form file data.
Almost working:
#app.post("/uploadfiles/")
async def create_files(files: List[bytes] = File(...)):
out_file = open("files/1.txt", "w") # open for [w]riting as [b]inary
out_file.write( str([(file) for file in files]))
out_file.close()
return {"file_sizes": [len(file) for file in files]}
The script results in a file that is no longer a readable .png. I assume I'm using the libraries incorrectly but I'm not sure which to start with: HTMLResponse, FastAPI, multipart or List maybe? Any ideas or docs on how to properly parse these bytes back together again?
Edit
Per a break and once over review of the FastAPI docs, I spotted that this particular array of byte data is multipart/form-data data (so maybe I'll find a python library for reading form data/images):
Here is a small example (first ~100chars) of the data that is generated:
[b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x03\xe8\x00\x00\x01\xf4\x08\x06\x00\x00\x00\xae(\x07-\x00\x00\x01\x86iCCPICC profile\x00\x00(\x91}\x91=H\
I did it!!!
The secret was pythons native byte recognition libraries and order of ops!!
#app.post("/uploadfiles/")
async def create_files(files: bytes = File(...)):
out_file = open("files/1.jpg", "wb") # open for [w]riting as [b]inary
out_file.write( bytes([(file) for file in files]))
out_file.close()
Still work to do on the file naming system :) GL Everyone!
Edit 2
Since the below answer didn't function, I scripted a file name appender:
#app.post("/uploadfiles/")
async def create_files(files: bytes = File(...)):
with open('C:/data/sample.txt', 'r', encoding='utf-8') as g:
data=g.readlines()
for line in data:
counter = int(line)
with open('C:/data/sample.txt', 'w') as f:
counter = counter + 1
f.write(str(counter))
out_file = open("files/" + str(counter) + ".jpg", "wb") # open for [w]riting as [b]inary
out_file.write( bytes([(file) for file in files]))
out_file.close()
Thanks for the help everyone! Happy hacking :^)
Edit 3
I've been informed that the method of which I am posting could be incorrect practice in conjunction with FastAPI so to better understand this I am posting the relevant javascript that posts to the backend:
Here is the relevant code from my reactjs form post script:
onSubmit = (e) => {
e.preventDefault();
const formData = new FormData();
if (this.state.images != null) {
var form = document.getElementById("apiupform");
document.getElementById("apiupform").hidden = true;
Array.from(this.state.images).forEach((image) => {
formData.append("files", image);
});
axios
.post(`https://****.com/uploadfiles/`, formData, {
headers: {
"Content-Type": "multipart/form-data",
},
})
Thank you everyone for the help with this work. I will update it as I find improvements :)
You can save the uploaded files this way,
from fastapi import FastAPI, File, UploadFile
app = FastAPI()
#app.post("/upload-file/")
async def create_upload_file(uploaded_file: UploadFile = File(...)):
file_location = f"files/{uploaded_file.filename}"
with open(file_location, "wb+") as file_object:
file_object.write(uploaded_file.file.read())
return {"info": f"file '{uploaded_file.filename}' saved at '{file_location}'"}
OR,
maybe a more efficient way using the shutil.copyfileobj(...) method as,
import shutil
from fastapi import FastAPI, File, UploadFile
app = FastAPI()
#app.post("/upload-file/")
async def create_upload_file(uploaded_file: UploadFile = File(...)):
file_location = f"files/{uploaded_file.filename}"
with open(file_location, "wb+") as file_object:
shutil.copyfileobj(uploaded_file.file, file_object)
return {"info": f"file '{uploaded_file.filename}' saved at '{file_location}'"}
Sample Swagger
I would use an asynchronous library like aiofiles for file operations.
Since you are running your app inside an event loop the file writing operation will block the entire execution of your app.
import aiofiles
#app.post("/uploadfiles/")
async def create_files(files: bytes = File(...)):
async with aiofiles.open("files/1.jpg", "wb") as f:
await f.write(bytes([(file) for file in files]))
this is what worked for me..
#app.post("/fileUpload/")
def fileUpload(ufile: UploadFile = File(...)):
s = str(ufile.file.read(), 'utf-8')
with open(ufile.filename, "w+") as buffer:
buffer.write(s)

Add a new entry to a json file in Python

I have a json file that works fine, I have a bot command on discord that displays a random entry from it.
The next command I would like to write is on how to add a new entry so that I don't need to do it manually through Atom.
async def addquote(self, ctx, message):
with open('quotes.json','r') as f:
quote = json.load(f)
#quote[str(message)] =
with open('quotes.json', 'w') as f:
json.dump(quote, f)
await ctx.send('Quote added.')
The commented # line is where I'm struggling the most I think.
Jsonfile
Here's a screenshot of the jsonfile, how it looks. I would like to add more "quotes" to it with that function
Thanks a lot
These code worked on my side:
import json
with open('quotes.json','r') as f:
quote = json.load(f)
print(quote)
quote['Quote'].append({
'quote':"test"
})
with open('prefises.json', 'w') as f:
json.dump(quote, f)
with the quotes.json:
{"Quote":[]}
and the prefises.json:
{"Quote": [{"quote": "test"}]}
I fixed my problem by using a list instead of a dictionary in my JSON.
async def addquote(self, ctx, *, message):
with open('quotes.json','r') as f:
quote = json.load(f)
quote.append(message)
with open('quotes.json', 'w') as f:
json.dump(quote, f)
await ctx.send('Quote added.')
The quote.json was cleared and the content was only []
Then writing to it worked.

Strage behaviour with texttospeech google api

I'm starting to know how to use google APIs modifying the python example code of the texttospeech API I found an issue, when I use ssml languaje in a txt file to pass the text to the API the resultant mp3 audio changed the character 'é' with the sentence 'derechos de autor' and the character 'á' with a silence. That only happens when I read the text from file, if i provide the ssml sentence direct to the applicacion by argunment when calling it this change doesn't happens.
I searched for this issue and I didn't find it, colud anyone give a hint of that is going on here?
This is the function that takes the ssml texto from the console, and creates the correct mp3 audio file:
def synthesize_ssml(ssml, output):
from google.cloud import texttospeech as texttospeech
client = texttospeech.TextToSpeechClient()
input_text = texttospeech.types.SynthesisInput(ssml=ssml)
voice = texttospeech.types.VoiceSelectionParams(language_code='es-ES')
audio_config = texttospeech.types.AudioConfig(
audio_encoding=texttospeech.enums.AudioEncoding.MP3)
response = client.synthesize_speech(input_text, voice, audio_config)
with open(output, 'wb') as out:
out.write(response.audio_content)
print('Audio content written to file "%s"' % output)
And this is the function that takes the ssml from a file, the same text, produce different audio files:
def synthesize_ssml_file(input, output):
from google.cloud import texttospeech as texttospeech
with open(input,'r') as inp:
input_text=texttospeech.types.SynthesisInput(ssml=str(inp.read()))
client = texttospeech.TextToSpeechClient()
voice = texttospeech.types.VoiceSelectionParams(language_code='es-ES')
audio_config = texttospeech.types.AudioConfig(
audio_encoding=texttospeech.enums.AudioEncoding.MP3)
response = client.synthesize_speech(input_text, voice, audio_config)
with open(output, 'wb') as out:
out.write(response.audio_content)
print('Audio content written to file "%s"' % output)

Categories