Skip to content

jackshendrikov/fjord-api

Repository files navigation

Fjord API

Welcome Logo

-----------------------------------------------------

Description β€’ Quickstart β€’ Project Structure β€’ Stack

-----------------------------------------------------

πŸ“– Description

The main goal of this project is to conveniently and quickly receive translations of texts.

You can get translations and detect the language of the input text, both individually (single) and for the whole document (Google Sheet).

Also, the project allows you to get valid proxies through separate endpoints.

Available languages for translation: English, German, Italian, Ukrainian, Norwegian and Japanese.

Available providers for translation: Google Translate, Libre Translate, MyMemory and DeepL.

The project is completely asynchronous, has an admin panel, integration with Mongo, Postgres and Redis.

If necessary, you can download the translations attached to the original Google sheet through a separate endpoint.

-----------------------------------------------------

⚑️ Quickstart

  • Clone the repo and navigate to the root folder.

  • Create and activate a python3 virtualenv via your preferred method or with:

     make ve
    • For remove virtualenv:
     make clean
  • If you setup virtualenv on your own - install the dependencies. Run:

     pip install -r requirements.txt
  • Install pre-commit hooks to ensure code quality checks and style checks:

     make install_hooks
    • You can also use these commands during dev process:

      • To run mypy checks:

         make types
      • To run flake8 checks:

         make style
      • To run black checks:

         make format
      • To run together:

         make lint
  • Replace .env.example with real .env, changing placeholders

     CURRENT_ENV=<staging|rc|production>
    
     SECRET_KEY=changeme
    
     REDIS_HOST=<redis-host>
     REDIS_PASSWORD=<redis-password>
     REDIS_PORT=<redis-port>
     REDIS_DB=<redis-db>
     REDIS_KEY=<redis-key>
    
     MONGO_HOST=<mongo-host>
     MONGO_DB=<mongo-db>
     MONGO_USER=<mongo-user>
     MONGO_PASSWORD=<mongo-password>
     MONGO_TASKS_COLLECTION=<mongo-tasks-collection>
     MONGO_USERS_COLLECTION=<mongo-users-collection>
    
     POSTGRES_HOST=<postgres-host>
     POSTGRES_PORT=<postgres-port>
     POSTGRES_DB=<postgres-db>
     POSTGRES_USER=<postgres-user>
     POSTGRES_PASSWORD=<postgres-password>
    
     TG_BOT_TOKEN=<tg-bot-token>
     TG_CHAT_ID=<tg-chat-id>
    
     MYMEMORY_EMAIL=<email-for-mymemory>
     DETECT_LANGUAGE_API_KEY=<detect-language-api-key>
    
     TCP_CONNECTOR_LIMIT=<tcp-connector-limit>
     ASYNC_TRANSLATION_TASKS_NUM=<async-translation-tasks-num>
    
     MAX_CONCURRENT_TASKS=<max-concurrent-tasks>
     RUN_BACKGROUND_TASKS=<1|0>
     SCHEDULER_TASK_INTERVAL=<seconds-interval>
    
  • Export path to Environment Variables:

     export PYTHONPATH='.'
  • Run following commands to make migrations anc create admin user:

     piccolo migrations forwards all
     piccolo user create
  • Start the Fjord API App:

    • Run server with test settings:

        make runserver-test
    • Run server with dev settings:

        make runserver-dev
    • Run server with prod settings:

        makerunserver-prod

    You will see something like this:

     $ uvicorn main.app:app --reload
     INFO:     Uvicorn running on http://127.0.0.1:5000 (Press CTRL+C to quit)
     INFO:     Started reloader process [28720]
     INFO:     Started server process [28722]
     INFO:     Waiting for application startup.
     INFO:     Application startup complete.
    About the command uvicorn main:app --reload...

    The command uvicorn main.app:app refers to:

    • main: the file main.py (the Python "module").
    • app: the object created inside of main.py with the line app = FastAPI().
    • --reload: make the server restart after code changes. Only do this for development.
  • If everything is fine, check this endpoint:

     curl -X "GET" http://host:port/api/v1/status

    Expected result:

     {
       "success": true,
       "version": "<version>",
       "message": "Fjord API"
     }

-----------------------------------------------------

πŸ› οΈ Project Structure

This shows the structure of the Ataman App.

fjord-api
β”œβ”€β”€ main                                # primary app folder
β”‚   β”œβ”€β”€ api                             # this houses for API packages
β”‚   β”‚   β”œβ”€β”€ routes                      # this is where all the routes live
β”‚   β”‚   β”‚   β”œβ”€β”€ __init__.py             # empty init file to make the routes folder a package
β”‚   β”‚   β”‚   β”œβ”€β”€ auth.py                 # module with auth endpoint
β”‚   β”‚   β”‚   β”œβ”€β”€ proxies.py              # module with proxy utils endpoint
β”‚   β”‚   β”‚   β”œβ”€β”€ status.py               # module with health check endpoint
β”‚   β”‚   β”‚   β”œβ”€β”€ tasks.py                # module with endpoints to handle translation task
β”‚   β”‚   β”‚   └── translation.py          # module with translation utils endpoint
β”‚   β”‚   β”œβ”€β”€ __init__.py                 # empty init file to make the api folder a package
β”‚   β”‚   β”œβ”€β”€ background.py               # file containing all background tasks
β”‚   β”‚   └── routes.py                   # manages all routers in the project
β”‚   β”œβ”€β”€ apps                            # this houses for Piccolo settings + template endpoints
β”‚   β”‚   β”œβ”€β”€ home                        # settings for Home App
β”‚   β”‚   β”‚   β”œβ”€β”€ piccolo_migrations      # this houses for postgres migrations
β”‚   β”‚   β”‚   β”‚   └── __init__.py         # empty init file to make the piccolo_migrations folder a package
β”‚   β”‚   β”‚   β”œβ”€β”€ templates               # jinja temolates for Home App
β”‚   β”‚   β”‚   β”‚   └── index.html.jinja    # home page template
β”‚   β”‚   β”‚   β”œβ”€β”€ __init__.py             # empty init file to make the home folder a package
β”‚   β”‚   β”‚   β”œβ”€β”€ endpoints.py            # endpoint settings for home page
β”‚   β”‚   β”‚   └── piccolo_app.py          # general piccolo app config
β”‚   β”‚   └── __init__.py                 # empty init file to make the apps folder a package
β”‚   β”œβ”€β”€ const                           # store all the consts necessary for the application
β”‚   β”‚   β”œβ”€β”€ __init__.py                 # empty init file to make the const folder a package
β”‚   β”‚   β”œβ”€β”€ common.py                   # common consts
β”‚   β”‚   β”œβ”€β”€ proxies.py                  # consts for proxy services
β”‚   β”‚   └── translator.py               # consts for translation services
β”‚   β”œβ”€β”€ core                            # this is where the configs live
β”‚   β”‚   β”œβ”€β”€ settings                    # home for all setting files
β”‚   β”‚   β”‚   β”œβ”€β”€ __init__.py             # empty init file to make the settings folder a package
β”‚   β”‚   β”‚   β”œβ”€β”€ app.py                  # base application settings
β”‚   β”‚   β”‚   β”œβ”€β”€ base.py                 # contains base app setting class and app envs
β”‚   β”‚   β”‚   β”œβ”€β”€ development.py          # development app settings
β”‚   β”‚   β”‚   β”œβ”€β”€ production.py           # production app settings
β”‚   β”‚   β”‚   └── test.py                 # test app settings
β”‚   β”‚   β”œβ”€β”€ __init__.py                 # empty init file to make the config folder a package
β”‚   β”‚   β”œβ”€β”€ config.py                   # sample config file
β”‚   β”‚   β”œβ”€β”€ dependencies.py             # auth dependency
β”‚   β”‚   β”œβ”€β”€ exceptions.py               # app exception handlers
β”‚   β”‚   β”œβ”€β”€ integrations.py             # module for project 3rd parties services
β”‚   β”‚   β”œβ”€β”€ logging.py                  # module configuration custom logger
β”‚   β”‚   └── security.py                 # auth security utils
β”‚   β”œβ”€β”€ db                              # this is where the repositories logic live
β”‚   β”‚   β”œβ”€β”€ models                      # postgres models
β”‚   β”‚   β”‚   β”œβ”€β”€ __init__.py             # empty init file to make the models folder a package
β”‚   β”‚   β”‚   └── postgres.py             # contains postgres models
β”‚   β”‚   β”œβ”€β”€ repositories                # home for all repository files
β”‚   β”‚   β”‚   β”œβ”€β”€ __init__.py             # empty init file to make the repositories folder a package
β”‚   β”‚   β”‚   β”œβ”€β”€ base.py                 # contains base repositories classes
β”‚   β”‚   β”‚   β”œβ”€β”€ proxies.py              # repository to manipulate with proxies in Redis
β”‚   β”‚   β”‚   β”œβ”€β”€ tasks.py                # repository to manipulate with translation tasks from Mongo collection
β”‚   β”‚   β”‚   └── users.py                # repository to manipulate with users from Mongo collection
β”‚   β”‚   β”œβ”€β”€ __init__.py                 # empty init file to make the repositories folder a package
β”‚   β”‚   β”œβ”€β”€ clients.py                  # provide client for MongoDB, Elasticsearch, etc.
β”‚   β”‚   β”œβ”€β”€ connections.py              # process Postgres database connections
β”‚   β”‚   └── errors.py                   # module for custom database errors
β”‚   β”œβ”€β”€ schemas                         # this is where the schemas live
β”‚   β”‚   β”œβ”€β”€ __init__.py                 # empty init file to make the schemas folder a package
β”‚   β”‚   β”œβ”€β”€ auth.py                     # users item schema
β”‚   β”‚   β”œβ”€β”€ common.py                   # contains common schemas
β”‚   β”‚   β”œβ”€β”€ notifier.py                 # notifier error schema
β”‚   β”‚   β”œβ”€β”€ proxies.py                  # proxy item schema
β”‚   β”‚   β”œβ”€β”€ status.py                   # health check schema
β”‚   β”‚   β”œβ”€β”€ tasks.py                    # schemas for translation tasks
β”‚   β”‚   └── translation.py              # single translation/detection schemas
β”‚   β”œβ”€β”€ services                        # this is where services live
β”‚   β”‚   β”œβ”€β”€ common                      # home for all main services
β”‚   β”‚   β”‚   β”œβ”€β”€ __init__.py             # empty init file to make the common folder a package
β”‚   β”‚   β”‚   β”œβ”€β”€ proxy.py                # proxy pool service
β”‚   β”‚   β”‚   └── translation.py          # service for single translation/detection
β”‚   β”‚   β”œβ”€β”€ extra                       # home for all extra services
β”‚   β”‚   β”‚   β”œβ”€β”€ proxynator.py           # module to gather fresh proxies
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ crawlers            # crawlers logic
β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ public          # public crawlers
β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ __init__.py # empty init file to make the public folder a package
β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   └── *           # different crawlers
β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ __init__.py     # empty init file to make the crawlers folder a package
β”‚   β”‚   β”‚   β”‚   β”‚   └── base.py         # abstract crawler class with all main proxy getter logic
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ __init__.py         # empty init file to make the proxynator folder a package
β”‚   β”‚   β”‚   β”‚   └── main.py             # fetching new fresh proxies and add them to Redis
β”‚   β”‚   β”‚   β”œβ”€β”€ translator.py           # module with translation providers
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ providers           # providers logic
β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ __init__.py     # empty init file to make the crawlers folder a package
β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ base.py         # abstract provider class with all main translation getter logic
β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ deepl.py        # logic to get translation from DeepL provider
β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ google.py       # logic to get translation from Google Translate provider
β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ libre.py        # logic to get translation from LibreTranslate provider
β”‚   β”‚   β”‚   β”‚   β”‚   └── mymemory.py     # logic to get translation from MyMemory provider
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ __init__.py         # empty init file to make the proxynator folder a package
β”‚   β”‚   β”‚   β”‚   └── main.py             # general logic to get single/multiple translations
β”‚   β”‚   β”‚   β”œβ”€β”€ __init__.py             # empty init file to make the extra folder a package
β”‚   β”‚   β”‚   β”œβ”€β”€ auth.py                 # handles users auth
β”‚   β”‚   β”‚   β”œβ”€β”€ errors.py               # handles async sessions and possible errors
β”‚   β”‚   β”‚   └── notifier.py             # service for sending notifications to Telegram
β”‚   β”‚   β”œβ”€β”€ __init__.py                 # empty init file to make the services folder a package
β”‚   β”‚   β”œβ”€β”€ executor.py                 # translation task executor
β”‚   β”‚   β”œβ”€β”€ scheduler.py                # translation task scheduler
β”‚   β”‚   └── tasks.py                    # service to handle translation tasks
β”‚   β”œβ”€β”€ static                          # contains static files
β”‚   └── *.css, *.js, *ico               # different static files like .css, .js or images
β”‚   β”œβ”€β”€ utils                           # this is where the utils live
β”‚   β”‚   β”œβ”€β”€ __init__.py                 # empty init file to make the utils folder a package
β”‚   β”‚   β”œβ”€β”€ common.py                   # contains common utils
β”‚   β”‚   β”œβ”€β”€ proxies.py                  # utils to check/convert proxies
β”‚   β”‚   └── tasks.py                    # includes tools for generating random IDs and form error messages
β”‚   β”œβ”€β”€ __init__.py                     # empty init file to make the main folder a package
β”‚   └── app.py                          # main file where the fastAPI() class is called
β”œβ”€β”€ .env                                # env file containing app variables
β”œβ”€β”€ .env.test                           # env file containing app test variables
β”œβ”€β”€ .pre-commit-config.yaml             # describes what repositories and hooks are installed
β”œβ”€β”€ docker-compose.yml                  # docker-compose file
β”œβ”€β”€ Dockerfile                          # prod Dockerfile
β”œβ”€β”€ Makefile                            # shell commands for convenient project use
β”œβ”€β”€ piccolo_conf.py                     # piccolo config (app registry, engine)
β”œβ”€β”€ pyproject.toml                      # pep-518 compliant config file
β”œβ”€β”€ requrements-ci.txt                  # pinned ci dependencies
β”œβ”€β”€ requirements-prod.txt               # pinned prod dependencies
β”œβ”€β”€ requirements.txt                    # pinned app dependencies
β”œβ”€β”€ setup.cfg                           # linter config file
└── version.py                          # app version file

-----------------------------------------------------

πŸ“š Stack

-----------------------------------------------------

✨ Contributors

Jack Shendrikov
πŸ‘‘ Jack Shendrikov πŸ‘‘

-----------------------------------------------------

✨ 🍰 ✨