Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hw19.2 #28

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added lesson_19/HLIT.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
54 changes: 54 additions & 0 deletions lesson_19/flask_server/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from flask import Flask, request, jsonify, send_from_directory
import os

app = Flask(__name__)

upload_directory = './uploads'
if not os.path.exists(upload_directory):
os.makedirs(upload_directory)


@app.route('/upload', methods=['POST'])
def upload_image():
if 'image' not in request.files:
return jsonify({'error': 'No image provided'}), 400

image = request.files['image']
if image.filename == '':
return jsonify({'error': 'No selected file'}), 400

filename = os.path.join(upload_directory, image.filename)
image.save(filename)

return jsonify({'image_url': request.host_url + 'uploads/' + image.filename}), 201


@app.route('/image/<filename>', methods=['GET'])
def get_image(filename):
content_type = request.headers.get('Content-Type')
filepath = os.path.join(upload_directory, filename)
if os.path.exists(filepath):
if content_type == 'text':
return jsonify({'image_url': request.host_url + 'uploads/' + filename}), 200
elif content_type == 'image':
return send_from_directory(upload_directory, filename)
else:
return jsonify({'error': 'Unsupported Content-Type'}), 400
else:
return jsonify({'error': 'Image not found'}), 404


@app.route('/delete/<filename>', methods=['DELETE'])
def delete_image(filename):
filepath = os.path.join(upload_directory, filename)
if not os.path.exists(filepath):
return jsonify({'error': 'Image not found'}), 404

os.remove(filepath)
return jsonify({'message': f'Image {filename} deleted'}), 200


if __name__ == '__main__':
host = '127.0.0.1'
port = 8080
app.run(host=host, port=port, debug=True)
107 changes: 107 additions & 0 deletions lesson_19/homework19.2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
"""
HW 19.2. POST/GET/DELETE.

In the Python virtual environment (venv),
install Flask using the command pip install flask.
Create a file named app.py in a separate directory
and copy the code for app.py provided in the initial data.
Run the HTTP server using the command python app.py.
The server will start at the base address http://127.0.0.1:8080.

Using the documentation provided below, write code that:
1. Uses the requests module to perform a POST request
to upload an image to the server.
2. Retrieves the link to this file using a GET request.
3. Deletes the file from the server using a DELETE request.
"""

import logging

import requests
from requests.exceptions import HTTPError, Timeout

# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
)
_log = logging.getLogger(__name__)


def upload_to_server(base_url: str, file: str):
"""Upload file to the server."""
try:
with open(file, 'rb') as fh:
files = {'image': (file, fh, 'image/png')}
upload_url = f'{base_url}/upload'
response = requests.post(upload_url, files=files, timeout=5)
response.raise_for_status()
_log.info(f'Server response: {response.json()}')
return response

except HTTPError as http_err:
_log.error(f'HTTP error: {http_err}')
except Timeout as time_err:
_log.error(f'Timeout error: {time_err}')
except FileNotFoundError as file_err:
_log.error(f'File not found: - {file_err}')
except Exception as err:
_log.error(f'An unexpected error occurred: {err}')
Comment on lines +42 to +49
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to add helper function do_request and put all request error handling there. No sense to keep duplicate code for upload/get/delete operations
Other error handling like FileNotFound could be placed to main block



def get_file_info(base_url: str, file: str, content_type: str):
"""Get file info from the server."""
try:
full_url = f'{base_url}/image/{file}'
headers = {'Content-Type': content_type}
response = requests.get(full_url, headers=headers, timeout=5)
response.raise_for_status()

if content_type == 'text':
_log.info(f'Server response: {response.json()}')
return response.json()

elif content_type == 'image':
with open(file, 'wb') as img_fh:
img_fh.write(response.content)
_log.info(f'File downloaded: {file}')
return file

except HTTPError as http_err:
_log.error(f'HTTP error: {http_err}')
except Timeout as time_err:
_log.error(f'Timeout error: {time_err}')
except Exception as err:
_log.error(f'An unexpected error occurred: {err}')


def delete_from_server(base_url: str, file: str):
"""Delete file from server."""
try:
headers = {'Content-Type': 'image'}
full_url = f'{base_url}/delete/{file}'
response = requests.delete(full_url, headers=headers, timeout=5)
response.raise_for_status()
_log.info(f'Server response: {response.json()}')
return response.json()

except HTTPError as http_err:
_log.error(f'HTTP error: {http_err}')
except Timeout as time_err:
_log.error(f'Timeout error: {time_err}')
except Exception as err:
_log.error(f'An unexpected error occurred: {err}')


if __name__ == '__main__':
base_addr = 'http://127.0.0.1:8080'
filename = 'HLIT.png'

_log.info('POST request')
upload_to_server(base_addr, filename)

_log.info('GET request')
get_file_info(base_addr, filename, 'text')

_log.info('DELETE request')
delete_from_server(base_addr, filename)