| # Console API base URL | # Console API base URL | ||||
| CONSOLE_API_URL=http://127.0.0.1:5001 | CONSOLE_API_URL=http://127.0.0.1:5001 | ||||
| # Console frontend web base URL | |||||
| CONSOLE_WEB_URL=http://127.0.0.1:3000 | CONSOLE_WEB_URL=http://127.0.0.1:3000 | ||||
| # Service API base URL | # Service API base URL | ||||
| SERVICE_API_URL=http://127.0.0.1:5001 | SERVICE_API_URL=http://127.0.0.1:5001 | ||||
| # Web APP API base URL | |||||
| # Web APP base URL | |||||
| APP_API_URL=http://127.0.0.1:5001 | APP_API_URL=http://127.0.0.1:5001 | ||||
| # Web APP frontend web base URL | |||||
| APP_WEB_URL=http://127.0.0.1:3000 | APP_WEB_URL=http://127.0.0.1:3000 | ||||
| # celery configuration | # celery configuration |
| ```bash | ```bash | ||||
| flask db upgrade | flask db upgrade | ||||
| ``` | ``` | ||||
| ⚠️ If you encounter problems with jieba, for example | |||||
| ``` | |||||
| > flask db upgrade | |||||
| Error: While importing 'app', an ImportError was raised: | |||||
| ``` | |||||
| Please run the following command instead. | |||||
| ``` | |||||
| pip install -r requirements.txt --upgrade --force-reinstall | |||||
| ``` | |||||
| 6. Start backend: | 6. Start backend: | ||||
| ```bash | ```bash | ||||
| flask run --host 0.0.0.0 --port=5001 --debug | flask run --host 0.0.0.0 --port=5001 --debug | ||||
| ``` | ``` | ||||
| 7. Setup your application by visiting http://localhost:5001/console/api/setup or other apis... | 7. Setup your application by visiting http://localhost:5001/console/api/setup or other apis... | ||||
| 8. If you need to debug local async processing, you can run `celery -A app.celery worker -Q dataset,generation,mail`, celery can do dataset importing and other async tasks. | |||||
| 8. If you need to debug local async processing, you can run `celery -A app.celery worker -Q dataset,generation,mail`, celery can do dataset importing and other async tasks. | |||||
| 8. Start frontend: | |||||
| ``` | |||||
| docker run -it -d --platform linux/amd64 -p 3000:3000 -e EDITION=SELF_HOSTED -e CONSOLE_URL=http://127.0.0.1:5000 --name web-self-hosted langgenius/dify-web:latest | |||||
| ``` | |||||
| This will start a dify frontend, now you are all set, happy coding! |
| class PassportResource(Resource): | class PassportResource(Resource): | ||||
| """Base resource for passport.""" | """Base resource for passport.""" | ||||
| def get(self): | def get(self): | ||||
| app_id = request.headers.get('X-App-Code') | |||||
| if app_id is None: | |||||
| app_code = request.headers.get('X-App-Code') | |||||
| if app_code is None: | |||||
| raise Unauthorized('X-App-Code header is missing.') | raise Unauthorized('X-App-Code header is missing.') | ||||
| # get site from db and check if it is normal | # get site from db and check if it is normal | ||||
| site = db.session.query(Site).filter( | site = db.session.query(Site).filter( | ||||
| Site.code == app_id, | |||||
| Site.code == app_code, | |||||
| Site.status == 'normal' | Site.status == 'normal' | ||||
| ).first() | ).first() | ||||
| if not site: | if not site: | ||||
| "iss": site.app_id, | "iss": site.app_id, | ||||
| 'sub': 'Web API Passport', | 'sub': 'Web API Passport', | ||||
| 'app_id': site.app_id, | 'app_id': site.app_id, | ||||
| 'app_code': app_code, | |||||
| 'end_user_id': end_user.id, | 'end_user_id': end_user.id, | ||||
| } | } | ||||
| from werkzeug.exceptions import NotFound, Unauthorized | from werkzeug.exceptions import NotFound, Unauthorized | ||||
| from extensions.ext_database import db | from extensions.ext_database import db | ||||
| from models.model import App, EndUser | |||||
| from models.model import App, EndUser, Site | |||||
| from libs.passport import PassportService | from libs.passport import PassportService | ||||
| def validate_jwt_token(view=None): | def validate_jwt_token(view=None): | ||||
| if auth_scheme != 'bearer': | if auth_scheme != 'bearer': | ||||
| raise Unauthorized('Invalid Authorization header format. Expected \'Bearer <api-key>\' format.') | raise Unauthorized('Invalid Authorization header format. Expected \'Bearer <api-key>\' format.') | ||||
| decoded = PassportService().verify(tk) | decoded = PassportService().verify(tk) | ||||
| app_code = decoded.get('app_code') | |||||
| app_model = db.session.query(App).filter(App.id == decoded['app_id']).first() | app_model = db.session.query(App).filter(App.id == decoded['app_id']).first() | ||||
| site = db.session.query(Site).filter(Site.code == app_code).first() | |||||
| if not app_model: | if not app_model: | ||||
| raise NotFound() | raise NotFound() | ||||
| if not app_code and not site: | |||||
| raise Unauthorized('Site URL is no longer valid.') | |||||
| if app_model.enable_site is False: | if app_model.enable_site is False: | ||||
| raise Unauthorized('Site is disabled.') | raise Unauthorized('Site is disabled.') | ||||
| end_user = db.session.query(EndUser).filter(EndUser.id == decoded['end_user_id']).first() | end_user = db.session.query(EndUser).filter(EndUser.id == decoded['end_user_id']).first() |