This commit is contained in:
dzikafoczka 2024-12-21 21:50:28 +01:00
commit c7bbd6eb92
3 changed files with 352 additions and 0 deletions

24
Dockerfile Normal file
View File

@ -0,0 +1,24 @@
FROM ubuntu:20.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get upgrade -y \
&& apt-get install -y \
python3 \
python3-pip \
python3-dev \
libpoppler-cpp-dev \
build-essential \
curl \
git \
&& apt-get clean
RUN pip3 install --no-cache-dir Flask PyMuPDF
WORKDIR /app
COPY . /app
EXPOSE 8080
CMD ["python3", "invoice_service.py"]

255
ec2.py Normal file
View File

@ -0,0 +1,255 @@
import boto3
import base64
REPOZYTORIUM = "https://git.wmi.amu.edu.pl/s464863/aws_faktury.git"
PREFIX = "s464863"
AMI_ID = "ami-0b5eea76982371e91"
REGION = "us-east-1"
INSTANCE_TYPE = "t2.micro"
user_data = f"""
#!/bin/bash
yum update -y
yum install -y amazon-linux-extras
amazon-linux-extras enable docker
yum install -y docker
yum install -y git
service docker start
usermod -a -G docker ec2-user
cd /home/ec2-user
git clone {REPOZYTORIUM}
cd aws_faktury
docker build -t flask-invoice-app .
docker run -d -p 8080:8080 flask-invoice-app
echo "Aplikacja działa na porcie 8080"
"""
def create_vpc(ec2_client):
# Create VPC
response = ec2_client.create_vpc(
CidrBlock='10.0.0.0/16',
TagSpecifications=[
{
'ResourceType': 'vpc',
'Tags': [{'Key': 'Name', 'Value': f"{PREFIX}-vpc"}]
}
]
)
vpc_id = response['Vpc']['VpcId']
print(f"Created VPC with ID: {vpc_id}")
# Enable DNS support and hostnames
ec2_client.modify_vpc_attribute(VpcId=vpc_id, EnableDnsSupport={'Value': True})
ec2_client.modify_vpc_attribute(VpcId=vpc_id, EnableDnsHostnames={'Value': True})
print("Enabled DNS support and hostnames.")
return vpc_id
def create_subnet(ec2_client, vpc_id, cidr_block, availability_zone):
# Create subnet
response = ec2_client.create_subnet(
VpcId=vpc_id,
CidrBlock=cidr_block,
AvailabilityZone=availability_zone,
TagSpecifications=[
{
'ResourceType': 'subnet',
'Tags': [{'Key': 'Name', 'Value': f"{PREFIX}-subnet"}]
}
]
)
subnet_id = response['Subnet']['SubnetId']
print(f"Created Subnet with ID: {subnet_id}")
# Public IP addresses for instances in the subnet
ec2_client.modify_subnet_attribute(SubnetId=subnet_id, MapPublicIpOnLaunch={'Value': True})
print("Configured subnet to auto-assign public IP addresses.")
return subnet_id
def create_internet_gateway(ec2_client, vpc_id):
# Create Internet Gateway
response = ec2_client.create_internet_gateway(
TagSpecifications=[
{
'ResourceType': 'internet-gateway',
'Tags': [{'Key': 'Name', 'Value': f"{PREFIX}-igw"}]
}
]
)
igw_id = response['InternetGateway']['InternetGatewayId']
print(f"Created Internet Gateway with ID: {igw_id}")
# Attach Internet Gateway to VPC
ec2_client.attach_internet_gateway(InternetGatewayId=igw_id, VpcId=vpc_id)
print("Attached Internet Gateway to VPC.")
return igw_id
def create_route_table(ec2_client, vpc_id, subnet_id, igw_id):
# Create Route Table
response = ec2_client.create_route_table(
VpcId=vpc_id,
TagSpecifications=[
{
'ResourceType': 'route-table',
'Tags': [{'Key': 'Name', 'Value': f"{PREFIX}-rt"}]
}
]
)
route_table_id = response['RouteTable']['RouteTableId']
print(f"Created Route Table with ID: {route_table_id}")
# Create route to Internet Gateway
ec2_client.create_route(
RouteTableId=route_table_id,
DestinationCidrBlock='0.0.0.0/0',
GatewayId=igw_id
)
print("Added route to Internet Gateway in Route Table.")
# Associate Route Table with Subnet
ec2_client.associate_route_table(RouteTableId=route_table_id, SubnetId=subnet_id)
print("Associated Route Table with Subnet.")
return route_table_id
def create_key_pair(ec2_client, key_name, save_to_file):
# Create key pair
response = ec2_client.create_key_pair(KeyName=key_name)
# Save private key to file
private_key = response['KeyMaterial']
with open(save_to_file, 'w') as file:
file.write(private_key)
print(f"Key pair '{key_name}' created and saved to '{save_to_file}'.")
return response['KeyName']
def create_security_group(ec2_client, vpc_id):
group_name = f"{PREFIX}-sg"
# Create Security Group
response = ec2_client.create_security_group(
GroupName=group_name,
Description=f"Security group for {PREFIX} webservices",
VpcId=vpc_id
)
security_group_id = response['GroupId']
print(f"Security group '{group_name}' created with ID: {security_group_id}")
# Set ingress rules
ec2_client.authorize_security_group_ingress(
GroupId=security_group_id,
IpPermissions=[
{
'IpProtocol': 'tcp',
'FromPort': 22,
'ToPort': 22,
'IpRanges': [{'CidrIp': '0.0.0.0/0', 'Description': 'SSH access'}]
},
{
'IpProtocol': 'tcp',
'FromPort': 8080,
'ToPort': 8080,
'IpRanges': [{'CidrIp': '0.0.0.0/0', 'Description': 'HTTP access'}]
}
]
)
print("Ingress rules added for SSH (22) and HTTP (80).")
return security_group_id
def create_launch_template(ec2_client, key_name, security_group_id):
# Create Launch Template
response = ec2_client.create_launch_template(
LaunchTemplateName=f"{PREFIX}-lt",
LaunchTemplateData={
'ImageId': AMI_ID,
'InstanceType': INSTANCE_TYPE,
'SecurityGroupIds': [security_group_id],
'KeyName': key_name,
'UserData': base64.b64encode(user_data.encode('utf-8')).decode('utf-8')
}
)
print(f"Launch Template created with ID: {response['LaunchTemplate']['LaunchTemplateId']}")
return response['LaunchTemplate']['LaunchTemplateId']
def run_instance(ec2_client, launch_template_id, subnet_id):
# Run EC2 instances
response = ec2_client.run_instances(
LaunchTemplate={
'LaunchTemplateId': launch_template_id
},
MaxCount=1,
MinCount=1,
SubnetId=subnet_id
)
instance_id = response['Instances'][0]['InstanceId']
print(f"Instance {instance_id} is running.")
ec2_client.get_waiter('instance_running').wait(InstanceIds=[instance_id])
instance_info = ec2_client.describe_instances(InstanceIds=[instance_id])
public_ip = instance_info['Reservations'][0]['Instances'][0].get('PublicIpAddress')
public_dns = instance_info['Reservations'][0]['Instances'][0].get('PublicDnsName')
if public_ip:
return public_ip
if public_dns:
print(f"Public DNS: {public_dns}")
return instance_id
def main():
# Create EC2 client
ec2_client = boto3.client('ec2', region_name=REGION)
# Create VPC
print("Creating VPC...")
vpc_id = create_vpc(ec2_client)
# Create subnet
print("Creating subnet...")
subnet = create_subnet(ec2_client, vpc_id, cidr_block='10.0.1.0/24', availability_zone='us-east-1a')
# Create Internet Gateway
print("Creating Internet Gateway...")
igw_id = create_internet_gateway(ec2_client, vpc_id)
# Create Route Table
print("Creating Route Table...")
route_table_id = create_route_table(ec2_client, vpc_id, subnet, igw_id)
# Create Key Pair
print("Creating Key Pair...")
key_name = create_key_pair(ec2_client, f"{PREFIX}-key", f"{PREFIX}-key.pem")
# Create Security Group
print("Creating Security Group...")
security_group_id = create_security_group(ec2_client, vpc_id)
# Create Launch Template
print("Creating Launch Template...")
launch_template_id = create_launch_template(ec2_client, key_name, security_group_id)
# Run EC2 instance
print("Running EC2 instance...")
ec2_id = run_instance(ec2_client, launch_template_id, subnet)
if __name__ == '__main__':
main()

73
invoice_service.py Normal file
View File

@ -0,0 +1,73 @@
from flask import Flask, request, jsonify
import fitz
import os
import re
app = Flask(__name__)
UPLOAD_FOLDER = 'uploads'
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
def extract_total_alternate(text):
try:
match = re.search(r'(?i)PODSUMOWANIE\nWartość netto\nStawka VAT\nVAT\nWartość brutto\n\d+(\.\d{1,2})?\n\d+%?\n\d+(\.\d{1,2})?\n(\d+\.\d{1,2})?', text, re.DOTALL)
print(match.groups())
if match:
return float(match.group(3).replace(',', '.'))
return None
except Exception:
return None
def extract_total(text):
total_match = re.search(r'(?i)Wartość brutto\n([0-9.,]+) PLN', text)
total = float(total_match.group(1).replace(',', '.')) if total_match else None
if total is None:
total = extract_total_alternate(text)
return total
def extract_invoice_data(text):
try:
seller_match = re.search(r'(?i)Sprzedawca:\n(.*?)\n', text)
seller_name = seller_match.group(1).strip() if seller_match else None
nip_match = re.search(r'(?i)Sprzedawca:.*?NIP:\s*(\d+)', text, re.DOTALL)
vat_id = nip_match.group(1) if nip_match else None
total = extract_total(text)
return {
"vat_id": vat_id,
"seller_name": seller_name,
"total": total
}
except Exception as e:
return {"error": f"Failed to extract data: {str(e)}"}
@app.route('/invoice', methods=['POST'])
def process_invoice():
if 'file' not in request.files:
return jsonify({"error": "No file provided"}), 400
file = request.files['file']
if file.filename == '':
return jsonify({"error": "Empty filename"}), 400
filepath = os.path.join(UPLOAD_FOLDER, file.filename)
file.save(filepath)
try:
text = ""
with fitz.open(filepath) as pdf:
for page in pdf:
text += page.get_text()
invoice_data = extract_invoice_data(text)
return jsonify(invoice_data), 200
except Exception as e:
return jsonify({"error": str(e)}), 500
finally:
os.remove(filepath)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)