Skip to content

Commit 5805530

Browse files
committed
feat: first commit 🎉
1 parent 7b14b2d commit 5805530

File tree

16 files changed

+1098
-0
lines changed

16 files changed

+1098
-0
lines changed

README.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Flask RESTful API
2+
3+
This is a web application developed with Flask that provides a RESTful API for managing users, posts, messages, and images. The application also includes JWT authentication and CORS support.
4+
5+
## Installation
6+
7+
1. Clone this repository:
8+
9+
```bash
10+
git clone https://github.com/your_username/your_repository.git
11+
cd your_repository
12+
```
13+
14+
2. Create and activate a virtual environment:
15+
16+
```bash
17+
python3 -m venv venv
18+
source venv/bin/activate # On Windows use `venv\Scripts\activate`
19+
```
20+
21+
3. Install the dependencies:
22+
23+
```bash
24+
pip install -r requirements.txt
25+
```
26+
27+
## Configuration
28+
29+
Make sure to configure the following variables in your configuration file:
30+
31+
```python
32+
app.config['JWT_SECRET_KEY'] = 'GRUWIN-ADMIN-ACCOUNT'
33+
app.config['JWT_ACCESS_TOKEN_EXPIRES'] = False
34+
```
35+
36+
## Usage
37+
38+
Run the application:
39+
40+
```bash
41+
flask run
42+
```
43+
44+
The application will be available at `http://127.0.0.1:5000/`.
45+
46+
## Endpoints
47+
48+
### Authentication
49+
50+
- `POST /signup`: Register new users.
51+
- `POST /login`: Log in existing users.
52+
53+
### Users
54+
55+
- `GET /users`: Get all users (Requires JWT authentication).
56+
- `POST /users`: Add a new user.
57+
- `GET /user/<string:id>`: Get a user by ID (Requires JWT authentication).
58+
59+
### Posts
60+
61+
- `GET /post`: Get all posts (Requires JWT authentication).
62+
- `POST /post`: Create a new post.
63+
64+
### Image Posts
65+
66+
- `GET /imagepost/<int:postid>`: Get an image post by post ID (Requires JWT authentication).
67+
- `POST /imagepost`: Create a new image post.
68+
69+
### Messages
70+
71+
- `GET /messages/<string:sender_id>/<string:recipient_id>`: Get messages between two users (Requires JWT authentication).
72+
- `POST /messages`: Create a new message (Requires JWT authentication).
73+
- `PUT /messages/<string:id>`: Update a message by ID (Requires JWT authentication).
74+
- `DELETE /messages/<string:id>`: Delete a message by ID (Requires JWT authentication).
75+
76+
### Emails
77+
78+
- `POST /email`: Send an email (Requires JWT authentication).
79+
80+
### Protected Routes
81+
82+
- `GET /protected`: Protected route that returns a welcome message with the current user's ID (Requires JWT authentication).
83+
84+
## Error Handling
85+
86+
- `404 Not Found`: Returned when the requested URL is not found on the server.
87+
88+
## Dependencies
89+
90+
- Flask
91+
- Flask-RESTful
92+
- Flask-JWT-Extended
93+
- Flask-CORS
94+
- smtplib
95+
- email.mime

__init__.py

Whitespace-only changes.

app.py

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
from src.services.userservice import UserService
2+
from flask import Flask, jsonify, request
3+
from flask_restful import Api
4+
from src.models.user import Users, User
5+
from src.models.post import Posts
6+
from src.models.message import MessageService
7+
from src.models.image_post import ImagePost
8+
from flask_jwt_extended import (
9+
JWTManager,
10+
jwt_required,
11+
get_jwt_identity
12+
)
13+
import smtplib
14+
from email.mime.text import MIMEText
15+
from email.mime.multipart import MIMEMultipart
16+
from flask_cors import CORS
17+
18+
app = Flask(__name__)
19+
CORS(app)
20+
21+
app.config['JWT_SECRET_KEY'] = 'GRUWIN-ADMIN-ACCOUNT'
22+
23+
app.config['JWT_ACCESS_TOKEN_EXPIRES'] = False
24+
25+
jwt = JWTManager(app)
26+
27+
api = Api(app)
28+
29+
uservice = UserService()
30+
31+
msg_service = MessageService()
32+
33+
@app.route('/')
34+
def welcome():
35+
return jsonify({'Flask restful': 'conected'})
36+
37+
38+
@app.route('/signup', methods=['POST'])
39+
def signup():
40+
return uservice.signup()
41+
42+
43+
@app.route('/login', methods=['POST'])
44+
def login():
45+
return uservice.login()
46+
47+
48+
@app.route('/users', methods=['GET'])
49+
@jwt_required()
50+
def getUsers():
51+
users = Users().get()
52+
return users
53+
54+
55+
@app.route('/users', methods=['POST'])
56+
def addUsers():
57+
users = Users()
58+
return users.post()
59+
60+
61+
@app.route('/user/<string:id>')
62+
@jwt_required()
63+
def getUserById(id):
64+
user = User().get(id)
65+
return jsonify(user)
66+
67+
68+
@app.route('/post', methods=['GET'])
69+
@jwt_required()
70+
def getPost():
71+
posts = Posts().get()
72+
return posts
73+
74+
75+
@app.route('/post', methods=['POST'])
76+
def createPost():
77+
post = Posts()
78+
return post.post()
79+
80+
81+
@app.route('/imagepost/<int:postid>', methods=['GET'])
82+
@jwt_required()
83+
def getImagePost(postid):
84+
Image = ImagePost()
85+
return Image.get(postid)
86+
87+
88+
@app.route('/imagepost', methods=['POST'])
89+
def createImagePost():
90+
image_post = ImagePost()
91+
return image_post.post()
92+
93+
94+
@app.route('/messages/<string:sender_id>/<string:recipient_id>', methods=['GET'])
95+
@jwt_required()
96+
def getMessages(sender_id, recipient_id):
97+
messages = msg_service.get_messages(sender_id, recipient_id)
98+
return jsonify(messages)
99+
100+
101+
@app.route('/messages', methods=['POST'])
102+
@jwt_required()
103+
def createMessage():
104+
data = request.get_json()
105+
message = msg_service.create_message(data['sender_id'], data['recipient_id'], data['content'])
106+
return jsonify(message)
107+
108+
109+
@app.route('/messages/<string:id>', methods=['PUT'])
110+
@jwt_required()
111+
def updateMessage(id):
112+
data = request.get_json()
113+
message = msg_service.update_message(id, data)
114+
return jsonify(message)
115+
116+
117+
@app.route('/messages/<string:id>', methods=['DELETE'])
118+
@jwt_required()
119+
def deleteMessage(id):
120+
msg_service.delete_message(id)
121+
return '', 204
122+
123+
124+
@app.route('/protected')
125+
@jwt_required()
126+
def protected():
127+
current_user_id = get_jwt_identity()
128+
return jsonify({'message': f'¡Bienvenido, usuario con id {current_user_id}!'}), 200
129+
130+
@app.route('/email', methods=['POST'])
131+
@jwt_required()
132+
def sendEmail():
133+
try:
134+
# Obtener los datos del cuerpo del mensaje
135+
data = request.get_json()
136+
137+
if data:
138+
name_client = data.get('name_client')
139+
email_client = data.get('email_client')
140+
phone_client = data.get('phone_client')
141+
email_address = data.get('email_address')
142+
message_subject = data.get('message_subject')
143+
message_send = data.get('message_send')
144+
145+
sender_email = "[email protected]"
146+
password = "ibdzsrjmsfkjhdbj"
147+
receiver_email = email_client
148+
149+
message = MIMEMultipart("alternative")
150+
message["Subject"] = message_subject
151+
message["From"] = "Intermediario <{}>".format(sender_email)
152+
message["To"] = receiver_email
153+
154+
# Crear el cuerpo del correo electrónico con los datos
155+
text = """<html>
156+
<body>
157+
<span style="font-size:15px;">Ey! Te estamos enviando este correo para informarte que tienes un nuevo mensaje:</span>
158+
<br>
159+
<br>
160+
<b style="font-size:15px;">Cliente:</b><br><span style="font-size:15px;">{}</span><br><br>
161+
<b style="font-size:15px;">Telefono:</b><br><span style="font-size:15px;">{}</span><br><br>
162+
<b style="font-size:15px;">Correo del cliente:</b><br><span style="font-size:15px;">{}</span><br><br>
163+
<b style="font-size:15px;">Mensaje del cliente:</b><br><span style="font-size:15px;">{}</span><br><br>
164+
</body>
165+
</html>""".format(name_client, phone_client, email_address, message_send)
166+
167+
message.attach(MIMEText(text, "html"))
168+
169+
# Iniciar sesión en el servidor SMTP y enviar el correo electrónico
170+
with smtplib.SMTP("smtp.gmail.com", 587) as server:
171+
server.starttls()
172+
server.login(sender_email, password)
173+
server.sendmail(sender_email, receiver_email, message.as_string())
174+
175+
return jsonify({"message": "Email sent successfully"})
176+
else:
177+
return jsonify({"message": "No data received"}), 400
178+
179+
except Exception as e:
180+
return jsonify({"message": "An error occurred: {}".format(str(e))}), 500
181+
182+
183+
@app.errorhandler(404)
184+
def not_found(error):
185+
return jsonify({'message': 'La URL solicitada no se encontró en el servidor.'}), 404
186+
187+
188+
if __name__ == '__main__':
189+
app.run()

env.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
DB_USER=gruwin
2+
DB_PASSWORD=marinmarin123
3+
DB_HOST=gruwin.mysql.pythonanywhere-services.com
4+
DB_NAME=gruwin$default

requirements.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
aniso8601==9.0.1
2+
autopep8==2.0.2
3+
click==8.1.3
4+
colorama==0.4.6
5+
Flask==2.2.3
6+
Flask-JWT-Extended==4.4.4
7+
Flask-RESTful==0.3.9
8+
itsdangerous==2.1.2
9+
Jinja2==3.1.2
10+
MarkupSafe==2.1.2
11+
mysql-connector-python==8.0.32
12+
protobuf==3.20.3
13+
pycodestyle==2.10.0
14+
PyJWT==2.6.0
15+
python-dotenv==1.0.0
16+
pytz==2023.2
17+
six==1.16.0
18+
Werkzeug==2.2.3

src/config/__init__.py

Whitespace-only changes.

src/config/database.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import mysql.connector
2+
3+
def config():
4+
dsource = mysql.connector.connect(
5+
user='gruwin',
6+
password='marinmarin123',
7+
host='gruwin.mysql.pythonanywhere-services.com',
8+
database='gruwin$default'
9+
)
10+
return dsource
11+

src/models/__init__.py

Whitespace-only changes.

src/models/image_post.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
from flask import request, jsonify, Response
2+
from flask_restful import Resource
3+
from src.config.database import config
4+
from werkzeug.utils import secure_filename
5+
import os
6+
7+
class ImagePost(Resource):
8+
def get(self, postid):
9+
db = config()
10+
cur = db.cursor()
11+
cur.execute("SELECT image FROM image_post WHERE postid = %s", (postid,))
12+
result = cur.fetchone()
13+
14+
if result is None:
15+
return {'message': 'La imagen solicitada no existe.'}, 404
16+
17+
image_data = result[0]
18+
cur.close()
19+
20+
# Obtener la extensión del archivo a partir del nombre de archivo
21+
filename = f'image_{postid}'
22+
extension = os.path.splitext(filename)[-1]
23+
24+
# Establecer el tipo MIME en la respuesta
25+
mimetype = f'image/{extension[1:]}'
26+
27+
return Response(image_data, mimetype=mimetype)
28+
29+
30+
def post(self):
31+
data = request.form
32+
postid = data['postid']
33+
image = request.files['image']
34+
35+
# Verificar que se haya enviado una imagen
36+
if image.filename == '':
37+
return jsonify({'message': 'No se ha seleccionado ninguna imagen.'}), 400
38+
39+
# Verificar que la extensión de la imagen sea permitida
40+
allowed_extensions = {'png', 'jpg', 'jpeg', 'gif'}
41+
if not allowed_file(image.filename, allowed_extensions):
42+
return jsonify({'message': 'El archivo de imagen no es válido.'}), 400
43+
44+
# Guardar la imagen en el servidor
45+
filename = secure_filename(image.filename)
46+
image.save(filename)
47+
48+
# Leer la imagen y guardarla en la base de datos
49+
with open(filename, 'rb') as f:
50+
image_data = f.read()
51+
52+
db = config()
53+
cur = db.cursor()
54+
cur.execute("INSERT INTO image_post (postid, image) VALUES (%s, %s)", (postid, image_data))
55+
db.commit()
56+
cur.close()
57+
58+
return jsonify({'message': 'La imagen ha sido agregada correctamente.'})
59+
60+
61+
def allowed_file(filename, allowed_extensions):
62+
return '.' in filename and filename.rsplit('.', 1)[1].lower() in allowed_extensions

0 commit comments

Comments
 (0)