НаблюдСниС Π½Π° микроуслуги Π½Π° Flask с Prometheus

Няколко Ρ€Π΅Π΄Π° ΠΊΠΎΠ΄ ΠΈ Π²Π°ΡˆΠ΅Ρ‚ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π° ΠΏΠΎΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ, ΡƒΠ°Ρƒ!

Π—Π° Π΄Π° Ρ€Π°Π·Π±Π΅Ρ€Π΅Ρ‚Π΅ ΠΊΠ°ΠΊ Ρ€Π°Π±ΠΎΡ‚ΠΈ ΠŸΡ€ΠΎΠΌΠ΅Ρ‚Π΅ΠΉ_ΠΊΠΎΠ»Π±Π°_износитСл Π΅ Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π΅Π½ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»Π΅Π½ ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

from flask import Flask
from prometheus_flask_exporter import PrometheusMetrics

app = Flask(__name__)
metrics = PrometheusMetrics(app)

@app.route('/')
def main():
    return 'OK'

Π’ΠΎΠ²Π° Π΅ всичко, ΠΎΡ‚ ΠΊΠΎΠ΅Ρ‚ΠΎ сС Π½ΡƒΠΆΠ΄Π°Π΅Ρ‚Π΅, Π·Π° Π΄Π° Π·Π°ΠΏΠΎΡ‡Π½Π΅Ρ‚Π΅! Π§Ρ€Π΅Π· добавянС Π½Π° ΠΈΠΌΠΏΠΎΡ€Ρ‚ ΠΈ Ρ€Π΅Π΄ Π·Π° инициализация ΠœΠ΅Ρ‚Ρ€ΠΈΠΊΠ° Π½Π° ΠŸΡ€ΠΎΠΌΠ΅Ρ‚Π΅ΠΉ, Ρ‰Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ ΠΏΡ€ΠΎΠ΄ΡŠΠ»ΠΆΠΈΡ‚Π΅Π»Π½ΠΎΡΡ‚ Π½Π° заявката ΠΈ броячи Π½Π° заявкипоказани Π² ΠΊΡ€Π°ΠΉΠ½Π°Ρ‚Π° Ρ‚ΠΎΡ‡ΠΊΠ° /ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠ° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Flask, с ΠΊΠΎΠ΅Ρ‚ΠΎ Π΅ рСгистрирано, плюс всички ΠΏΠΎΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ ΠΏΠΎ ΠΏΠΎΠ΄Ρ€Π°Π·Π±ΠΈΡ€Π°Π½Π΅, ΠΊΠΎΠΈΡ‚ΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°Ρ‚Π΅ ΠΎΡ‚ Π±Π°Π·Π°Ρ‚Π° ΠšΠ»ΠΈΠ΅Π½Ρ‚ΡΠΊΠ° Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Π½Π° Prometheus.

ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π½Π°ΠΌΠ΅Ρ€ΠΈΡ‚Π΅ лСсСн Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π² Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅Ρ‚ΠΎ Π½Π° GitHub, ΠΊΠΎΠ΅Ρ‚ΠΎ стартира СкзСмпляра ΠŸΡ€ΠΎΠΌΠ΅Ρ‚Π΅ΠΉ ΠΈ Π“Ρ€Π°Ρ„Π°Π½Π° Π·Π°Π΅Π΄Π½ΠΎ с дСмонстрационно ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π·Π° Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΏΠΎΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ, ΠΊΠΎΠ΅Ρ‚ΠΎ Π±ΠΈ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π°Π»ΠΎ Ρ‚Π°ΠΊΠ°:

НаблюдСниС Π½Π° микроуслуги Π½Π° Flask с Prometheus

Π©Π΅ Π½Π°ΠΌΠ΅Ρ€ΠΈΡ‚Π΅ ΠΈ списък с ΠΈΠ½Π΄ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΈ Π² README ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ сС появяват Π² Ρ‚Π°Π±Π»ΠΎΡ‚ΠΎ Π·Π° ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅, Π·Π°Π΅Π΄Π½ΠΎ със заявкитС Π½Π° Prometheus, ΠΊΠΎΠΈΡ‚ΠΎ ΠΏΠΎΠΏΡŠΠ»Π²Π°Ρ‚ Ρ‚Π°Π±Π»Π°Ρ‚Π° Π·Π° ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅.

Ρ€Π΅Π³ΡƒΠ»ΠΈΡ€Π°Π½Π΅

Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° ΠΈΠΌΠ° ΠΌΠ½ΠΎΠ³ΠΎ ΠΎΠΏΡ†ΠΈΠΈ Π·Π° конфигурация, Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΉΡ‚Π΅ README ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈΡ€Π°Ρ‚ своитС ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ с ΠΊΡ€Π°Ρ‚ΠΊΠΎ обяснСниС.

ΠžΡΠ½ΠΎΠ²Π½Π°Ρ‚Π° конфигурация Π΅ ΠΏΠΎΠΊΠ°Π·Π°Π½Π° ΠΏΠΎ-Π³ΠΎΡ€Π΅. ΠŸΡ€ΠΎΡΡ‚ΠΎ инстанцирайтС ΠœΠ΅Ρ‚Ρ€ΠΈΠΊΠ° Π½Π° ΠŸΡ€ΠΎΠΌΠ΅Ρ‚Π΅ΠΉ, Π΄Π° Π³ΠΎ Π½Π°Ρ€Π΅Ρ‡Π΅ΠΌ ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠ°ΠΈ слСд Ρ‚ΠΎΠ²Π° Π³ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΡ‚Π΅, Π·Π° Π΄Π° Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°Ρ‚Π΅ Π΄ΠΎΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»Π½ΠΈ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ искатС Π΄Π° ΡΡŠΠ±Π΅Ρ€Π΅Ρ‚Π΅ Ρ‡Ρ€Π΅Π· Π΄Π΅ΠΊΠΎΡ€ΠΈΡ€Π°Ρ‰ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ:

  • @metrics.counter(..)

  • @metrics.gauge(..)

  • @metrics.summary(..)

  • @metrics.histogram(..)

БроячитС ΠΎΡ‚Ρ‡ΠΈΡ‚Π°Ρ‚ обаТданията, Π° останалитС ΡΡŠΠ±ΠΈΡ€Π°Ρ‚ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ въз основа Π½Π° ΠΏΡ€ΠΎΠ΄ΡŠΠ»ΠΆΠΈΡ‚Π΅Π»Π½ΠΎΡΡ‚Ρ‚Π° Π½Π° Ρ‚Π΅Π·ΠΈ обаТдания. ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°Ρ‚Π΅ Π΅Ρ‚ΠΈΠΊΠ΅Ρ‚ΠΈ Π·Π° всСки ΠΎΡ‚ тях, ΠΊΠ°Ρ‚ΠΎ ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»Π½ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ свойства Π½Π° заявка ΠΈΠ»ΠΈ ΠΎΡ‚Π³ΠΎΠ²ΠΎΡ€. НапримСр:

from flask import Flask, request
from prometheus_flask_exporter import PrometheusMetrics

app = Flask(__name__)

# group by endpoint rather than path
metrics = PrometheusMetrics(app, group_by='endpoint')

@app.route('/collection/:collection_id/item/:item_id')
@metrics.counter(
    'cnt_collection', 'Number of invocations per collection', labels={
        'collection': lambda: request.view_args['collection_id'],
        'status': lambda resp: resp.status_code
    })
def get_item_from_collection(collection_id, item_id):
    pass

Π’ горния ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ‰Ρ€Π°ΠΊΠ²Π°Π½Π΅ Π²ΡŠΡ€Ρ…Ρƒ ΠΊΡ€Π°ΠΉΠ½Π°Ρ‚Π° Ρ‚ΠΎΡ‡ΠΊΠ° /колСкция/10002/Ρ‚./76 Ρ‰Π΅ Π½Π°ΠΊΠ°Ρ€Π° брояча Π΄Π° сС ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈ, Π½Π°ΠΏΡ€. cnt_collection{collection = "10002", status = "200"}, освСн Ρ‚ΠΎΠ²Π° Ρ‰Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈΡ‚Π΅ ΠΏΠΎ ΠΏΠΎΠ΄Ρ€Π°Π·Π±ΠΈΡ€Π°Π½Π΅ (Π·Π° всяка ΠΊΡ€Π°ΠΉΠ½Π° Ρ‚ΠΎΡ‡ΠΊΠ° Π² Ρ‚ΠΎΠ·ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€) ΠΎΡ‚ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° ΠΏΠΎ ΠΏΠΎΠ΄Ρ€Π°Π·Π±ΠΈΡ€Π°Π½Π΅:

  • flask_http_request_duration_seconds - ΠŸΡ€ΠΎΠ΄ΡŠΠ»ΠΆΠΈΡ‚Π΅Π»Π½ΠΎΡΡ‚ Π½Π° HTTP заявката Π² сСкунди Π·Π° всички Flask заявки ΠΏΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄, ΠΏΡŠΡ‚ ΠΈ статус

  • flask_http_request_total β€” ΠžΠ±Ρ‰ Π±Ρ€ΠΎΠΉ HTTP заявки ΠΏΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ ΠΈ ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΡ

Има ΠΎΠΏΡ†ΠΈΠΈ Π·Π° пропусканС Π½Π° прослСдяванС Π½Π° ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΈ ΠΊΡ€Π°ΠΉΠ½ΠΈ Ρ‚ΠΎΡ‡ΠΊΠΈ, рСгистриранС Π½Π° Π΄ΠΎΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»Π½ΠΈ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ ΠΏΠΎ ΠΏΠΎΠ΄Ρ€Π°Π·Π±ΠΈΡ€Π°Π½Π΅ ΠΈΠ»ΠΈ пропусканС Π½Π° Ρ‚Π΅Π·ΠΈ ΠΏΠΎ-Π³ΠΎΡ€Π΅, ΠΈΠ»ΠΈ ΠΏΡ€ΠΈΠ»Π°Π³Π°Π½Π΅ Π½Π° Π΅Π΄ΠΈΠ½ ΠΈ ΡΡŠΡ‰ потрСбитСлски ΠΏΠΎΠΊΠ°Π·Π°Ρ‚Π΅Π» към мноТСство ΠΊΡ€Π°ΠΉΠ½ΠΈ Ρ‚ΠΎΡ‡ΠΊΠΈ. Π Π°Π·Π³Π»Π΅Π΄Π°ΠΉΡ‚Π΅ README ΠΏΡ€ΠΎΠ΅ΠΊΡ‚, Π·Π° Π΄Π° Π²ΠΈΠ΄ΠΈΡ‚Π΅ ΠΊΠ°ΠΊΠ²ΠΎ Π΅ Π½Π°Π»ΠΈΡ‡Π½ΠΎ.

app = Flask(__name__)
metrics = PrometheusMetrics(app)

@app.route('/')
def main():
    pass  # requests tracked by default

@app.route('/skip')
@metrics.do_not_track()
def skip():
    pass  # default metrics are not collected

# custom metric to be applied to multiple endpoints
common_counter = metrics.counter(
    'by_endpoint_counter', 'Request count by endpoints',
    labels={'endpoint': lambda: request.endpoint}
)

@app.route('/common/one')
@common_counter
def endpoint_one():
    pass  # tracked by the custom and the default metrics

@app.route('/common/two')
@common_counter
def endpoint_two():
    pass  # also tracked by the custom and the default metrics

# register additional default metrics
metrics.register_default(
    metrics.counter(
        'by_path_counter', 'Request count by request paths',
        labels={'path': lambda: request.path}
    )
)

Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° ΠΈΠΌΠ° ΡƒΠ΄ΠΎΠ±Π½ΠΈ Ρ€Π°Π·ΡˆΠΈΡ€Π΅Π½ΠΈΡ Π·Π° популярни многопроцСсорни Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ ΠΊΠ°Ρ‚ΠΎ uWSGI ΠΈ Gunicorn. ΠœΠΎΠΆΠ΅Ρ‚Π΅ ΡΡŠΡ‰ΠΎ Ρ‚Π°ΠΊΠ° Π΄Π° Π½Π°ΠΌΠ΅Ρ€ΠΈΡ‚Π΅ ΠΌΠ°Π»ΠΊΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ Π·Π° случаи Π½Π° Ρ†Π΅Π»Π΅Π²Π° ΡƒΠΏΠΎΡ‚Ρ€Π΅Π±Π°, Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»Π½ΠΎ многопроцСсорни.

ΠšΠΎΠ»Π΅ΠΊΡ†ΠΈΡ ΠΎΡ‚ ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ

ΠšΠ°ΠΊΡ‚ΠΎ Π±Π΅ спомСнато ΠΏΠΎ-Π³ΠΎΡ€Π΅, Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° ΠΏΠΎ ΠΏΠΎΠ΄Ρ€Π°Π·Π±ΠΈΡ€Π°Π½Π΅ прСдоставя ΠΊΡ€Π°ΠΉΠ½Π° Ρ‚ΠΎΡ‡ΠΊΠ° /ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠ° Π² ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π° Flask, ΠΊΠΎΠ΅Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° слуТи ΠΊΠ°Ρ‚ΠΎ Ρ†Π΅Π» Π·Π° асСмблСр ΠŸΡ€ΠΎΠΌΠ΅Ρ‚Π΅ΠΉ.

Π’ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π½Π° Ρ‚Π°Π±Π»ΠΎΡ‚ΠΎ Π·Π° ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΠΎ-Π³ΠΎΡ€Π΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° насочитС вашия Prometheus към ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π° Flask с настройки ΠΏΠΎ ΠΏΠΎΠ΄Ρ€Π°Π·Π±ΠΈΡ€Π°Π½Π΅ ΠΊΠ°Ρ‚ΠΎ Ρ‚Π΅Π·ΠΈ:

scrape_configs:
  - job_name: 'example'

    dns_sd_configs:
      - names: ['app']
        port: 5000
        type: A
        refresh_interval: 5s

Π’ΠΈΠΆΡ‚Π΅ пълния ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π½Π° Π₯Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π° Π½Π° GitHub. Π’ΠΎΠ²Π° ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°, Ρ‡Π΅ Prometheus ΠΌΠΎΠΆΠ΅ Π΄Π° Π½Π°ΠΌΠ΅Ρ€ΠΈ Π²Π°ΡˆΠΈΡ‚Π΅ СкзСмпляри Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Flask Π½Π° http://app:5000/metrics, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ ΠΈΠΌΠ΅Ρ‚ΠΎ Π½Π° Π΄ΠΎΠΌΠ΅ΠΉΠ½Π° Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅ ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»Π½ΠΎ Π΄Π° сС Ρ€Π°Π·Ρ€Π΅ΡˆΠΈ Π½Π° мноТСство IP адрСси, ΠΊΠ°Ρ‚ΠΎ Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΡ€ΠΈ стартиранС Kubernetes ΠΈΠ»ΠΈ Π”ΠΎΠΊΠ΅Ρ€ рояк.

Ако ΠΈΠ·Π»Π°Π³Π°Π½Π΅Ρ‚ΠΎ Π½Π° ΠΊΡ€Π°ΠΉΠ½Π°Ρ‚Π° Ρ‚ΠΎΡ‡ΠΊΠ° Π½Π° ΠΏΠΎΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈΡ‚Π΅ ΠΏΠΎ Ρ‚ΠΎΠ·ΠΈ Π½Π°Ρ‡ΠΈΠ½ Π½Π΅ Π²ΠΈ ΠΏΠΎΠ΄Ρ…ΠΎΠΆΠ΄Π°, ΠΌΠΎΠΆΠ΅ Π±ΠΈ Π·Π°Ρ‰ΠΎΡ‚ΠΎ Π½Π΅ искатС Π΄Π° Ρ€Π°Π·Ρ€Π΅ΡˆΠΈΡ‚Π΅ външСн Π΄ΠΎΡΡ‚ΡŠΠΏ Π΄ΠΎ нСя, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ лСсно Π΄Π° я Π΄Π΅Π°ΠΊΡ‚ΠΈΠ²ΠΈΡ€Π°Ρ‚Π΅, ΠΊΠ°Ρ‚ΠΎ ΠΏΡ€Π΅ΠΌΠΈΠ½Π΅Ρ‚Π΅ ΠΏΡŠΡ‚=Няма ΠΏΡ€ΠΈ инстанциранС ΠœΠ΅Ρ‚Ρ€ΠΈΠΊΠ° Π½Π° ΠŸΡ€ΠΎΠΌΠ΅Ρ‚Π΅ΠΉ.

from flask import Flask, request
from prometheus_flask_exporter import PrometheusMetrics

app = Flask(__name__)
metrics = PrometheusMetrics(app, path=None)

...

metrics.start_http_server(5099)

Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π° ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ start_http_server(ΠΏΠΎΡ€Ρ‚)Π·Π° Π΄Π° ΠΎΡ‚Π²ΠΎΡ€ΠΈΡ‚Π΅ Ρ‚Π°Π·ΠΈ ΠΊΡ€Π°ΠΉΠ½Π° Ρ‚ΠΎΡ‡ΠΊΠ° Π½Π° Ρ€Π°Π·Π»ΠΈΡ‡Π΅Π½ HTTP ΠΏΠΎΡ€Ρ‚, 5099 Π² горния ΠΏΡ€ΠΈΠΌΠ΅Ρ€. ΠšΠ°Ρ‚ΠΎ Π°Π»Ρ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π°, Π°ΠΊΠΎ стС Π΄ΠΎΠ²ΠΎΠ»Π½ΠΈ ΠΎΡ‚ Ρ‚ΠΎΠ²Π°, Ρ‡Π΅ ΠΊΡ€Π°ΠΉΠ½Π°Ρ‚Π° Ρ‚ΠΎΡ‡ΠΊΠ° Π΅ Π² ΡΡŠΡ‰ΠΎΡ‚ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π° Flask, Π½ΠΎ трябва Π΄Π° ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈΡ‚Π΅ ΠΏΡŠΡ‚Ρ ΠΌΡƒ ΠΎΡ‚ /ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠ°, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΏΠΎΠ΄Π°Π΄Π΅Ρ‚Π΅ Ρ€Π°Π·Π»ΠΈΡ‡Π΅Π½ URI ΠΊΠ°Ρ‚ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚ΡŠΡ€ Π½Π° ΠΏΡŠΡ‚Ρ ΠΈΠ»ΠΈ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ Ρ€Π΅Π³ΠΈΡΡ‚ΡŠΡ€_ΠΊΡ€Π°ΠΉΠ½Π° Ρ‚ΠΎΡ‡ΠΊΠ°(..)Π·Π° Π΄Π° Π³ΠΎ инсталиратС ΠΏΠΎ-късно.

ΠŸΠΎΠ·ΠΎΠ²Π°Π²Π°Π½Π΅Ρ‚ΠΎ

Ако Ρ€Π΅ΡˆΠΈΡ‚Π΅ Π΄Π° ΠΎΠΏΠΈΡ‚Π°Ρ‚Π΅, Π½Π΅ сС ΠΊΠΎΠ»Π΅Π±Π°ΠΉΡ‚Π΅ Π΄Π° ΠΎΡ‚Π²ΠΎΡ€ΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ Π² GitHub ΠΈΠ»ΠΈ Π΄Π° оставитС своитС ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈ, ΠΎΡ‚Π·ΠΈΠ²ΠΈ ΠΈ прСдлоТСния!

Благодаря Π²ΠΈ!

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: www.habr.com