被遗忘的 Python 框架 # 1 : 瓶子

2026年8月31日1 次浏览来源:Dev.to阅读原文

正文保留英文原文(机翻易破坏代码与排版),标题/摘要已提供中文

In an era where bootstrapping a basic web application often requires downloading a huge framework or navigating complex dependency trees, there's a quiet, radical alternative in the Python ecosystem.

Bottle.

Many new Python developers probably haven't heard of it.

And some might think the framework must be forgotten by now.

Well!

No.

Bottle is a fast, simple, and lightweight WSGI micro web framework for Python.

It was developed by Marcel Hellkamp, aka defnull, and released in

2009.

He built it out of frustration with the heavy, over-engineered frameworks of the time, taking inspiration from a smaller Ruby framework called Sinatra.

Later, a developer named Armin Ronacher built Flask, taking inspiration from Bottle in turn.

While it's lost the mainstream popularity battle to giants like Flask, Django, and FastAPI, Bottle remains actively maintained.

The core philosophy of Bottle is simplicity, and with its one-file approach, it can surprisingly build a variety of projects, from small web apps and scrapers to IoT monitoring dashboards or tools.

Why take my word for it?

Let's build a URL shortener with it — and this time, let's actually finish it, instead of leaving it as a toy that falls over the moment someone pokes at it.

First, we need to install it in our environment with this command in your terminal: I'm using a global environment, but virtual environments are recommended.

Save it as and run it.

Open http://localhost:8080, and that's it.

You have a working web application.

But that's just the basic setup.

Now let's build out our URL shortener — for real this time.

Building ShortyURL We're going to build a small, actually-usable URL-shortening service.

The idea is simple.

A user sends us: https://example.com/a-very-long-url Our application gives them: http://localhost:8080/abc123 Visiting redirects the user to the original URL.

Nothing revolutionary.

So let's build it.

Project setup First, create a directory.

Open up your terminal and fire up these commands: Create a virtual environment: Activate it.

On Linux/macOS: On Windows: Install Bottle into the virtual environment: Our initial project can be incredibly small: We'll let SQLite handle persistence.

Building routes Let's start with the homepage.

Bottle uses decorators to define routes.

This: means: "when someone makes a request to , call this function." That's a very simple mental model.

Now let's create an endpoint for creating short URLs: A couple of interesting things here. gives us access to the incoming HTTP request: gets form data.

And: lets us control the response.

Bottle also lets us return plain Python dictionaries and it'll serialize them to JSON automatically.

Let's add SQLite We don't need a database server for this project.

SQLite is enough.

Create a database helper — using a context manager this time, so a connection always gets closed even if something inside it blows up: Then create our table: We'll call this once, when the application starts.

Generating short codes We need a short identifier for every URL.

We can use Python's module: Now we can generate values like: There's a small catch, though — nothing stops two different URLs from generating the same code.

We'll fix that properly in a minute instead of just hoping it never happens.

Validating the URL In the original draft of this project, someone could submit the string and we'd happily store it as a "URL." That's not great.

Before saving anything, we should check it's actually a URL with a scheme and a host: returns . returns .

That's enough to keep garbage out without writing a full URL grammar by hand.

Handling code collisions A 6-character alphanumeric code has billions of possible values, so collisions are rare — but "rare" isn't "impossible," and a URL shortener that occasionally overwrites someone else's link is a bad URL shortener.

So we check before we insert, and retry if we happen to land on a code that's already taken: Putting it together Our endpoint now validates, checks for collisions, and saves the URL: Now we have a functional URL-shortening API — one that actually checks its inputs.

Redirecting short URLs Now comes the fun part.

Someone visits: We look up in the database and redirect them.

Bottle gives us a convenient function: Bottle's dynamic routes are straightforward: means the value in that part of the URL becomes the argument.

So a request to calls .

Keeping it from being abused A public "paste any URL, get a link back" endpoint is exactly the kind of thing that gets hammered by scripts the moment it's live.

We don't need anything heavyweight — a simple in-memory sliding window per IP is enough to stop casual abuse: It resets if the process restarts and won't survive multiple worker processes without a shared store like Redis — but for a small tool running as a single process, it does the job.

Making it something you can actually click around in Everything so far has been API-only — fine for , useless for a person with a browser.

So the home page now renders a small HTML form, and responds with HTML by default and JSON when the client asks for it ().

That way the same endpoint works whether a person is filling in a form or a script is calling it.

Configuration Hardcoding and is fine for a five-minute experiment, but the moment you want to run this anywhere else, you're editing source code to change a setting.

Instead, we read everything from environment variables, with sensible local defaults: To keep this post short, I've kept the version below to just this basic app — validation, collisions, config, rate limiting, and a bare-bones HTML form.

For the full application with the polished UI, custom aliases, click tracking, and a stats page, check out the repo: Here The complete application At this point, our entire application still fits comfortably inside one file — it's just a more honest file than before.

How to actually use it Save that as , then: Open http://localhost:8080 in a browser.

You'll get a form — paste a long URL in, hit "Shorten," and it hands back a working short link on the same page.

Click it, and it redirects you straight to the original URL.

If you'd rather drive it from the command line or a script, send and you get JSON back instead of HTML: Then visiting redirects you to the original URL.

Feed it garbage instead of a URL and it tells you so instead of silently storing it: Everything about where it runs is configurable through environment variables, no code edits required: Variable Default What it controls Path to the SQLite database file Host the server binds to Port the server binds to Base used when building short links Starting length of generated codes Requests per IP per window before a 429 Window length, in seconds unset Set to to run Bottle's debug mode For example, to run it on a different port with a shorter rate-limit window while testing: What's still missing, and on purpose Even after all that, this still isn't something you'd point the whole internet at without a second look.

Worth naming honestly: Database management.

Opening a fresh SQLite connection per request is fine for the traffic a tool like this gets.

A busier app would want a connection pool or a proper ORM.

Authentication.

There's no concept of ownership here — anyone can shorten anything, and nobody can log in to manage or delete their own links.

Deployment.

Bottle's built-in server () is a development server.

Behind real traffic, you'd put it behind a production WSGI server like or , and probably a reverse proxy in front of that.

Multi-process rate limiting.

The in-memory limiter works for a single process.

Scale to multiple workers and each one keeps its own counters — you'd want Redis or a similar shared store.

None of that is a knock on Bottle.

It's just the honest line between "a small, working tool" and "a service." Is Bottle still a good framework?

Yes.

After working through this project, Bottle's biggest strength becomes obvious: it gets out of your way.

But it has its trade-offs too.

The same s

分享