Горячее
Лучшее
Свежее
Подписки
Сообщества
Блоги
Эксперты
Войти
Забыли пароль?
или продолжите с
Создать аккаунт
Регистрируясь, я даю согласие на обработку данных и условия почтовых рассылок.
или
Восстановление пароля
Восстановление пароля
Получить код в Telegram
Войти с Яндекс ID Войти через VK ID
ПромокодыРаботаКурсыРекламаИгрыПополнение Steam
Пикабу Игры +1000 бесплатных онлайн игр Веселая аркада с Печенькой для новогоднего настроения. Объезжайте препятствия, а подарки, варежки, конфеты и прочие приятности не объезжайте: они помогут набрать очки и установить новый рекорд.

Сноуборд

Спорт, Аркады, На ловкость

Играть

Топ прошлой недели

  • cristall75 cristall75 6 постов
  • 1506DyDyKa 1506DyDyKa 2 поста
  • Animalrescueed Animalrescueed 35 постов
Посмотреть весь топ

Лучшие посты недели

Рассылка Пикабу: отправляем самые рейтинговые материалы за 7 дней 🔥

Нажимая «Подписаться», я даю согласие на обработку данных и условия почтовых рассылок.

Спасибо, что подписались!
Пожалуйста, проверьте почту 😊

Помощь Кодекс Пикабу Команда Пикабу Моб. приложение
Правила соцсети О рекомендациях О компании
Промокоды Биг Гик Промокоды Lamoda Промокоды МВидео Промокоды Яндекс Маркет Промокоды Пятерочка Промокоды Aroma Butik Промокоды Яндекс Путешествия Промокоды Яндекс Еда Постила Футбол сегодня
0 просмотренных постов скрыто
1188
neurogenerated
neurogenerated
Искусственный интеллект

Пользуемся бесплатно API ChatGPT без ограничений⁠⁠

2 года назад

Использование API для ChatGPT дает нам расширение возможностей работы с ним: переводчик текста, персональный помощник, работа с документами, кастомные клиент и многое другое. Чтобы получить ко всему этому доступ, нам понадобится - актуальная версия моего форка FreeGPT c Github, и поддержка установки кастомного endpoint (openai api) сервера со стороны нужной нам программы. О том, как работает FreeGPT я рассказывал в самом само первом посте, связанным с проектом: ChatGPT-4 и ChatGPT-3.5 в 1 клик на вашем ПК. Работает без VPN

Итак, качаем самую актуальную версию FreeGPT. Вы можете как установить обычную версию самостоятельно, так и воспользоваться портативной версией, не требующей установки и запускающуюся в один клик. Портативные версии можно найти в релизах на Github проекта, они помечены припиской portable.

На данный момент есть 2 портативные версии - архив с python скриптами и виртуальной средой, и скомпилированный exe файл. Второй более компактный, но к сожалению, из-за сборки в exe некоторые антивирусы выдают ложные срабатывания, поэтому если вас это смущает - воспользуйтесь версией в архиве.



После загрузки/распаковки нам нужно запустить bat файл start_endpoint.bat или же start_portable_endpoint.bat, в зависимости от того, какая у вас версия программы - обычная или портативная.

После запуска, у вас откроется окно консоли:

Адрес нашего Endpoint сервера - http://127.0.0.1:1337

Именно его мы и будем использовать в различных программах и плагинах вместо родного https://api.openai.com

Учтите, что называться он может по-разному: Endpoint, OpenAI API Server, API URL, и т.д. Самое главное, что обычно по умолчанию это идет адрес https://api.openai.com и его нам надо заменить на наш http://127.0.0.1:1337

Давайте разберем на примере.

Возьмем программу ChatGPT Next. В настройках у нас есть графа Endpoint, где указан официальный API сервер OpenAI:

Пишем сюда наш адрес: http://127.0.0.1:1337 а в поле ключ указываем псевдо-ключ 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

На самом деле ключ указывать не обязательно, просто некоторые программы проверяют его наличие и отказываются работать без него. Именно по этому мы используем ключ заглушку. Вы можете указать тут абслютно любой ключ, который найдете в сети, или же воспользоваться генератором псевдо-ключей

Затем закрываем настройки и начинаем чат. Программа подхватила наш сервер и отправляет запросы на него, а тот, в свою очередь, отправляет запросы сайту-провайдеру. Это можно увидеть, открыв консоль нашего endpoint сервера:

Точно такой же принцип и в других программах, позволяющих устанавливать кастомный endpoint сервер.

К примеру, вот программа и плагин для Chrome OpenAI Translator:


Или плагин помощник для Visual Studio Code:


Важный нюанс: работать будут только те модели, которые есть в FreeGPT. Если вы попытаетесь работать с моделями, не добавленными в FreeGPT, у вас будут лишь ошибки.

На данный момент, работают: ChatGPT-3.5-Turbo, ChatGPT-3.5-Turbo-0613, ChatGPT-3.5-Turbo-16k, ChatGPT-3.5-Turbo-16k-0613


Больше информации по работе с FreeGPT, а также по различным популярным и интересным нейронным сетям, включая их портативные сборки, можно найти в моем телеграм канале.

Показать полностью 6
[моё] Нейронные сети ChatGPT API Бесплатно Чат-бот Гайд Python Длиннопост
150
420
YouZ63
Исследователи космоса

А вы знали что у NASA есть API?⁠⁠2

3 года назад
Оказывается NASA довольно щедрая организация, и бесплатно делится результатами своей работы, так например вы обращаясь по определенным конечным точкам API можете получить некоторую информацию, например фото Земли, и т д, со всеми вариантами можно ознакомится на главной странице, достаточно нажать кнопку Browse APIs, и там весь список😁


Для использования API вам нужен специальный API ключ, который вы получите после заполнения короткой анкеты:

Сразу же я решил что-то интересное придумать с этим делом, и так как я довольно неплохо разбираюсь в Телеграм API, я решил сделать телеграм канал в который буду раз в сутки постить какое-то астрономическое фото с пояснением в красивом виде, как это сделать? сейчас поясню.


1 - Создаете бота, как создать телеграм бота почитайте тут

2 - Создайте телеграм канал, и добавьте ранее созданного бота в этот канал как администратора

3 - Теперь вы сможете отправлять в свой канал сообщения посредством создания POST запроса, например вот с использованием Python, например ниже отправка картинки с подписью:

Где:

AUTH_TOKEN = Токен бота который вы ранее создали
CHANNEL_NAME = Имя канала, например @my_channel
CAPTION = Текстовая подпись к фото
URL = Ссылка на фото которое отправить в телегу

Естественно можете использовать хоть JavaScript, про остальные методы для телеги можно почитать тут.


Теперь про получения данных из NASA, там все просто, делаете GET запрос на то API которое вы выбрали (на том же сайте предоставляются линки, примерно в таком виде:

https://api.nasa.gov/planetary/earth/imagery?lon=100.75&... , вот DEMO_KEY нужно заменить на от ключ, который вы от NASA получили после заполенния анкеты)


Все, готово😁


То что я сделал, это канал, куда раз в сутки будет публиковаться красивое фото космоса, с описанием и автоматическим переводом на русский язык (после нажатия на ссылку под каждым постом идет переход на telegraph где описание доступно в дух языках, оригинала и русском) + добавлена возможность скачать эту картинку в HD качестве, ссылка на канал -> https://t.me/daily_nasa


Спасибо за внимание😁

Показать полностью 2
[моё] Telegram IT Python NASA API Разработка Программирование Космос Наука Бот Научпоп Телеграмма Длиннопост
41
336
Есть официальный ответ
AlexeyBunak
AlexeyBunak
Про сайт объявлений

Avito игнорирует разработчиков⁠⁠

3 года назад

В январе я получил от AVITO ключи для своего приложения, и начал разработку. Пришлось смириться с отсутствием какой-либо поддержки, объяснения, информирования об изменениях, обратной связи и так далее. Но решение было мое железным - я создаю приложение, которое будет использовать только белые схемы, мне нужно построить долгие и плодотворные отношения с Авито и другими площадками, чтобы перевести свой сервис на коммерческую основу.

За пол года я пытался писать в ТП о недоработках, участвовать в вебинарах, вставляя свои три копейки по поводу работы API и Автозагрузки. Но все это был разговор со стеной. Приходилось решать проблемы самостоятельно. За пол года у моего приложения появилось несколько сотен пользователей, мой бот обработал более миллиона сообщений, помогая людям в коммуникации с клиентами. На прошлой неделе Авито начало выдавать текст системных сообщений, и я уже строил планы по внедрению новых функций. Все было хорошо до 24 июня.


И вот, в ту "черную пятницу" мне звонит девушка, пока я шел из магазина, и говорит, что она представляет AVITO, что они хотели бы провести интервью в Zoom с теми, кто активно пользуется Авито.Доставкой и API. Назначили интервью на вторник. И так совпало, что примерно в эти же 30 минут мне в ЛС начали жаловаться пользователи, что все пропало, ничего не работает. Мало ли что произошло, подумал я, и вернувшись домой начал искать проблему в коде. Но искал не там. Оказалось, что мое приложение просто удалили, его не стало, будто и не было. Куда бежать? что делать? Как говорится, «В 4 часа утра без объявления войны…», только у меня это было 4 часа дня...


ТехПоддержка по телефону? Ха... номер для разработчиков? Да он ведет на все тот же неработающий для простых смертных телефон 8-800-6000001. Почта? Коммуникация не быстрая... Пишу в чат ТП, жду час. Пытаюсь объяснить ситуацию, на что сотрудник ТП "6288" рапортует о том, что он передал вопрос далее, и что мне ответят в течение 3х дней. ОК, вечер пятницы, 3 календарных дня или рабочих - не понятно. На почту пришло письмо, что создана заявка за номером "31335100", но никаких данных с меня не взяли. Остается только ждать, а пока жду, полез пробовать разобраться самостоятельно. На странице для разработчиков в футере есть ссылка "Правила использования API" и ведет она на некую PDF, точнее должна вести, но Авито рапортует, что нет такого файла по тому пути. То есть я даже в теории не могу понять, за что же со мной так поступили. Хотя в моем понимании, "что есть в API, то разрешено", ибо по-другому никак. Есть метод - используешь, нет метода - не используешь.


И вот тем временем настал вторник, в запланированное время началась Zoom-конференция, меня начали расспрашивать о пользовательском опыте, пытались склонить к ответам про использование официальных интеграций типа Bitrix и AmoCRM, а я им каждый раз пояснял, что я сам себе разработчик, и ничего мне не нужно, я пытаюсь подстроиться под Авито самостоятельно. Я, как мне кажется, довольно подробно описал проблемы и недоработки API, описал чего не хватает, в том числе ресурса с новостями для разработчиков, чтобы мы не из Телеграм-каналов друг друга узнавали о каких-то изменениях, а централизованно. Представителям AVITO я дал название своего приложения, мне обещали что посмотрят и постараются ответить за 3 дня...


Уже 30.06, прошло 2 раза по три дня. Но ответа нет, тогда я снова пишу в ТП, и спрашиваю, что же происходит с моим запросом за номером "31335100". И через час, вместо ~15 минут, мне отвечает сотрудник ТП "8342", а текст его ответа на скриншоте...

То есть я жду 6 дней, чтобы просто кому-то дать вводные данные. Вопрос "КТО и ЗА ЧТО удалил мое приложение", по ходу, требует вмешательства от акционеров Prosus. Я выразил свое негодование именно таким же вопросом, и тут быстро нарисовался мой "друг", агент ТП "6288", с которым я общался неделю назад, и его ответ выглядит просто издевательством

Да, господа из ТП, я могу вас различать! И если для обычных пользователей вы все с одной аватаркой, и кажется что прикидываетесь дурачками, то с разработчиком такое не прокатит.

Зато пока я жду ответа на свой, казалось бы, простой вопрос, Авито выпускает очередную партию авитологов, которые должны выбивать из клиентов деньги. AVITO не заинтересовано в магазинах с тысячами SKU (отчет о автозагрузке просто не отдается, с 3-5-10 попытке ты можешь его получить, но там информации полезной около ноля), с интеграцией, с синхронизацией БД, ставка делается на "продвигаем 1 сантехника" и "продаем 3 велосипеда с помощью 130 объявлений".


Лично у нас в магазине свыше 30000 SKU, но даже взяв пакет всего на 1000 объявлений, я не могу сделать сквозную интеграцию и синхронизацию из-за проблем с получением отчетов через API


Обращаюсь к представителям Авито... вот вы "боретесь" с теми, кто использует черные и серые схемы, но проблема в том, что борьба именно в кавычках. Вы тратите большие деньги на антифрод системы, на идентификацию пользователей, но при этом вы не идете на диалог с теми, кто хочет работать с вами честно, в белую, вы нас не слышите и вам лучше чтобы нас не было, да, я не 1С, но это не значит что я не могу создать полезный продукт для части ваших же пользователей. Что мне делать с моими 300+ клиентами, которые меня каждый час дергают вопросом, когда заработает сервис? Вы всеми своими действиями (или бездействием) подталкиваете меня к тому, чтобы я тоже перешел на темную сторону и боролся с системой, а не интегрировался в нее. Я сказал на интервью, что готов приехать в офис Авито в Москве и обсудить лично, если есть какие-то вопросы к моему сервису и найти решение возникших проблем, заключить договор и все сделать официально. Дело за вами, но я сомневаюсь что хоть какой-то ЛПР Авито увидит данную статью.

Показать полностью 2
[моё] Авито API Разработчики Интеграция Сервис Длиннопост Жалоба
114
136
it.stories
it.stories

Гаражный контроллер на NodeMCU (ESP8266)⁠⁠

5 лет назад

Надоела мне ардуинка в шкафу, мотающаяся на проводах. Да и от работы с контакторами она уходит на перезагрузку и может зависнуть.

Решено было перейти на что то более интересное и выбор пал на NodeMCU с ESP8266 на борту.

Программку написал за вечер, благо исходники от первой версии остались. Логика плюс минус такая же, но с доработками.

Компоновка получилась примерно такая.

Контроллер в боксе внизу, силовая часть сверху

Все крышки закрыты, контроллер запущен

Для серверной части решил все полностью переработать.

Осталось почти такая же только структура. Решил в этот раз не халтурить, а сделать все красиво. На ООП PHP все уместилось в один класс.

Ну а с веб интерфейсом решил не мудрить, сделал примитивненько, для себя ж.

такое вот чудо-юдо

Для Вас, мои малочисленные читатели, я выложил все исходники на Github (https://github.com/rsgrinko/nmcu-garage-controller). Так что изучайте:)

Показать полностью 4
[моё] Nodemcu Самоделки Гараж Контроллер Arduino PHP Сайт API Удаленный доступ Длиннопост
34
94
DobroMax1
IT-юмор

Леонид Каганов: Про дебилов из ozon.ru⁠⁠

3 года назад

Источник: Леонид Каганов, https://lleo.me/dnevnik/2022/02/04


Маркетплейс сегодня — самое прибыльное дело. Человечество в 21 веке недалеко ушло от концепции «Басурман-Паша центральным рынком завладел». Достаточно сказать, что владелец главной в мире барахолки Amazon — уже много лет самый богатый человек на планете и лишь изредка уступает это звание Илону Маску. Тому самому Маску, который (в отличие от директора рынка по перепродаже чужих лампочек, книжек и лифчиков) сегодня главный инноватор, двигатель технологий, космоса и прогресса. При этом, в отличие от проектов Маска, практически все барахолки сделаны криво, неудобно, с дизайном прошлого века и постоянными глюками.


По образу и подобию Амазона был сделан когда-то и российский Озон — даже название немножко спиздили. Весьма унылая на мой покупательский взгляд площадка, поскольку любую позицию из ассортимента Озона мне всегда удавалось в пару кликов найти в каком-нибудь другом месте по цене на 10-20% ниже. Но дело не в этом.


У Озона есть API для продавцов — система, которая позволяет зарегистрированному продавцу выставлять свои товары по специальному протоколу. Мелкая продавщица домашнего мыла API не использует — она заполняет карточку товара руками через кривую форму на сайте. Но большой склад не может ежедневно заводить тысячи карточек вручную, поэтому я помогаю другу с программированием системы, работающей через API. Судя по всему (в том числе по общению с техподдержкой) я единственный программист, который с их API работает. Потому что там лютый пиздец.


Я уже рассказывал вам поржать, как криворукие быдлокодеры Озона перешли на API v.2, где карточка для продажи сраного коробка спичек (условно говоря) состоит из многих десятков «параметров», имена и значения которых следует заполнять не словами, а специальными кодами. Вместо того, чтобы вписать «материал изделия»:«сосна» следует писать что-то вроде «9876543210»:«12345». А для выяснения этих нечеловеческих кодов предлагается по каждому параметру заранее выкачать себе так называемый словарь для позиции «материал изделия», и из него на своей стороне узнать, что «сосна» это «12345». Причем, этот словарь еще на серверах Озона периодически меняется. В API нельзя сделать короткий запрос, каков код материала «сосна». Нет, ты должен в тысячу приемов выкачать гигантский словарь всех мыслимых материалов, которые тебе никогда не понадобятся. Но и это еще не всё. Некоторые «словари» короткие, другие гигантские. Например, загадочная, но почему-то обязательная для любых товаров графа «Серии» имеет словарь на 305816 позиций, который начинается так: «Тестовая серия имени Мымрика», «Феникс», «Параметры судьбы», «Вершины», «История цивилизации», «Живи с умом», «Мастерим бумажный город», «Столицы туризма», «Уроки колдовства», «Это вы можете», «Славяне»... Нахуя это спичкам или видеокарте?! Словарь «Бренд» содержит 44270 позиций — от «Intel» до «Благовещенская Икона», хотя к сраным спичкам не относится даже она. В словаре «Коммерческий тип» 10206 наименований вида «Носки для рыбалки», «Бижу кольцо на 3 фаланги мужское», «Бижу кольцо на 3 пальца мужское», «Кассетный плеер»... Время от времени в словарях тупо встречаются дубли. Уникальные индексы базы? Нет, не слышали.


Но и это еще не всё! Для получения словаря по каждой графе в описании сраных спичек ты должен указать номер категории (спички) и номер атрибута (материал изделия). И в ответ на эти два числа тебе приедет словарь. Может, он будет содержать всего две позиции («да», «нет»). Может, миллион. Может, для «материал изделия» по спичкам приедет точно такой же словарь, как был «материал изделия» по стульям. А может — совершенно другой, хотя номер dictionary_id будет совпадать. Нет никакой возможности понять, следует ли порциями по 500 штук несколько часов выкачивать 305816 позиций словаря «Серии», либо он в итоге — полный дубль уже выкачанного для другой категории. Можно только строить на своей стороне эвристики.


Но даже это еще не всё! Потому что параметры на Озоне придумывают вручную полные дебилы. Зацените, сегодняшняя вишенка. Заводили категорию «Видеокамера». Ну казалось бы, ну видеокамера, хули там? Запросили список характеристик карточки. Там среди «Тип матрицы», «Тип крепления», «Формат записи видео» почему-то есть характеристика «Персонаж»... со словарем, размером — внимание! — миллион записей. 1063978 персонажей! От Эльдара Рязанова до Франца Кафки. А также мусор, в котором их имена перемешаны с посторонними словами. Например, Кафка как персонаж представлен такими позициями:


543259: Кафка Франц
11325450: Кафка Ф.
349207: Франц Кафка. Собрание сочинений
734798: Франц Кафка. Собрание сочинений в 4 томах
970739354: Франц Кафка. Собрание сочинений в 5-ти томах
126794522: Франц Кафка. Собрание сочинений («Пальмира»)
Да что Кафка! В словаре персонажей для видеокамеры есть «Путин», «Путин В.В.», «Путин Владимир Владимирович», «Путин + 7», а также зловещий «Проект Путин» номер 10041457 и еще два таких же в кавычках «Проект "Путин"» с номерами 184709005, 595678. И конечно заманчивый персонаж «После Путина» номер 10815017. Кстати о птичках. Там есть даже экстремисты братья Навальные с фото:
1086890: Навальный Алексей Анатольевич
970714723: Навальный Алексей
11376102: Навальный Олег
Там есть даже я пару раз! Тоже с фотографией!
Леонид Каганов: Про дебилов из ozon.ru

Вот нахуя эти криворукие школьники (говорят, штат программистов Озон насчитывает 2000 человек) присобачили товарам категории «Видеокамера» характеристику «Персонаж»?! Что это блять было?!! Чернила для пятого класса, глобус Грузии и видеокамера для съемок Каганова?


Что любопытно, поле description для опции «Персонаж» гласит: «Выберите из списка героя/персонажа, которые изображены на изделии». Для мониторов или, скажем, ковриков для мыши это поле не предусмотрено. Только для товаров «Видеокамера» и «Веб-камера». Видимо, надо указать товарищу майору, кого именно предполагается снимать этой камерой. Эдварда Радзинского будем, блять, ею снимать. Что также интересно: стоит атрибут is_collection=1, означающий, что в этой графе следует указывать не одно из значений, а перечислить номера всех нужных. Выберите из миллиона персонажей только тех, кого можно снимать вебкамерой.


В общем, пацаны и девчонки, если вы вдруг продаете на Озоне видеокамеры и заполняете торговую карточку товара, прошу в графе «Персонаж» указывать меня — номер 10863082. Вам без разницы, а мне приятно.


PS: Саш, ты извини, но я вписал в наш код: if($attribute_name=='Персонаж') $value='Навальный Алексей Анатольевич'; Вдруг ФСИН на Госзакупках объявит тендер на закупку камер наблюдения, станут выбирать, опа — даже персонаж сходится.


Источник: Леонид Каганов, https://lleo.me/dnevnik/2022/02/04

Показать полностью 1
Леонид Каганов Владимир Путин Алексей Навальный Олег Навальный OZON API Быдлокодинг Мат Длиннопост
99
70
DocHum
DocHum

Длиннопост про Mantle⁠⁠

12 лет назад
Длиннопост, в котором вы узнаете о том, что такое AMD Mantle, получите общее представление об API и расширите свой кругозор :)
Длиннопост про Mantle
Показать полностью 1
[моё] AMD Mantle Длиннопост API
20
55
noopel
noopel
Лига программистов

Разработка системы заметок с нуля. Часть 2: REST API для RESTful API Service + JWT + Swagger⁠⁠

4 года назад

Продолжаем серию материалов про создание системы заметок. В этой части мы спроектируем и разработаем RESTful API Service на Go cо Swagger и авторизацией. Будет много кода, ещё больше рефакторинга и даже немного интеграционных тестов.

В первой части мы спроектировали систему и посмотрели, какие сервисы требуются для построения микросервисной архитектуры.


Исходники проекта — в репозитории на GitHub.


Подробности в видео и текстовой расшифровке под ним.

Прототипирование


Начнём с макетов интерфейса. Нам нужно понять, какие ручки будут у нашего API и какой состав данных он должен отдавать. Макеты мы будем делать, чтобы понять, какие сущности, поля и эндпоинты нам нужны. Используем для этого онлайн-сервис NinjaMock. Он подходит, если макет надо сделать быстро и без лишних действий.

Страницу регистрации сделаем простую, с четырьмя полями: Name, Email, Password и Repeat Password. Лейблы делать не будем, обойдемся плейсходерами. Авторизацию сделаем по юзернейму и паролю.

После входа в приложение пользователь увидит список заметок, который будет выглядеть примерно так:

Интерфейс, который будет у нашего веб-приложения:

- Слева — список категорий любой вложенности.

- Справа — список заметок в виде карточек, который делится на два списка: прикреплённые и обычные карточки.

- Каждая карточка состоит из заголовка, который урезается, если он очень длинный.

- Справа указано, сколько секунд/минут/часов/дней назад была создана заметка.

- Тело заголовка — отрендеренный Markdown.

- Панель инструментов. Через неё можно изменить цвет, прикрепить или удалить заметку.


Тут важно отметить, что файлы заметки мы не отображаем и не будем запрашивать у API для списка заметок.


Полная карточка открывается по клику на заметку. Тут можно сразу отобразить полностью длинный заголовок. Высота заметки зависит от количества текста. Для файлов появляется отдельная секция. Мы их будем получать отдельным асинхронным запросом, который не помешает пользователю редактировать заметку. Файлы можно скачать по ссылке, также есть отдельная кнопка на добавление файлов.

Так будет выглядеть открытая заметка


В ходе прототипирования стало понятно, что в первой части мы забыли добавить еще один микросервис — TagsService. Он будет управлять тегами.


Определение эндпоинтов


Для страниц авторизации и регистрации нам нужны эндпоинты аутентификации и регистрации соответственно. В качестве аутентификации и сессий пользователя мы будем использовать JWT. Что это такое и как работает, разберём чуть позднее. Пока просто запомните эти 3 буквы.

Для страницы списка заметок нам нужны эндпоинты /api/categories для получения древовидного списка категорий и /api/notes?category_id=? для получения списка заметок текущей категории. Перемещаясь по другим категориям, мы будем отдельно запрашивать заметки для выбранной категории, а на фронтенде сделаем кэш на клиенте. В ходе работы с заметками нам нужно уметь создавать новую категорию. Это будет метод POST на URL /api/categories. Также мы будем создавать новый тег при помощи метода POST на URL /api/tags.

Чтобы обновить заметку, используем метод PATCH на URL /api/notes/:uuid с измененными полями. Делаем PATCH, а не PUT, потому что PUT требует отправки всех полей сущности по спецификации HTTP, а PATCH как раз нужен для частичного обновления. Для отображения заметки нам ещё нужен эндпоинт /api/notes/:uuid/files с методами POST и GET. Также нам нужно скачивать файл, поэтому сделаем метод GET на URL /api/files/:uuid.

Структура репозитория системы


Ещё немного общей информации. Структура репозитория всей системы будет выглядеть следующим образом:

В директории app будет исходный код сервиса (если он будет). На уровне с app будут другие директории других продуктов, которые используются с этим сервисом, например, MongoDB или ELK. Продукты, которые будут использоваться на уровне всей системы, например, Consul, будут в отдельных директориях на уровне с сервисами.


Разработка сервиса


Писать будем на Go


- Идём на официальный сайт.

- Копируем ссылку до архива, скачиваем, проверяем хеш-сумму.

- Распаковываем и добавляем в переменную PATH путь до бинарников Go

- Пишем небольшой тест проверки работоспособности, собираем бинарник и запускаем.


Установка завершена, всё работает


Теперь создаём проект. Структура стандартная:

- build — для сборок,

- cmd — точка входа в приложение,

- internal — внутренняя бизнес-логика приложения,

- pkg — для кода, который можно переиспользовать из проекта в проект.


Я очень люблю логировать ход работы приложения, поэтому перенесу свою обёртку над логером logrus из другого проекта. Основная функция здесь Init, которая создает логер, папку logs и в ней файл all.log со всеми логами. Кроме файла логи будут выводиться в STDOUT. Также в пакете реализована поддержка логирования в разные файлы с разным уровнем логирования, но в текущем проекте мы это использовать не будем.


APIService будет работать на сокете. Создаём роутер, затем файл с сокетом и начинаем его слушать. Также мы хотим перехватывать от системы сигналы завершения работы. Например, если кто-то пошлёт приложению сигнал SIGHUP, приложение должно корректно завершиться, закрыв все текущие соединения и сессии. Хотел перехватывать все сигналы, но линтер предупреждает, что os.Kill и SIGSTOP перехватить не получится, поэтому их удаляем из этого списка.


Теперь давайте добавим сразу стандартный handler для метрик. Я его копирую в директорию pkg, далее добавляю в роутер. Все последующие роутеры будем добавлять так же.

Далее создаём точку входа в приложение. В директории cmd создаём директорию main, а в ней — файл app.go. В нём мы создаём функцию main, в которой инициализируем и создаём логер. Роутер создаём через ключевое слово defer, чтобы метод Init у роутера вызвался только тогда, когда завершится функция main. Таким образом можно выполнять очистку ресурсов, закрытие контекстов и отложенный запуск методов. Запускаем, проверяем логи и сокет, всё работает.

Но для разработки нам нужно запускать приложение на порту, а не на сокете. Поэтому давайте добавим запуск приложения на порту в наш роутер. Определять, как запускать приложение, мы будем с помощью конфига.


Создадим для приложения контекст. Сделаем его синглтоном при помощи механизма sync.Once. Пока что в нём будет только конфиг. Контекст в виде синглтона создаю исключительно в учебных целях, впоследствии он будет выпилен. В большинстве случаев синглтоны — необходимое зло, в нашем проекте они не нужны. Далее создаём конфиг. Это будет YAML-файл, который мы будем парсить в структуру.


В роутере мы вытаскиваем из контекста конфиг и на основании listen.type либо создаем сокет, либо вешаем приложение на порт. Код graceful shutdown выделяем в отдельный пакет и передаём на вход список сигналов и список интерфейсов io.Close, которые надо закрывать. Запускаем приложение и проверяем наш эндпоинт heartbeat. Всё работает. Давайте и конфиг сделаем синглтоном через механизм sync.Once, чтобы потом безболезненно удалить контекст, который создавался в учебных целях.


Теперь переходим к API. Создаём эндпоинты, полученные при анализе прототипов интерфейса. Тут важно отметить, что у нас все данные привязаны к пользователю. На первый взгляд, все ручки должны начинаться с пользователя и его идентификатора /api/users/:uuid. Но у нас будет авторизация, иначе любой пользователь сможет программно запросить заметки любого другого пользователя. Авторизацию можно сделать следующим образом: Basic Auth, Digest Auth, JSON Web Token, сессии и OAuth2. У всех способов есть свои плюсы и минусы. Для этого проекта мы возьмём JSON Web Token.


Работа с JSON Web Token


JSON Web Token (JWT) — это JSON-объект, который определён в открытом стандарте RFC 7519. Он считается одним из безопасных способов передачи информации между двумя участниками. Для его создания необходимо определить заголовок (header) с общей информацией по токену, полезные данные (payload), такие как id пользователя, его роль и т.д., а также подписи (signature).


JWT использует преимущества подхода цифровой подписи JWS (Signature) и кодирования JWE (Encrypting). Подпись не даёт кому-то подделать токен без информации о секретном ключе, а кодирование защищает от прочтения данных третьими лицами. Давайте разберёмся, как они могут нам помочь для аутентификации и авторизации пользователя.


Аутентификация — процедура проверки подлинности. Мы проверяем, есть ли пользователь с полученной связкой логин-пароль в нашей системе.


Авторизация — предоставление пользователю прав на выполнение определённых действий, а также процесс проверки (подтверждения) данных прав при попытке выполнения этих действий.

Другими словами, аутентификация проверяет легальность пользователя. Пользователь становится авторизированным, если может выполнять разрешённые действия.


Важно понимать, что использование JWT не скрывает и не маскирует данные автоматически. Причина использования JWT — проверка, что отправленные данные были действительно отправлены авторизованным источником. Данные внутри JWT закодированы и подписаны, но не зашифрованы. Цель кодирования данных — преобразование структуры. Подписанные данные позволяют получателю данных проверить аутентификацию источника данных.


Реализация JWT в нашем APIService:

- Создаём директории middleware и jwt, а также файл jwt.go.

- Описываем кастомные UserClaims и сам middlware.

- Получаем заголовок Authorization, оттуда берём токен.

- Берём секрет из конфига.

- Создаём верификатор HMAC.

- Парсим и проверяем токен.

- Анмаршалим полученные данные в модель UserClaims.

- Проверяем, что токен валидный на текущий момент.


При любой ошибке отдаём ответ с кодом 401 Unauthorized. Если ошибок не было, в контекст сохраняем ID пользователя в параметр user_id, чтобы во всех хендлерах его можно было получить. Теперь надо этот токен сгенерировать. Это будет делать хендлер авторизации с методом POST и эндпоинтом /api/auth. Он получает входные данные в виде полей username и password, которые мы описываем отдельной структурой user. Здесь также будет взаимодействие с UserService, нам надо там искать пользователя по полученным данным. Если такой пользователь есть, то создаём для него UserClaims, в которых указываем все нужные для нас данные. Определяем время жизни токена при помощи переменной ExpiresAt — берём текущее время и добавляем 15 секунд. Билдим токен и отдаём в виде JSON в параметре token. Клиента к UserService у нас пока нет, поэтому делаем заглушку.


Добавим в хендлер с heartbeat еще один тестовый хендлер, чтобы проверить работу аутентификации. Пишем небольшой тест. Для этого используем инструмент sketch, встроенный в IDE. Делаем POST-запрос на /api/auth, получаем токен и подставляем его в следующий запрос. Получаем ответ от эндпоинта /api/heartbeat, по истечении 5 секунд мы начнём получать ошибку с кодом 401 Unauthorized.


Наш токен действителен очень ограниченное время. Сейчас это 15 секунд, а будет минут 30. Но этого всё равно мало. Когда токен протухнет, пользователю необходимо будет заново авторизовываться в системе. Это сделано для того, чтобы защитить пользовательские данные. Если злоумышленник украдет токен авторизации, который будет действовать очень большой промежуток времени или вообще бессрочно, то это будет провал.


Чтобы этого избежать, прикрутим refresh-токен. Он позволит пересоздать основной токен доступа без запроса данных авторизации пользователя. Такие токены живут очень долго или вообще бессрочно. После того как только старый JWT истекает мы больше не можем обратиться к API. Тогда отправляем refresh-токен. Нам приходит новая пара токена доступа и refresh-токена.

Хранить refresh-токены на сервере мы будем в кэше. В качестве реализации возьмём FreeCache. Я использую свою обёртку над кэшем из другого проекта, которая позволяет заменить реализацию FreeCache на любую другую, так как отдает интерфейс Repository с методами, которые никак не связаны с библиотекой.


Пока рассуждал про кэш, решил зарефакторить существующий код, чтобы было удобней прокидывать объекты без dependency injection и синглтонов. Обернул хендлеры и роутер в структуры. В хендлерах сделал интерфейс с методом Register, которые регистрируют его в роутере. Все объекты теперь инициализируются в main, весь роутер переехал в мейн. Старт приложения выделили в отдельную функцию также в main-файле. Теперь, если хендлеру нужен какой-то объект, я его просто буду добавлять в конструктор структуры хендлера, а инициализировать в main. Плюс появилась возможность прокидывать всем хендлерам свой логер. Это будет удобно когда надо будет добавлять поле trace_id от Zipkin в строчку лога.

Вернемся к refresh_token. Теперь при создании токена доступа создадим refresh_token и отдадим его вместе с основным. Сделаем обработку метода PUT для эндпоинта /api/auth, а в теле запроса будем ожидать параметр refresh_token, чтобы сгенерировать новую пару токена доступа и refresh-токена. Refresh-токен мы кладём в кэш в качестве ключа. Значением будет user_id, чтобы по нему можно было запросить данные пользователя у UserService и сгенерировать новый токен доступа. Refresh-токен одноразовый, поэтому сразу после получения токена из кэша удаляем его.


Описание API


Для описания нашего API будем использовать спецификацию OpenAPI 3.0 и Swagger — YAML-файл, который описывает все схемы данных и все эндпоинты. По нему очень легко ориентироваться, у него приятный интерфейс. Но описывать вручную всё очень муторно, поэтому лучше генерировать его кодом.


- Создаём эндпоинты /api/auth с методами POST и PUT для получения токена по юзернейму и паролю и по Refresh-токену соответственно.

- Добавляем схемы объектов Token и User.

- Создаём эндпоинты /api/users с методом POST для регистрации нового пользователя. Для него создаём схему CreateUser.


Понимаем, что забыли сделать хендлер для регистрации пользователя. Создаём метод Signup у хенлера Auth и структуру newUser со всеми полями для регистрации. Генерацию JWT выделяем в отдельный метод, чтобы можно было его вызывать как в Auth, так и в Signup-хендлерах. У нас всё еще нет UserService, поэтому проставляем TODO. Нам надо будет провалидировать полученные данные от пользователя и потом отправить их в UserService, чтобы он уже создал пользователя и ответил нам об успехе. Далее вызываем функцию создания пары токена доступа и refresh-токена и отдаём с кодом 201.


У нас есть подсказка в виде Swagger-файла. На его основе создаём все нужные хендлеры. Там, где вызов микросервисов, будем проставлять комментарий с TODO.


Создаём хендлер для категорий, определяем URL в константах. Далее создаём структуры. Опираемся на Swagger-файл, который создали ранее. Далее создаём сам хендлер и реализуем метод Register, который регистрирует его в роутере. Затем создаём методы с логикой работы и сразу пишем тест API на этот метод. Проверяем, находим ошибки в сваггере. Таким образом мы создаём все методы по работе с категориями: получение и создание.


Далее создаём таким же образом хендлер для заметок. Понимаем, что забыли методы частичного обновления и удаления как для заметок, так и для категорий. Дописываем их в Swagger и реализуем методы в коде. Также обязательно тестируем Swagger в онлайн-редакторе.

Здесь надо обратить внимание на то, что методы создания сущности возвращают код ответа 201 и заголовок Location, в котором находится URL для получения сущности. Оттуда можно вытащить идентификатор созданной сущности.


В третьей части мы познакомимся с графовой базой данных Neo4j, а также будем работать над микросервисами CategoryService и APIService.

Показать полностью 5
[моё] API Программирование Golang Python Mockup Rest Видео Длиннопост
4
47
wegdrt34

История одной интеграции с API служб доставки. Деловые линии⁠⁠

4 года назад

Немного айтишного нытья вам в ленту, из рубрики "Пригорело".


У меня есть небольшой интернет-магазин.


И, владея некоторыми навыками программирования в 1С, решил немного подкрутить себе конфигурацию, чтобы иметь возможность делать заказы в службе доставки и отслеживать статусы. Бог мой, я не знал, во что я влезаю. Я был радостным и жизнерадостным ребенком 30 лет, почему меня никто не предупредил, что я поседею и начну трястись при одной мысли об IT?


Я решил начать с Деловых Линий. Самые популярные потому что. Богатенькие, заказали всё у специализированной конторы, биатех.  Сходил, почитал их документацию на dev.dellin.ru, вроде с первого взгляда все понятно, приступил. Меня обнадеживал тот факт, что адреса у меня уже к тому моменту в базе сохранялись с УИДами адресных объектов согласно базе ФИАС.


Ну, думаю, ключевые данные у меня уже есть, остальное раз плюнуть. Что мне нужно клиенту? Калькулятор это потом, для начала мне надо вообще определить, есть ли по адресу клиента терминалы деловых. Казалось бы, чего проще, адрес есть, УИД ФИАС есть. Пишу запрос к АПИ. И тут....


Проблема 1. Нельзя получить терминалы в городе по УИД ФИАС. Нельзя получить и терминалы по коду КЛАДР. Нельзя вообще никак получить терминалы, кроме как одним огромным куском JSON. Гм......

А, я догадался. Вы хотите, чтобы я хранил все терминалы у себя, и не дергал сервер каждый раз. Отлично. Завожу у себя в БД таблицу, начинаю парсинг JSON.


Проблема 2. В файле нет никакого указания на то, что это за город, кроме двух(!!!) их внутренних ID и КЛАДР.


КЛАДР, в 21 веке? Неподдерживаемый уже давно, устаревший и прочая... Вы серьезно? Ну.... хрен с вами. Наверное где-то можно список какой-то получить, да?


Да. Нашел метод. Он возвращает... Что? JSON? Нет, что вы. Ссылку. А по ней - файл в формате CSV....

Пишу парсер, чтобы получать адресный объект по КЛАДР.

И....


Проблема 3. У ник какие-то свои коды КЛАДР.

WTF???? Свои коды? Твою ж мать, как мне город чертов ваш получить, где терминал ваш гребаный расположен?


Ну ок. Наверняка есть справочник городов, да? Нашел, действительно есть. Пишу запрос к API. Он возвращает.... Что? JSON? Нет. XML? Опять нет. Он возвращает URL. На файл в формате CSV:

Ну хрен с ним. Качаю файл с городами, начинаю парсинг. Всего 4 поля.


Фак. Этого явно недостаточно. В России многие города существуют в десятках версий. Например есть как минимум 2 Кирова, множество Алексеевок и т.п. Охрененный справочник. Как сопоставить-то их города с настоящими? Наверное есть еще что-то?


Ищу. Есть.


Ну конечно, разработчики позаботились. Еще один файл на 40 Мб, все деревня и веси, несколько сотен тысяч записей. 7 полей, в том числе ID и КЛАДР. Окей, пишу запрос, качаю, готовлюсь сшивать два файла в одну таблицу по полю кладр. Иииии......

Проблема 4. В этих файлах РАЗНЫЕ коды кладр. Разной длины, и вполне возможно что разные и не только по длине. Так как они какие-то их там собственные внутренние. Ааааааа четыреждылядская ярость, да как так-то? Зачем вам 2 разных кода КЛАДР?

Ну хорошо, сошьем по ИДшнику. И.....


Проблема 5. А вот хрен там. Это разные ИДшники. В одной таблице ИДшник - числовой, во второй - строка УИД. УИД? Откуда он там сссука? Что он вообще там делает? Зачем их столько разных? Как сшить ваши две сраные таблицы?

Как, господа из биатека? Кааак сцуко вы могли наплодить столько бесполезных полей(3 ИДшника и 2 кода КЛАДР - пять!!!! полей для идентификации адресного объекта. И вроде как все должны быть уникальными), и так по-ублюдски спроектировать API, чтобы для создания локальной копии терминалов надо было заниматься вот таким вот?


сокращу свое нытье. В общем, еще два дня я трахался с их API.


1) Нет никакой возможности определить надежно адресный объект(населенный пункт), где расположен тот или иной терминал. База ФИАС уже много лет лежит и обновляется, но у биатека свой глобус пилять. Нафига давать клиенту эту информацию, да? Главное что мы в биатеке знаем, и хорошо.


2) невозможно даже просто получить нормальный список городов, где расположены терминалы. Списки приходят, но определить город при парсинге однозначно невозможно.


3) Куча ошибок в координатах. Из-за чего использование геокодера яндекса мне не помогло в коррекции ошибок


4) в апи заявлен функционал поиска по адресам - он, ну естественно, не работает. Вообще. То есть "Москва, ул. Ленина, д. 1, кв. 10" ищет, а "Москва, ул. Ленина, д. 1, оф. 10" - нет. И делай что хочешь


По итогам: API (именно в роли API) - нерабочий.


Работать начинает только если ты каким-то образом умудрился получить копию справочников себе однажды без ошибок.


Я не знаю, сколько руководство Деловых башляет биатеку, но за такое по сути практически нерабочее говно с них еще и денег брать надо, вы лишаете своих клиентов возможности нормально работать по API и снижать операционные затраты.

Показать полностью 7
[моё] IT Интеграция API 1С Деловые Линии Бесит Рукожоп Длиннопост
25
Посты не найдены
О нас
О Пикабу Контакты Реклама Сообщить об ошибке Сообщить о нарушении законодательства Отзывы и предложения Новости Пикабу Мобильное приложение RSS
Информация
Помощь Кодекс Пикабу Команда Пикабу Конфиденциальность Правила соцсети О рекомендациях О компании
Наши проекты
Блоги Работа Промокоды Игры Курсы
Партнёры
Промокоды Биг Гик Промокоды Lamoda Промокоды Мвидео Промокоды Яндекс Маркет Промокоды Пятерочка Промокоды Aroma Butik Промокоды Яндекс Путешествия Промокоды Яндекс Еда Постила Футбол сегодня
На информационном ресурсе Pikabu.ru применяются рекомендательные технологии