feat: model proxy domain in SQLAlchemy
This commit is contained in:
parent
3c38333e9c
commit
9360077c5e
117
src/proxy_pool/proxy/models.py
Normal file
117
src/proxy_pool/proxy/models.py
Normal file
@ -0,0 +1,117 @@
|
||||
import enum
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy import (
|
||||
Boolean,
|
||||
Float,
|
||||
ForeignKey,
|
||||
Index,
|
||||
Integer,
|
||||
String,
|
||||
Text,
|
||||
func,
|
||||
)
|
||||
from sqlalchemy.dialects.postgresql import ENUM, INET
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from proxy_pool.db.base import Base, TimestampMixin, UUIDPrimaryKeyMixin
|
||||
|
||||
|
||||
class ProxyProtocol(str, enum.Enum):
|
||||
HTTP = "http"
|
||||
HTTPS = "https"
|
||||
SOCKS4 = "socks4"
|
||||
SOCKS5 = "socks5"
|
||||
|
||||
|
||||
class ProxyStatus(str, enum.Enum):
|
||||
UNCHECKED = "unchecked"
|
||||
ACTIVE = "active"
|
||||
DEAD = "dead"
|
||||
|
||||
|
||||
class AnonymityLevel(str, enum.Enum):
|
||||
TRANSPARENT = "transparent"
|
||||
ANONYMOUS = "anonymous"
|
||||
ELITE = "elite"
|
||||
|
||||
|
||||
class ProxySource(UUIDPrimaryKeyMixin, TimestampMixin, Base):
|
||||
__tablename__ = "proxy_sources"
|
||||
|
||||
url: Mapped[str] = mapped_column(String(2048), unique=True)
|
||||
parser_name: Mapped[str] = mapped_column(String(64))
|
||||
cron_schedule: Mapped[str | None] = mapped_column(String(64))
|
||||
default_protocol: Mapped[ProxyProtocol] = mapped_column(
|
||||
ENUM(ProxyProtocol, name="proxy_protocol"),
|
||||
)
|
||||
is_active: Mapped[bool] = mapped_column(default=True)
|
||||
last_scraped_at: Mapped[datetime | None] = mapped_column()
|
||||
|
||||
proxies: Mapped[list["Proxy"]] = relationship(back_populates="source")
|
||||
|
||||
|
||||
class Proxy(UUIDPrimaryKeyMixin, TimestampMixin, Base):
|
||||
__tablename__ = "proxies"
|
||||
__table_args__ = (
|
||||
Index("ix_proxies_ip_port_proto", "ip", "port", "protocol", unique=True),
|
||||
Index("ix_proxies_status_score", "status", "score"),
|
||||
)
|
||||
|
||||
ip: Mapped[str] = mapped_column(INET)
|
||||
port: Mapped[int] = mapped_column(Integer)
|
||||
protocol: Mapped[ProxyProtocol] = mapped_column(
|
||||
ENUM(ProxyProtocol, name="proxy_protocol", create_type=False),
|
||||
)
|
||||
source_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("proxy_sources.id"),
|
||||
)
|
||||
status: Mapped[ProxyStatus] = mapped_column(
|
||||
ENUM(ProxyStatus, name="proxy_status"),
|
||||
default=ProxyStatus.UNCHECKED,
|
||||
)
|
||||
anonymity: Mapped[AnonymityLevel | None] = mapped_column(
|
||||
ENUM(AnonymityLevel, name="anonymity_level"),
|
||||
)
|
||||
exit_ip: Mapped[str | None] = mapped_column(INET)
|
||||
country: Mapped[str | None] = mapped_column(String(2))
|
||||
score: Mapped[float] = mapped_column(Float, default=0.0)
|
||||
avg_latency_ms: Mapped[float | None] = mapped_column(Float)
|
||||
uptime_pct: Mapped[float | None] = mapped_column(Float)
|
||||
first_seen_at: Mapped[datetime] = mapped_column(server_default=func.now())
|
||||
last_checked_at: Mapped[datetime | None] = mapped_column()
|
||||
|
||||
source: Mapped["ProxySource"] = relationship(back_populates="proxies")
|
||||
checks: Mapped[list["ProxyCheck"]] = relationship(back_populates="proxy")
|
||||
tags: Mapped[list["ProxyTag"]] = relationship(back_populates="proxy")
|
||||
|
||||
|
||||
class ProxyCheck(UUIDPrimaryKeyMixin, TimestampMixin, Base):
|
||||
__tablename__ = "proxy_checks"
|
||||
__table_args__ = (Index("ix_checks_proxy_created", "proxy_id", "created_at"),)
|
||||
|
||||
proxy_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("proxies.id", ondelete="CASCADE"),
|
||||
)
|
||||
checker_name: Mapped[str] = mapped_column(String(64))
|
||||
stage: Mapped[int] = mapped_column(Integer)
|
||||
passed: Mapped[bool] = mapped_column(Boolean)
|
||||
latency_ms: Mapped[float | None] = mapped_column(Float)
|
||||
detail: Mapped[str | None] = mapped_column(Text)
|
||||
exit_ip: Mapped[str | None] = mapped_column(INET)
|
||||
|
||||
proxy: Mapped["Proxy"] = relationship(back_populates="checks")
|
||||
|
||||
|
||||
class ProxyTag(UUIDPrimaryKeyMixin, Base):
|
||||
__tablename__ = "proxy_tags"
|
||||
__table_args__ = (Index("ix_tags_proxy_key", "proxy_id", "key", unique=True),)
|
||||
|
||||
proxy_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("proxies.id", ondelete="CASCADE"),
|
||||
)
|
||||
key: Mapped[str] = mapped_column(String(64))
|
||||
value: Mapped[str] = mapped_column(String(256))
|
||||
|
||||
proxy: Mapped["Proxy"] = relationship(back_populates="tags")
|
||||
Loading…
x
Reference in New Issue
Block a user