Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
Sichere ProgrammierungRecovering API Usage Automatically in Static Analysis?(20.09.2026 um 04:32 Uhr)
•
Sicherheitslücken (CVE)just dropped macos lpe - CVE-2026-43786(21.09.2026 um 21:48 Uhr)
••
Malware / Trojaner / VirenCDC-ACM Serial Interface Bypasses TCC on macOS(25.09.2026 um 19:18 Uhr)
•
Malware / Trojaner / VirenHow to start?(26.09.2026 um 00:24 Uhr)
•
Malware / Trojaner / VirenNeed an honest advice from seniors(26.09.2026 um 04:36 Uhr)
•
Malware / Trojaner / VirenFree malware analysis, reverse engineering and exploit development resources(27.09.2026 um 18:01 Uhr)
•••
Malware / Trojaner / VirenWhere to get resources and get started with malware dev?(30.09.2026 um 08:17 Uhr)
•
Sichere ProgrammierungRecovering API Usage Automatically in Static Analysis?(20.09.2026 um 04:32 Uhr)
•
Sicherheitslücken (CVE)just dropped macos lpe - CVE-2026-43786(21.09.2026 um 21:48 Uhr)
••
Malware / Trojaner / VirenCDC-ACM Serial Interface Bypasses TCC on macOS(25.09.2026 um 19:18 Uhr)
•
Malware / Trojaner / VirenHow to start?(26.09.2026 um 00:24 Uhr)
•
Malware / Trojaner / VirenNeed an honest advice from seniors(26.09.2026 um 04:36 Uhr)
•
Malware / Trojaner / VirenFree malware analysis, reverse engineering and exploit development resources(27.09.2026 um 18:01 Uhr)
•••
Malware / Trojaner / VirenWhere to get resources and get started with malware dev?(30.09.2026 um 08:17 Uhr)
•
Intelligence View
⚡ tsecurity.de Intelligence

Flask API Tutorial: Build, Document, and Secure a REST API

This article is written by Alvaro, a member of the Zuplo community and > longtime API builder. You can check out more of his work > here. All opinions…

Beitrag
0
Seite
0
↗ Quelle (dev.to)
Social ReaktionenReagiere als Erste:r — dein Feedback zählt!

This article is written by Alvaro, a member of the Zuplo community and > longtime API builder. You can check out more of his work > here. All opinions expressed are his own.




A while back, I wrote a blog post on building an API using Ruby and Sinatra, which you can check out here. This time, I’m not just switching frameworks (or microframeworks) but also languages—so let’s talk about Python and Flask. 🤓



In the Ruby post, I had some fun weaving in quotes from Dune, but for this one, I’m keeping things simple and focusing more on the API management side of things.



We’ll build a straightforward Blog Post CRUD API, handling everything from creating and reading posts to updating and deleting them. Let’s get started!






What are we going to do today?




  1. Creating the project

  2. Adding the required packages

  3. Creating the API

  4. Testing our API

  5. Hosting our API for the world to see

  6. Creating a project on Zuplo

  7. Adding a Rate Limit

  8. Setting API Key Authentication

  9. Developer Documentation Portal

  10. Wrapping Up






Creating the project



First, create a folder called SimpleBlogAPI and add a file named app.py inside it. Since this is a simple project, we’ll keep all the source code in a single file to keep things lightweight and easy to follow.




$ mkdir SimpleBlogAPI && cd SimpleBlogAPI
$ nano app.py









Adding the required packages



For this project, we’ll use Flask and Flask-RESTX.



Create a file named requirements.txt and type the following:




Flask==3.1.0
flask_restx==1.3.0
Gunicorn==23.0.0
uvicorn==0.34.0






To install all the dependencies, run the following command:




pip3 install -r requirements.txt









Creating the API



Since we're using Flask-RESTX, the structure will be a bit different and slightly more complex. But trust me, this extra structure will pay off—it'll help us generate the OpenAPI Spec, which we'll need later 😌:




from flask import Flask
from flask_restx import Api, Resource, fields, reqparse
from dataclasses import dataclass

app = Flask(__name__)

@dataclass
class Post:
id: int
title: str
description: str

post_array = []
next_id = 1

@app.route("/")
def root_home():
return "Welcome to the Simple Blog API!"

api = Api(
app,
version="1.0",
title="Simple Blog API",
description="An API to control a micro blog",
doc="/swagger",
)

ns = api.namespace("posts", description="Blog posts")

post_parser = reqparse.RequestParser()
post_parser.add_argument("title", type=str, required=True, help="Post title")
post_parser.add_argument("description", type=str, required=True, help="Post content")

model = api.model("BlogModel", {
"id": fields.Integer(readOnly=True, description="Post identifier"),
"title": fields.String(required=True, description="Post title"),
"description": fields.String(required=True, description="Post content"),
})

@ns.route("/")
class BlogResource(Resource):
@ns.doc("get_posts")
@ns.marshal_list_with(model)
def get(self):
return post_array

@ns.doc("add_post")
@ns.expect(post_parser)
@ns.marshal_with(model, code=201)
def post(self):
global next_id
args = post_parser.parse_args()
post = Post(id=next_id, title=args["title"], description=args["description"])
post_array.append(post)
next_id += 1
return post, 201

@ns.route("/<int:id>")
@ns.response(404, "Post not found")
@ns.param("id", "The post identifier")
class PostResource(Resource):
@ns.doc("get_post")
@ns.marshal_with(model)
def get(self, id):
post = next((post for post in post_array if post.id == id), None)
if post is None:
api.abort(404, "Post not found")
return post

@ns.doc("update_post")
@ns.expect(post_parser)
@ns.marshal_with(model)
def put(self, id):
post = next((post for post in post_array if post.id == id), None)
if post is None:
api.abort(404, "Post not found")
args = post_parser.parse_args()
post.title = args["title"]
post.description = args["description"]
return post

@ns.doc("delete_post")
@ns.marshal_with(model)
def delete(self, id):
global post_array
post = next((post for post in post_array if post.id == id), None)
if post is None:
api.abort(404, "Post not found")
post_array = [post for post in post_array if post.id != id]
return "", 204

if __name__ == "__main__":
app.run(debug=True)









Testing our API



Now that we have data to work with, let’s start our server and test the API.




python3 app.py






Open your favorite web browser and navigate to http://127.0.0.1:5000/:



hello world



Success! It’s working as expected, although we have only tested the presentation endpoint 😅 Let's add some entries:




curl -X POST "http://127.0.0.1:5000/posts/" \
-H "Content-Type: application/json" \
-d '{"title": "Hello World", "description": "The first post of the blog"}'









curl -X POST "http://127.0.0.1:5000/posts/" \
-H "Content-Type: application/json" \
-d '{"title": "Coding on Python", "description": "Doing some Python coding"}'









curl -X POST "http://127.0.0.1:5000/posts/" \
-H "Content-Type: application/json" \
-d '{"title": "Python, Flask and Zuplo", "description": "Making APIs better"}'






We should have three new entries, let's check them out.



Navigate to http://127.0.0.1:5000/posts:



API response



Great news! It works as expected, but only on our local machine. Wouldn’t it be amazing to share it with the world?



First, we need to upload our project to GitHub.






Hosting our API for the world to see



When it comes to hosting an API, there are plenty of options available. For this particular API, we’ll use Render.



We need to create a new web service and select the repository we want to use—in this case, SimpleBlogAPI.



Render hosting



Connect git repo



Don’t forget to update the start command to correctly call our app.py file:



Change render command



Once Render finishes deploying our API, we’ll be able to access the main entry point using:




https://simpleblogapi.onrender.com/






As we just uploaded our API, it's going to be empty and without records, so we need to create some.



Keep in mind that we don't have any kind of authorization in place yet.



As we have created our API with Swagger UI, we can take advantage of it 😎



In our browser, we need to navigate to:




https://simpleblogapi.onrender.com/swagger






swagger docs



It might not look like much right now, but if you click on the arrow on the right-hand side, you can expand the endpoints and see everything in action.



full swagger docs



Now, if you expand the POST endpoint and click on the Try it out button, you'll be able to test the API directly from the documentation:



opening an endpoint



Once you hit the Execute button, you'll be able to add some entries (I've already added the first one). Finally, just press Execute, and the request will be sent! 🚀



testing from docs



When we finished, we can check that the entries had been entered correctly:




https://simpleblogapi.onrender.com/posts






Hosted API response



Are we done yet? Yes and no. If we’re happy with it as is—simple, unsecured, and, well, a bit amateurish—then we’re good. But if we want to make it cooler without too much effort, we can start using Zuplo and level up the experience.






Creating a project on Zuplo



After creating a Zuplo account, we’ll need to set up a new project. We’ll name it simple-blog-api, select an empty project, and then create it. Wondering why Zuplo? Imagine having to build rate limits, authentication, monetization, and other features entirely on your own. That’s a lot of work and hassle. Zuplo simplifies all of that, making it a breeze.



Create a zuplo project



Once the project is created, we’ll be greeted with this screen. From here, simply press Start Building:



Start building



To start enhancing our API, click on routes.oas.json:



routes.oas.json



Next, we need to add a route, which Zuplo will manage:



Import an OpenAPI



In the Ruby post, we went with Add Route, but this time, we’ll select Import OpenAPI instead. Now, you might be wondering—how exactly do we do that? No worries, it’s easier than you think. 🤓



On the browser we just need to call




https://simpleblogapi.onrender.com/swagger.json






Getting the raw OpenAPI



And download it as swagger.json or any other name that we prefer.



Now, we can go back to Zuplo and upload the file.



Choosing the OpenAPI file



All of our endpoints will be imported automagically 🤩



Finishing import



Here, we just need to add a Summary (a brief description of our endpoint) and replace the default Forward to value with our URL from Render. Simple as that!



Adding summaries



After configuring the routes, we need to save them. The save button is located at the bottom, or we can press [Command + S] on a Mac.



Saving changes



The build process is blazing fast. Clicking the Test button allows us to, no pun intended, test our API integration.



Testing API



Success! 🥳🥳🥳 Our Zuplo integration is working perfectly!






Adding a Rate Limit



Most likely, we don’t want people abusing our API or attempting to take down our server with DDoS attacks. While coding a rate limit policy isn’t difficult, there are many factors to consider—so why bother? Let’s have Zuplo manage that for us.



Adding policy



We need to add a new policy on the request side. Since we’ll be dealing with many policies, simply type rate and select Rate Limiting:



Choose rate limiting



All we need to do here is press Ok. Easy, right?



Configure policy



Our rate limit has been added. Now, we just need to save and run the test three times. On the third attempt, we’ll hit the rate limit. Of course, we can adjust this in the policy, as shown in the image above, where requestsAllowed is set to 2.



Policy added



We can do that for all the other endpoints if we want to.



Exceeding the request limit will temporarily block further data requests. We’ll need to wait a minute before trying again.



Rate limit exceeded



So far, so good—but what if we want to prevent unauthorized access to our API? We’ll need to implement some sort of authentication. While it’s not overly difficult to build, it involves multiple steps, configurations, and testing. Wouldn’t it be great to let Zuplo handle those details for us? That way, we can focus solely on our API.






Setting API Key Authentication



We need to navigate back to the Policies section and add a new policy—this time, API Key Authentication:



Add API key auth



There’s not much to do here—just press OK.



Configure API key auth



It’s important to move the api-key-inbound policy to the top:



API key auth applied



If we save it and try testing the API, access will be denied:



Unauthorized response



At the top of the screen, click Services, then select Configure under API Key Service:



Go to services tab



We need to create a consumer, which will function as a token:



Create API consumer



We need to set a name for the subject and specify the email or emails associated with the key:



Configure consumer



Once we click Save consumer, an API key will be generated. We can either view it or copy it:



Consumer created



Now, we can go back to Code → routes.oas.json to test our API. Here, we need to add the authorization header and pass the Bearer token along with the API key:



200 Response



Success once again! It’s working as expected! 🥳🥳🥳



If you think that doing this manually is not for you, read this:



Automatic API keys



And that’s how you enhance your API with Zuplo 😎 But wait, there’s more! As always, we have a cherry on top.






Developer Documentation Portal



If we click on Gateway at the bottom of the screen, we’ll see a link to the Developer Portal:



Developer portal



Copy it and add /docs to the very end:




https://simple-blog-api-main-7f50b25.d2.zuplo.dev/docs






Here, we can see that every route we create will be added to the Stripe-style Developer Portal:



New developer portal



If we log in, we can see our API keys:



Login






Wrapping Up



If you’d like to check out the source code for the API, you can see it on my Github repo SimpleBlogAPI.



If you want to learn more about the tools I used - here are some quick documentation links:





Now, what kind of API will you build with Flask? 😎

🔍 CTI & Forensik

Cyber Threat Intelligence & Forensik

Bedrohungsgraph · ATT&CK-Mapping · Exploit-Belege
CTI Threat Relationship Graph
Akteure · Techniken · Beziehungen
3 Knoten · 2 Relationen
CVE / Incident Threat Actor Software MITRE ATT&CK CWE Weakness IoC
MITRE ATT&CK Matrix Navigator
Enterprise-Matrix · nur belegte Techniken
14 Taktiken
1 belegte Technik
T1498TA0040 · Impact
Network Denial of Service
Mitigation: M1037 Filter Network Traffic
Quelle: Kontext-Klassifikation des Artikeltextes
Reconnaissance
Resource Development
Initial Access
Execution
Persistence
Privilege Escalation
Defense Evasion
Credential Access
Discovery
Lateral Movement
Collection
Command and Control
Exfiltration
Impact
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Flask API Tutorial: Build, Document, and Secure a REST API

Thematisch verwandte Begriffe: Flask, Tutorial, Build, Document · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

💬 Kommentare werden geladen…
Zum Aktualisieren ziehen
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag