diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..90f8fbb --- /dev/null +++ b/.gitignore @@ -0,0 +1,176 @@ +# Created by https://www.toptal.com/developers/gitignore/api/python +# Edit at https://www.toptal.com/developers/gitignore?templates=python + +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +### Python Patch ### +# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration +poetry.toml + +# ruff +.ruff_cache/ + +# LSP config files +pyrightconfig.json + +# End of https://www.toptal.com/developers/gitignore/api/python \ No newline at end of file diff --git a/README.md b/README.md index e734019..3962e92 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,96 @@ -# UE-AD-A1-REST +# Introduction -test +This Repo contains the Practical work on REST and FLASK + +## Installation + +### 1. With a docker container + +If docker is installed on your computer, you must : + +1. clone the github repository +2. open a cmd +3. go into the repository using + + ```bash + cd path/to/your/repository + ``` + +4. open the docker app to start the kernel +5. run + + ``` + docker-compose up --build + ``` + +### 2. Without a docker container + +If you don't have docker on your computer, you can : + +1. clone the github repository +2. open a 4 cmd +3. go into the repository using + + ```bash + cd path/to/your/repository + ``` + +4. go into showtimes using + + ```bash + cd ./showtime + ``` + +5. then, to launch the service, use + + ```bash + python showtime.py + ``` + +6. repeat in a different cmd for user, movie and booking + +## What we did + +We suceeded to finish the integrality of what was asked in this pratical work. Moreover, we add enough time to complexify a +the services Movies, Bookings and User. Let's see what we add in each service : + +### Movies + +As explained before we suceeded to produce a service movie which respects what was ask in the practical work. +Furthemore, we added few entry points which were not asked : + +1. _/help_ which gives all the entries available in the service movie + +2. _/directors_ which returns all the **directors** of the movies available + +3. _/directors/<**movie_id**>/<**director_name**>_ which change the **director** of the movie with the id **movie_id** + +4. _/movies_per_ratings_ which returns the list of the movies available \*sorted by **decreasing rate\*** + +5. _/movieid_linked_movietitle_ which returns a dict python which associates an **id** to a **movie name** (used in **User**) + +We also added few **error code** to our service. + +### Bookings + +Same as above : + +1. _/bookings/<**userid**>_ which change a little. Here decided to not throw and error and take account of the case when the _user isn't in the database_, when _the user is in the database and there isn't any bookings at the date_ given and finally when _the user is in the database and the date exists but the movie wasn't booked at this date_. + +2. _/movies_at_the_date/<**date**>_ which calls the service showtime and return all the movies available at the date **date** + +### User + +We decided to deem this service as our frontend so all the entry points returns a html page associated with a template located in the folder _/templates_. + +Moreover, we decided to suppose that user of this service give only his name and not his id. Thus we convert his name into an id thanks to the user.json database + +Let's see what is able **User** : + +1. _/movies_per_ratings_ : It is able to show the list of the movies available calling **Movies**. + +2. _/movies_available/<**date**>_ : By calling **Movies** (to get the names of the movies) and **Bookings**, this service can show the name of the movies available at **date**. + +3. _/book_a_movie_ : this entry call **Booking** to book a movie at the specified date. It needs to also call **Movies** because the user gives the name of the movie and we need the id of the movie + +4. _/booking_made/<**username**>_ : It calls **Booking** to get all the bookings made by the user **username** diff --git a/booking/Dockerfile b/booking/Dockerfile index df84401..360a96a 100644 --- a/booking/Dockerfile +++ b/booking/Dockerfile @@ -3,4 +3,4 @@ WORKDIR /app COPY requirements.txt /app RUN pip install -r requirements.txt ADD . /app/ -CMD ["python","-u","booking.py"] +CMD ["python","-u","booking.py","docker"] diff --git a/booking/UE-archi-distribuees-Booking-1.0.0-resolved.yaml b/booking/UE-archi-distribuees-Booking-1.0.0-resolved.yaml index b53555c..cc1e86a 100644 --- a/booking/UE-archi-distribuees-Booking-1.0.0-resolved.yaml +++ b/booking/UE-archi-distribuees-Booking-1.0.0-resolved.yaml @@ -99,8 +99,37 @@ paths: application/json: schema: $ref: '#/components/schemas/BookingsUser' + "201": + description: 'bad input parameter' + "400": + description: 'Wrong input"' "409": description: an existing item already exists + /movies_at_the_date/{date}: + get: + tags: + - admins + - developers + summary: get all the bookings available at the date date + description: Contact the API Times to get all the bookings available at the date date + operationId: get_movie_at_date + parameters: + - name: date + in: path + description: date of the booking + required: true + style: simple + schema: + type: string + responses: + "200": + description: Boonkings returned + content: + application/json: + schema: + $ref: '#/components/schemas/Schedule' + "400": + description: There was a problem with the request components: schemas: AllBookings: @@ -146,3 +175,17 @@ components: movieid: type: string example: 276c79ec-a26a-40a6-b3d3-fb242a5947b6 + Schedule: + required: + - date + - movies + type: object + properties: + date: + type: string + example: "20151130" + movies: + type: array + items: + type: string + example: 720d006c-3a57-4b6a-b18f-9b713b073f3c diff --git a/booking/booking.py b/booking/booking.py index 267e439..54663bb 100644 --- a/booking/booking.py +++ b/booking/booking.py @@ -1,21 +1,109 @@ from flask import Flask, render_template, request, jsonify, make_response import requests import json +import sys from werkzeug.exceptions import NotFound app = Flask(__name__) PORT = 3201 HOST = '0.0.0.0' +PATH_TIMES:str = "http://localhost:3202" with open('{}/databases/bookings.json'.format("."), "r") as jsf: bookings = json.load(jsf)["bookings"] @app.route("/", methods=['GET']) def home(): - return "

Welcome to the Booking service!

" + """This function return the homepage of the API booking""" + return make_response("

Welcome to the Booking service!

",200) +@app.route("/bookings",methods=["GET"]) +def get_json(): + """This function return all the movie's reservations""" + return make_response(jsonify(bookings),200) + +@app.route("/bookings/",methods=["GET"]) +def get_booking_for_user(userid:str): + """This function get all the bookings made by the user user_id """ + for reservation in bookings: + if userid == reservation["userid"]: # We found the good user + return make_response({"dates":reservation["dates"],"userid":userid},200) + # We didn't find the user so we return an error + return make_response(jsonify({"error": "bad input parameter"}),400) + +@app.route("/bookings/",methods=["POST"]) +def add_booking_byuser(userid:str): + """This function adds a booking at the bookings made by the user user_id""" + # We check if the user gave a new movie + + if request.args: + req = request.args + # Firstly we check if the movie is available at the date req["date"] + # We get the movies wich will be projected at the date req["date"] + movies_available_response = requests.request('GET', PATH_TIMES + "/showmovies" + "/" + req["date"] ) + # The date doesn't exist + if movies_available_response.status_code == 400: + return make_response(jsonify({"error": "bad input parameter"}),201) + else: + # The movie ins't projected + if req["movieid"] not in movies_available_response.json()["movies"]: + return make_response(jsonify({"error": "bad input parameter"}),201) + for reservation in bookings: + if userid == reservation["userid"]: # We found the good user + for date in reservation["dates"]: + if date["date"] == req["date"] : + # We need to check if the user didn't already book this movie + if req["movieid"] in date["movies"]: + return make_response(jsonify({"error": "an existing item already exists"}),409) + else: + # We add the movie + date["movies"].append(req["movieid"]) + # We write in the database + write(bookings) + + res = make_response({"userid":userid,"dates": date["movies"]},200) # We return the bookings of the day we add a booking + return res + #It is a new date + reservation["dates"].append({"date":req["date"],"movies":[req["movieid"]]}) + # We write in the database + write(bookings) + # We return the bookings of the day we add a booking + res = make_response({"userid":userid,"dates":[{"date":req["date"],"movies":[req["movieid"]]}]},200) + return res + + # We didn't find the user so we need to add this user to our database + bookings.append({ + "userid":userid, + "dates": [{ + "date":req["date"], + "movies":[req["movieid"]] + }] + }) + # We write in the database + write(bookings) + return make_response({"userid":userid,"dates":[{"date":req["date"],"movies":[req["movieid"]]}]},200) + return make_response(jsonify({"error": "Wrong input"}),400) + +@app.route("/movies_at_the_date/",methods=["GET"]) +def get_movie_at_date(date:str): + """This function will get all the movies available at the date date""" + # We ask the microservice times the movies available at date + req = requests.request("GET", PATH_TIMES + f"/showmovies/{date}") + if req.status_code == 200: + # We have gotten the id of the movies + return make_response(req.json(),200) + # The request failed + return make_response({"error":"There was a problem with the request"},400) + +def write(book): + with open('{}/databases/bookings.json'.format("."), 'w') as f: + + json.dump({"bookings" : book}, f) if __name__ == "__main__": print("Server running in port %s"%(PORT)) + if len(sys.argv) > 1 and sys.argv[1] == "docker": + print("Image loaded with docker") + PATH_TIMES = "http://showtime:3202" app.run(host=HOST, port=PORT) diff --git a/booking/databases/bookings.json b/booking/databases/bookings.json index 55e4853..b3dabbf 100644 --- a/booking/databases/bookings.json +++ b/booking/databases/bookings.json @@ -1,39 +1,51 @@ { - "bookings": [ - { - "userid": "chris_rivers", - "dates": [ + "bookings": [ { - "date": "20151201", - "movies": ["267eedb8-0f5d-42d5-8f43-72426b9fb3e6"] - } - ] - }, - { - "userid": "garret_heaton", - "dates": [ - { - "date": "20151201", - "movies": ["267eedb8-0f5d-42d5-8f43-72426b9fb3e6"] + "userid": "chris_rivers", + "dates": [ + { + "date": "20151201", + "movies": [ + "267eedb8-0f5d-42d5-8f43-72426b9fb3e6" + ] + } + ] }, { - "date": "20151202", - "movies": ["276c79ec-a26a-40a6-b3d3-fb242a5947b6"] - } - ] - }, - { - "userid": "dwight_schrute", - "dates": [ - { - "date": "20151201", - "movies": ["7daf7208-be4d-4944-a3ae-c1c2f516f3e6","267eedb8-0f5d-42d5-8f43-72426b9fb3e6"] + "userid": "garret_heaton", + "dates": [ + { + "date": "20151201", + "movies": [ + "267eedb8-0f5d-42d5-8f43-72426b9fb3e6" + ] + }, + { + "date": "20151202", + "movies": [ + "276c79ec-a26a-40a6-b3d3-fb242a5947b6" + ] + } + ] }, { - "date": "20151205", - "movies": ["a8034f44-aee4-44cf-b32c-74cf452aaaae","276c79ec-a26a-40a6-b3d3-fb242a5947b6"] + "userid": "dwight_schrute", + "dates": [ + { + "date": "20151201", + "movies": [ + "7daf7208-be4d-4944-a3ae-c1c2f516f3e6", + "267eedb8-0f5d-42d5-8f43-72426b9fb3e6" + ] + }, + { + "date": "20151205", + "movies": [ + "a8034f44-aee4-44cf-b32c-74cf452aaaae", + "276c79ec-a26a-40a6-b3d3-fb242a5947b6" + ] + } + ] } - ] - } - ] + ] } \ No newline at end of file diff --git a/movie/Dockerfile b/movie/Dockerfile index b539c89..05fa0ef 100644 --- a/movie/Dockerfile +++ b/movie/Dockerfile @@ -3,4 +3,4 @@ WORKDIR /app COPY requirements.txt /app RUN pip install -r requirements.txt ADD . /app/ -CMD ["python","-u","movie.py"] +CMD ["python","-u","movie.py","docker"] diff --git a/movie/UE-archi-distribuees-Movie-1.0.0-resolved.yaml b/movie/UE-archi-distribuees-Movie-1.0.0-resolved.yaml index 73dfb68..6d26e78 100644 --- a/movie/UE-archi-distribuees-Movie-1.0.0-resolved.yaml +++ b/movie/UE-archi-distribuees-Movie-1.0.0-resolved.yaml @@ -2,7 +2,6 @@ openapi: 3.0.3 info: title: Movie API - summary: This is the API of the Movie service description: This is the API of the Movie service, it should be much much much much much much much much much much much much much much much much much much much much much longer contact: name: Helene Coullon @@ -173,12 +172,80 @@ paths: schema: maximum: 10 minimum: 0 - type: integer + type: number responses: "200": description: rate updated "400": description: movie ID not found + /help: + get: + tags: + - admins + - developers + summary: give all the entries of this microservice + description: give all the entries of this microservice + operationId: help + responses: + "200": + description: return JSON + /movies_per_ratings: + get: + tags: + - developers + summary: gives the list of the movies sorted by decreasing rate + description: gives the list of the movies sorted by decreasing rate + operationId: get_movies_classify_per_ratings + responses: + "200": + description: Return a MovieList + content: + application/json: + schema: + $ref: '#/components/schemas/MovieList' + /directors: + get: + tags: + - developers + summary: gives all the directors who have directed a movie + description: gives all the directors who have directed a movie + operationId: get_directors + responses: + "200": + description: return an object + content: + application/json: + schema: + $ref: '#/components/schemas/DirectorList' + /directors/{movie_id}{director_name}: + put: + tags: + - developers + summary: change the director of the movie movie_id + description: change the director of the movie movie_id + operationId: update_director_movie + parameters: + - name: director_name + in: path + description: director name + required: true + style: simple + explode: false + schema: + type: string + - name: movie_id + in: path + description: movie id + required: true + style: simple + explode: false + schema: + type: string + responses: + "200": + description: return a HTML page + "400": + description: director not found components: schemas: AllMovies: @@ -211,5 +278,20 @@ components: id: type: string example: 39ab85e5-5e8e-4dc5-afea-65dc368bd7ab + MovieList: + required: + - list_movies_sorted + properties: + list_movies_sorted: + type: array + example: [[7.8,"Peter Pan"],[4.1,"Spider man : Across the spidervers"]] + DirectorList: + required: + - list_directors + properties: + list_directors: + type: array + example: ["James Gun", "Steven Spielberg"] + diff --git a/movie/databases/movies.json b/movie/databases/movies.json index 260bc88..43ae81b 100644 --- a/movie/databases/movies.json +++ b/movie/databases/movies.json @@ -1,52 +1,52 @@ { - "movies": [ - { - "title": "The Good Dinosaur", - "rating": 7.4, - "director": "Peter Sohn", - "id": "720d006c-3a57-4b6a-b18f-9b713b073f3c" - }, - { - "title": "The Martian", - "rating": 8.2, - "director": "Ridley Scott", - "id": "a8034f44-aee4-44cf-b32c-74cf452aaaae" - }, - { - "title": "The Night Before", - "rating": 7.4, - "director": "Jonathan Levine", - "id": "96798c08-d19b-4986-a05d-7da856efb697" - }, - { - "title": "Creed", - "rating": 8.8, - "director": "Ryan Coogler", - "id": "267eedb8-0f5d-42d5-8f43-72426b9fb3e6" - }, - { - "title": "Victor Frankenstein", - "rating": 6.4, - "director": "Paul McGuigan", - "id": "7daf7208-be4d-4944-a3ae-c1c2f516f3e6" - }, - { - "title": "The Danish Girl", - "rating": 5.3, - "director": "Tom Hooper", - "id": "276c79ec-a26a-40a6-b3d3-fb242a5947b6" - }, - { - "title": "Spectre", - "rating": 7.1, - "director": "Sam Mendes", - "id": "39ab85e5-5e8e-4dc5-afea-65dc368bd7ab" - }, - { - "title": "Test", - "rating": 1.2, - "director": "Someone", - "id": "xxx" - } - ] + "movies": [ + { + "title": "The Good Dinosaur", + "rating": 7.4, + "director": "Peter Sohn", + "id": "720d006c-3a57-4b6a-b18f-9b713b073f3c" + }, + { + "title": "The Martian", + "rating": 8.2, + "director": "Ridley Scott", + "id": "a8034f44-aee4-44cf-b32c-74cf452aaaae" + }, + { + "title": "The Night Before", + "rating": 7.4, + "director": "Jonathan Levine", + "id": "96798c08-d19b-4986-a05d-7da856efb697" + }, + { + "title": "Creed", + "rating": 8.8, + "director": "Ryan Coogler", + "id": "267eedb8-0f5d-42d5-8f43-72426b9fb3e6" + }, + { + "title": "Victor Frankenstein", + "rating": 6.4, + "director": "Paul McGuigan", + "id": "7daf7208-be4d-4944-a3ae-c1c2f516f3e6" + }, + { + "title": "The Danish Girl", + "rating": 5.3, + "director": "Tom Hooper", + "id": "276c79ec-a26a-40a6-b3d3-fb242a5947b6" + }, + { + "title": "Spectre", + "rating": 7.1, + "director": "Sam Mendes", + "id": "39ab85e5-5e8e-4dc5-afea-65dc368bd7ab" + }, + { + "title": "Test", + "rating": 1.2, + "director": "Someone", + "id": "xxx" + } + ] } \ No newline at end of file diff --git a/movie/movie.py b/movie/movie.py index a0ddb16..50cce74 100644 --- a/movie/movie.py +++ b/movie/movie.py @@ -16,6 +16,137 @@ def home(): return make_response("

Welcome to the Movie service!

",200) +@app.route("/template", methods=['GET']) +def template(): + return make_response(render_template('index.html', body_text='This is my HTML template for Movie service'),200) + +@app.route("/json", methods=['GET']) +def get_json(): + res = make_response(jsonify(movies), 200) + return res + +@app.route("/movies/", methods=['GET']) +def get_movie_byid(movieid): + for movie in movies: + if str(movie["id"]) == str(movieid): + res = make_response(jsonify(movie),200) + return res + return make_response(jsonify({"error":"Movie ID not found"}),400) + +@app.route("/moviesbytitle", methods=['GET']) +def get_movie_bytitle(): + json = "" + print("request.args : ", request.args) + if request.args: + req = request.args + for movie in movies: + if str(movie["title"]) == str(req["title"]): + json = movie + + if not json: + res = make_response(jsonify({"error":"movie title not found"}),400) + else: + res = make_response(jsonify(json),200) + return res + +{ + "title": "Test", + "rating": 1.2, + "director": "Someone", + "id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx" +} + +@app.route("/addmovie/", methods=['POST']) +def add_movie(movieid): + req = request.get_json() + print("req : ", req) + for movie in movies: + if str(movie["id"]) == str(movieid): + return make_response(jsonify({"error":"movie ID already exists"}),409) + + movies.append(req) + write(movies) + res = make_response(jsonify({"message":"movie added"}),200) + return res + +@app.route("/movies//", methods=['PUT']) +def update_movie_rating(movieid, rate): + for movie in movies: + if str(movie["id"]) == str(movieid): + movie["rating"] = rate + res = make_response(jsonify(movie),200) + return res + + res = make_response(jsonify({"error":"movie ID not found"}),201) + return res + +@app.route("/movies/", methods=['DELETE']) +def del_movie(movieid): + for movie in movies: + if str(movie["id"]) == str(movieid): + movies.remove(movie) + return make_response(jsonify(movie),200) + + res = make_response(jsonify({"error":"movie ID not found"}),400) + return res + +def write(movies): + with open('{}/databases/movies.json'.format("."), 'w') as f: + + json.dump({"movies" : movies}, f) + +##################################### +##### ADDED ##### +##################################### +all_methods = { + "GET": ["/","/help","/template","/json","/movies/","/moviesbytitle","/movies_per_ratings","/directors"], + "POST": ["/addmovie/"], + "PUT": ["/movies//","/directors//"], + "DELETE": ["/movies/"] +} + +@app.route("/help",methods=["GET"]) +def help(): + return all_methods + +@app.route("/movies_per_ratings",methods=["GET"]) +def get_movies_classify_per_ratings(): + """Function which sort the movies by ratings""" + list_movies:list = [] + + # We get the list of movies associated with there ranking + for movie in movies: + list_movies.append([movie["rating"],movie["title"]]) + list_movies.sort(reverse=True) + return make_response({"list_movies_sorted":list_movies},200) + +@app.route("/directors",methods=["GET"]) +def get_all_directors(): + """This function get the directors of all movies""" + list_directors = [] + for movie in movies: + list_directors.append(movie["director"]) + return jsonify({"list_directors" : list_directors}) + +@app.route("/directors//",methods=["PUT"]) +def update_director_movie(director_name:str,movie_id:str): + """This function change the director name of the movie whixh has as id movie_id""" + for movie in movies: + if str(movie["id"])==movie_id: + movie["director"] = director_name + res = make_response(jsonify(movie),200) + return res + return make_response(jsonify({"error":"movie ID not found"}),201) + +@app.route("/movieid_linked_movietitle") +def get_movieid_linked_movie_title(): + """This function links the title of the movie and its id""" + dict_movie = {} + # We read the whole database and we link the name of the movie with its id + for movie in movies: + dict_movie[movie["id"]] = movie["title"] + return make_response(dict_movie,200) + if __name__ == "__main__": #p = sys.argv[1] print("Server running in port %s"%(PORT)) diff --git a/movie/test.py b/movie/test.py new file mode 100644 index 0000000..e289147 --- /dev/null +++ b/movie/test.py @@ -0,0 +1,3 @@ +l = [{"rate":6,"nom":"bidule"},{"rate":5,"nom":"machin"},{"rate":7,"nom":"truc"}] +l2 = sorted(l,key=lambda x:x["rate"]) +print(l2) \ No newline at end of file diff --git a/showtime/Dockerfile b/showtime/Dockerfile index 5a2de0c..acc875d 100644 --- a/showtime/Dockerfile +++ b/showtime/Dockerfile @@ -3,4 +3,4 @@ WORKDIR /app COPY requirements.txt /app RUN pip install -r requirements.txt ADD . /app/ -CMD ["python","-u","showtime.py"] +CMD ["python","-u","showtime.py", "docker"] diff --git a/showtime/showtime.py b/showtime/showtime.py index 6cf26fd..6834828 100644 --- a/showtime/showtime.py +++ b/showtime/showtime.py @@ -12,7 +12,25 @@ @app.route("/", methods=['GET']) def home(): - return "

Welcome to the Showtime service!

" + return make_response("

Welcome to the Showtime service!

",200) + +# Fonction pour retourner toute la base de données times : La liste des +# dates avec les films qui seraient projetés +@app.route("/showtimes", methods=['GET']) +def get_schedule(): + result = make_response({"schedule":schedule},200) + return result + +# Fonction pour retourner la liste des films projetés pour une date donnée +@app.route("/showmovies/", methods=['GET']) +def get_movies_bydate(date): + for showtime in schedule: + if str(showtime["date"]) == str(date): + result = make_response(jsonify(showtime),200) + return result + + return make_response(jsonify({"error":"Date not available"}),400) + if __name__ == "__main__": print("Server running in port %s"%(PORT)) diff --git a/user/Dockerfile b/user/Dockerfile index 44b96ef..84c870a 100644 --- a/user/Dockerfile +++ b/user/Dockerfile @@ -3,4 +3,4 @@ WORKDIR /app COPY requirements.txt /app RUN pip install -r requirements.txt ADD . /app/ -CMD ["python","-u","user.py"] +CMD ["python","-u","user.py", "docker"] diff --git a/user/UE-archi-distribuees-User-1.0.0.0.resolved.yaml b/user/UE-archi-distribuees-User-1.0.0.0.resolved.yaml new file mode 100644 index 0000000..85e99cf --- /dev/null +++ b/user/UE-archi-distribuees-User-1.0.0.0.resolved.yaml @@ -0,0 +1,171 @@ +openapi: 3.0.1 +info: + title: User API + version: 1.0.0 + description: API made to manage the request by the user + contact: + email: gabriel.bocquet@imt-atlantique.fr + license: + name: GPL v3 + url: https://www.gnu.org/licenses/gpl-3.0.en.html +tags: +- name: admins + description: Secured Admin-only calls +- name: developers + description: Operations available to regular developers +paths: + /: + get: + summary: Home page + tags: + - developers + description: Return a welome message + responses: + '200': + description: Welcome page + content: + text/html: + schema: + type: string + example: "

Welcome to the User service!

" + /movies_per_ratings: + get: + summary: return the movies sorted by decreasing rate + description: Get and return all the movies, sorted by decreasing rate + responses: + '200': + description: Html page which prints the movies sorted by decreasing rate + content: + text/html: + schema: + type: string + example: "
  • Film A : 4.5
  • Film B : 4.0
" + '400': + description: There was a problem during the request. + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /movies_available/{date}: + get: + summary: Get the moveis at the specified date + description: Print all the movies which can be booked at the date date + parameters: + - in: path + name: date + required: true + explode: false + style: simple + schema: + type: string + description: Date YYYYMMDD + responses: + '200': + description: HTML page which shows the movies available at the date date + content: + text/html: + schema: + type: string + example: "
  • Film A
  • Film B
" + '400': + description: There was a problem during the request + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /book_a_movie: + post: + summary: Book a movie + description: Book a movie for the user at the specified date + requestBody: + description: Informations needed + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/BookingRequest' + responses: + '200': + description: Booking successful + content: + text/html: + schema: + type: string + example: "

Example

" + '205': + description: Impossible to book the movie + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + example: + message: "We couldn't book the date, Sadge :'(" + '400': + description: Bad argument + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /booking_made/{username}: + get: + summary: Get the bookings made by the user + description: Get the bookings made by the user + parameters: + - in: path + name: username + required: true + schema: + type: string + description: Name of the user + responses: + '200': + description: HTML page which shows the bookings made by the user + content: + text/html: + schema: + type: string + example: "
  • 2024/04/30
    • Film A
" + '300': + description: The user name doesn't exist + content: + text/html: + schema: + type: string + example: "

The user john_doe doesn't exist

" + '301': + description: The user exists but have zero booking + content: + text/html: + schema: + type: string + example: "

Zero booking was made with the user john_doe

" +components: + schemas: + BookingRequest: + type: object + required: + - moviename + - date + - username + properties: + moviename: + type: string + description: Name of the movie which have to be booked. + example: Beetlejuice + date: + type: string + description: Date of the booking wanted YYYYMMDD. + example: "20240430" + username: + type: string + description: Name of the user who wants to book the movie + example: "john_doe" + Error: + type: object + required: + - error + properties: + error: + type: string + description: Error Message + example: "Bad argument" diff --git a/user/templates/add_a_booking.html b/user/templates/add_a_booking.html new file mode 100644 index 0000000..2c14e90 --- /dev/null +++ b/user/templates/add_a_booking.html @@ -0,0 +1,11 @@ + + + + + Movies booked + + +

The user {{username}} succeded to book: {{body_text}}

+ + + \ No newline at end of file diff --git a/user/templates/booking_made.html b/user/templates/booking_made.html new file mode 100644 index 0000000..82be55c --- /dev/null +++ b/user/templates/booking_made.html @@ -0,0 +1,10 @@ + + + + + Movies booked by the user + + +

The user {{username}} booked suceeded to book the movie wanted !

+ + \ No newline at end of file diff --git a/user/templates/error_get_booking_per_user.html b/user/templates/error_get_booking_per_user.html new file mode 100644 index 0000000..3b74206 --- /dev/null +++ b/user/templates/error_get_booking_per_user.html @@ -0,0 +1,10 @@ + + + + + Movies available + + +

Sorry...😢 Error {{error}} : {{body_text}}

+ + \ No newline at end of file diff --git a/user/templates/get_movies_available_at_date.html b/user/templates/get_movies_available_at_date.html new file mode 100644 index 0000000..2488d02 --- /dev/null +++ b/user/templates/get_movies_available_at_date.html @@ -0,0 +1,14 @@ + + + + + Movies available + + +

The ⌚ {{date}} , these movies are availables :

+

+

    {{ body_text | safe}}
+

+ + + \ No newline at end of file diff --git a/user/templates/movies_per_ratings.html b/user/templates/movies_per_ratings.html new file mode 100644 index 0000000..e865a86 --- /dev/null +++ b/user/templates/movies_per_ratings.html @@ -0,0 +1,14 @@ + + + + + Ranking of the best movies + + +

Movies sorted by rank

+ +
    {{ body_text | safe}}
+ + + + \ No newline at end of file diff --git a/user/templates/response_add_booking.html b/user/templates/response_add_booking.html new file mode 100644 index 0000000..19901d0 --- /dev/null +++ b/user/templates/response_add_booking.html @@ -0,0 +1,12 @@ + + + + Ranking of the best movies + + +

+

    ✅ The booking {{body_text}} was added !
+

+ + + \ No newline at end of file diff --git a/user/user.py b/user/user.py index 8a17e84..e28d521 100644 --- a/user/user.py +++ b/user/user.py @@ -2,11 +2,14 @@ import requests import json from werkzeug.exceptions import NotFound +import sys app = Flask(__name__) PORT = 3203 HOST = '0.0.0.0' +BOOKING_PATH="http://localhost:3201" +MOVIE_PATH="http://localhost:3200" with open('{}/databases/users.json'.format("."), "r") as jsf: users = json.load(jsf)["users"] @@ -15,7 +18,112 @@ def home(): return "

Welcome to the User service!

" +@app.route("/movies_per_ratings",methods=["GET"]) +def get_movies_per_ratings(): + """This function will get all the movies available sorted by rating""" + req = requests.request("GET", MOVIE_PATH +"/movies_per_ratings") + if req.status_code == 200: + list_movies = req.json()["list_movies_sorted"] + # We format the text to create a list in the html screen + body_text = "" + for elem in list_movies: + body_text += f"
  • {elem[1]} : {elem[0]}
  • \n" #elem[1] = movie_name & elem[2] = rating + return make_response(render_template('movies_per_ratings.html', body_text=body_text),200) + # The request failed + return make_response({"error": "There was a problem during the request"},400) + +@app.route("/movies_available/",methods=["GET"]) +def get_movies_available_at_date(date:str): + """This function shows what are the movies (their name) available at the date date""" + # We get the ids of the movies available + req = requests.request("GET", BOOKING_PATH + f"/movies_at_the_date/{date}") + if req.status_code==200: + # Now we get all the dict which link the movie id with their title + print("req.json() : ", req.json()) + req2 = requests.request("GET", MOVIE_PATH + "/movieid_linked_movietitle") + if req2.status_code == 200: + list_name = [] + dict_id_title = req2.json() # With this dict, we can convert an id into a title + print("dict_id_title : ", dict_id_title) + for movieid in req.json()["movies"]: + print("") + list_name.append(dict_id_title[movieid]) + body_text = "" + for elem in list_name: + body_text += f"
  • {elem}
  • \n" #elem[1] = movie_name & elem[2] = rating + print("body_text = ", body_text) + return make_response(render_template('get_movies_available_at_date.html',body_text=body_text,date=f"{date[0:4]}/{date[4:6]}/{date[6:]}")) + return make_response({"error":"There was a problem during the request"},400) + + return make_response({"error":"There was a problem during the request"},400) + +@app.route("/book_a_movie",methods=["POST"]) +def book_the_movie(): + if request.get_json(): + """This function books the movie name moviename for the user username""" + # We get the informations we want + request_json = request.get_json() + moviename, date, username = request_json["moviename"], request_json["date"],request_json["username"] + # We need to convert the moviename into a movie_id + req = requests.request("GET", MOVIE_PATH + "/movieid_linked_movietitle") + if req.status_code == 200: + print("Req a finit ") + dict_id_to_name = req.json() + # We seek the id corresponding to the title moviename + for key in dict_id_to_name.keys(): + if moviename == dict_id_to_name[key]: + # The id of the movie is key + new_movie = {"date":date,"movieid":key} + req2 = requests.request("POST",BOOKING_PATH + f"/bookings/{convert_username_id(username)}", + params=new_movie) + if req2.status_code==200: + print("movie name : ", moviename) + return make_response(render_template('booking_made.html',username=username),200) + else: + return make_response({"message":"We couldn't book the date, Sadge :'("},205) + return make_response({"error": "Bad argument"},400) + print("request.args : ", request) + return make_response({"error":"Bad argument"},400) + +@app.route("/booking_made/",methods=["GET"]) # TO DO : ajouter l'utilisateur au lieu de lever une erreur ??? +def get_booking_made(username:str): + """This function will get all the booking already made by username""" + # We check if the user is register in the user database + for user_registered in users: + if user_registered["name"] == username: + print("username : ", username) + # The user is in the database + # We ask the api booking to give us all the booking of username + req = requests.request("GET", BOOKING_PATH + "/bookings/" + convert_username_id(username)) #list_json + if req.status_code==200: + if len(req.json()["dates"]) > 0: + # The user made reservations + # We get the dict which allow us to convert the id into a movie title + req2 = requests.request("GET", MOVIE_PATH + "/movieid_linked_movietitle") # return a list + if req2.status_code == 200: + dict_id_to_name = req2.json() + body_text = "" + for elem in req.json()["dates"]: + body_text+= f"
  • The {elem['date'][0:4]}/{elem['date'][4:6]}/{elem['date'][6:]}: \n
      " + for movieid in elem["movies"]: + body_text += "
    • "+dict_id_to_name[movieid] + "
    • \n" + body_text += "
  • \n" + return make_response(render_template('booking_made.html',body_text=body_text,username=username)) + # If we are here, it means that the user didn't book any movies + return make_response(render_template('error_get_booking_per_user.html',body_text=f"Zero booking was made with the user {username}",error="301"),301) + return make_response(render_template('error_get_booking_per_user.html',body_text=f"The user {username} doesn't exist",error="300"),300) + +def convert_username_id(username:str): + """This get the id corresponding to the user username""" + for user in users: + if user["name"]==username: + return user["id"] + if __name__ == "__main__": print("Server running in port %s"%(PORT)) - app.run(host=HOST, port=PORT) + if len(sys.argv) > 1 and sys.argv[1] == "docker": + print("Image loaded with docker") + BOOKING_PATH = "http://booking:3201" + MOVIE_PATH = "http://movie:3200" + app.run(host=HOST, port=PORT) \ No newline at end of file diff --git a/venv1/Scripts/Activate.ps1 b/venv1/Scripts/Activate.ps1 new file mode 100644 index 0000000..953fd89 --- /dev/null +++ b/venv1/Scripts/Activate.ps1 @@ -0,0 +1,384 @@ +<# +.Synopsis +Activate a Python virtual environment for the current PowerShell session. + +.Description +Pushes the python executable for a virtual environment to the front of the +$Env:PATH environment variable and sets the prompt to signify that you are +in a Python virtual environment. Makes use of the command line switches as +well as the `pyvenv.cfg` file values present in the virtual environment. + +.Parameter VenvDir +Path to the directory that contains the virtual environment to activate. The +default value for this is the parent of the directory that the Activate.ps1 +script is located within. + +.Parameter Prompt +The prompt prefix to display when this virtual environment is activated. By +default, this prompt is the name of the virtual environment folder (VenvDir) +surrounded by parentheses and followed by a single space (ie. '(.venv) '). + +.Example +Activate.ps1 +Activates the Python virtual environment that contains the Activate.ps1 script. + +.Example +Activate.ps1 -Verbose +Activates the Python virtual environment that contains the Activate.ps1 script, +and shows extra information about the activation as it executes. + +.Example +Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv +Activates the Python virtual environment located in the specified location. + +.Example +Activate.ps1 -Prompt "MyPython" +Activates the Python virtual environment that contains the Activate.ps1 script, +and prefixes the current prompt with the specified string (surrounded in +parentheses) while the virtual environment is active. + +.Notes +On Windows, it may be required to enable this Activate.ps1 script by setting the +execution policy for the user. You can do this by issuing the following PowerShell +command: + +PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + +For more information on Execution Policies: +https://go.microsoft.com/fwlink/?LinkID=135170 + +#> +Param( + [Parameter(Mandatory = $false)] + [String] + $VenvDir, + [Parameter(Mandatory = $false)] + [String] + $Prompt +) + +<# Function declarations --------------------------------------------------- #> + +<# +.Synopsis +Remove all shell session elements added by the Activate script, including the +addition of the virtual environment's Python executable from the beginning of +the PATH variable. + +.Parameter NonDestructive +If present, do not remove this function from the global namespace for the +session. + +#> +function global:deactivate ([switch]$NonDestructive) { + # Revert to original values + + # The prior prompt: + if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { + Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt + Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT + } + + # The prior PYTHONHOME: + if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { + Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME + Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME + } + + # The prior PATH: + if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { + Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH + Remove-Item -Path Env:_OLD_VIRTUAL_PATH + } + + # Just remove the VIRTUAL_ENV altogether: + if (Test-Path -Path Env:VIRTUAL_ENV) { + Remove-Item -Path env:VIRTUAL_ENV + } + + # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: + if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { + Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force + } + + # Leave deactivate function in the global namespace if requested: + if (-not $NonDestructive) { + Remove-Item -Path function:deactivate + } +} + +<# +.Description +Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the +given folder, and returns them in a map. + +For each line in the pyvenv.cfg file, if that line can be parsed into exactly +two strings separated by `=` (with any amount of whitespace surrounding the =) +then it is considered a `key = value` line. The left hand string is the key, +the right hand is the value. + +If the value starts with a `'` or a `"` then the first and last character is +stripped from the value before being captured. + +.Parameter ConfigDir +Path to the directory that contains the `pyvenv.cfg` file. +#> +function Get-PyVenvConfig( + [String] + $ConfigDir +) { + Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" + + # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). + $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue + + # An empty map will be returned if no config file is found. + $pyvenvConfig = @{ } + + if ($pyvenvConfigPath) { + + Write-Verbose "File exists, parse `key = value` lines" + $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath + + $pyvenvConfigContent | ForEach-Object { + $keyval = $PSItem -split "\s*=\s*", 2 + if ($keyval[0] -and $keyval[1]) { + $val = $keyval[1] + + # Remove extraneous quotations around a string value. + if ("'""".Contains($val.Substring(0, 1))) { + $val = $val.Substring(1, $val.Length - 2) + } + + $pyvenvConfig[$keyval[0]] = $val + Write-Verbose "Adding Key: '$($keyval[0])'='$val'" + } + } + } + return $pyvenvConfig +} + + +<# Begin Activate script --------------------------------------------------- #> + +# Determine the containing directory of this script +$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition +$VenvExecDir = Get-Item -Path $VenvExecPath + +Write-Verbose "Activation script is located in path: '$VenvExecPath'" +Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" +Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" + +# Set values required in priority: CmdLine, ConfigFile, Default +# First, get the location of the virtual environment, it might not be +# VenvExecDir if specified on the command line. +if ($VenvDir) { + Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" +} +else { + Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." + $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") + Write-Verbose "VenvDir=$VenvDir" +} + +# Next, read the `pyvenv.cfg` file to determine any required value such +# as `prompt`. +$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir + +# Next, set the prompt from the command line, or the config file, or +# just use the name of the virtual environment folder. +if ($Prompt) { + Write-Verbose "Prompt specified as argument, using '$Prompt'" +} +else { + Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" + if ($pyvenvCfg -and $pyvenvCfg['prompt']) { + Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" + $Prompt = $pyvenvCfg['prompt']; + } + else { + Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virutal environment)" + Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" + $Prompt = Split-Path -Path $venvDir -Leaf + } +} + +Write-Verbose "Prompt = '$Prompt'" +Write-Verbose "VenvDir='$VenvDir'" + +# Deactivate any currently active virtual environment, but leave the +# deactivate function in place. +deactivate -nondestructive + +# Now set the environment variable VIRTUAL_ENV, used by many tools to determine +# that there is an activated venv. +$env:VIRTUAL_ENV = $VenvDir + +if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { + + Write-Verbose "Setting prompt to '$Prompt'" + + # Set the prompt to include the env name + # Make sure _OLD_VIRTUAL_PROMPT is global + function global:_OLD_VIRTUAL_PROMPT { "" } + Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT + New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt + + function global:prompt { + Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " + _OLD_VIRTUAL_PROMPT + } +} + +# Clear PYTHONHOME +if (Test-Path -Path Env:PYTHONHOME) { + Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME + Remove-Item -Path Env:PYTHONHOME +} + +# Add the venv to the PATH +Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH +$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" + +# SIG # Begin signature block +# MIIaHgYJKoZIhvcNAQcCoIIaDzCCGgsCAQExDzANBglghkgBZQMEAgEFADB5Bgor +# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG +# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAwnDYwEHaCQq0n +# 8NAvsN7H7BO7/48rXCNwrg891FS5vaCCFBgwggPuMIIDV6ADAgECAhB+k+v7fMZO +# WepLmnfUBvw7MA0GCSqGSIb3DQEBBQUAMIGLMQswCQYDVQQGEwJaQTEVMBMGA1UE +# CBMMV2VzdGVybiBDYXBlMRQwEgYDVQQHEwtEdXJiYW52aWxsZTEPMA0GA1UEChMG +# VGhhd3RlMR0wGwYDVQQLExRUaGF3dGUgQ2VydGlmaWNhdGlvbjEfMB0GA1UEAxMW +# VGhhd3RlIFRpbWVzdGFtcGluZyBDQTAeFw0xMjEyMjEwMDAwMDBaFw0yMDEyMzAy +# MzU5NTlaMF4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3Jh +# dGlvbjEwMC4GA1UEAxMnU3ltYW50ZWMgVGltZSBTdGFtcGluZyBTZXJ2aWNlcyBD +# QSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsayzSVRLlxwS +# CtgleZEiVypv3LgmxENza8K/LlBa+xTCdo5DASVDtKHiRfTot3vDdMwi17SUAAL3 +# Te2/tLdEJGvNX0U70UTOQxJzF4KLabQry5kerHIbJk1xH7Ex3ftRYQJTpqr1SSwF +# eEWlL4nO55nn/oziVz89xpLcSvh7M+R5CvvwdYhBnP/FA1GZqtdsn5Nph2Upg4XC +# YBTEyMk7FNrAgfAfDXTekiKryvf7dHwn5vdKG3+nw54trorqpuaqJxZ9YfeYcRG8 +# 4lChS+Vd+uUOpyyfqmUg09iW6Mh8pU5IRP8Z4kQHkgvXaISAXWp4ZEXNYEZ+VMET +# fMV58cnBcQIDAQABo4H6MIH3MB0GA1UdDgQWBBRfmvVuXMzMdJrU3X3vP9vsTIAu +# 3TAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnRoYXd0 +# ZS5jb20wEgYDVR0TAQH/BAgwBgEB/wIBADA/BgNVHR8EODA2MDSgMqAwhi5odHRw +# Oi8vY3JsLnRoYXd0ZS5jb20vVGhhd3RlVGltZXN0YW1waW5nQ0EuY3JsMBMGA1Ud +# JQQMMAoGCCsGAQUFBwMIMA4GA1UdDwEB/wQEAwIBBjAoBgNVHREEITAfpB0wGzEZ +# MBcGA1UEAxMQVGltZVN0YW1wLTIwNDgtMTANBgkqhkiG9w0BAQUFAAOBgQADCZuP +# ee9/WTCq72i1+uMJHbtPggZdN1+mUp8WjeockglEbvVt61h8MOj5aY0jcwsSb0ep +# rjkR+Cqxm7Aaw47rWZYArc4MTbLQMaYIXCp6/OJ6HVdMqGUY6XlAYiWWbsfHN2qD +# IQiOQerd2Vc/HXdJhyoWBl6mOGoiEqNRGYN+tjCCBKMwggOLoAMCAQICEA7P9DjI +# /r81bgTYapgbGlAwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxHTAbBgNV +# BAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMTAwLgYDVQQDEydTeW1hbnRlYyBUaW1l +# IFN0YW1waW5nIFNlcnZpY2VzIENBIC0gRzIwHhcNMTIxMDE4MDAwMDAwWhcNMjAx +# MjI5MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29y +# cG9yYXRpb24xNDAyBgNVBAMTK1N5bWFudGVjIFRpbWUgU3RhbXBpbmcgU2Vydmlj +# ZXMgU2lnbmVyIC0gRzQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCi +# Yws5RLi7I6dESbsO/6HwYQpTk7CY260sD0rFbv+GPFNVDxXOBD8r/amWltm+YXkL +# W8lMhnbl4ENLIpXuwitDwZ/YaLSOQE/uhTi5EcUj8mRY8BUyb05Xoa6IpALXKh7N +# S+HdY9UXiTJbsF6ZWqidKFAOF+6W22E7RVEdzxJWC5JH/Kuu9mY9R6xwcueS51/N +# ELnEg2SUGb0lgOHo0iKl0LoCeqF3k1tlw+4XdLxBhircCEyMkoyRLZ53RB9o1qh0 +# d9sOWzKLVoszvdljyEmdOsXF6jML0vGjG/SLvtmzV4s73gSneiKyJK4ux3DFvk6D +# Jgj7C72pT5kI4RAocqrNAgMBAAGjggFXMIIBUzAMBgNVHRMBAf8EAjAAMBYGA1Ud +# JQEB/wQMMAoGCCsGAQUFBwMIMA4GA1UdDwEB/wQEAwIHgDBzBggrBgEFBQcBAQRn +# MGUwKgYIKwYBBQUHMAGGHmh0dHA6Ly90cy1vY3NwLndzLnN5bWFudGVjLmNvbTA3 +# BggrBgEFBQcwAoYraHR0cDovL3RzLWFpYS53cy5zeW1hbnRlYy5jb20vdHNzLWNh +# LWcyLmNlcjA8BgNVHR8ENTAzMDGgL6AthitodHRwOi8vdHMtY3JsLndzLnN5bWFu +# dGVjLmNvbS90c3MtY2EtZzIuY3JsMCgGA1UdEQQhMB+kHTAbMRkwFwYDVQQDExBU +# aW1lU3RhbXAtMjA0OC0yMB0GA1UdDgQWBBRGxmmjDkoUHtVM2lJjFz9eNrwN5jAf +# BgNVHSMEGDAWgBRfmvVuXMzMdJrU3X3vP9vsTIAu3TANBgkqhkiG9w0BAQUFAAOC +# AQEAeDu0kSoATPCPYjA3eKOEJwdvGLLeJdyg1JQDqoZOJZ+aQAMc3c7jecshaAba +# tjK0bb/0LCZjM+RJZG0N5sNnDvcFpDVsfIkWxumy37Lp3SDGcQ/NlXTctlzevTcf +# Q3jmeLXNKAQgo6rxS8SIKZEOgNER/N1cdm5PXg5FRkFuDbDqOJqxOtoJcRD8HHm0 +# gHusafT9nLYMFivxf1sJPZtb4hbKE4FtAC44DagpjyzhsvRaqQGvFZwsL0kb2yK7 +# w/54lFHDhrGCiF3wPbRRoXkzKy57udwgCRNx62oZW8/opTBXLIlJP7nPf8m/PiJo +# Y1OavWl0rMUdPH+S4MO8HNgEdTCCBTAwggQYoAMCAQICEAQJGBtf1btmdVNDtW+V +# UAgwDQYJKoZIhvcNAQELBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lD +# ZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGln +# aUNlcnQgQXNzdXJlZCBJRCBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAy +# MjEyMDAwMFowcjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ +# MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hB +# MiBBc3N1cmVkIElEIENvZGUgU2lnbmluZyBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +# ggEPADCCAQoCggEBAPjTsxx/DhGvZ3cH0wsxSRnP0PtFmbE620T1f+Wondsy13Hq +# dp0FLreP+pJDwKX5idQ3Gde2qvCchqXYJawOeSg6funRZ9PG+yknx9N7I5TkkSOW +# kHeC+aGEI2YSVDNQdLEoJrskacLCUvIUZ4qJRdQtoaPpiCwgla4cSocI3wz14k1g +# GL6qxLKucDFmM3E+rHCiq85/6XzLkqHlOzEcz+ryCuRXu0q16XTmK/5sy350OTYN +# kO/ktU6kqepqCquE86xnTrXE94zRICUj6whkPlKWwfIPEvTFjg/BougsUfdzvL2F +# sWKDc0GCB+Q4i2pzINAPZHM8np+mM6n9Gd8lk9ECAwEAAaOCAc0wggHJMBIGA1Ud +# EwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUF +# BwMDMHkGCCsGAQUFBwEBBG0wazAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGln +# aWNlcnQuY29tMEMGCCsGAQUFBzAChjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5j +# b20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3J0MIGBBgNVHR8EejB4MDqgOKA2 +# hjRodHRwOi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290 +# Q0EuY3JsMDqgOKA2hjRodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRB +# c3N1cmVkSURSb290Q0EuY3JsME8GA1UdIARIMEYwOAYKYIZIAYb9bAACBDAqMCgG +# CCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAoGCGCGSAGG +# /WwDMB0GA1UdDgQWBBRaxLl7KgqjpepxA8Bg+S32ZXUOWDAfBgNVHSMEGDAWgBRF +# 66Kv9JLLgjEtUYunpyGd823IDzANBgkqhkiG9w0BAQsFAAOCAQEAPuwNWiSz8yLR +# FcgsfCUpdqgdXRwtOhrE7zBh134LYP3DPQ/Er4v97yrfIFU3sOH20ZJ1D1G0bqWO +# WuJeJIFOEKTuP3GOYw4TS63XX0R58zYUBor3nEZOXP+QsRsHDpEV+7qvtVHCjSSu +# JMbHJyqhKSgaOnEoAjwukaPAJRHinBRHoXpoaK+bp1wgXNlxsQyPu6j4xRJon89A +# y0BEpRPw5mQMJQhCMrI2iiQC/i9yfhzXSUWW6Fkd6fp0ZGuy62ZD2rOwjNXpDd32 +# ASDOmTFjPQgaGLOBm0/GkxAG/AeB+ova+YJJ92JuoVP6EpQYhS6SkepobEQysmah +# 5xikmmRR7zCCBkcwggUvoAMCAQICEAM+1e2gZdG4yR38+Spsm9gwDQYJKoZIhvcN +# AQELBQAwcjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcG +# A1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBB +# c3N1cmVkIElEIENvZGUgU2lnbmluZyBDQTAeFw0xODEyMTgwMDAwMDBaFw0yMTEy +# MjIxMjAwMDBaMIGDMQswCQYDVQQGEwJVUzEWMBQGA1UECBMNTmV3IEhhbXBzaGly +# ZTESMBAGA1UEBxMJV29sZmVib3JvMSMwIQYDVQQKExpQeXRob24gU29mdHdhcmUg +# Rm91bmRhdGlvbjEjMCEGA1UEAxMaUHl0aG9uIFNvZnR3YXJlIEZvdW5kYXRpb24w +# ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqvaRLsnW5buglHGWx2sRM +# CMpqt+gflMjw9ZJPphvbE+ig/u8dPiJpVfIvkvN7V/ncnDrtKn67nbh8ld/fSodW +# IRbG6bLZFYbSdyJTZ36YyrOOVoBZJk0XS7hFy/IMmiQRXRFQ6ojkIbnM8jdb25Do +# uJSTccJhbqSkfXvsDlPenD8+jw7woSskafVqdqq0ggKr33JLGsxp3/aE8wFF/o11 +# qHt/sc+fWCRJJMCh6PK6oXmH4HSojj4krn5Uu/Prn1VNsBYmxhqSTFnFVZikW/gp +# 5BJLCijQPMy+YRGxPM29UExaG706uIk2D5B8WZ/3rNVO73dxn6vvEyltfJ8g4YqE +# cxpG5nyKG5YjHeAj1YcMVfp8EpHz4eWF2RqIERYixdGjL4RBTIrvNSz4Wo6jaxFi +# 21uzwxMX1gMoVnDI+Of1af6AsZ3k1QRXI28P1BUYES03u/Hztt24lQHwXgPKUSwy +# 1lN+PD9q7oCY6ead4rlRypIm7BHJloY2TvLeqPTq63H4dNOoeCL3vlSnF/KvACqS +# i+hkRYFVKm+S7w9WGQFdwuY17owQeUWJoyiIAMB4qZflEVGQ35WuZgZODjNqPF90 +# d4hjxO8t/jy1N+adAl33yB4lC//TU1TL8XG7CoC5ORp7Pk2XUvE/QKlMeGCHM7gV +# EPiK1PbCpOHiOmiPD1BmewIDAQABo4IBxTCCAcEwHwYDVR0jBBgwFoAUWsS5eyoK +# o6XqcQPAYPkt9mV1DlgwHQYDVR0OBBYEFPwqv37Uvqzzgpykz3siATu4jwfyMA4G +# A1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzB3BgNVHR8EcDBuMDWg +# M6Axhi9odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc2hhMi1hc3N1cmVkLWNzLWcx +# LmNybDA1oDOgMYYvaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJl +# ZC1jcy1nMS5jcmwwTAYDVR0gBEUwQzA3BglghkgBhv1sAwEwKjAoBggrBgEFBQcC +# ARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAIBgZngQwBBAEwgYQGCCsG +# AQUFBwEBBHgwdjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29t +# ME4GCCsGAQUFBzAChkJodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNl +# cnRTSEEyQXNzdXJlZElEQ29kZVNpZ25pbmdDQS5jcnQwDAYDVR0TAQH/BAIwADAN +# BgkqhkiG9w0BAQsFAAOCAQEAS3WhLbVfRrGJp8+PJj6+ViqNYq5S79gW5hYgSrqJ +# FFoVps0OGP1EEVAX9omITmaytAQ58APr/qBVIf3WVlYGqDo0R4b1P1JduIA+8n0I +# RYWx2RdSuNtaG8Ke5nuSpS5TkEC6YjVBFuliBkvdQD6JleSaNsaHWWfytSFYjFsF +# gvhKDaeqkHjinsJQViQ+P8xvBTaC8FXaleOPlZqyShm2wAIy/mDjYE2hUuhECL56 +# /qzTs8634m0dEibzuVPK5zzCHSzBM9TCSwpstTVl2P0Kmq3Nee5UTTDnR7Em9FIr +# dW3iD7S+KCkjeo+YN2mR/37gy/LRcw1yqu2HDbRH4+QiUzGCBVwwggVYAgEBMIGG +# MHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsT +# EHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJl +# ZCBJRCBDb2RlIFNpZ25pbmcgQ0ECEAM+1e2gZdG4yR38+Spsm9gwDQYJYIZIAWUD +# BAIBBQCggZgwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIB +# CzEOMAwGCisGAQQBgjcCARUwLAYKKwYBBAGCNwIBDDEeMBygGoAYAFAAeQB0AGgA +# bwBuACAAMwAuADkALgAwMC8GCSqGSIb3DQEJBDEiBCAGueLiZxG/uwwkezGlE6NG +# ik7PbC5BWsmef6UPtfvL6DANBgkqhkiG9w0BAQEFAASCAgCmlnDsuHhfTf6Nrazl +# nJs0izDY16fS2h6UJ0ihdy48JIUQAWSVIcvnYtkZ42IYgT3JIHalcv6qPQIElpaL +# CCeR1HWT2qQLLJbQxQv3J0gzffrJkn+1u5FB3y9WCpQLS7PhfItXlZhWMjpbLNIU +# miJ0xstY/jyzY1Kt9HyF6ZXqo3BMSCV6mbZLXxlanNAuptxbJEzqOenNL0IQ2Vx8 +# 3UlBnqGnRfkyB9TjF73SHCiF44V3PDOo/HIxzM43v6H3Qznn5pdVYUf8w02k+jFS +# jXRflnKZDd95PVNTGXUGpr2fE1rQcK+a09NkyXtKQQizKPauZ1oHjksV0GvN4h5z +# Vg0wYJN+akYzCPY7q+tL4hDmPxXgmZgBifqyDT/5g6FamNsjmAvhCAeqkWNhq/qb +# ecRPBDI6p3N1cFAEQmMsswN4cpK7tmG4mOKjJozc+yn2K7e67amJc6rI1FFJ4Z6Q +# bbMK6wDWw4hr0FZu/UuTr151m3gFXuRWQmE2z8seKT/CS/Qu+FPwPdB0Y4KJrdzu +# i5xWtlAfO53Bbvj0zI+f+MU5MBSw/uz/N/UltMDRGEz1NxiXDyxI9dzZwLItm7LC +# f6fAlTN2I8c/FJ0mVRysli1clwuggdqOMTsjyBxTANXaxMg3O7BkbZVt2MFASnuF +# TjoSqcY1rryaCs3Tr5dXnIIDaKGCAgswggIHBgkqhkiG9w0BCQYxggH4MIIB9AIB +# ATByMF4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlv +# bjEwMC4GA1UEAxMnU3ltYW50ZWMgVGltZSBTdGFtcGluZyBTZXJ2aWNlcyBDQSAt +# IEcyAhAOz/Q4yP6/NW4E2GqYGxpQMAkGBSsOAwIaBQCgXTAYBgkqhkiG9w0BCQMx +# CwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0yMDEwMDUxNTQ1MjlaMCMGCSqG +# SIb3DQEJBDEWBBRra0P9KGMrllTs7BUKY5/9M2+k5DANBgkqhkiG9w0BAQEFAASC +# AQBjfGRZMDtH8pawNQ1Go21uB4YZ34oTDuo0/aYGPVBORJhMtFseh+oMPSbw1PZq +# pzA0ZmKU2GXLyC2pRRiScVG3bV7Maeq8jZq95dZpzGG4vlfhAfb1u/d6NTTq4+53 +# 5zVqwmsCJeSvOymE18MiM+eC9JVYK6OR8km2d0/lqi+q+/4L/4XkpxS7z+2FwpnS +# 1/HgIbgsvojt8viDjpfc0vkiWS8bymyTokFwhES4v2YGI+FqXbWdAeQR+rAlKVtd +# /slNskA83aeom7iz6jc3sQs2frWt3Rrxux2YSREFEY0508ZzlI0iTLLpflVaewxg +# VbwCut7qb3zyI8S5Sl4milVC +# SIG # End signature block diff --git a/venv1/Scripts/activate b/venv1/Scripts/activate new file mode 100644 index 0000000..ab38ddb --- /dev/null +++ b/venv1/Scripts/activate @@ -0,0 +1,66 @@ +# This file must be used with "source bin/activate" *from bash* +# you cannot run it directly + +deactivate () { + # reset old environment variables + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then + PATH="${_OLD_VIRTUAL_PATH:-}" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # This should detect bash and zsh, which have a hash command that must + # be called to get it to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r 2> /dev/null + fi + + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then + PS1="${_OLD_VIRTUAL_PS1:-}" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + if [ ! "${1:-}" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +VIRTUAL_ENV="C:\Users\Admin\Documents\IMT Atlantique\UE -Conteneurisation-\Séance 1\UE-AD-A1-REST\venv1" +export VIRTUAL_ENV + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/Scripts:$PATH" +export PATH + +# unset PYTHONHOME if set +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) +# could use `if (set -u; : $PYTHONHOME) ;` in bash +if [ -n "${PYTHONHOME:-}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1:-}" + PS1="(venv1) ${PS1:-}" + export PS1 +fi + +# This should detect bash and zsh, which have a hash command that must +# be called to get it to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r 2> /dev/null +fi diff --git a/venv1/Scripts/activate.bat b/venv1/Scripts/activate.bat new file mode 100644 index 0000000..9a459d3 --- /dev/null +++ b/venv1/Scripts/activate.bat @@ -0,0 +1,33 @@ +@echo off + +rem This file is UTF-8 encoded, so we need to update the current code page while executing it +for /f "tokens=2 delims=:." %%a in ('"%SystemRoot%\System32\chcp.com"') do ( + set _OLD_CODEPAGE=%%a +) +if defined _OLD_CODEPAGE ( + "%SystemRoot%\System32\chcp.com" 65001 > nul +) + +set VIRTUAL_ENV=C:\Users\Admin\Documents\IMT Atlantique\UE -Conteneurisation-\Séance 1\UE-AD-A1-REST\venv1 + +if not defined PROMPT set PROMPT=$P$G + +if defined _OLD_VIRTUAL_PROMPT set PROMPT=%_OLD_VIRTUAL_PROMPT% +if defined _OLD_VIRTUAL_PYTHONHOME set PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME% + +set _OLD_VIRTUAL_PROMPT=%PROMPT% +set PROMPT=(venv1) %PROMPT% + +if defined PYTHONHOME set _OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME% +set PYTHONHOME= + +if defined _OLD_VIRTUAL_PATH set PATH=%_OLD_VIRTUAL_PATH% +if not defined _OLD_VIRTUAL_PATH set _OLD_VIRTUAL_PATH=%PATH% + +set PATH=%VIRTUAL_ENV%\Scripts;%PATH% + +:END +if defined _OLD_CODEPAGE ( + "%SystemRoot%\System32\chcp.com" %_OLD_CODEPAGE% > nul + set _OLD_CODEPAGE= +) diff --git a/venv1/Scripts/deactivate.bat b/venv1/Scripts/deactivate.bat new file mode 100644 index 0000000..1205c61 --- /dev/null +++ b/venv1/Scripts/deactivate.bat @@ -0,0 +1,21 @@ +@echo off + +if defined _OLD_VIRTUAL_PROMPT ( + set "PROMPT=%_OLD_VIRTUAL_PROMPT%" +) +set _OLD_VIRTUAL_PROMPT= + +if defined _OLD_VIRTUAL_PYTHONHOME ( + set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%" + set _OLD_VIRTUAL_PYTHONHOME= +) + +if defined _OLD_VIRTUAL_PATH ( + set "PATH=%_OLD_VIRTUAL_PATH%" +) + +set _OLD_VIRTUAL_PATH= + +set VIRTUAL_ENV= + +:END diff --git a/venv1/Scripts/easy_install-3.9.exe b/venv1/Scripts/easy_install-3.9.exe new file mode 100644 index 0000000..ad5ba1d Binary files /dev/null and b/venv1/Scripts/easy_install-3.9.exe differ diff --git a/venv1/Scripts/easy_install.exe b/venv1/Scripts/easy_install.exe new file mode 100644 index 0000000..ad5ba1d Binary files /dev/null and b/venv1/Scripts/easy_install.exe differ diff --git a/venv1/Scripts/flask.exe b/venv1/Scripts/flask.exe new file mode 100644 index 0000000..e0b25d0 Binary files /dev/null and b/venv1/Scripts/flask.exe differ diff --git a/venv1/Scripts/normalizer.exe b/venv1/Scripts/normalizer.exe new file mode 100644 index 0000000..18c1dfa Binary files /dev/null and b/venv1/Scripts/normalizer.exe differ diff --git a/venv1/Scripts/pip.exe b/venv1/Scripts/pip.exe new file mode 100644 index 0000000..4f3afee Binary files /dev/null and b/venv1/Scripts/pip.exe differ diff --git a/venv1/Scripts/pip3.9.exe b/venv1/Scripts/pip3.9.exe new file mode 100644 index 0000000..4f3afee Binary files /dev/null and b/venv1/Scripts/pip3.9.exe differ diff --git a/venv1/Scripts/pip3.exe b/venv1/Scripts/pip3.exe new file mode 100644 index 0000000..4f3afee Binary files /dev/null and b/venv1/Scripts/pip3.exe differ diff --git a/venv1/Scripts/pymon.exe b/venv1/Scripts/pymon.exe new file mode 100644 index 0000000..c792127 Binary files /dev/null and b/venv1/Scripts/pymon.exe differ diff --git a/venv1/Scripts/python.exe b/venv1/Scripts/python.exe new file mode 100644 index 0000000..0fd3d48 Binary files /dev/null and b/venv1/Scripts/python.exe differ diff --git a/venv1/Scripts/pythonw.exe b/venv1/Scripts/pythonw.exe new file mode 100644 index 0000000..297a6a1 Binary files /dev/null and b/venv1/Scripts/pythonw.exe differ diff --git a/venv1/Scripts/watchmedo.exe b/venv1/Scripts/watchmedo.exe new file mode 100644 index 0000000..d1b7333 Binary files /dev/null and b/venv1/Scripts/watchmedo.exe differ diff --git a/venv1/pyvenv.cfg b/venv1/pyvenv.cfg new file mode 100644 index 0000000..6bf242a --- /dev/null +++ b/venv1/pyvenv.cfg @@ -0,0 +1,3 @@ +home = C:\Users\Admin\AppData\Local\Programs\Python\Python39 +include-system-site-packages = false +version = 3.9.0