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