https://github.com/id-andyyy/url-alias-api
🔗🌐 Сервис для создания коротких URL с возможностью просмотра статистики
https://github.com/id-andyyy/url-alias-api
alembic docker docker-compose fastapi postgresql pydantic pytest python shorturl sqlalchemy
Last synced: 3 months ago
JSON representation
🔗🌐 Сервис для создания коротких URL с возможностью просмотра статистики
- Host: GitHub
- URL: https://github.com/id-andyyy/url-alias-api
- Owner: id-andyyy
- Created: 2025-05-31T10:07:34.000Z (about 1 year ago)
- Default Branch: master
- Last Pushed: 2025-07-01T14:18:04.000Z (12 months ago)
- Last Synced: 2025-08-12T00:22:52.815Z (11 months ago)
- Topics: alembic, docker, docker-compose, fastapi, postgresql, pydantic, pytest, python, shorturl, sqlalchemy
- Language: Python
- Homepage:
- Size: 106 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README-en.md
Awesome Lists containing this project
README





# URL Alias Service
A service for converting long URLs into short unique URLs, with the ability to view statistics 🔗.
## 🔌 API Endpoints
The following endpoints are implemented:
- 🧭 `GET /{short_id}/` - redirect to the original URL using the short link. Each redirect is tracked in the statistics.
- 🔗 `POST /api/links/` - create a short link. You can specify the number of seconds after which the link will become invalid. Authorization required 🔒.
- 📋 `GET /api/links/` - get information about your created links. You can filter by inactive and expired links. Pagination is available. Authorization required 🔒.
- 📊 `GET /api/stats/` - get statistics on your most visited links in the last hour, last day, or all time. You can configure sorting and the number of links displayed. Authorization required 🔒.
- 📈 `GET /api/stats/{short_id}/` - get statistics for a specific link. Authorization required 🔒.
- 💡 `GET /health/` - service health check.
## 📚 Technologies and Tools








- Python 3.11
- REST API with FastAPI
- PostgreSQL 13 on the production stack and in Docker Compose
- In-memory SQLite for tests
- SQLAlchemy for database operations
- Alembic for migrations
- Basic Authentication
- Password hashing with bcrypt
- Pytest, TestClient, and Monkeypatch for testing
- Docker and Docker Compose
## 💡 Technical Decisions
- Data Validation and Schema
- Pydantic v2 + pydantic-settings (description of input/output JSON models)
- ORM and Database Operations
- SQLAlchemy (Declarative Base + `Mapped`/`mapped_column`)
- Schema Migrations
- Alembic (provides the ability to scale the database without losing existing data)
- In Docker, `alembic upgrade head` is always executed on container startup to keep the data up to date
- Link Shortening
- Generation of random short identifiers (short_id) from letters and numbers
- Uniqueness check of short_id before saving
- Configurable link lifetime (expire_seconds)
- Tracking of link click statistics
- Authentication
- Basic Authentication
- Secure password storage using bcrypt (via passlib)
- Scripts for manual user creation (create_user.py)
- Automatic creation of a default user when the service starts
- Containerization
- Docker Compose
- `db` service (Postgres 13 + volume for persistence)
- `web` service (Healthcheck `pg_isready`, `depends_on: condition: service_healthy` dependency)
- `entrypoint.sh` script for automatic execution of migrations, user creation, and application launch
- `.env` file (standard variables `POSTGRES_USER`, `POSTGRES_PASSWORD`, `POSTGRES_DB` for compatibility with the Postgres Docker image, and `DEFAULT_USER_USERNAME` and `DEFAULT_USER_PASSWORD` for automatic user creation at startup)
- Testing
- >98% code coverage
- TestClient (for end-to-end API tests without running an external server)
- In-memory SQLite (a lightweight, isolated database to speed up tests)
- Fixtures with transaction rollback (each `db_session` rolls back changes after the test, keeping the state clean)
- Error Handling
- Explicit input data checks
- Global `exception_handler` for IntegrityError
- Layer Separation
- `routers/` - HTTP + validation
- `crud/` - database operations
- `utils/` - utility functions
## ✍ Data Models
- User 👨💻 - user model with hashed passwords
- Link 🔗 - model for storing original and short URLs
- Click 👆 - model for registering link clicks and collecting statistics
## 🚀 How to run the service
1. Clone the repository and navigate to the project folder:
```bash
git clone https://github.com/id-andyyy/url-alias-api.git
cd url-alias-api
```
2. Create an environment file based on `.env.example`:
```bash
cp .env.example .env
```
3. If necessary, fill in the `DEFAULT_USER_USERNAME` and `DEFAULT_USER_PASSWORD` variables in the `.env` file to automatically create a user when the server starts. By default, a user `admin` with the password `admin` is created.
4. Start Docker Compose (don't forget to start the Docker daemon first):
```bash
docker-compose up --build
```
Wait for the process to finish.
5. Check the service's health via the terminal:
```bash
curl http://0.0.0.0:8080/api/health
```
Expected response:
```bash
{"status":"ok"}
```
Or via the Swagger UI in your browser:
```bash
http://127.0.0.1:8080/docs
```
6. To create another user:
1. Go to the console:
```bash
docker-compose exec web sh
```
2. In the console, execute the command (replace `new_user` and `secret_password` with your desired values):
```bash
python3 create_user.py -u new_user -p secret_password
```
3. If the user is created successfully, after a message about version incompatibility (which can be ignored), you will receive a message:
```bash
New user created: username='new_user', id=2
```
4. To exit the console, execute:
```bash
exit
```
## 🧪 How to run tests
1. Create and activate a virtual environment:
```bash
python3 -m venv .venv
source .venv/bin/activate # On macOS / Linux
.\.venv\Scripts\Activate.ps1 # On Windows
```
2. Install the dependencies:
```bash
pip install -r requirements.txt
```
3. Run the tests with the command:
```bash
pytest
```
## 📝 Project Structure
```
alembic/
│ ├── versions/ # Migration scripts
│ └── env.py # Alembic configuration
app/
├── api/
│ ├── routes/ # Endpoints and their logic
│ └── deps.py # FastAPI dependencies
├── core/
│ ├── config.py # Reading .env
├── crud/ # Database operation functions
├── db/
│ ├── base.py # Base class for DeclarativeBase
│ └── session.py # Engine and SessionLocal setup
├── models/ # Declarative models
├── schemas/ # Request and response models
├── utils/ # Utility functions
└── main.py # Application creation
tests/
├── api/ # API tests via TestClient
├── crud/ # Unit tests for CRUD functions
├── fixtures/ # Additional fixtures
├── utils/ # Unit tests for utility functions
└── conftest.py # Common fixtures
.dockerignore # Files ignored by Docker
.env # Local environment variables
.env.example # Example .env content
.gitignore # Files ignored by Git
alembic.ini # Alembic configuration
create_default_user.py # Script for automatic user creation at startup
create_user.py # Script for manual user creation
docker-compose.yaml # Docker services description
Dockerfile # Docker image build instructions
entrypoint.sh # web container startup script
requirements.txt # List of dependencies
```
## 📨 Feedback
I would appreciate it if you give it a star ⭐. If you find a bug or have suggestions for improvement, please use the [Issues](https://github.com/id-andyyy/url-alias-api/issues) section.
Читать на [русском 🇷🇺](README.md)