Creating a complete Fast-API service with frontend and deployment in half an hour

First, let's bind the static file handler (style.css and script.js). To do this, we need to write the following in the app/main.py file:

from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles

from app.api.router import router as router_api

app = FastAPI()

app.mount('/static', StaticFiles(directory='app/static'), 'static')

app.include_router(router_api)

You can see that we have mounted static files here. I wrote about how this works and why in detail in the article “Creating Your Own API in Python (FastAPI): Connecting the Frontend and Static Files”.

Now we just need to describe the call to index.html when going to the root of our application. To do this, we will change the code of the file app/api/router.py as follows:

from fastapi import APIRouter, Request, HTTPException, Depends
from fastapi.templating import Jinja2Templates
from curl_fetch2py import CurlFetch2Py
from app.api.schemas import RequestData
from app.api.utils import execute_request

router = APIRouter(prefix='', tags=['API'])
templates = Jinja2Templates(directory='app/templates')


@router.get('/')
async def get_main_page(request: Request):
    return templates.TemplateResponse(name="index.html", context={'request': request})


@router.post('/api', summary='Основной API метод')
async def main_logic(request_body: RequestData):
    request_type = request_body.request_type
    target = request_body.target
    data_str = request_body.data_str

    try:
        if request_type == 'curl':
            context = CurlFetch2Py.parse_curl_context(data_str)
        elif request_type == 'fetch':
            context = CurlFetch2Py.parse_fetch_context(data_str)
        else:
            raise ValueError("Unsupported start type")
        return {"request_string": execute_request(context, target).strip()}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

Here we have attached a renderer that will pull up our index.html and return it when going to the root of the application.

Let's restart the application and go to the address: http://127.0.0.1:8000/

We see that the page has loaded successfully with all the styles that we put into it.

Let's run some tests of our application, and then decide what we would like to further improve.

We see that everything works, but there are definitely some things we need to fix.

Let's go back to the WebSim website and describe what we would like to change or add to our design. I got this prompt:

  • При смене вкладки CURL/FETCH пусть очищается поле ввода данных.

  • Добавь кнопку для очистки строки ввода

  • добавь визуальный перенос в результате, если ширина полученной строки превышает ширину экрана демонстрации. При этом влияния на ответ быть не должно (при копировании)

  • стилизуй кнопку копирования, чтоб появлялся не обычный alert, a html

  • стилизуй поле результата и поле ввода.

Then I figured that the application could be used from a phone and asked for the following:

I don’t know about you, but I’m completely satisfied with the design.

We save, break the code into pieces again and run some tests of the updated application.

Both cURL and FETCH work correctly, as we intended, which means that everything works correctly.

Now, in order to get practical benefit from the application, I suggest preparing a complex requests site request, which without correct transfer of cookies will not return the correct data.

To do this, I will take the DNS site, copy the CURL string into it, transform it into a requests request through our web application and then look at the execution result.

I paste the received data and copy the result:

In Pycharm I got this result:

I'll change it a little, namely, I won't just print the result, but save it to an HTML file. Let's sign it as request_curl.html

rez = asyncio.run(fetch())
with open('request_curl.html', 'w', encoding='utf-8') as result:
    result.write(rez)

We see that the data has been received.

Now let's transform curl into httpx and try again.

We get the same result!

It turned out interesting, but we would like other users to be able to evaluate our work, right? In order for this to be possible, we need to deploy the application to some service that supports working with FastAPI.

As such a service, not for the first time, I choose Amvera Cloud.

Deploying an application to Amvera Cloud

The main reason I choose this service is its simplicity. You just need to throw files into the service via GIT or directly, via the console, and the service will pick everything up and run it.

The only thing is that in order for the service to understand what exactly you are going to launch, it needs to be given instructions. There are two options:

  • Dockerfile – for those who know what Docker is

  • amvera.yml – a file with simple instructions that can be generated directly on the Amvera website.

Next I will show how using amvera.yml file and GIT we will perform deployment in 5 minutes. Time it.

  1. Let's go to the website Amvera Cloud

  2. We perform a simple registration, if it has not yet been (new users receive 111 rubles on their balance, which will be enough to use the service for a couple of weeks, since the price tag is more than affordable)

  3. Let's move on to projects section

  4. Create a new project

  • Here I will focus on the last stage – forming the settings file. Fill in the settings, approximately as in the screenshot below. The most important thing here is to correctly specify the name of the requirements.txt file, since the Amvera system will need to understand which libraries need to be installed.

Then, when the project is created, you need to go into it and open the settings tab there. On this tab, you can activate a free domain name that you can use to access your project.

What is noteworthy is that the service takes care of the hassle with Nginx/Apache, as well as with the htpps protocol, and all you have to do is prepare the files and upload them to the service.

Next, go to the “Repository” tab. There you will be interested in the git link to your repository.

Copy the link and on the local machine, sequentially, execute the following commands (first install GIT on the local computer):

git init
git remote add amvera ptoject_link

In my case it is:

git remote add amvera https://git.amvera.ru/yakvenalex/curl-fetch2py

At this stage, if you are working with Amvera via GIT for the first time, you will need to enter your login and password to access your Amvera personal account.

Next, you need to pick up the application settings file. To do this, use:

git pull amvera master

The settings file should look like this:

---
meta:
  environment: python
  toolchain:
    name: pip
    version: 3.12
build:
  requirementsPath: requirements.txt
run:
  persistenceMount: /data
  containerPort: 8000
  command: uvicorn app.main:app --host 0.0.0.0 --port 8000

It is important here that the container port matches the port you use in your command. If you see that the ports are different here, fix it in the settings file.

After that, we will send the applications to the Amvera service.

git add .
git commit -m "init commit"
git push amvera master

After this, the files should be in the service.

Next, you just have to wait 2-3 minutes before your application becomes publicly available via the link we received at the stage of entering the settings in the application.

In my case the link is: https://curl-fetch2py-yakvenalex.amvera.io/

Let's follow the link and check if the application works:

And what's in the API documentation:

Everything works, which means that our application has passed all stages of development and is completely ready!

Conclusion

With this simple example, I tried to show that today, with the help of modern tools like WebSim, you can create full-fledged (Full Stack) applications yourself, even without being an experienced front-end developer. I hope that this information was useful for you and gave you an important understanding: using WebSim and FastAPI, you can visualize any of your code without much effort.

You will find the full source code for this and other examples from my articles in my telegram channel “The Easy Way in Python“In addition, the channel has an active community where we discuss issues and decide together which article will be published next.

If you liked this article, don't forget to like it, leave a nice comment or subscribe to me. It's free, but for the author it's not just nice – it's a huge motivation to create even more useful and high-quality content for you.

That's all for now. All the best and see you soon!

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *